* [PATCH 5/5] net: ethernet: mtk_eth_mac: use devm_register_netdev()
From: Bartosz Golaszewski @ 2020-05-20 11:44 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger, John Crispin,
Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann, Fabien Parent,
Heiner Kallweit, Edwin Peer
Cc: devicetree, linux-kernel, netdev, linux-arm-kernel,
linux-mediatek, Stephane Le Provost, Pedro Tsai, Andrew Perepech,
Bartosz Golaszewski
In-Reply-To: <20200520114415.13041-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Use the new devres variant of register_netdev() in the mtk-eth-mac
driver and shrink the code by a couple lines.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/net/ethernet/mediatek/mtk_eth_mac.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_mac.c b/drivers/net/ethernet/mediatek/mtk_eth_mac.c
index 4dfe7c2c4e3d..2919ce27efeb 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_mac.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_mac.c
@@ -1513,13 +1513,6 @@ static void mtk_mac_clk_disable_unprepare(void *data)
clk_bulk_disable_unprepare(MTK_MAC_NCLKS, priv->clks);
}
-static void mtk_mac_unregister_netdev(void *data)
-{
- struct net_device *ndev = data;
-
- unregister_netdev(ndev);
-}
-
static int mtk_mac_probe(struct platform_device *pdev)
{
struct device_node *of_node;
@@ -1631,15 +1624,7 @@ static int mtk_mac_probe(struct platform_device *pdev)
netif_napi_add(ndev, &priv->napi, mtk_mac_poll, MTK_MAC_NAPI_WEIGHT);
- ret = register_netdev(ndev);
- if (ret)
- return ret;
-
- ret = devm_add_action_or_reset(dev, mtk_mac_unregister_netdev, ndev);
- if (ret)
- return ret;
-
- return 0;
+ return devm_register_netdev(dev, ndev);
}
static const struct of_device_id mtk_mac_of_match[] = {
--
2.25.0
^ permalink raw reply related
* [PATCH v9 1/2] PCI: Microchip: Add host driver for Microchip PCIe controller
From: Daire.McNamara @ 2020-05-20 11:44 UTC (permalink / raw)
To: amurray, lorenzo.pieralisi, linux-pci, bhelgaas, robh-dt,
devicetree
This patch adds device tree bindings for the Microchip
PCIe PolarFire PCIe controller when configured in
host (Root Complex) mode.
Signed-off-by: Daire McNamara <daire.mcnamara@microchip.com>
---
.../bindings/pci/microchip,pcie-host.yaml | 94 +++++++++++++++++++
1 file changed, 94 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
new file mode 100644
index 000000000000..d3bcdab282c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/microchip,pcie-host.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip PCIe Root Port Bridge Controller
+
+maintainers:
+ - Daire McNamara <daire.mcnamara@microchip.com>
+
+allOf:
+ - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+ compatible:
+ const: microchip,pcie-host-1.0 # PolarFire
+
+ reg:
+ maxItems: 2
+
+ reg-names:
+ items:
+ - const: cfg
+ - const: apb
+
+ interrupts:
+ minItems: 1
+ maxItems: 1
+ items:
+ - description: PCIe host controller and builtin MSI controller
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 1
+ items:
+ - const: pcie/msi
+
+ ranges:
+ maxItems: 1
+
+ dma-ranges:
+ maxItems: 1
+
+ msi-controller:
+ description: Identifies the node as an MSI controller.
+
+ msi-parent:
+ description: MSI controller the device is capable of using.
+
+required:
+ - reg
+ - reg-names
+ - dma-ranges
+ - "#interrupt-cells"
+ - interrupts
+ - interrupt-names
+ - interrupt-map-mask
+ - interrupt-map
+ - msi-controller
+
+examples:
+ - |
+ soc {
+ pcie0: pcie@2030000000 {
+ #address-cells = <0x3>;
+ #interrupt-cells = <0x1>;
+ #size-cells = <0x2>;
+ compatible = "microchip,pcie-host-1.0";
+ device_type = "pci";
+ bus-range = <0x00 0x7f>;
+ // PCI_DEVICE(3) INT#(1) CONTROLLER(PHANDLE) CONTROLLER_DATA(1)
+ interrupt-map = <0 0 0 1 &pcie0 0>,
+ <0 0 0 2 &pcie0 1>,
+ <0 0 0 3 &pcie0 2>,
+ <0 0 0 4 &pcie0 3>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-parent = <&plic0>;
+ interrupts = <32>;
+
+ // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2)
+ ranges = <0x03000000 0x0 0x40000000 0x0 0x40000000 0x0 0x20000000>;
+ dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000 0x1 0x00000000>;
+
+ // CPU_PHYSICAL(2) SIZE(2)
+ reg = <0x20 0x30000000 0x0 0x4000000>,
+ <0x20 0x0 0x0 0x100000>;
+ reg-names = "cfg", "apb";
+ msi-parent = <&pcie0>;
+ msi-controller;
+ interrupt-controller;
+ };
+ };
+...
--
2.17.1
^ permalink raw reply related
* [PATCH 3/5] net: devres: define a separate devres structure for devm_alloc_etherdev()
From: Bartosz Golaszewski @ 2020-05-20 11:44 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger, John Crispin,
Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann, Fabien Parent,
Heiner Kallweit, Edwin Peer
Cc: devicetree, linux-kernel, netdev, linux-arm-kernel,
linux-mediatek, Stephane Le Provost, Pedro Tsai, Andrew Perepech,
Bartosz Golaszewski
In-Reply-To: <20200520114415.13041-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Not using a proxy structure to store struct net_device doesn't save
anything in terms of compiled code size or memory usage but significantly
decreases the readability of the code with all the pointer casting.
Define struct net_device_devres and use it in devm_alloc_etherdev_mqs().
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
net/devres.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/net/devres.c b/net/devres.c
index c1465d9f9019..b97b0c5a8216 100644
--- a/net/devres.c
+++ b/net/devres.c
@@ -7,30 +7,34 @@
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
-static void devm_free_netdev(struct device *dev, void *res)
+struct net_device_devres {
+ struct net_device *ndev;
+};
+
+static void devm_free_netdev(struct device *dev, void *this)
{
- free_netdev(*(struct net_device **)res);
+ struct net_device_devres *res = this;
+
+ free_netdev(res->ndev);
}
struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
unsigned int txqs, unsigned int rxqs)
{
- struct net_device **dr;
- struct net_device *netdev;
+ struct net_device_devres *dr;
dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
if (!dr)
return NULL;
- netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
- if (!netdev) {
+ dr->ndev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
+ if (!dr->ndev) {
devres_free(dr);
return NULL;
}
- *dr = netdev;
devres_add(dev, dr);
- return netdev;
+ return dr->ndev;
}
EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
--
2.25.0
^ permalink raw reply related
* [PATCH 2/5] net: move devres helpers into a separate source file
From: Bartosz Golaszewski @ 2020-05-20 11:44 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger, John Crispin,
Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann, Fabien Parent,
Heiner Kallweit, Edwin Peer
Cc: devicetree, linux-kernel, netdev, linux-arm-kernel,
linux-mediatek, Stephane Le Provost, Pedro Tsai, Andrew Perepech,
Bartosz Golaszewski
In-Reply-To: <20200520114415.13041-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
There's currently only a single devres helper in net/ - devm variant
of alloc_etherdev. Let's move it to net/devres.c with the intention of
assing a second one: devm_register_netdev(). This new routine will need
to know the address of the release function of devm_alloc_etherdev() so
that it can verify (using devres_find()) that the struct net_device
that's being passed to it is also resource managed.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
net/Makefile | 2 +-
net/devres.c | 36 ++++++++++++++++++++++++++++++++++++
net/ethernet/eth.c | 28 ----------------------------
3 files changed, 37 insertions(+), 29 deletions(-)
create mode 100644 net/devres.c
diff --git a/net/Makefile b/net/Makefile
index 07ea48160874..5744bf1997fd 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -6,7 +6,7 @@
# Rewritten to use lists instead of if-statements.
#
-obj-$(CONFIG_NET) := socket.o core/
+obj-$(CONFIG_NET) := devres.o socket.o core/
tmp-$(CONFIG_COMPAT) := compat.o
obj-$(CONFIG_NET) += $(tmp-y)
diff --git a/net/devres.c b/net/devres.c
new file mode 100644
index 000000000000..c1465d9f9019
--- /dev/null
+++ b/net/devres.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * This file contains all networking devres helpers.
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+
+static void devm_free_netdev(struct device *dev, void *res)
+{
+ free_netdev(*(struct net_device **)res);
+}
+
+struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
+ unsigned int txqs, unsigned int rxqs)
+{
+ struct net_device **dr;
+ struct net_device *netdev;
+
+ dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return NULL;
+
+ netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
+ if (!netdev) {
+ devres_free(dr);
+ return NULL;
+ }
+
+ *dr = netdev;
+ devres_add(dev, dr);
+
+ return netdev;
+}
+EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index c8b903302ff2..dac65180c4ef 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -400,34 +400,6 @@ struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
}
EXPORT_SYMBOL(alloc_etherdev_mqs);
-static void devm_free_netdev(struct device *dev, void *res)
-{
- free_netdev(*(struct net_device **)res);
-}
-
-struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
- unsigned int txqs, unsigned int rxqs)
-{
- struct net_device **dr;
- struct net_device *netdev;
-
- dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
- if (!dr)
- return NULL;
-
- netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
- if (!netdev) {
- devres_free(dr);
- return NULL;
- }
-
- *dr = netdev;
- devres_add(dev, dr);
-
- return netdev;
-}
-EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
-
ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len)
{
return scnprintf(buf, PAGE_SIZE, "%*phC\n", len, addr);
--
2.25.0
^ permalink raw reply related
* Subject: [PATCH v9 2/2] PCI: Microchip: Add host driver for Microchip PCIe controller
From: Daire.McNamara @ 2020-05-20 11:46 UTC (permalink / raw)
To: amurray, lorenzo.pieralisi, linux-pci, bhelgaas, robh+dt,
devicetree
This patch adds support for the Microchip PCIe PolarFire PCIe
controller when configured in host (Root Complex) mode.
Signed-off-by: Daire McNamara <daire.mcnamara@microchip.com>
---
drivers/pci/controller/Kconfig | 9 +
drivers/pci/controller/Makefile | 1 +
drivers/pci/controller/pcie-microchip-host.c | 664 +++++++++++++++++++
3 files changed, 674 insertions(+)
create mode 100644 drivers/pci/controller/pcie-microchip-host.c
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 91bfdb784829..5ec760466bd9 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -258,6 +258,15 @@ config PCI_HYPERV_INTERFACE
The Hyper-V PCI Interface is a helper driver allows other drivers to
have a common interface with the Hyper-V PCI frontend driver.
+config PCIE_MICROCHIP_HOST
+ bool "Microchip AXI PCIe host bridge support"
+ depends on PCI_MSI && OF
+ select PCI_MSI_IRQ_DOMAIN
+ select GENERIC_MSI_IRQ_DOMAIN
+ help
+ Say Y here if you want kernel to support the Microchip AXI PCIe
+ Host Bridge driver.
+
source "drivers/pci/controller/dwc/Kconfig"
source "drivers/pci/controller/mobiveil/Kconfig"
source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 158c59771824..416528d8553e 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o
obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
+obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
obj-$(CONFIG_VMD) += vmd.o
obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c
new file mode 100644
index 000000000000..bdea416aff79
--- /dev/null
+++ b/drivers/pci/controller/pcie-microchip-host.c
@@ -0,0 +1,664 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Microchip AXI PCIe Bridge host controller driver
+ *
+ * Copyright (c) 2018 - 2019 Microchip Corporation. All rights reserved.
+ *
+ * Author: Daire McNamara <daire.mcnamara@microchip.com>
+ *
+ * Based on:
+ * pcie-rcar.c
+ * pcie-xilinx.c
+ * pcie-altera.c
+ */
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci-ecam.h>
+#include <linux/platform_device.h>
+
+#include "../pci.h"
+
+/* Number of MSI IRQs */
+#define MC_NUM_MSI_IRQS 32
+#define MC_NUM_MSI_IRQS_CODED 5
+
+/* PCIe Bridge Phy and Controller Phy offsets */
+#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
+#define MC_PCIE1_CTRL_ADDR 0x0000a000u
+
+/* PCIe Controller Phy Regs */
+#define MC_SEC_ERROR_INT 0x28
+#define SEC_ERROR_INT_TX_RAM_SEC_ERR_INT GENMASK(3, 0)
+#define SEC_ERROR_INT_RX_RAM_SEC_ERR_INT GENMASK(7, 4)
+#define SEC_ERROR_INT_PCIE2AXI_RAM_SEC_ERR_INT GENMASK(11, 8)
+#define SEC_ERROR_INT_AXI2PCIE_RAM_SEC_ERR_INT GENMASK(15, 12)
+#define MC_SEC_ERROR_INT_MASK 0x2c
+#define MC_DED_ERROR_INT 0x30
+#define DED_ERROR_INT_TX_RAM_DED_ERR_INT GENMASK(3, 0)
+#define DED_ERROR_INT_RX_RAM_DED_ERR_INT GENMASK(7, 4)
+#define DED_ERROR_INT_PCIE2AXI_RAM_DED_ERR_INT GENMASK(11, 8)
+#define DED_ERROR_INT_AXI2PCIE_RAM_DED_ERR_INT GENMASK(15, 12)
+#define MC_DED_ERROR_INT_MASK 0x34
+#define MC_ECC_CONTROL 0x38
+#define ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS BIT(27)
+#define ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS BIT(26)
+#define ECC_CONTROL_RX_RAM_ECC_BYPASS BIT(25)
+#define ECC_CONTROL_TX_RAM_ECC_BYPASS BIT(24)
+#define MC_LTSSM_STATE 0x5c
+#define LTSSM_L0_STATE 0x10
+#define MC_PCIE_EVENT_INT 0x14c
+#define PCIE_EVENT_INT_L2_EXIT_INT BIT(0)
+#define PCIE_EVENT_INT_HOTRST_EXIT_INT BIT(1)
+#define PCIE_EVENT_INT_DLUP_EXIT_INT BIT(2)
+#define PCIE_EVENT_INT_L2_EXIT_INT_MASK BIT(16)
+#define PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK BIT(17)
+#define PCIE_EVENT_INT_DLUP_EXIT_INT_MASK BIT(18)
+
+/* PCIe Bridge Phy Regs */
+#define MC_PCIE_PCI_IDS_DW1 0x9c
+
+/* PCIe Config space MSI capability structure */
+#define MC_MSI_CAP_CTRL 0xe0u
+#define MSI_ENABLE (0x01u << 16)
+#define MSI_CAP_MULTI (MC_NUM_MSI_IRQS_CODED << 17)
+#define MSI_ENABLE_MULTI (MC_NUM_MSI_IRQS_CODED << 20)
+#define MC_MSI_MSG_LO_ADDR 0xe4u
+#define MC_MSI_MSG_HI_ADDR 0xe8u
+#define MC_MSI_MSG_DATA 0xf0u
+
+#define MC_IMASK_LOCAL 0x180
+#define PCIE_LOCAL_INT_ENABLE 0x0f000000u
+#define PCI_INTS 0x0f000000u
+#define PM_MSI_INT_SHIFT 24
+#define PCIE_ENABLE_MSI 0x10000000u
+#define MSI_INT 0x10000000u
+#define MSI_INT_SHIFT 28
+#define MC_ISTATUS_LOCAL 0x184
+#define MC_IMASK_HOST 0x188
+#define MC_ISTATUS_HOST 0x18c
+#define MC_MSI_ADDR 0x190
+#define MC_ISTATUS_MSI 0x194
+
+/* PCIe Master table init defines */
+#define MC_ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+#define ATR0_PCIE_ATR_SIZE 0x1f
+#define ATR0_PCIE_ATR_SIZE_SHIFT 1
+#define MC_ATR0_PCIE_WIN0_SRC_ADDR 0x604u
+#define MC_ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
+#define MC_ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
+#define MC_ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
+
+/* PCIe AXI slave table init defines */
+#define MC_ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
+#define ATR_SIZE_SHIFT 1
+#define ATR_IMPL_ENABLE 1
+#define MC_ATR0_AXI4_SLV0_SRC_ADDR 0x804u
+#define MC_ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
+#define MC_ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
+#define MC_ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
+#define PCIE_TX_RX_INTERFACE 0x00000000u
+#define PCIE_CONFIG_INTERFACE 0x00000001u
+
+#define ATT_ENTRY_SIZE 32
+
+struct mc_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+ struct irq_domain *dev_domain;
+ u32 num_vectors;
+ u64 vector_phy;
+ DECLARE_BITMAP(used, MC_NUM_MSI_IRQS);
+};
+
+struct mc_pcie {
+ struct platform_device *pdev;
+ void __iomem *cfg_base_addr;
+ void __iomem *bridge_base_addr;
+ void __iomem *ctrl_base_addr;
+ u64 cfghw_base_addr;
+ u64 cfg_size;
+ u32 atr_sz;
+ u32 irq;
+ struct irq_domain *intx_domain;
+ raw_spinlock_t intx_mask_lock;
+ struct mc_msi msi;
+};
+
+static inline u32 cfg_readl(struct mc_pcie *pcie, const u32 reg)
+{
+ return readl_relaxed(pcie->cfg_base_addr + reg);
+}
+
+static inline void cfg_writel(struct mc_pcie *pcie, const u32 val,
+ const u32 reg)
+{
+ writel_relaxed(val, pcie->cfg_base_addr + reg);
+}
+
+static void mc_pcie_enable(struct mc_pcie *pcie)
+{
+ u32 enb;
+
+ enb = readl(pcie->bridge_base_addr + MC_LTSSM_STATE);
+ enb |= LTSSM_L0_STATE;
+ writel(enb, pcie->bridge_base_addr + MC_LTSSM_STATE);
+}
+
+static void mc_pcie_isr(struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct mc_pcie *pcie = irq_desc_get_handler_data(desc);
+ struct device *dev = &pcie->pdev->dev;
+ struct mc_msi *msi = &pcie->msi;
+ unsigned long status;
+ unsigned long intx_status;
+ unsigned long msi_status;
+ u32 bit;
+ u32 virq;
+
+ /*
+ * The core provides a single interrupt for both INTx/MSI messages.
+ * So we'll read both INTx and MSI status.
+ */
+ chained_irq_enter(chip, desc);
+
+ status = readl(pcie->bridge_base_addr + MC_ISTATUS_LOCAL);
+ while (status & (PCI_INTS | MSI_INT)) {
+ intx_status = (status & PCI_INTS) >> PM_MSI_INT_SHIFT;
+ for_each_set_bit(bit, &intx_status, PCI_NUM_INTX) {
+ virq = irq_find_mapping(pcie->intx_domain, bit + 1);
+ if (virq)
+ generic_handle_irq(virq);
+ else
+ dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
+ bit);
+
+ /* Clear that interrupt bit */
+ writel(1 << (bit + PM_MSI_INT_SHIFT),
+ pcie->bridge_base_addr + MC_ISTATUS_LOCAL);
+ }
+
+ msi_status = (status & MSI_INT);
+ if (msi_status) {
+ msi_status = readl(pcie->bridge_base_addr +
+ MC_ISTATUS_MSI);
+ for_each_set_bit(bit, &msi_status, msi->num_vectors) {
+ virq = irq_find_mapping(msi->dev_domain, bit);
+ if (virq)
+ generic_handle_irq(virq);
+ else
+ dev_err_ratelimited(dev,
+ "bad MSI IRQ %d\n",
+ bit);
+
+ /* Clear that MSI interrupt bit */
+ writel((1 << bit), pcie->bridge_base_addr +
+ MC_ISTATUS_MSI);
+ }
+ /* Clear the ISTATUS MSI bit */
+ writel(1 << MSI_INT_SHIFT, pcie->bridge_base_addr +
+ MC_ISTATUS_LOCAL);
+ }
+
+ status = readl(pcie->bridge_base_addr + MC_ISTATUS_LOCAL);
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static int mc_pcie_parse_dt(struct mc_pcie *pcie)
+{
+ struct platform_device *pdev = pcie->pdev;
+ struct device *dev = &pcie->pdev->dev;
+ struct mc_msi *msi = &pcie->msi;
+ struct resource *res;
+ void __iomem *axi_base_addr;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ axi_base_addr = devm_ioremap_resource(dev, res);
+ if (IS_ERR(axi_base_addr))
+ return PTR_ERR(axi_base_addr);
+
+ pcie->bridge_base_addr = axi_base_addr + MC_PCIE1_BRIDGE_ADDR;
+ pcie->ctrl_base_addr = axi_base_addr + MC_PCIE1_CTRL_ADDR;
+
+ msi->vector_phy = MC_MSI_ADDR;
+
+ msi->num_vectors = MC_NUM_MSI_IRQS;
+
+ pcie->irq = platform_get_irq(pdev, 0);
+ if (pcie->irq < 0) {
+ dev_err(dev, "unable to request IRQ%d\n", pcie->irq);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void mc_pcie_enable_msi(struct mc_pcie *pcie)
+{
+ struct mc_msi *msi = &pcie->msi;
+ u32 msg_ctrl = cfg_readl(pcie, MC_MSI_CAP_CTRL);
+
+ msg_ctrl |= MSI_ENABLE_MULTI | MSI_CAP_MULTI | MSI_ENABLE;
+ cfg_writel(pcie, msg_ctrl, MC_MSI_CAP_CTRL);
+
+ cfg_writel(pcie, lower_32_bits(msi->vector_phy), MC_MSI_MSG_LO_ADDR);
+ cfg_writel(pcie, upper_32_bits(msi->vector_phy), MC_MSI_MSG_HI_ADDR);
+}
+
+static int mc_host_init(struct mc_pcie *pcie)
+{
+ u32 val;
+
+ mc_pcie_enable(pcie);
+
+ val = ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS |
+ ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
+ ECC_CONTROL_RX_RAM_ECC_BYPASS | ECC_CONTROL_TX_RAM_ECC_BYPASS;
+ writel(val, pcie->ctrl_base_addr + MC_ECC_CONTROL);
+
+ val = PCIE_EVENT_INT_L2_EXIT_INT | PCIE_EVENT_INT_HOTRST_EXIT_INT |
+ PCIE_EVENT_INT_DLUP_EXIT_INT | PCIE_EVENT_INT_L2_EXIT_INT_MASK |
+ PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
+ PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
+ writel(val, pcie->ctrl_base_addr + MC_PCIE_EVENT_INT);
+
+ val = SEC_ERROR_INT_TX_RAM_SEC_ERR_INT |
+ SEC_ERROR_INT_RX_RAM_SEC_ERR_INT |
+ SEC_ERROR_INT_PCIE2AXI_RAM_SEC_ERR_INT |
+ SEC_ERROR_INT_AXI2PCIE_RAM_SEC_ERR_INT;
+ writel(val, pcie->ctrl_base_addr + MC_SEC_ERROR_INT);
+ writel(val, pcie->ctrl_base_addr + MC_SEC_ERROR_INT_MASK);
+
+ val = DED_ERROR_INT_TX_RAM_DED_ERR_INT |
+ DED_ERROR_INT_RX_RAM_DED_ERR_INT |
+ DED_ERROR_INT_PCIE2AXI_RAM_DED_ERR_INT |
+ DED_ERROR_INT_AXI2PCIE_RAM_DED_ERR_INT;
+ writel(val, pcie->ctrl_base_addr + MC_DED_ERROR_INT);
+ writel(val, pcie->ctrl_base_addr + MC_DED_ERROR_INT_MASK);
+
+ writel(0, pcie->bridge_base_addr + MC_IMASK_LOCAL);
+ writel(GENMASK(31, 0), pcie->bridge_base_addr + MC_ISTATUS_LOCAL);
+ writel(0, pcie->bridge_base_addr + MC_IMASK_HOST);
+ writel(GENMASK(31, 0), pcie->bridge_base_addr + MC_ISTATUS_HOST);
+
+ /* Configure Address Translation Table 0 for PCIe config space */
+ writel(PCIE_CONFIG_INTERFACE, pcie->bridge_base_addr +
+ MC_ATR0_AXI4_SLV0_TRSL_PARAM);
+
+ val = lower_32_bits(pcie->cfghw_base_addr) |
+ (pcie->atr_sz << ATR_SIZE_SHIFT) | ATR_IMPL_ENABLE;
+ writel(val, pcie->bridge_base_addr + MC_ATR0_AXI4_SLV0_SRCADDR_PARAM);
+ writel(0, pcie->bridge_base_addr + MC_ATR0_AXI4_SLV0_SRC_ADDR);
+
+ val = lower_32_bits(pcie->cfghw_base_addr);
+ writel(val, pcie->bridge_base_addr + MC_ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
+ val = upper_32_bits(pcie->cfghw_base_addr);
+ writel(val, pcie->bridge_base_addr + MC_ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
+
+ val = readl(pcie->bridge_base_addr + MC_ATR0_PCIE_WIN0_SRCADDR_PARAM);
+ val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
+ writel(val, pcie->bridge_base_addr + MC_ATR0_PCIE_WIN0_SRCADDR_PARAM);
+ writel(0, pcie->bridge_base_addr + MC_ATR0_PCIE_WIN0_SRC_ADDR);
+
+ return 0;
+}
+
+static void mc_mask_intx_irq(struct irq_data *data)
+{
+ struct irq_desc *desc = irq_to_desc(data->irq);
+ struct mc_pcie *pcie;
+ unsigned long flags;
+ u32 mask, val;
+
+ pcie = irq_desc_get_chip_data(desc);
+ mask = PCIE_LOCAL_INT_ENABLE;
+ raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
+ val = readl(pcie->bridge_base_addr + MC_IMASK_LOCAL);
+ val &= ~mask;
+ writel(val, pcie->bridge_base_addr + MC_IMASK_LOCAL);
+ raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
+}
+
+static void mc_unmask_intx_irq(struct irq_data *data)
+{
+ struct irq_desc *desc = irq_to_desc(data->irq);
+ struct mc_pcie *pcie;
+ unsigned long flags;
+ u32 mask, val;
+
+ pcie = irq_desc_get_chip_data(desc);
+ mask = PCIE_LOCAL_INT_ENABLE;
+ raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
+ val = readl(pcie->bridge_base_addr + MC_IMASK_LOCAL);
+ val |= mask;
+ writel(val, pcie->bridge_base_addr + MC_IMASK_LOCAL);
+ raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
+}
+
+static struct irq_chip mc_intx_irq_chip = {
+ .name = "microchip_pcie:intx",
+ .irq_enable = mc_unmask_intx_irq,
+ .irq_disable = mc_mask_intx_irq,
+ .irq_mask = mc_mask_intx_irq,
+ .irq_unmask = mc_unmask_intx_irq,
+};
+
+static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_simple_irq);
+ irq_set_chip_data(irq, domain->host_data);
+
+ return 0;
+}
+
+static const struct irq_domain_ops intx_domain_ops = {
+ .map = mc_pcie_intx_map,
+};
+
+static struct irq_chip mc_msi_irq_chip = {
+ .name = "Microchip PCIe MSI",
+ .irq_mask = pci_msi_mask_irq,
+ .irq_unmask = pci_msi_unmask_irq,
+};
+
+static struct msi_domain_info mc_msi_domain_info = {
+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+ MSI_FLAG_PCI_MSIX),
+ .chip = &mc_msi_irq_chip,
+};
+
+static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+ struct mc_pcie *pcie = irq_data_get_irq_chip_data(data);
+ phys_addr_t addr = pcie->msi.vector_phy;
+
+ msg->address_lo = lower_32_bits(addr);
+ msg->address_hi = upper_32_bits(addr);
+ msg->data = data->hwirq;
+
+ dev_dbg(&pcie->pdev->dev, "msi#%x address_hi %#x address_lo %#x\n",
+ (int)data->hwirq, msg->address_hi, msg->address_lo);
+}
+
+static int mc_msi_set_affinity(struct irq_data *irq_data,
+ const struct cpumask *mask, bool force)
+{
+ return -EINVAL;
+}
+
+static struct irq_chip mc_msi_bottom_irq_chip = {
+ .name = "Microchip MSI",
+ .irq_compose_msi_msg = mc_compose_msi_msg,
+ .irq_set_affinity = mc_msi_set_affinity,
+};
+
+static int mc_irq_msi_domain_alloc(struct irq_domain *domain,
+ unsigned int virq, unsigned int nr_irqs,
+ void *args)
+{
+ struct mc_pcie *pcie = domain->host_data;
+ struct mc_msi *msi = &pcie->msi;
+ unsigned long bit;
+ u32 reg;
+
+ WARN_ON(nr_irqs != 1);
+ mutex_lock(&msi->lock);
+ bit = find_first_zero_bit(msi->used, msi->num_vectors);
+ if (bit >= msi->num_vectors) {
+ mutex_unlock(&msi->lock);
+ return -ENOSPC;
+ }
+
+ set_bit(bit, msi->used);
+ mutex_unlock(&msi->lock);
+
+ irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
+ domain->host_data, handle_simple_irq, NULL, NULL);
+
+ /* Enable MSI interrupts */
+ reg = readl(pcie->bridge_base_addr + MC_IMASK_LOCAL);
+ reg |= PCIE_ENABLE_MSI;
+ writel(reg, pcie->bridge_base_addr + MC_IMASK_LOCAL);
+
+ return 0;
+}
+
+static void mc_irq_msi_domain_free(struct irq_domain *domain,
+ unsigned int virq, unsigned int nr_irqs)
+{
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+ struct mc_pcie *pcie = irq_data_get_irq_chip_data(d);
+ struct mc_msi *msi = &pcie->msi;
+
+ mutex_lock(&msi->lock);
+
+ if (test_bit(d->hwirq, msi->used))
+ __clear_bit(d->hwirq, msi->used);
+ else
+ dev_err(&pcie->pdev->dev, "trying to free unused MSI%lu\n",
+ d->hwirq);
+
+ mutex_unlock(&msi->lock);
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+ .alloc = mc_irq_msi_domain_alloc,
+ .free = mc_irq_msi_domain_free,
+};
+
+static int mc_allocate_msi_domains(struct mc_pcie *pcie)
+{
+ struct device *dev = &pcie->pdev->dev;
+ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+ struct mc_msi *msi = &pcie->msi;
+
+ mutex_init(&pcie->msi.lock);
+
+ msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
+ &msi_domain_ops, pcie);
+ if (!msi->dev_domain) {
+ dev_err(dev, "failed to create IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
+ &mc_msi_domain_info,
+ msi->dev_domain);
+ if (!msi->msi_domain) {
+ dev_err(dev, "failed to create MSI domain\n");
+ irq_domain_remove(msi->dev_domain);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int mc_pcie_init_irq_domains(struct mc_pcie *pcie)
+{
+ struct device *dev = &pcie->pdev->dev;
+ struct device_node *node = dev->of_node;
+
+ pcie->intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
+ &intx_domain_ops, pcie);
+ if (!pcie->intx_domain) {
+ dev_err(dev, "failed to get an INTx IRQ domain\n");
+ return -ENOMEM;
+ }
+ raw_spin_lock_init(&pcie->intx_mask_lock);
+
+ return mc_allocate_msi_domains(pcie);
+}
+
+static void mc_pci_unmap_cfg(void *ptr)
+{
+ pci_ecam_free((struct pci_config_window *)ptr);
+}
+
+static int mc_pcie_probe(struct platform_device *pdev)
+{
+ struct mc_pcie *pcie;
+ struct pci_host_bridge *bridge;
+ struct pci_config_window *cfg;
+ struct device *dev = &pdev->dev;
+ struct resource_entry *win;
+ struct resource *bus_range = NULL;
+ struct resource *cfgres;
+ int ret;
+ resource_size_t size;
+ u32 index;
+ u32 atr_sz;
+ u32 val;
+
+ if (!dev->of_node)
+ return -ENODEV;
+
+ /* Allocate the PCIe port */
+ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
+ if (!bridge)
+ return -ENOMEM;
+
+ pcie = pci_host_bridge_priv(bridge);
+
+ pcie->pdev = pdev;
+
+ cfgres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pcie->cfghw_base_addr = cfgres->start;
+ size = resource_size(cfgres);
+ pcie->cfg_size = size;
+ pcie->atr_sz = find_first_bit((const unsigned long *)&size, 64) - 1;
+
+ ret = mc_pcie_parse_dt(pcie);
+ if (ret) {
+ dev_err(dev, "parsing devicetree failed, ret %x\n", ret);
+ return ret;
+ }
+
+ irq_set_chained_handler_and_data(pcie->irq, mc_pcie_isr, pcie);
+
+ ret = mc_host_init(pcie);
+ if (ret) {
+ dev_err(dev, "failed to initialize host\n");
+ return ret;
+ }
+
+ /*
+ * Configure all inbound and outbound windows and prepare
+ * for config access
+ */
+ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+ &bridge->dma_ranges, &bus_range);
+ if (ret) {
+ dev_err(dev, "failed to parse PCI ranges\n");
+ return ret;
+ }
+
+ index = 1;
+ resource_list_for_each_entry(win, &bridge->windows) {
+ if ((resource_type(win->res) != IORESOURCE_MEM) &&
+ (resource_type(win->res) != IORESOURCE_IO))
+ continue;
+
+ size = resource_size(win->res);
+ atr_sz = find_first_bit((const unsigned long *)&size, 64) - 1;
+
+ /*
+ * Configure Address Translation Table index for PCI
+ * mem space
+ */
+ writel(PCIE_TX_RX_INTERFACE, pcie->bridge_base_addr +
+ (index * ATT_ENTRY_SIZE) +
+ MC_ATR0_AXI4_SLV0_TRSL_PARAM);
+
+ val = lower_32_bits(win->res->start) |
+ (atr_sz << ATR_SIZE_SHIFT) |
+ ATR_IMPL_ENABLE;
+
+ writel(val, pcie->bridge_base_addr +
+ (index * ATT_ENTRY_SIZE) +
+ MC_ATR0_AXI4_SLV0_SRCADDR_PARAM);
+
+ val = upper_32_bits(win->res->start);
+ writel(val, pcie->bridge_base_addr + (index * ATT_ENTRY_SIZE) +
+ MC_ATR0_AXI4_SLV0_SRC_ADDR);
+
+ val = lower_32_bits(win->res->start - win->offset);
+ writel(val, pcie->bridge_base_addr +
+ (index * ATT_ENTRY_SIZE) +
+ MC_ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
+
+ val = upper_32_bits(win->res->start);
+ writel(val, pcie->bridge_base_addr + (index * ATT_ENTRY_SIZE) +
+ MC_ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
+
+ index++;
+ }
+
+ ret = mc_pcie_init_irq_domains(pcie);
+ if (ret) {
+ dev_err(dev, "failed creating IRQ domains\n");
+ return ret;
+ }
+
+ /* Parse and map our Configuration Space windows */
+ cfg = pci_ecam_create(dev, cfgres, bus_range, &pci_generic_ecam_ops);
+ if (IS_ERR(cfg)) {
+ dev_err(dev, "failed creating Configuration Space\n");
+ return PTR_ERR(cfg);
+ }
+
+ pcie->cfg_base_addr = cfg->win;
+
+ val = cfg_readl(pcie, PCI_PRIMARY_BUS);
+ val &= 0xff000000;
+ val |= 0x00ff0100;
+ cfg_writel(pcie, val, PCI_PRIMARY_BUS);
+
+ /* Hardware doesn't setup MSI by default */
+ mc_pcie_enable_msi(pcie);
+
+ val = PCIE_ENABLE_MSI | PCIE_LOCAL_INT_ENABLE;
+ writel(val, pcie->bridge_base_addr + MC_IMASK_LOCAL);
+
+ ret = devm_add_action_or_reset(dev, mc_pci_unmap_cfg, cfg);
+ if (ret)
+ return ret;
+
+ /* Initialize bridge */
+ bridge->dev.parent = dev;
+ bridge->sysdata = cfg;
+ bridge->busnr = cfg->busr.start;
+ bridge->ops = &pci_generic_ecam_ops.pci_ops;
+ bridge->map_irq = of_irq_parse_and_map_pci;
+ bridge->swizzle_irq = pci_common_swizzle;
+
+ return pci_host_probe(bridge);
+}
+
+static const struct of_device_id mc_pcie_of_match[] = {
+ { .compatible = "microchip,pf-axi-pcie-host-1.0" },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, mc_pcie_of_match)
+
+static struct platform_driver mc_pcie_driver = {
+ .probe = mc_pcie_probe,
+ .driver = {
+ .name = "microchip-pcie",
+ .of_match_table = mc_pcie_of_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+builtin_platform_driver(mc_pcie_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Microchip PCIe host controller driver");
+MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v11 2/3] i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver
From: Andy Shevchenko @ 2020-05-20 11:49 UTC (permalink / raw)
To: Avi Fishman
Cc: Tali Perry, ofery, Brendan Higgins, Tomer Maimon, kfting,
Patrick Venture, Nancy Yuen, Benjamin Fair, Rob Herring, wsa,
Linux ARM, linux-i2c, OpenBMC Maillist, devicetree,
Linux Kernel Mailing List
In-Reply-To: <CAKKbWA5L_n7iC6-d22Am62SOoDBwNWO87+sXtRbwxwuVdjmRYA@mail.gmail.com>
On Wed, May 20, 2020 at 02:37:13PM +0300, Avi Fishman wrote:
> On Wed, May 20, 2020 at 1:24 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> >
> > On Wed, May 20, 2020 at 12:51:12PM +0300, Tali Perry wrote:
> > > Add Nuvoton NPCM BMC I2C controller driver.
> >
> > ...
> >
> > > +#ifdef CONFIG_DEBUG_FS
> >
> > Why?!
>
> It is made to save code size if CONFIG_DEBUG_FS is not defined?
Nope (in cases I have commented on). Try again.
> We see a lot of kernel code that is doing it.
Cargo cult, okay. So, somebody should try to understand what they are doing.
> So could you elaborate what is the problem?
Problem 1: ugly code.
Problem 2: some of the code is not guarded (seems never been tested with disabled debugfs).
Problem 3: it's not needed.
> > > +#include <linux/debugfs.h>
> > > +#endif
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 2/3] bindings: sound: Add documentation for TI j721e EVM (CPB and IVI)
From: Peter Ujfalusi @ 2020-05-20 11:50 UTC (permalink / raw)
To: Rob Herring; +Cc: broonie, lgirdwood, alsa-devel, devicetree, linux-kernel
In-Reply-To: <20200519222132.GA488519@bogus>
[-- Attachment #1: Type: text/plain, Size: 6535 bytes --]
Hi Rob,
On 20/05/2020 1.21, Rob Herring wrote:
> On Tue, May 12, 2020 at 04:16:32PM +0300, Peter Ujfalusi wrote:
>> The audio support on the Common Processor Board board is using
>> pcm3168a codec connected to McASP10 serializers in parallel setup.
>>
>> The Infotainment board plugs into the Common Processor Board, the support
>> of the extension board is extending the CPB audio support by adding
>> the two codecs on the expansion board.
>>
>> The audio support on the Infotainment Expansion Board consists of McASP0
>> connected to two pcm3168a codecs with dedicated set of serializers to each.
>> The SCKI for pcm3168a is sourced from j721e AUDIO_REFCLK0 pin.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>> ---
>> .../bindings/sound/ti,j721e-cpb-audio.yaml | 93 ++++++++++++
>> .../sound/ti,j721e-cpb-ivi-audio.yaml | 142 ++++++++++++++++++
>> 2 files changed, 235 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml
>> create mode 100644 Documentation/devicetree/bindings/sound/ti,j721e-cpb-ivi-audio.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml b/Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml
>> new file mode 100644
>> index 000000000000..0355ffc2b01b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml
>> @@ -0,0 +1,93 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/sound/ti,j721e-cpb-audio.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Texas Instruments J721e Common Processor Board Audio Support
>> +
>> +maintainers:
>> + - Peter Ujfalusi <peter.ujfalusi@ti.com>
>> +
>> +description: |
>> + The audio support on the board is using pcm3168a codec connected to McASP10
>> + serializers in parallel setup.
>> + The pcm3168a SCKI clock is sourced from j721e AUDIO_REFCLK2 pin.
>> + In order to support 48KHz and 44.1KHz family of sampling rates the parent
>> + clock for AUDIO_REFCLK2 needs to be changed between PLL4 (for 48KHz) and
>> + PLL15 (for 44.1KHz). The same PLLs are used for McASP10's AUXCLK clock via
>> + different HSDIVIDER.
>> +
>> +properties:
>> + compatible:
>> + items:
>> + - const: ti,j721e-cpb-audio
>> +
>> + model:
>> + $ref: /schemas/types.yaml#/definitions/string
>> + description: User specified audio sound card name
>> +
>> + ti,cpb-mcasp:
>> + description: phandle to McASP10
>> + allOf:
>> + - $ref: /schemas/types.yaml#/definitions/phandle
>> +
>> + ti,cpb-codec:
>> + description: phandle to the pcm3168a codec used on the CPB
>> + allOf:
>> + - $ref: /schemas/types.yaml#/definitions/phandle
>> +
>> + clocks:
>> + items:
>> + - description: PLL4 clock
>> + - description: PLL15 clock
>> + - description: McASP10 auxclk clock
>> + - description: PLL4_HSDIV0 parent for McASP10 auxclk (for 48KHz)
>> + - description: PLL15_HSDIV0 parent for McASP10 auxclk (for 44.1KHz)
>> + - description: AUDIO_REFCLK2 clock
>> + - description: PLL4_HSDIV2 parent for AUDIO_REFCLK2 clock (for 48KHz)
>> + - description: PLL15_HSDIV2 parent for AUDIO_REFCLK2 clock (for 44.1KHz)
>
> What h/w are these connected to?
These clocks are internal to the SoC with the exception of AUDIO_REFCLK2
which is routed to SoC pin.
> You have no control interface here, so how do you have clocks?
I need to control these clocks, the sound card is the user of these clocks.
> Defining parent clocks seems wrong, too. This seems to just be a
> collection of clocks a driver happens to need. Really, you should be
> able query possible parents and select one with the right frequency
> multiple.
The issue in hand is that I need to dynamically switch between certain
parents of the cpb-mcasp (for McASP) and audio-refclk2 (for the codec)
based on sampling rate of the stream.
The McASP auxclk parent can be selected from 7 source and I must use the
two dedicated ones.
The REFCLK2 parent can be selected from 30 source.
It is also a limitation of the system that I can not query directly the
PLL4/PLL15 frequencies, I can only get the frequency on the HSDIVs, but
I can not get the divider on them.
In order to handle the constraints on clocking I need to know the source
rate so the dividers can be taken into account. The codec is picky when
it comes to clocking and there is a need to switch between
256/512/768xFS based SCKI in order to be able to support sampling rates.
At the moment I have fixed clocks in place for the pll4/15 with the
rates they are configured so the dts can switch to a real clock which I
can use in the future.
As things are it is unlikely that I will ever going to have access to
them, but I wanted to avoid in the bindings:
ti,j721e-pll4-rate = <1179648000>;
ti,j721e-pll15-rate = <1083801600>;
>> +
>> + clock-names:
>> + items:
>> + - const: pll4
>> + - const: pll15
>> + - const: cpb-mcasp
>> + - const: cpb-mcasp-48000
>> + - const: cpb-mcasp-44100
>> + - const: audio-refclk2
>> + - const: audio-refclk2-48000
>> + - const: audio-refclk2-44100
>> +
>> +required:
>> + - compatible
>> + - model
>> + - ti,cpb-mcasp
>> + - ti,cpb-codec
>> + - clocks
>> + - clock-names
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> + - |+
>> + sound {
>> + compatible = "ti,j721e-cpb-audio";
>> + model = "j721e-cpb";
>> +
>> + status = "okay";
>
> Don't show status in examples.
Oops, it is a leftower
>
>> +
>> + ti,cpb-mcasp = <&mcasp10>;
>> + ti,cpb-codec = <&pcm3168a_1>;
>> +
>> + clocks = <&pll4>, <&pll15>,
>> + <&k3_clks 184 1>,
>> + <&k3_clks 184 2>, <&k3_clks 184 4>,
>> + <&k3_clks 157 371>,
>> + <&k3_clks 157 400>, <&k3_clks 157 401>;
>> + clock-names = "pll4", "pll15",
>> + "cpb-mcasp",
>> + "cpb-mcasp-48000", "cpb-mcasp-44100",
>> + "audio-refclk2",
>> + "audio-refclk2-48000", "audio-refclk2-44100";
>> + };
- Péter
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[-- Attachment #2: pEpkey.asc --]
[-- Type: application/pgp-keys, Size: 1783 bytes --]
^ permalink raw reply
* Re: [PATCH v2 5/6] irqchip: Add Loongson PCH MSI controller
From: Jiaxun Yang @ 2020-05-20 11:51 UTC (permalink / raw)
To: Thomas Gleixner, maz
Cc: Jason Cooper, Rob Herring, Huacai Chen, linux-kernel, devicetree,
linux-mips
In-Reply-To: <871rno3uab.fsf@nanos.tec.linutronix.de>
于 2020年5月13日 GMT+08:00 下午8:15:40, Thomas Gleixner <tglx@linutronix.de> 写到:
>Thomas Gleixner <tglx@linutronix.de> writes:
>> Jiaxun Yang <jiaxun.yang@flygoat.com> writes:
>>> +
>>> +struct pch_msi_data {
>>> + spinlock_t msi_map_lock;
>>> + phys_addr_t doorbell;
>>> + u32 irq_first; /* The vector number that MSIs starts */
>>> + u32 num_irqs; /* The number of vectors for MSIs */
>>> + unsigned long *msi_map;
>>> +};
>>> +
>>> +static void pch_msi_mask_msi_irq(struct irq_data *d)
>>> +{
>>> + pci_msi_mask_irq(d);
>>> + irq_chip_mask_parent(d);
>>> +}
>>> +
>>> +static void pch_msi_unmask_msi_irq(struct irq_data *d)
>>> +{
>>> + pci_msi_unmask_irq(d);
>>> + irq_chip_unmask_parent(d);
>>
>> The ordering of mask and unmask is assymetric. That does not make sense.
>>
>>> +static struct msi_domain_info pch_msi_domain_info = {
>>> + .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
>>> + MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX,
>>> + .chip = &pch_msi_irq_chip,
>>
>> Please maintain tabular layout.
>
>Ooops. Wanted to reply to V3, but the comments are valid for V3 as well.
All fixed in v4.
Please review.
Thanks!
>
>Thanks,
>
> tglx
--
Jiaxun Yang
^ permalink raw reply
* Re: [PATCH v10 2/5] PCI: Add Loongson PCI Controller support
From: Jiaxun Yang @ 2020-05-20 11:57 UTC (permalink / raw)
To: linux-pci
Cc: Rob Herring, Bjorn Helgaas, Rob Herring, Thomas Bogendoerfer,
Huacai Chen, Lorenzo Pieralisi, Paul Burton, devicetree,
linux-kernel, linux-mips
In-Reply-To: <20200514131650.3587281-2-jiaxun.yang@flygoat.com>
于 2020年5月14日 GMT+08:00 下午9:16:38, Jiaxun Yang <jiaxun.yang@flygoat.com> 写到:
>This controller can be found on Loongson-2K SoC, Loongson-3
>systems with RS780E/LS7A PCH.
>
>The RS780E part of code was previously located at
>arch/mips/pci/ops-loongson3.c and now it can use generic PCI
>driver implementation.
>
>Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>Reviewed-by: Rob Herring <robh@kernel.org>
>
Hi there,
Is it possible to let this series go into next tree soon?
As LS7A dts patch would depend on this series, and I want to
make the whole LS7A basic support as a part of 5.8 release.
Thanks!
--
Jiaxun Yang
^ permalink raw reply
* Re: [PATCH v2 18/20] mips: csrc-r4k: Decrease r4k-clocksource rating if CPU_FREQ enabled
From: Serge Semin @ 2020-05-20 11:59 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Serge Semin, Alexey Malahov, Paul Burton, Ralf Baechle,
Greg Kroah-Hartman, Arnd Bergmann, Rob Herring, linux-pm,
devicetree, Vincenzo Frascino, Thomas Gleixner, linux-mips,
linux-kernel
In-Reply-To: <20200519155053.GB15797@alpha.franken.de>
On Tue, May 19, 2020 at 05:50:53PM +0200, Thomas Bogendoerfer wrote:
> On Mon, May 18, 2020 at 11:57:52PM +0300, Serge Semin wrote:
> > On Mon, May 18, 2020 at 06:32:06PM +0200, Thomas Bogendoerfer wrote:
> > > On Mon, May 18, 2020 at 04:48:20PM +0300, Serge Semin wrote:
> > > > On Fri, May 15, 2020 at 11:06:47PM +0200, Thomas Bogendoerfer wrote:
> > > > > On Fri, May 15, 2020 at 10:48:27AM +0300, Serge Semin wrote:
> > > > > > Thomas,
> > > > > > Could you take a look at my comment below so I could proceed with the
> > > > > > patchset v3 development?
> > > > >
> > > > > I can't help, but using r4k clocksource with changing frequency is
> > > > > probaly only usefull as a random generator. So IMHO the only two
> > > > > options are disabling it or implement what arch/x86/kernel/tsc.c does.
> > > > >
> > > > > Thomas.
> > > >
> > > > Thomas, could you proceed with the rest of the patches review?
> > > > ├─>[PATCH v2 16/20] bus: cdmm: Add MIPS R5 arch support
> > > > ├─>[PATCH v2 15/20] mips: cdmm: Add mti,mips-cdmm dtb node support
> > >
> > > both are not my call, but look ok to me.
> >
> > Can I add your Reviewed-by tag there then?
>
> only for 16/20. 15/20 looks ok to me, but I have not enough insides
> on the hardware to say this is good.
Ok.
>
> > > > ├─>[PATCH v2 13/20] mips: early_printk_8250: Use offset-sized IO-mem accessors
> > >
> > > that's broken. A reg shift of 2 doesn't mean we could use 32bit access
> > > to the registers on other platforms. As I don't think adding some ifdefery
> > > makes things nicer, just implement the your prom_putchar in board code.
> >
> > I thought about that initially, but then I decided to alter the generic
> > early_printk_8250 code instead. My version of prom_putchar() would be almost
> > the same as one implemented in the early_printk_8250 module except minor
> > modification of replacing readb/writeb methods with readl/writel. So I didn't
> > want to duplicate the code, but wanted to provide a general way to fix the
> > problem potentially also for another platforms.
> >
> > Since you don't like this fix alternatively I'd suggest to add the reg_width
> > parameter passed to the setup_8250_early_printk_port() method like this:
> > -setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift,
> > - unsigned int timeout)
> > +setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift,
> > + unsigned int reg_width, unsigned int timeout)
> >
> > By reg_width parameter we could determine the actual width of the register:
> > static inline u8 serial_in(int offset)
> > {
> > - return readb(serial8250_base + (offset << serial8250_reg_shift));
> > + u8 ret = 0xFF;
> > +
> > + offset <<= serial8250_reg_shift;
> > + switch (serial8250_reg_width) {
> > + case 1:
> > + ret = readb(serial8250_base + offset);
> > + break;
> > + case 2:
> > + ret = readw(serial8250_base + offset);
> > + break;
> > + case 4:
> > + ret = readl(serial8250_base + offset);
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + return ret;
> > }
> >
> > The similar modification will be implemented for serial_out(). I'll also modify
>
> look at the lines of code you are adding. Doing your own prom_putchar will
> probably have less lines.
>
> > What do you think about this?
>
> please do your own prom_putchar.
>
Ok.
>
> > >
> > > > ├─>[PATCH v2 12/20] mips: MAAR: Add XPA mode support
> > >
> > > looks ok so far.
> >
> > Can I add your Reviewed-by tag there then?
>
> As I'm the maintainer of the part, I've simply applied it.
>
> > >
> > > > ├─>[PATCH v2 10/20] mips: Add CONFIG/CONFIG6/Cause reg fields macro
> > >
> > > that is fine
> >
> > Can I add your Reviewed-by tag there then?
>
> As this didn't apply cleanly, I'll apply it after you've resent it.
> IMHO no need for a Reviewed-by.
Ok.
>
> > > > └─>[PATCH v2 09/20] mips: Add CP0 Write Merge config support
> > >
> > > this is IMHO a dangerous change. Enabling write merging for any
> > > CPU supporting it might triggers bugs. Do it in your board bringup
> > > code and at the moment I don't see a reason for the rest of that
> > > patch.
> >
> > Let's at least leave the mm_config() implementation but without the write-merge
> > enabling by default. Providing features availability macro
> > cpu_has_mm_sysad/cpu_has_mm_full and c0 config fields
>
> do you have a user of that ? I'm not introducing code nobody uses.
>
See my comment below.
> > I could use them to implement a code pattern like:
> >
> > + if (cpu_has_mm_full) {
> > + unsigned int config0 = read_c0_config();
> > + config0 = (config0 & ~MIPS_CONF_MM) | MIPS_CONF_MM_FULL;
> > + write_c0_config(config0);
> > + }
>
> you know you are running on a R5 core, so you know you have MM_FULL.
> No need to check this.
>
> > By doing so I can manually enable/disable the MM feature in the
> > cpu-feature-overrides.h. Without that I'd have to locally define these macro,
> > which isn't good seeing they are in fact generic and can be useful for other
> > platforms with SYSAD and FULL MM feature available. What do you think?
>
> To me this is a hardware feature I expect to be done by firmware and
> Linux shouldn't care about it, if it doesn't have any software
> implications.
I think there is a misunderstanding here. In this patch I am not enabling
Write-Merge feature for any memory range. I am enabling the UCA Cache Coherency
attribute to be available for utilization. See the user-manual info regarding
the CP0.CONFIG.MM field:
Write Merge.This bit indicates whether write-through merging is enabled
in the 32-byte collapsing write buffer.
0: No merging allowed
1: Merging allowed
In order to have the Write-merging really enabled for a particular PFN one have
to mark its TLB entry with UCA (EntryLoX.C[3:5] = 7) attribute. So in this patch
I am attempting to detect whether the feature is either already enabled or if
available to enable it for utilization.
If there is no misunderstanding and you said what you said, that even enabling
the feature for utilization might be dangerous, let's at least leave the
MIPS_CONF_MM, MIPS_CONF_MM_FULL and MIPS_CONF_MM_SYS_SYSAD fields
definition in the "arch/mips/include/asm/mipsregs.h" header. I'll use
them to enable the write-merge in my platform code.
What do you think?
-Sergey
>
> Thomas.
>
> --
> Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
> good idea. [ RFC1925, 2.3 ]
^ permalink raw reply
* [PATCH v2] of: Fix a refcounting bug in __of_attach_node_sysfs()
From: Dan Carpenter @ 2020-05-20 12:04 UTC (permalink / raw)
To: Rob Herring, Frank Rowand
Cc: Michael Ellerman, devicetree, linux-kernel, kernel-janitors
In-Reply-To: <877dx69az4.fsf@mpe.ellerman.id.au>
The problem in this code is that if kobject_add() fails, then it should
call of_node_put(np) to drop the reference count. I've actually moved
the of_node_get(np) later in the function to avoid needing to do clean
up.
Fixes: 5b2c2f5a0ea3 ("of: overlay: add missing of_node_get() in __of_attach_node_sysfs")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
v2: move the of_node_get() instead of doing clean up. Also the v1 had a
confusing typo in the commit message.
drivers/of/kobj.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/of/kobj.c b/drivers/of/kobj.c
index c72eef988041..a32e60b024b8 100644
--- a/drivers/of/kobj.c
+++ b/drivers/of/kobj.c
@@ -134,8 +134,6 @@ int __of_attach_node_sysfs(struct device_node *np)
if (!name)
return -ENOMEM;
- of_node_get(np);
-
rc = kobject_add(&np->kobj, parent, "%s", name);
kfree(name);
if (rc)
@@ -144,6 +142,7 @@ int __of_attach_node_sysfs(struct device_node *np)
for_each_property_of_node(np, pp)
__of_add_property_sysfs(np, pp);
+ of_node_get(np);
return 0;
}
--
2.26.2
^ permalink raw reply related
* Re: [PATCH v2 18/20] mips: csrc-r4k: Decrease r4k-clocksource rating if CPU_FREQ enabled
From: Serge Semin @ 2020-05-20 12:12 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Serge Semin, Alexey Malahov, Paul Burton, Ralf Baechle,
Greg Kroah-Hartman, Arnd Bergmann, Rob Herring, linux-pm,
devicetree, Vincenzo Frascino, Thomas Gleixner, linux-mips,
linux-kernel
In-Reply-To: <20200519155053.GB15797@alpha.franken.de>
On Tue, May 19, 2020 at 05:50:53PM +0200, Thomas Bogendoerfer wrote:
> On Mon, May 18, 2020 at 11:57:52PM +0300, Serge Semin wrote:
> > On Mon, May 18, 2020 at 06:32:06PM +0200, Thomas Bogendoerfer wrote:
> > > On Mon, May 18, 2020 at 04:48:20PM +0300, Serge Semin wrote:
> > > > On Fri, May 15, 2020 at 11:06:47PM +0200, Thomas Bogendoerfer wrote:
> > > > > On Fri, May 15, 2020 at 10:48:27AM +0300, Serge Semin wrote:
> > > > > > Thomas,
> > > > > > Could you take a look at my comment below so I could proceed with the
> > > > > > patchset v3 development?
> > > > >
> > > > > I can't help, but using r4k clocksource with changing frequency is
> > > > > probaly only usefull as a random generator. So IMHO the only two
> > > > > options are disabling it or implement what arch/x86/kernel/tsc.c does.
> > > > >
> > > > > Thomas.
> > > >
> > > > Thomas, could you proceed with the rest of the patches review?
> > > > ├─>[PATCH v2 16/20] bus: cdmm: Add MIPS R5 arch support
> > > > ├─>[PATCH v2 15/20] mips: cdmm: Add mti,mips-cdmm dtb node support
> > >
> > > both are not my call, but look ok to me.
> >
> > Can I add your Reviewed-by tag there then?
>
> only for 16/20. 15/20 looks ok to me, but I have not enough insides
> on the hardware to say this is good.
>
> > > > ├─>[PATCH v2 13/20] mips: early_printk_8250: Use offset-sized IO-mem accessors
> > >
> > > that's broken. A reg shift of 2 doesn't mean we could use 32bit access
> > > to the registers on other platforms. As I don't think adding some ifdefery
> > > makes things nicer, just implement the your prom_putchar in board code.
> >
> > I thought about that initially, but then I decided to alter the generic
> > early_printk_8250 code instead. My version of prom_putchar() would be almost
> > the same as one implemented in the early_printk_8250 module except minor
> > modification of replacing readb/writeb methods with readl/writel. So I didn't
> > want to duplicate the code, but wanted to provide a general way to fix the
> > problem potentially also for another platforms.
> >
> > Since you don't like this fix alternatively I'd suggest to add the reg_width
> > parameter passed to the setup_8250_early_printk_port() method like this:
> > -setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift,
> > - unsigned int timeout)
> > +setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift,
> > + unsigned int reg_width, unsigned int timeout)
> >
> > By reg_width parameter we could determine the actual width of the register:
> > static inline u8 serial_in(int offset)
> > {
> > - return readb(serial8250_base + (offset << serial8250_reg_shift));
> > + u8 ret = 0xFF;
> > +
> > + offset <<= serial8250_reg_shift;
> > + switch (serial8250_reg_width) {
> > + case 1:
> > + ret = readb(serial8250_base + offset);
> > + break;
> > + case 2:
> > + ret = readw(serial8250_base + offset);
> > + break;
> > + case 4:
> > + ret = readl(serial8250_base + offset);
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + return ret;
> > }
> >
> > The similar modification will be implemented for serial_out(). I'll also modify
>
> look at the lines of code you are adding. Doing your own prom_putchar will
> probably have less lines.
>
> > What do you think about this?
>
> please do your own prom_putchar.
One more time regarding this problem but in appliance to another part of the
MIPS code. I've missed the patch to draw your attention to:
[PATCH v2 14/20] mips: Use offset-sized IO-mem accessors in CPS debug printout
There I've applied the same fix as in the patch:
[PATCH v2 13/20] mips: early_printk_8250: Use offset-sized IO-mem accessors
Since you don't like the way I initially fixed it, suppose there we don't have
another way but to introduce something like CONFIG_MIPS_CPS_NS16550_WIDTH
parameter to select a proper accessors, like sw in our case, and sb by defaul).
Right?
(Note UART_L is incorrectly created in that patch, I'll remove that macro in
v3.)
-Sergey
>
>
> > >
> > > > ├─>[PATCH v2 12/20] mips: MAAR: Add XPA mode support
> > >
> > > looks ok so far.
> >
> > Can I add your Reviewed-by tag there then?
>
> As I'm the maintainer of the part, I've simply applied it.
>
> > >
> > > > ├─>[PATCH v2 10/20] mips: Add CONFIG/CONFIG6/Cause reg fields macro
> > >
> > > that is fine
> >
> > Can I add your Reviewed-by tag there then?
>
> As this didn't apply cleanly, I'll apply it after you've resent it.
> IMHO no need for a Reviewed-by.
>
> > > > └─>[PATCH v2 09/20] mips: Add CP0 Write Merge config support
> > >
> > > this is IMHO a dangerous change. Enabling write merging for any
> > > CPU supporting it might triggers bugs. Do it in your board bringup
> > > code and at the moment I don't see a reason for the rest of that
> > > patch.
> >
> > Let's at least leave the mm_config() implementation but without the write-merge
> > enabling by default. Providing features availability macro
> > cpu_has_mm_sysad/cpu_has_mm_full and c0 config fields
>
> do you have a user of that ? I'm not introducing code nobody uses.
>
> > I could use them to implement a code pattern like:
> >
> > + if (cpu_has_mm_full) {
> > + unsigned int config0 = read_c0_config();
> > + config0 = (config0 & ~MIPS_CONF_MM) | MIPS_CONF_MM_FULL;
> > + write_c0_config(config0);
> > + }
>
> you know you are running on a R5 core, so you know you have MM_FULL.
> No need to check this.
>
> > By doing so I can manually enable/disable the MM feature in the
> > cpu-feature-overrides.h. Without that I'd have to locally define these macro,
> > which isn't good seeing they are in fact generic and can be useful for other
> > platforms with SYSAD and FULL MM feature available. What do you think?
>
> To me this is a hardware feature I expect to be done by firmware and
> Linux shouldn't care about it, if it doesn't have any software
> implications.
>
> Thomas.
>
> --
> Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
> good idea. [ RFC1925, 2.3 ]
^ permalink raw reply
* Re: [PATCH v2 06/12] i2c: designware: slave: Set DW I2C core module dependency
From: Jarkko Nikula @ 2020-05-20 12:15 UTC (permalink / raw)
To: Serge Semin
Cc: Serge Semin, Alexey Malahov, Thomas Bogendoerfer, Paul Burton,
Ralf Baechle, Andy Shevchenko, Mika Westerberg, Wolfram Sang,
Rob Herring, Frank Rowand, linux-mips, devicetree, Wolfram Sang,
Jean Delvare, Krzysztof Kozlowski, Max Staudt, Stefan Roese,
linux-i2c, linux-kernel
In-Reply-To: <20200510095019.20981-7-Sergey.Semin@baikalelectronics.ru>
On 5/10/20 12:50 PM, Serge Semin wrote:
> DW APB I2C slave code in fact depends on the DW I2C driver core, but not
> on the platform code. Yes, the I2C slave interface is currently supported
> by the platform version of the IP core, but it doesn't make it dependent
> on it. So make sure the DW APB I2C slave config is only available if the
> I2C_DESIGNWARE_CORE config is enabled.
>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Wolfram Sang <wsa@the-dreams.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: linux-mips@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> ---
> drivers/i2c/busses/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v2 05/12] i2c: designware: Use `-y` to build multi-object modules
From: Jarkko Nikula @ 2020-05-20 12:16 UTC (permalink / raw)
To: Serge Semin
Cc: Serge Semin, Alexey Malahov, Thomas Bogendoerfer, Paul Burton,
Ralf Baechle, Andy Shevchenko, Mika Westerberg, Wolfram Sang,
Rob Herring, Frank Rowand, linux-mips, devicetree, Wolfram Sang,
Jean Delvare, Max Staudt, Stefan Roese, linux-i2c, linux-kernel
In-Reply-To: <20200510095019.20981-6-Sergey.Semin@baikalelectronics.ru>
On 5/10/20 12:50 PM, Serge Semin wrote:
> Since commit 4f8272802739 ("Documentation: update kbuild loadable modules
> goals & examples") `-objs` is fitted for building host programs, lets
> change DW I2C core, platform and PCI driver kbuild directives to using
> `-y`, which more straightforward for device drivers. By doing so we can
> discard the ifeq construction in favor to the more natural and less bulky
> `<module>-$(CONFIG_X) += x.o`
>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Wolfram Sang <wsa@the-dreams.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: linux-mips@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> ---
> drivers/i2c/busses/Makefile | 17 ++++++++---------
> 1 file changed, 8 insertions(+), 9 deletions(-)
>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v2 07/12] i2c: designware: Move Baytrail sem config to the platform if-clause
From: Jarkko Nikula @ 2020-05-20 12:16 UTC (permalink / raw)
To: Serge Semin
Cc: Serge Semin, Alexey Malahov, Thomas Bogendoerfer, Paul Burton,
Ralf Baechle, Andy Shevchenko, Mika Westerberg, Wolfram Sang,
Rob Herring, Frank Rowand, linux-mips, devicetree, Wolfram Sang,
Jean Delvare, Krzysztof Kozlowski, Max Staudt, Stefan Roese,
linux-i2c, linux-kernel
In-Reply-To: <20200510095019.20981-8-Sergey.Semin@baikalelectronics.ru>
On 5/10/20 12:50 PM, Serge Semin wrote:
> Currently Intel Baytrail I2C semaphore is a feature of the DW APB I2C
> platform driver. It's a bit confusing to see it's config in the menu at
> some separated place with no reference to the platform code. Lets move the
> config definition under the if-I2C_DESIGNWARE_PLATFORM clause. By doing so
> the config menu will display the feature right below the DW I2C platform
> driver item and will indent it to the right so signifying its belonging.
>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Wolfram Sang <wsa@the-dreams.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: linux-mips@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> ---
> drivers/i2c/busses/Kconfig | 30 +++++++++++++++++-------------
> 1 file changed, 17 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index 368aa64e9266..ed6927c4c540 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig
> @@ -530,8 +530,8 @@ config I2C_DESIGNWARE_CORE
>
> config I2C_DESIGNWARE_PLATFORM
> tristate "Synopsys DesignWare Platform"
> - select I2C_DESIGNWARE_CORE
> depends on (ACPI && COMMON_CLK) || !ACPI
> + select I2C_DESIGNWARE_CORE
> help
> If you say yes to this option, support will be included for the
> Synopsys DesignWare I2C adapter.
> @@ -539,6 +539,22 @@ config I2C_DESIGNWARE_PLATFORM
> This driver can also be built as a module. If so, the module
> will be called i2c-designware-platform.
>
> +if I2C_DESIGNWARE_PLATFORM
> +
> +config I2C_DESIGNWARE_BAYTRAIL
> + bool "Intel Baytrail I2C semaphore support"
> + depends on ACPI
> + depends on (I2C_DESIGNWARE_PLATFORM=m && IOSF_MBI) || \
> + (I2C_DESIGNWARE_PLATFORM=y && IOSF_MBI=y)
> + help
> + This driver enables managed host access to the PMIC I2C bus on select
> + Intel BayTrail platforms using the X-Powers AXP288 PMIC. It allows
> + the host to request uninterrupted access to the PMIC's I2C bus from
> + the platform firmware controlling it. You should say Y if running on
> + a BayTrail system using the AXP288.
> +
> +endif # I2C_DESIGNWARE_PLATFORM
> +
Is the added "if I2C_DESIGNWARE_PLATFORM" needed here? Should the
"depends on" be enough?
Jarkko
^ permalink raw reply
* Re: [PATCH v2 04/12] i2c: designware: Convert driver to using regmap API
From: Jarkko Nikula @ 2020-05-20 12:16 UTC (permalink / raw)
To: Serge Semin, Andy Shevchenko, Mika Westerberg
Cc: Serge Semin, Alexey Malahov, Thomas Bogendoerfer, Paul Burton,
Ralf Baechle, Wolfram Sang, Rob Herring, Frank Rowand, devicetree,
linux-mips, Wolfram Sang, Jean Delvare, Krzysztof Kozlowski,
Max Staudt, Stefan Roese, Uwe Kleine-König, Shaokun Zhang,
linux-i2c, linux-kernel
In-Reply-To: <20200510095019.20981-5-Sergey.Semin@baikalelectronics.ru>
On 5/10/20 12:50 PM, Serge Semin wrote:
> Seeing the DW I2C driver is using flags-based accessors with two
> conditional clauses it would be better to replace them with the regmap
> API IO methods and to initialize the regmap object with read/write
> callbacks specific to the controller registers map implementation. This
> will be also handy for the drivers with non-standard registers mapping
> (like an embedded into the Baikal-T1 System Controller DW I2C block, which
> glue-driver is a part of this series).
>
> As before the driver tries to detect the mapping setup at probe stage and
> creates a regmap object accordingly, which will be used by the rest of the
> code to correctly access the controller registers. In two places it was
> appropriate to convert the hand-written read-modify-write and
> read-poll-loop design patterns to the corresponding regmap API
> ready-to-use methods.
>
> Note the regmap IO methods return value is checked only at the probe
> stage. The rest of the code won't do this because basically we have
> MMIO-based regmap so non of the read/write methods can fail (this also
> won't be needed for the Baikal-T1-specific I2C controller).
>
> Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Wolfram Sang <wsa@the-dreams.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: devicetree@vger.kernel.org
> Cc: linux-mips@vger.kernel.org
> ---
> drivers/i2c/busses/Kconfig | 1 +
> drivers/i2c/busses/i2c-designware-common.c | 171 +++++++++++++++------
> drivers/i2c/busses/i2c-designware-core.h | 18 +--
> drivers/i2c/busses/i2c-designware-master.c | 125 ++++++++-------
> drivers/i2c/busses/i2c-designware-slave.c | 77 +++++-----
> 5 files changed, 239 insertions(+), 153 deletions(-)
>
Looking at patches 4/12-12/12 I think it would be good to move fixes and
less invasive patches before this. Like
i2c: designware: slave: Set DW I2C core module dependency
i2c: designware: Use `-y` to build multi-object modules
i2c: designware: Move Baytrail sem config to the platform if-clause
That said, you may add:
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v2 10/12] i2c: designware: Discard Cherry Trail model flag
From: Jarkko Nikula @ 2020-05-20 12:17 UTC (permalink / raw)
To: Serge Semin, Andy Shevchenko, Mika Westerberg
Cc: Serge Semin, Alexey Malahov, Thomas Bogendoerfer, Paul Burton,
Ralf Baechle, Rob Herring, Frank Rowand, linux-mips, devicetree,
Wolfram Sang, Jean Delvare, Felipe Balbi, Chuhong Yuan,
Rafael J. Wysocki, Hanjun Guo, Hans de Goede, linux-i2c,
linux-kernel
In-Reply-To: <20200510095019.20981-11-Sergey.Semin@baikalelectronics.ru>
On 5/10/20 12:50 PM, Serge Semin wrote:
> A PM workaround activated by the flag MODEL_CHERRYTRAIL has been removed
> since commit 9cbeeca05049 ("i2c: designware: Remove Cherry Trail PMIC I2C
> bus pm_disabled workaround"), but the flag most likely by mistake has been
> left in the Dw I2C drivers. Lets remove it.
>
> By doing so we get rid from the last DW APB I2C IP-core model flag, so we
> can remove the MODEL_MASK macro too.
>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: linux-mips@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> ---
> drivers/i2c/busses/i2c-designware-core.h | 3 ---
> drivers/i2c/busses/i2c-designware-pcidrv.c | 1 -
> drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
> 3 files changed, 1 insertion(+), 5 deletions(-)
>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
^ permalink raw reply
* [PATCH net-next v2 0/4] DP83869 Enhancements
From: Dan Murphy @ 2020-05-20 12:18 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem
Cc: netdev, linux-kernel, devicetree, Dan Murphy
Hello
These are improvements to the DP83869 Ethernet PHY driver. OP-mode and port
mirroring may be strapped on the device but the software only retrives these
settings from the device tree. Reading the straps and initializing the
associated stored variables so when setting the PHY up and down the PHY's
configuration values will be retained.
The PHY also supports RGMII internal delays. Implement this feature as it
was done in the DP83867 device.
Dan Murphy (4):
net: phy: dp83869: Update port-mirroring to read straps
net: phy: dp83869: Set opmode from straps
dt-bindings: net: Add RGMII internal delay for DP83869
net: dp83869: Add RGMII internal delay configuration
.../devicetree/bindings/net/ti,dp83869.yaml | 16 +++
drivers/net/phy/dp83869.c | 120 +++++++++++++++++-
include/dt-bindings/net/ti-dp83869.h | 18 +++
3 files changed, 150 insertions(+), 4 deletions(-)
--
2.26.2
^ permalink raw reply
* [PATCH net-next v2 1/4] net: phy: dp83869: Update port-mirroring to read straps
From: Dan Murphy @ 2020-05-20 12:18 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200520121835.31190-1-dmurphy@ti.com>
The device tree may not have the property set for port mirroring
because the hardware may have it strapped. If the property is not in the
DT then check the straps and set the port mirroring bit appropriately.
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
drivers/net/phy/dp83869.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index 7996a4aea8d2..073a0f7754a5 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c
@@ -66,6 +66,7 @@
/* STRAP_STS1 bits */
#define DP83869_STRAP_STS1_RESERVED BIT(11)
+#define DP83869_STRAP_MIRROR_ENABLED BIT(12)
/* PHYCTRL bits */
#define DP83869_RX_FIFO_SHIFT 12
@@ -191,10 +192,18 @@ static int dp83869_of_init(struct phy_device *phydev)
else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN;
- if (of_property_read_bool(of_node, "enet-phy-lane-swap"))
+ if (of_property_read_bool(of_node, "enet-phy-lane-swap")) {
dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;
- else
- dp83869->port_mirroring = DP83869_PORT_MIRRORING_DIS;
+ } else {
+ /* If the lane swap is not in the DT then check the straps */
+ ret = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);
+ if (ret < 0)
+ return ret;
+ if (ret & DP83869_STRAP_MIRROR_ENABLED)
+ dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;
+ else
+ dp83869->port_mirroring = DP83869_PORT_MIRRORING_DIS;
+ }
if (of_property_read_u32(of_node, "rx-fifo-depth",
&dp83869->rx_fifo_depth))
--
2.26.2
^ permalink raw reply related
* [PATCH net-next v2 3/4] dt-bindings: net: Add RGMII internal delay for DP83869
From: Dan Murphy @ 2020-05-20 12:18 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200520121835.31190-1-dmurphy@ti.com>
Add the internal delay values into the header and update the binding
with the internal delay properties.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
.../devicetree/bindings/net/ti,dp83869.yaml | 16 ++++++++++++++++
include/dt-bindings/net/ti-dp83869.h | 18 ++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/ti,dp83869.yaml b/Documentation/devicetree/bindings/net/ti,dp83869.yaml
index 5b69ef03bbf7..344015ab9081 100644
--- a/Documentation/devicetree/bindings/net/ti,dp83869.yaml
+++ b/Documentation/devicetree/bindings/net/ti,dp83869.yaml
@@ -64,6 +64,20 @@ properties:
Operational mode for the PHY. If this is not set then the operational
mode is set by the straps. see dt-bindings/net/ti-dp83869.h for values
+ ti,rx-internal-delay:
+ $ref: /schemas/types.yaml#definitions/uint32
+ description: |
+ RGMII Receive Clock Delay - see dt-bindings/net/ti-dp83869.h
+ for applicable values. Required only if interface type is
+ PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_RXID.
+
+ ti,tx-internal-delay:
+ $ref: /schemas/types.yaml#definitions/uint32
+ description: |
+ RGMII Transmit Clock Delay - see dt-bindings/net/ti-dp83869.h
+ for applicable values. Required only if interface type is
+ PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_TXID.
+
required:
- reg
@@ -80,5 +94,7 @@ examples:
ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
ti,max-output-impedance = "true";
ti,clk-output-sel = <DP83869_CLK_O_SEL_CHN_A_RCLK>;
+ ti,rx-internal-delay = <DP83869_RGMIIDCTL_2_25_NS>;
+ ti,tx-internal-delay = <DP83869_RGMIIDCTL_2_75_NS>;
};
};
diff --git a/include/dt-bindings/net/ti-dp83869.h b/include/dt-bindings/net/ti-dp83869.h
index 218b1a64e975..77d104a40f1f 100644
--- a/include/dt-bindings/net/ti-dp83869.h
+++ b/include/dt-bindings/net/ti-dp83869.h
@@ -16,6 +16,24 @@
#define DP83869_PHYCR_FIFO_DEPTH_6_B_NIB 0x02
#define DP83869_PHYCR_FIFO_DEPTH_8_B_NIB 0x03
+/* RGMIIDCTL internal delay for rx and tx */
+#define DP83869_RGMIIDCTL_250_PS 0x0
+#define DP83869_RGMIIDCTL_500_PS 0x1
+#define DP83869_RGMIIDCTL_750_PS 0x2
+#define DP83869_RGMIIDCTL_1_NS 0x3
+#define DP83869_RGMIIDCTL_1_25_NS 0x4
+#define DP83869_RGMIIDCTL_1_50_NS 0x5
+#define DP83869_RGMIIDCTL_1_75_NS 0x6
+#define DP83869_RGMIIDCTL_2_00_NS 0x7
+#define DP83869_RGMIIDCTL_2_25_NS 0x8
+#define DP83869_RGMIIDCTL_2_50_NS 0x9
+#define DP83869_RGMIIDCTL_2_75_NS 0xa
+#define DP83869_RGMIIDCTL_3_00_NS 0xb
+#define DP83869_RGMIIDCTL_3_25_NS 0xc
+#define DP83869_RGMIIDCTL_3_50_NS 0xd
+#define DP83869_RGMIIDCTL_3_75_NS 0xe
+#define DP83869_RGMIIDCTL_4_00_NS 0xf
+
/* IO_MUX_CFG - Clock output selection */
#define DP83869_CLK_O_SEL_CHN_A_RCLK 0x0
#define DP83869_CLK_O_SEL_CHN_B_RCLK 0x1
--
2.26.2
^ permalink raw reply related
* [PATCH net-next v2 4/4] net: dp83869: Add RGMII internal delay configuration
From: Dan Murphy @ 2020-05-20 12:18 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200520121835.31190-1-dmurphy@ti.com>
Add RGMII internal delay configuration for Rx and Tx.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
drivers/net/phy/dp83869.c | 84 +++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index cfb22a21a2e6..f08008050177 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c
@@ -99,6 +99,14 @@
#define DP83869_OP_MODE_MII BIT(5)
#define DP83869_SGMII_RGMII_BRIDGE BIT(6)
+/* RGMIIDCTL bits */
+#define DP83869_RGMII_TX_CLK_DELAY_MAX 0xf
+#define DP83869_RGMII_TX_CLK_DELAY_SHIFT 4
+#define DP83869_RGMII_TX_CLK_DELAY_INV (DP83869_RGMII_TX_CLK_DELAY_MAX + 1)
+#define DP83869_RGMII_RX_CLK_DELAY_MAX 0xf
+#define DP83869_RGMII_RX_CLK_DELAY_SHIFT 0
+#define DP83869_RGMII_RX_CLK_DELAY_INV (DP83869_RGMII_RX_CLK_DELAY_MAX + 1)
+
enum {
DP83869_PORT_MIRRORING_KEEP,
DP83869_PORT_MIRRORING_EN,
@@ -108,6 +116,8 @@ enum {
struct dp83869_private {
int tx_fifo_depth;
int rx_fifo_depth;
+ u32 rx_id_delay;
+ u32 tx_id_delay;
int io_impedance;
int port_mirroring;
bool rxctrl_strap_quirk;
@@ -232,6 +242,26 @@ static int dp83869_of_init(struct phy_device *phydev)
&dp83869->tx_fifo_depth))
dp83869->tx_fifo_depth = DP83869_PHYCR_FIFO_DEPTH_4_B_NIB;
+ dp83869->rx_id_delay = DP83869_RGMII_RX_CLK_DELAY_INV;
+ ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
+ &dp83869->rx_id_delay);
+ if (!ret && dp83869->rx_id_delay > DP83869_RGMII_RX_CLK_DELAY_MAX) {
+ phydev_err(phydev,
+ "ti,rx-internal-delay value of %u out of range\n",
+ dp83869->rx_id_delay);
+ return -EINVAL;
+ }
+
+ dp83869->tx_id_delay = DP83869_RGMII_TX_CLK_DELAY_INV;
+ ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
+ &dp83869->tx_id_delay);
+ if (!ret && dp83869->tx_id_delay > DP83869_RGMII_TX_CLK_DELAY_MAX) {
+ phydev_err(phydev,
+ "ti,tx-internal-delay value of %u out of range\n",
+ dp83869->tx_id_delay);
+ return -EINVAL;
+ }
+
return ret;
}
#else
@@ -270,6 +300,29 @@ static int dp83869_configure_rgmii(struct phy_device *phydev,
return ret;
}
+static int dp83869_verify_rgmii_cfg(struct phy_device *phydev)
+{
+ struct dp83869_private *dp83869 = phydev->priv;
+
+ /* RX delay *must* be specified if internal delay of RX is used. */
+ if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) &&
+ dp83869->rx_id_delay == DP83869_RGMII_RX_CLK_DELAY_INV) {
+ phydev_err(phydev, "ti,rx-internal-delay must be specified\n");
+ return -EINVAL;
+ }
+
+ /* TX delay *must* be specified if internal delay of TX is used. */
+ if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) &&
+ dp83869->tx_id_delay == DP83869_RGMII_TX_CLK_DELAY_INV) {
+ phydev_err(phydev, "ti,tx-internal-delay must be specified\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int dp83869_configure_mode(struct phy_device *phydev,
struct dp83869_private *dp83869)
{
@@ -371,6 +424,11 @@ static int dp83869_config_init(struct phy_device *phydev)
{
struct dp83869_private *dp83869 = phydev->priv;
int ret, val;
+ u16 delay;
+
+ ret = dp83869_verify_rgmii_cfg(phydev);
+ if (ret)
+ return ret;
ret = dp83869_configure_mode(phydev, dp83869);
if (ret)
@@ -394,6 +452,32 @@ static int dp83869_config_init(struct phy_device *phydev)
dp83869->clk_output_sel <<
DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT);
+ if (phy_interface_is_rgmii(phydev)) {
+ val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL);
+
+ val &= ~(DP83869_RGMII_TX_CLK_DELAY_EN | DP83869_RGMII_RX_CLK_DELAY_EN);
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ val |= (DP83869_RGMII_TX_CLK_DELAY_EN | DP83869_RGMII_RX_CLK_DELAY_EN);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ val |= DP83869_RGMII_TX_CLK_DELAY_EN;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ val |= DP83869_RGMII_RX_CLK_DELAY_EN;
+
+ phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL, val);
+
+ delay = 0;
+ if (dp83869->rx_id_delay != DP83869_RGMII_RX_CLK_DELAY_INV)
+ delay |= dp83869->rx_id_delay;
+ if (dp83869->tx_id_delay != DP83869_RGMII_TX_CLK_DELAY_INV)
+ delay |= dp83869->tx_id_delay <<
+ DP83869_RGMII_TX_CLK_DELAY_SHIFT;
+
+ phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL,
+ delay);
+ }
+
return ret;
}
--
2.26.2
^ permalink raw reply related
* [PATCH net-next v2 2/4] net: phy: dp83869: Set opmode from straps
From: Dan Murphy @ 2020-05-20 12:18 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200520121835.31190-1-dmurphy@ti.com>
If the op-mode for the device is not set in the device tree then set
the strapped op-mode and store it for later configuration.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
v2 - Fixed val declaration from u16 to int
drivers/net/phy/dp83869.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index 073a0f7754a5..cfb22a21a2e6 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c
@@ -65,6 +65,7 @@
#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0)
/* STRAP_STS1 bits */
+#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0)
#define DP83869_STRAP_STS1_RESERVED BIT(11)
#define DP83869_STRAP_MIRROR_ENABLED BIT(12)
@@ -161,6 +162,20 @@ static int dp83869_config_port_mirroring(struct phy_device *phydev)
DP83869_CFG3_PORT_MIRROR_EN);
}
+static int dp83869_set_strapped_mode(struct phy_device *phydev)
+{
+ struct dp83869_private *dp83869 = phydev->priv;
+ int val;
+
+ val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);
+ if (val < 0)
+ return val;
+
+ dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK;
+
+ return 0;
+}
+
#ifdef CONFIG_OF_MDIO
static int dp83869_of_init(struct phy_device *phydev)
{
@@ -185,6 +200,10 @@ static int dp83869_of_init(struct phy_device *phydev)
if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET ||
dp83869->mode > DP83869_SGMII_COPPER_ETHERNET)
return -EINVAL;
+ } else {
+ ret = dp83869_set_strapped_mode(phydev);
+ if (ret)
+ return ret;
}
if (of_property_read_bool(of_node, "ti,max-output-impedance"))
@@ -218,7 +237,7 @@ static int dp83869_of_init(struct phy_device *phydev)
#else
static int dp83869_of_init(struct phy_device *phydev)
{
- return 0;
+ return dp83869_set_strapped_mode(phydev);
}
#endif /* CONFIG_OF_MDIO */
--
2.26.2
^ permalink raw reply related
* [PATCH v8 0/3] Add JEITA properties and introduce the bq2515x charger
From: Dan Murphy @ 2020-05-20 12:20 UTC (permalink / raw)
To: sre; +Cc: sspatil, dmurphy, linux-pm, robh, linux-kernel, devicetree
Hello,
This patchset adds additional health properties to the power_supply header.
These additional properties are taken from the JEITA specification. This
patchset also introduces the bq2515x family of charging ICs.
Dan Murphy (1):
power_supply: Add additional health properties to the header
Ricardo Rivera-Matos (2):
Add the bindings for the bq25150 and bq25155 500mA charging ICs from
Texas Instruments.
power: supply: bq25150 introduce the bq25150
Documentation/ABI/testing/sysfs-class-power | 2 +-
.../bindings/power/supply/bq2515x.yaml | 106 ++
drivers/power/supply/Kconfig | 13 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/bq2515x_charger.c | 1159 +++++++++++++++++
drivers/power/supply/power_supply_sysfs.c | 2 +-
include/linux/power_supply.h | 3 +
7 files changed, 1284 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/supply/bq2515x.yaml
create mode 100644 drivers/power/supply/bq2515x_charger.c
--
2.26.2
^ permalink raw reply
* [PATCH v8 1/3] power_supply: Add additional health properties to the header
From: Dan Murphy @ 2020-05-20 12:20 UTC (permalink / raw)
To: sre
Cc: sspatil, dmurphy, linux-pm, robh, linux-kernel, devicetree,
Guru Das Srinagesh
In-Reply-To: <20200520122027.31320-1-dmurphy@ti.com>
Add HEALTH_WARM, HEALTH_COOL and HEALTH_HOT to the health enum.
HEALTH_WARM, HEALTH_COOL, and HEALTH_HOT properties are taken from the JEITA spec.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
Tested-by: Guru Das Srinagesh <gurus@codeaurora.org>
---
Documentation/ABI/testing/sysfs-class-power | 2 +-
drivers/power/supply/power_supply_sysfs.c | 2 +-
include/linux/power_supply.h | 3 +++
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power
index bf3b48f022dc..9f3fd01a9373 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -190,7 +190,7 @@ Description:
Valid values: "Unknown", "Good", "Overheat", "Dead",
"Over voltage", "Unspecified failure", "Cold",
"Watchdog timer expire", "Safety timer expire",
- "Over current"
+ "Over current", "Warm", "Cool", "Hot"
What: /sys/class/power_supply/<supply_name>/precharge_current
Date: June 2017
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index f37ad4eae60b..d0d549611794 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -61,7 +61,7 @@ static const char * const power_supply_charge_type_text[] = {
static const char * const power_supply_health_text[] = {
"Unknown", "Good", "Overheat", "Dead", "Over voltage",
"Unspecified failure", "Cold", "Watchdog timer expire",
- "Safety timer expire", "Over current"
+ "Safety timer expire", "Over current", "Warm", "Cool", "Hot"
};
static const char * const power_supply_technology_text[] = {
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index dcd5a71e6c67..8670e90c1d51 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -61,6 +61,9 @@ enum {
POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE,
POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE,
POWER_SUPPLY_HEALTH_OVERCURRENT,
+ POWER_SUPPLY_HEALTH_WARM,
+ POWER_SUPPLY_HEALTH_COOL,
+ POWER_SUPPLY_HEALTH_HOT,
};
enum {
--
2.26.2
^ permalink raw reply related
* [PATCH v8 2/3] Add the bindings for the bq25150 and bq25155 500mA charging ICs from Texas Instruments.
From: Dan Murphy @ 2020-05-20 12:20 UTC (permalink / raw)
To: sre
Cc: sspatil, dmurphy, linux-pm, robh, linux-kernel, devicetree,
Ricardo Rivera-Matos
In-Reply-To: <20200520122027.31320-1-dmurphy@ti.com>
From: Ricardo Rivera-Matos <r-rivera-matos@ti.com>
The BQ2515X family of devices are highly integrated battery management
ICs that integrate the most common functions for wearable devices
namely a charger, an output voltage rail, ADC for battery and system
monitoring, and a push-button controller.
Datasheets:
http://www.ti.com/lit/ds/symlink/bq25150.pdf
http://www.ti.com/lit/ds/symlink/bq25155.pdf
Signed-off-by: Ricardo Rivera-Matos <r-rivera-matos@ti.com>
---
.../bindings/power/supply/bq2515x.yaml | 106 ++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/supply/bq2515x.yaml
diff --git a/Documentation/devicetree/bindings/power/supply/bq2515x.yaml b/Documentation/devicetree/bindings/power/supply/bq2515x.yaml
new file mode 100644
index 000000000000..83487957fc8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/bq2515x.yaml
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) 2020 Texas Instruments Incorporated
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/power/supply/bq2515x.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: TI bq2515x 500-mA Linear charger family
+
+maintainers:
+ - Dan Murphy <dmurphy@ti.com>
+ - Ricardo Rivera-Matos <r-rivera-matos@ti.com>
+
+description: |
+ The BQ2515x family is a highly integrated battery charge management IC that
+ integrates the most common functions for wearable devices, namely a charger,
+ an output voltage rail, ADC for battery and system monitoring, and
+ push-button controller.
+
+ Specifications about the charger can be found at:
+ http://www.ti.com/lit/ds/symlink/bq25150.pdf
+ http://www.ti.com/lit/ds/symlink/bq25155.pdf
+
+properties:
+ compatible:
+ enum:
+ - ti,bq25150
+ - ti,bq25155
+
+ reg:
+ maxItems: 1
+ description: I2C address of the charger.
+
+ ac-detect-gpios:
+ description: |
+ GPIO used for connecting the bq2515x device PG (AC Detect)
+ pin. This pin should be used if possible as this is the
+ recommended way to obtain the charger's input PG state.
+ If this pin is not specified a software-based approach for PG
+ detection is used.
+
+ reset-gpios:
+ description: |
+ GPIO used for hardware reset.
+
+ low-power-gpios:
+ description: |
+ GPIO used for low power mode of IC.
+
+ charge-enable-gpios:
+ description: |
+ GPIO used to turn on and off charging.
+
+ constant-charge-current-max-microamp:
+ description: |
+ Maximum charging current in micro Amps.
+ minimum: 50000
+ maximum: 600000
+
+ precharge-current-max-microamp:
+ description: |
+ Maximum precharging current in micro Amps.
+ minimum: 1250
+ maximum: 77500
+
+ input-current-limit-microamp:
+ description: |
+ Maximum input current in micro Amps.
+ minimum: 50000
+ maximum: 500000
+
+ constant-charge-voltage-max-microvolt:
+ description: |
+ Maximum charging voltage in micro volts.
+ minimum: 3600000
+ maximum: 4600000
+
+required:
+ - compatible
+ - reg
+
+examples:
+ - |
+ bat: battery {
+ compatible = "simple-battery";
+ constant-charge-current-max-microamp = <50000>;
+ precharge-current-microamp = <2500>;
+ constant-charge-voltage-max-microvolt = <4000000>;
+ };
+ #include <dt-bindings/gpio/gpio.h>
+ i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq25150: charger@6b {
+ compatible = "ti,bq25150";
+ reg = <0x6b>;
+ monitored-battery = <&bat>;
+ input-current-limit-microamp = <100000>;
+
+ ac-detect-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ low-power-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ charge-enable-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+ };
+ };
--
2.26.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox