* [PATCH v3 05/11] MAINTAINERS: pci: imx: update imx6* to imx* since rename driver file
From: Frank Li @ 2024-04-02 14:33 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Philipp Zabel, Liam Girdwood, Mark Brown,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, imx, linux-arm-kernel, linux-kernel, bpf, devicetree,
Frank Li
In-Reply-To: <20240402-pci2_upstream-v3-0-803414bdb430@nxp.com>
Add me to imx pcie driver maintainer.
Add mail list imx@lists.linux.dev.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
MAINTAINERS | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8d1052fa6a692..59a409dd604d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16736,14 +16736,16 @@ F: drivers/pci/controller/pci-host-generic.c
PCI DRIVER FOR IMX6
M: Richard Zhu <hongxing.zhu@nxp.com>
+M: Frank Li <Frank.Li@nxp.com>
M: Lucas Stach <l.stach@pengutronix.de>
L: linux-pci@vger.kernel.org
+L: imx@lists.linux.dev
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
-F: drivers/pci/controller/dwc/*imx6*
+F: drivers/pci/controller/dwc/*imx*
PCI DRIVER FOR INTEL IXP4XX
M: Linus Walleij <linus.walleij@linaro.org>
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 04/11] PCI: imx6: Rename pci-imx6.c to pcie-imx.c
From: Frank Li @ 2024-04-02 14:33 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Philipp Zabel, Liam Girdwood, Mark Brown,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, imx, linux-arm-kernel, linux-kernel, bpf, devicetree,
Frank Li
In-Reply-To: <20240402-pci2_upstream-v3-0-803414bdb430@nxp.com>
Update the filename from 'pci-imx6.c' to 'pcie-imx.c' to accurately reflect
its applicability to all i.MX chips (i.MX6x, i.MX7x, i.MX8x, i.MX9x).
Eliminate the '6' to prevent confusion. Additionally, correct the prefix
from 'pci-' to 'pcie-'.
Retain the previous configuration CONFIG_PCI_IMX6 unchanged to maintain
compatibility.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/Makefile | 2 +-
drivers/pci/controller/dwc/{pci-imx6.c => pcie-imx.c} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index bac103faa5237..eaea7abbabc2c 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
-obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_PCI_IMX6) += pcie-imx.o
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pcie-imx.c
similarity index 100%
rename from drivers/pci/controller/dwc/pci-imx6.c
rename to drivers/pci/controller/dwc/pcie-imx.c
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 03/11] PCI: imx6: Rename imx6_* with imx_*
From: Frank Li @ 2024-04-02 14:33 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Philipp Zabel, Liam Girdwood, Mark Brown,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, imx, linux-arm-kernel, linux-kernel, bpf, devicetree,
Frank Li
In-Reply-To: <20240402-pci2_upstream-v3-0-803414bdb430@nxp.com>
imx6_* actually mean for all imx chips (imx6x, imx7x, imx8x and imx9x).
Rename imx6_* with imx_* to avoid confuse.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 760 +++++++++++++++++-----------------
1 file changed, 380 insertions(+), 380 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 6c4d25b92225e..e93070d60df52 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -55,9 +55,9 @@
#define IMX95_PE0_GEN_CTRL_3 0x1058
#define IMX95_PCIE_LTSSM_EN BIT(0)
-#define to_imx6_pcie(x) dev_get_drvdata((x)->dev)
+#define to_imx_pcie(x) dev_get_drvdata((x)->dev)
-enum imx6_pcie_variants {
+enum imx_pcie_variants {
IMX6Q,
IMX6SX,
IMX6QP,
@@ -72,25 +72,25 @@ enum imx6_pcie_variants {
IMX95_EP,
};
-#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
-#define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1)
-#define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND BIT(2)
-#define IMX6_PCIE_FLAG_HAS_PHYDRV BIT(3)
-#define IMX6_PCIE_FLAG_HAS_APP_RESET BIT(4)
-#define IMX6_PCIE_FLAG_HAS_PHY_RESET BIT(5)
-#define IMX6_PCIE_FLAG_HAS_SERDES BIT(6)
-#define IMX6_PCIE_FLAG_SUPPORT_64BIT BIT(7)
+#define IMX_PCIE_FLAG_IMX_PHY BIT(0)
+#define IMX_PCIE_FLAG_IMX_SPEED_CHANGE BIT(1)
+#define IMX_PCIE_FLAG_SUPPORTS_SUSPEND BIT(2)
+#define IMX_PCIE_FLAG_HAS_PHYDRV BIT(3)
+#define IMX_PCIE_FLAG_HAS_APP_RESET BIT(4)
+#define IMX_PCIE_FLAG_HAS_PHY_RESET BIT(5)
+#define IMX_PCIE_FLAG_HAS_SERDES BIT(6)
+#define IMX_PCIE_FLAG_SUPPORT_64BIT BIT(7)
-#define imx6_check_flag(pci, val) (pci->drvdata->flags & val)
+#define imx_check_flag(pci, val) (pci->drvdata->flags & val)
-#define IMX6_PCIE_MAX_CLKS 6
+#define IMX_PCIE_MAX_CLKS 6
-#define IMX6_PCIE_MAX_INSTANCES 2
+#define IMX_PCIE_MAX_INSTANCES 2
-struct imx6_pcie;
+struct imx_pcie;
-struct imx6_pcie_drvdata {
- enum imx6_pcie_variants variant;
+struct imx_pcie_drvdata {
+ enum imx_pcie_variants variant;
enum dw_pcie_device_mode mode;
u32 flags;
int dbi_length;
@@ -99,18 +99,18 @@ struct imx6_pcie_drvdata {
const u32 clks_cnt;
const u32 ltssm_off;
const u32 ltssm_mask;
- const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
- const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
+ const u32 mode_off[IMX_PCIE_MAX_INSTANCES];
+ const u32 mode_mask[IMX_PCIE_MAX_INSTANCES];
const struct pci_epc_features *epc_features;
- int (*init_phy)(struct imx6_pcie *pcie);
+ int (*init_phy)(struct imx_pcie *pcie);
};
-struct imx6_pcie {
+struct imx_pcie {
struct dw_pcie *pci;
int reset_gpio;
bool gpio_active_high;
bool link_is_up;
- struct clk_bulk_data clks[IMX6_PCIE_MAX_CLKS];
+ struct clk_bulk_data clks[IMX_PCIE_MAX_CLKS];
struct regmap *iomuxc_gpr;
u16 msi_ctrl;
u32 controller_id;
@@ -131,7 +131,7 @@ struct imx6_pcie {
/* power domain for pcie phy */
struct device *pd_pcie_phy;
struct phy *phy;
- const struct imx6_pcie_drvdata *drvdata;
+ const struct imx_pcie_drvdata *drvdata;
};
/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -186,28 +186,28 @@ struct imx6_pcie {
#define PHY_RX_OVRD_IN_LO_RX_DATA_EN BIT(5)
#define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3)
-static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
+static unsigned int imx_pcie_grp_offset(const struct imx_pcie *imx_pcie)
{
- WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ &&
- imx6_pcie->drvdata->variant != IMX8MQ_EP &&
- imx6_pcie->drvdata->variant != IMX8MM &&
- imx6_pcie->drvdata->variant != IMX8MM_EP &&
- imx6_pcie->drvdata->variant != IMX8MP &&
- imx6_pcie->drvdata->variant != IMX8MP_EP);
- return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
+ WARN_ON(imx_pcie->drvdata->variant != IMX8MQ &&
+ imx_pcie->drvdata->variant != IMX8MQ_EP &&
+ imx_pcie->drvdata->variant != IMX8MM &&
+ imx_pcie->drvdata->variant != IMX8MM_EP &&
+ imx_pcie->drvdata->variant != IMX8MP &&
+ imx_pcie->drvdata->variant != IMX8MP_EP);
+ return imx_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
}
-static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie)
{
- regmap_update_bits(imx6_pcie->iomuxc_gpr,
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
IMX95_PCIE_SS_RW_REG_0,
IMX95_PCIE_PHY_CR_PARA_SEL,
IMX95_PCIE_PHY_CR_PARA_SEL);
- regmap_update_bits(imx6_pcie->iomuxc_gpr,
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
IMX95_PCIE_PHY_GEN_CTRL,
IMX95_PCIE_REF_USE_PAD, 0);
- regmap_update_bits(imx6_pcie->iomuxc_gpr,
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
IMX95_PCIE_SS_RW_REG_0,
IMX95_PCIE_REF_CLKEN,
IMX95_PCIE_REF_CLKEN);
@@ -215,9 +215,9 @@ static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
return 0;
}
-static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_configure_type(struct imx_pcie *imx_pcie)
{
- const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
+ const struct imx_pcie_drvdata *drvdata = imx_pcie->drvdata;
unsigned int mask, val, mode, id;
if (drvdata->mode == DW_PCIE_EP_TYPE)
@@ -225,7 +225,7 @@ static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
else
mode = PCI_EXP_TYPE_ROOT_PORT;
- id = imx6_pcie->controller_id;
+ id = imx_pcie->controller_id;
/* If mode_mask[id] is zero, means each controller have its individual gpr */
if (!drvdata->mode_mask[id])
@@ -234,12 +234,12 @@ static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
mask = drvdata->mode_mask[id];
val = mode << (ffs(mask) - 1);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->mode_off[id], mask, val);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, drvdata->mode_off[id], mask, val);
}
-static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val)
+static int pcie_phy_poll_ack(struct imx_pcie *imx_pcie, bool exp_val)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
bool val;
u32 max_iterations = 10;
u32 wait_counter = 0;
@@ -258,9 +258,9 @@ static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val)
return -ETIMEDOUT;
}
-static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
+static int pcie_phy_wait_ack(struct imx_pcie *imx_pcie, int addr)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
u32 val;
int ret;
@@ -270,24 +270,24 @@ static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
val |= PCIE_PHY_CTRL_CAP_ADR;
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);
- ret = pcie_phy_poll_ack(imx6_pcie, true);
+ ret = pcie_phy_poll_ack(imx_pcie, true);
if (ret)
return ret;
val = PCIE_PHY_CTRL_DATA(addr);
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);
- return pcie_phy_poll_ack(imx6_pcie, false);
+ return pcie_phy_poll_ack(imx_pcie, false);
}
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
-static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, u16 *data)
+static int pcie_phy_read(struct imx_pcie *imx_pcie, int addr, u16 *data)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
u32 phy_ctl;
int ret;
- ret = pcie_phy_wait_ack(imx6_pcie, addr);
+ ret = pcie_phy_wait_ack(imx_pcie, addr);
if (ret)
return ret;
@@ -295,7 +295,7 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, u16 *data)
phy_ctl = PCIE_PHY_CTRL_RD;
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, phy_ctl);
- ret = pcie_phy_poll_ack(imx6_pcie, true);
+ ret = pcie_phy_poll_ack(imx_pcie, true);
if (ret)
return ret;
@@ -304,18 +304,18 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, u16 *data)
/* deassert Read signal */
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x00);
- return pcie_phy_poll_ack(imx6_pcie, false);
+ return pcie_phy_poll_ack(imx_pcie, false);
}
-static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
+static int pcie_phy_write(struct imx_pcie *imx_pcie, int addr, u16 data)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
u32 var;
int ret;
/* write addr */
/* cap addr */
- ret = pcie_phy_wait_ack(imx6_pcie, addr);
+ ret = pcie_phy_wait_ack(imx_pcie, addr);
if (ret)
return ret;
@@ -326,7 +326,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
var |= PCIE_PHY_CTRL_CAP_DAT;
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
- ret = pcie_phy_poll_ack(imx6_pcie, true);
+ ret = pcie_phy_poll_ack(imx_pcie, true);
if (ret)
return ret;
@@ -335,7 +335,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
- ret = pcie_phy_poll_ack(imx6_pcie, false);
+ ret = pcie_phy_poll_ack(imx_pcie, false);
if (ret)
return ret;
@@ -344,7 +344,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack */
- ret = pcie_phy_poll_ack(imx6_pcie, true);
+ ret = pcie_phy_poll_ack(imx_pcie, true);
if (ret)
return ret;
@@ -353,7 +353,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
- ret = pcie_phy_poll_ack(imx6_pcie, false);
+ ret = pcie_phy_poll_ack(imx_pcie, false);
if (ret)
return ret;
@@ -362,74 +362,74 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
return 0;
}
-static int imx8mq_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static int imx8mq_pcie_init_phy(struct imx_pcie *imx_pcie)
{
/* TODO: Currently this code assumes external oscillator is being used */
- regmap_update_bits(imx6_pcie->iomuxc_gpr,
- imx6_pcie_grp_offset(imx6_pcie),
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ imx_pcie_grp_offset(imx_pcie),
IMX8MQ_GPR_PCIE_REF_USE_PAD,
IMX8MQ_GPR_PCIE_REF_USE_PAD);
/*
* Regarding the datasheet, the PCIE_VPH is suggested to be 1.8V. If the PCIE_VPH is
* supplied by 3.3V, the VREG_BYPASS should be cleared to zero.
*/
- if (imx6_pcie->vph && regulator_get_voltage(imx6_pcie->vph) > 3000000)
- regmap_update_bits(imx6_pcie->iomuxc_gpr,
- imx6_pcie_grp_offset(imx6_pcie),
+ if (imx_pcie->vph && regulator_get_voltage(imx_pcie->vph) > 3000000)
+ regmap_update_bits(imx_pcie->iomuxc_gpr,
+ imx_pcie_grp_offset(imx_pcie),
IMX8MQ_GPR_PCIE_VREG_BYPASS,
0);
return 0;
}
-static int imx7d_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static int imx7d_pcie_init_phy(struct imx_pcie *imx_pcie)
{
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
return 0;
}
-static int imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_init_phy(struct imx_pcie *imx_pcie)
{
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
/* configure constant input signal to the pcie ctrl and phy */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN1,
- imx6_pcie->tx_deemph_gen1 << 0);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_deemph_gen1 << 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB,
- imx6_pcie->tx_deemph_gen2_3p5db << 6);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_deemph_gen2_3p5db << 6);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB,
- imx6_pcie->tx_deemph_gen2_6db << 12);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_deemph_gen2_6db << 12);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_SWING_FULL,
- imx6_pcie->tx_swing_full << 18);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+ imx_pcie->tx_swing_full << 18);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_SWING_LOW,
- imx6_pcie->tx_swing_low << 25);
+ imx_pcie->tx_swing_low << 25);
return 0;
}
-static int imx6sx_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static int imx6sx_pcie_init_phy(struct imx_pcie *imx_pcie)
{
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_RX_EQ_MASK, IMX6SX_GPR12_PCIE_RX_EQ_2);
- return imx6_pcie_init_phy(imx6_pcie);
+ return imx_pcie_init_phy(imx_pcie);
}
-static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
+static void imx7d_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
{
u32 val;
- struct device *dev = imx6_pcie->pci->dev;
+ struct device *dev = imx_pcie->pci->dev;
- if (regmap_read_poll_timeout(imx6_pcie->iomuxc_gpr,
+ if (regmap_read_poll_timeout(imx_pcie->iomuxc_gpr,
IOMUXC_GPR22, val,
val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED,
PHY_PLL_LOCK_WAIT_USLEEP_MAX,
@@ -437,19 +437,19 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
dev_err(dev, "PCIe PLL lock timeout\n");
}
-static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
+static int imx_setup_phy_mpll(struct imx_pcie *imx_pcie)
{
unsigned long phy_rate = 0;
int mult, div;
u16 val;
int i;
- if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
+ if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_IMX_PHY))
return 0;
- for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
- if (strncmp(imx6_pcie->clks[i].id, "pcie_phy", 8) == 0)
- phy_rate = clk_get_rate(imx6_pcie->clks[i].clk);
+ for (i = 0; i < imx_pcie->drvdata->clks_cnt; i++)
+ if (strncmp(imx_pcie->clks[i].id, "pcie_phy", 8) == 0)
+ phy_rate = clk_get_rate(imx_pcie->clks[i].clk);
switch (phy_rate) {
case 125000000:
@@ -467,46 +467,46 @@ static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
div = 1;
break;
default:
- dev_err(imx6_pcie->pci->dev,
+ dev_err(imx_pcie->pci->dev,
"Unsupported PHY reference clock rate %lu\n", phy_rate);
return -EINVAL;
}
- pcie_phy_read(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, &val);
+ pcie_phy_read(imx_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, &val);
val &= ~(PCIE_PHY_MPLL_MULTIPLIER_MASK <<
PCIE_PHY_MPLL_MULTIPLIER_SHIFT);
val |= mult << PCIE_PHY_MPLL_MULTIPLIER_SHIFT;
val |= PCIE_PHY_MPLL_MULTIPLIER_OVRD;
- pcie_phy_write(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, val);
+ pcie_phy_write(imx_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, val);
- pcie_phy_read(imx6_pcie, PCIE_PHY_ATEOVRD, &val);
+ pcie_phy_read(imx_pcie, PCIE_PHY_ATEOVRD, &val);
val &= ~(PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK <<
PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT);
val |= div << PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT;
val |= PCIE_PHY_ATEOVRD_EN;
- pcie_phy_write(imx6_pcie, PCIE_PHY_ATEOVRD, val);
+ pcie_phy_write(imx_pcie, PCIE_PHY_ATEOVRD, val);
return 0;
}
-static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_reset_phy(struct imx_pcie *imx_pcie)
{
u16 tmp;
- if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
+ if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_IMX_PHY))
return;
- pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp);
+ pcie_phy_read(imx_pcie, PHY_RX_OVRD_IN_LO, &tmp);
tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN |
PHY_RX_OVRD_IN_LO_RX_PLL_EN);
- pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp);
+ pcie_phy_write(imx_pcie, PHY_RX_OVRD_IN_LO, tmp);
usleep_range(2000, 3000);
- pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp);
+ pcie_phy_read(imx_pcie, PHY_RX_OVRD_IN_LO, &tmp);
tmp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN |
PHY_RX_OVRD_IN_LO_RX_PLL_EN);
- pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp);
+ pcie_phy_write(imx_pcie, PHY_RX_OVRD_IN_LO, tmp);
}
#ifdef CONFIG_ARM
@@ -545,22 +545,22 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
}
#endif
-static int imx6_pcie_attach_pd(struct device *dev)
+static int imx_pcie_attach_pd(struct device *dev)
{
- struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
struct device_link *link;
/* Do nothing when in a single power domain */
if (dev->pm_domain)
return 0;
- imx6_pcie->pd_pcie = dev_pm_domain_attach_by_name(dev, "pcie");
- if (IS_ERR(imx6_pcie->pd_pcie))
- return PTR_ERR(imx6_pcie->pd_pcie);
+ imx_pcie->pd_pcie = dev_pm_domain_attach_by_name(dev, "pcie");
+ if (IS_ERR(imx_pcie->pd_pcie))
+ return PTR_ERR(imx_pcie->pd_pcie);
/* Do nothing when power domain missing */
- if (!imx6_pcie->pd_pcie)
+ if (!imx_pcie->pd_pcie)
return 0;
- link = device_link_add(dev, imx6_pcie->pd_pcie,
+ link = device_link_add(dev, imx_pcie->pd_pcie,
DL_FLAG_STATELESS |
DL_FLAG_PM_RUNTIME |
DL_FLAG_RPM_ACTIVE);
@@ -569,11 +569,11 @@ static int imx6_pcie_attach_pd(struct device *dev)
return -EINVAL;
}
- imx6_pcie->pd_pcie_phy = dev_pm_domain_attach_by_name(dev, "pcie_phy");
- if (IS_ERR(imx6_pcie->pd_pcie_phy))
- return PTR_ERR(imx6_pcie->pd_pcie_phy);
+ imx_pcie->pd_pcie_phy = dev_pm_domain_attach_by_name(dev, "pcie_phy");
+ if (IS_ERR(imx_pcie->pd_pcie_phy))
+ return PTR_ERR(imx_pcie->pd_pcie_phy);
- link = device_link_add(dev, imx6_pcie->pd_pcie_phy,
+ link = device_link_add(dev, imx_pcie->pd_pcie_phy,
DL_FLAG_STATELESS |
DL_FLAG_PM_RUNTIME |
DL_FLAG_RPM_ACTIVE);
@@ -585,20 +585,20 @@ static int imx6_pcie_attach_pd(struct device *dev)
return 0;
}
-static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie)
{
unsigned int offset;
int ret = 0;
- switch (imx6_pcie->drvdata->variant) {
+ switch (imx_pcie->drvdata->variant) {
case IMX6SX:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
break;
case IMX6QP:
case IMX6Q:
/* power up core phy and enable ref clock */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
/*
* the async reset input need ref clock to sync internally,
@@ -607,7 +607,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
* add one ~10us delay here.
*/
usleep_range(10, 100);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
break;
case IMX7D:
@@ -620,15 +620,15 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
case IMX8MQ_EP:
case IMX8MP:
case IMX8MP_EP:
- offset = imx6_pcie_grp_offset(imx6_pcie);
+ offset = imx_pcie_grp_offset(imx_pcie);
/*
* Set the over ride low and enabled
* make sure that REF_CLK is turned on.
*/
- regmap_update_bits(imx6_pcie->iomuxc_gpr, offset,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, offset,
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE,
0);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, offset,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, offset,
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN);
break;
@@ -637,19 +637,19 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
return ret;
}
-static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_disable_ref_clk(struct imx_pcie *imx_pcie)
{
- switch (imx6_pcie->drvdata->variant) {
+ switch (imx_pcie->drvdata->variant) {
case IMX6QP:
case IMX6Q:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 0);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD,
IMX6Q_GPR1_PCIE_TEST_PD);
break;
case IMX7D:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
break;
@@ -658,17 +658,17 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
}
}
-static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_clk_enable(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
struct device *dev = pci->dev;
int ret;
- ret = clk_bulk_prepare_enable(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+ ret = clk_bulk_prepare_enable(imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
if (ret)
return ret;
- ret = imx6_pcie_enable_ref_clk(imx6_pcie);
+ ret = imx_pcie_enable_ref_clk(imx_pcie);
if (ret) {
dev_err(dev, "unable to enable pcie ref clock\n");
goto err_ref_clk;
@@ -679,41 +679,41 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
return 0;
err_ref_clk:
- clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+ clk_bulk_disable_unprepare(imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
return ret;
}
-static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_clk_disable(struct imx_pcie *imx_pcie)
{
- imx6_pcie_disable_ref_clk(imx6_pcie);
- clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+ imx_pcie_disable_ref_clk(imx_pcie);
+ clk_bulk_disable_unprepare(imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
}
-static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
{
- reset_control_assert(imx6_pcie->pciephy_reset);
- reset_control_assert(imx6_pcie->apps_reset);
+ reset_control_assert(imx_pcie->pciephy_reset);
+ reset_control_assert(imx_pcie->apps_reset);
- switch (imx6_pcie->drvdata->variant) {
+ switch (imx_pcie->drvdata->variant) {
case IMX6SX:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
/* Force PCIe PHY reset */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
IMX6SX_GPR5_PCIE_BTNRST_RESET,
IMX6SX_GPR5_PCIE_BTNRST_RESET);
break;
case IMX6QP:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_SW_RST,
IMX6Q_GPR1_PCIE_SW_RST);
break;
case IMX6Q:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
break;
default:
@@ -721,47 +721,47 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
}
/* Some boards don't have PCIe reset GPIO. */
- if (gpio_is_valid(imx6_pcie->reset_gpio))
- gpio_set_value_cansleep(imx6_pcie->reset_gpio,
- imx6_pcie->gpio_active_high);
+ if (gpio_is_valid(imx_pcie->reset_gpio))
+ gpio_set_value_cansleep(imx_pcie->reset_gpio,
+ imx_pcie->gpio_active_high);
}
-static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
struct device *dev = pci->dev;
- reset_control_deassert(imx6_pcie->pciephy_reset);
+ reset_control_deassert(imx_pcie->pciephy_reset);
- switch (imx6_pcie->drvdata->variant) {
+ switch (imx_pcie->drvdata->variant) {
case IMX7D:
/* Workaround for ERR010728, failure of PCI-e PLL VCO to
* oscillate, especially when cold. This turns off "Duty-cycle
* Corrector" and other mysterious undocumented things.
*/
- if (likely(imx6_pcie->phy_base)) {
+ if (likely(imx_pcie->phy_base)) {
/* De-assert DCC_FB_EN */
writel(PCIE_PHY_CMN_REG4_DCC_FB_EN,
- imx6_pcie->phy_base + PCIE_PHY_CMN_REG4);
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG4);
/* Assert RX_EQS and RX_EQS_SEL */
writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL
| PCIE_PHY_CMN_REG24_RX_EQ,
- imx6_pcie->phy_base + PCIE_PHY_CMN_REG24);
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG24);
/* Assert ATT_MODE */
writel(PCIE_PHY_CMN_REG26_ATT_MODE,
- imx6_pcie->phy_base + PCIE_PHY_CMN_REG26);
+ imx_pcie->phy_base + PCIE_PHY_CMN_REG26);
} else {
dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n");
}
- imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
+ imx7d_pcie_wait_for_phy_pll_lock(imx_pcie);
break;
case IMX6SX:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
break;
case IMX6QP:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_SW_RST, 0);
usleep_range(200, 500);
@@ -771,10 +771,10 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
}
/* Some boards don't have PCIe reset GPIO. */
- if (gpio_is_valid(imx6_pcie->reset_gpio)) {
+ if (gpio_is_valid(imx_pcie->reset_gpio)) {
msleep(100);
- gpio_set_value_cansleep(imx6_pcie->reset_gpio,
- !imx6_pcie->gpio_active_high);
+ gpio_set_value_cansleep(imx_pcie->reset_gpio,
+ !imx_pcie->gpio_active_high);
/* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
msleep(100);
}
@@ -782,9 +782,9 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
return 0;
}
-static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
+static int imx_pcie_wait_for_speed_change(struct imx_pcie *imx_pcie)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
struct device *dev = pci->dev;
u32 tmp;
unsigned int retries;
@@ -801,33 +801,33 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
return -ETIMEDOUT;
}
-static void imx6_pcie_ltssm_enable(struct device *dev)
+static void imx_pcie_ltssm_enable(struct device *dev)
{
- struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
- const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ const struct imx_pcie_drvdata *drvdata = imx_pcie->drvdata;
if (drvdata->ltssm_mask)
- regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->ltssm_off, drvdata->ltssm_mask,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, drvdata->ltssm_off, drvdata->ltssm_mask,
drvdata->ltssm_mask);
- reset_control_deassert(imx6_pcie->apps_reset);
+ reset_control_deassert(imx_pcie->apps_reset);
}
-static void imx6_pcie_ltssm_disable(struct device *dev)
+static void imx_pcie_ltssm_disable(struct device *dev)
{
- struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
- const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ const struct imx_pcie_drvdata *drvdata = imx_pcie->drvdata;
if (drvdata->ltssm_mask)
- regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->ltssm_off,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, drvdata->ltssm_off,
drvdata->ltssm_mask, 0);
- reset_control_assert(imx6_pcie->apps_reset);
+ reset_control_assert(imx_pcie->apps_reset);
}
-static int imx6_pcie_start_link(struct dw_pcie *pci)
+static int imx_pcie_start_link(struct dw_pcie *pci)
{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
struct device *dev = pci->dev;
u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
u32 tmp;
@@ -846,7 +846,7 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
dw_pcie_dbi_ro_wr_dis(pci);
/* Start LTSSM. */
- imx6_pcie_ltssm_enable(dev);
+ imx_pcie_ltssm_enable(dev);
ret = dw_pcie_wait_for_link(pci);
if (ret)
@@ -869,8 +869,8 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
dw_pcie_dbi_ro_wr_dis(pci);
- if (imx6_pcie->drvdata->flags &
- IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE) {
+ if (imx_pcie->drvdata->flags &
+ IMX_PCIE_FLAG_IMX_SPEED_CHANGE) {
/*
* On i.MX7, DIRECT_SPEED_CHANGE behaves differently
* from i.MX6 family when no link speed transition
@@ -880,7 +880,7 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
* failure.
*/
- ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
+ ret = imx_pcie_wait_for_speed_change(imx_pcie);
if (ret) {
dev_err(dev, "Failed to bring link up!\n");
goto err_reset_phy;
@@ -895,37 +895,37 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
dev_info(dev, "Link: Only Gen1 is enabled\n");
}
- imx6_pcie->link_is_up = true;
+ imx_pcie->link_is_up = true;
tmp = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
dev_info(dev, "Link up, Gen%i\n", tmp & PCI_EXP_LNKSTA_CLS);
return 0;
err_reset_phy:
- imx6_pcie->link_is_up = false;
+ imx_pcie->link_is_up = false;
dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0),
dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1));
- imx6_pcie_reset_phy(imx6_pcie);
+ imx_pcie_reset_phy(imx_pcie);
return 0;
}
-static void imx6_pcie_stop_link(struct dw_pcie *pci)
+static void imx_pcie_stop_link(struct dw_pcie *pci)
{
struct device *dev = pci->dev;
/* Turn off PCIe LTSSM */
- imx6_pcie_ltssm_disable(dev);
+ imx_pcie_ltssm_disable(dev);
}
-static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
+static int imx_pcie_host_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct device *dev = pci->dev;
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
int ret;
- if (imx6_pcie->vpcie) {
- ret = regulator_enable(imx6_pcie->vpcie);
+ if (imx_pcie->vpcie) {
+ ret = regulator_enable(imx_pcie->vpcie);
if (ret) {
dev_err(dev, "failed to enable vpcie regulator: %d\n",
ret);
@@ -933,83 +933,83 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
}
}
- imx6_pcie_assert_core_reset(imx6_pcie);
+ imx_pcie_assert_core_reset(imx_pcie);
- if (imx6_pcie->drvdata->init_phy)
- imx6_pcie->drvdata->init_phy(imx6_pcie);
+ if (imx_pcie->drvdata->init_phy)
+ imx_pcie->drvdata->init_phy(imx_pcie);
- imx6_pcie_configure_type(imx6_pcie);
+ imx_pcie_configure_type(imx_pcie);
- ret = imx6_pcie_clk_enable(imx6_pcie);
+ ret = imx_pcie_clk_enable(imx_pcie);
if (ret) {
dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
goto err_reg_disable;
}
- if (imx6_pcie->phy) {
- ret = phy_init(imx6_pcie->phy);
+ if (imx_pcie->phy) {
+ ret = phy_init(imx_pcie->phy);
if (ret) {
dev_err(dev, "pcie PHY power up failed\n");
goto err_clk_disable;
}
}
- if (imx6_pcie->phy) {
- ret = phy_power_on(imx6_pcie->phy);
+ if (imx_pcie->phy) {
+ ret = phy_power_on(imx_pcie->phy);
if (ret) {
dev_err(dev, "waiting for PHY ready timeout!\n");
goto err_phy_off;
}
}
- ret = imx6_pcie_deassert_core_reset(imx6_pcie);
+ ret = imx_pcie_deassert_core_reset(imx_pcie);
if (ret < 0) {
dev_err(dev, "pcie deassert core reset failed: %d\n", ret);
goto err_phy_off;
}
- imx6_setup_phy_mpll(imx6_pcie);
+ imx_setup_phy_mpll(imx_pcie);
return 0;
err_phy_off:
- if (imx6_pcie->phy)
- phy_exit(imx6_pcie->phy);
+ if (imx_pcie->phy)
+ phy_exit(imx_pcie->phy);
err_clk_disable:
- imx6_pcie_clk_disable(imx6_pcie);
+ imx_pcie_clk_disable(imx_pcie);
err_reg_disable:
- if (imx6_pcie->vpcie)
- regulator_disable(imx6_pcie->vpcie);
+ if (imx_pcie->vpcie)
+ regulator_disable(imx_pcie->vpcie);
return ret;
}
-static void imx6_pcie_host_exit(struct dw_pcie_rp *pp)
+static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
- if (imx6_pcie->phy) {
- if (phy_power_off(imx6_pcie->phy))
+ if (imx_pcie->phy) {
+ if (phy_power_off(imx_pcie->phy))
dev_err(pci->dev, "unable to power off PHY\n");
- phy_exit(imx6_pcie->phy);
+ phy_exit(imx_pcie->phy);
}
- imx6_pcie_clk_disable(imx6_pcie);
+ imx_pcie_clk_disable(imx_pcie);
- if (imx6_pcie->vpcie)
- regulator_disable(imx6_pcie->vpcie);
+ if (imx_pcie->vpcie)
+ regulator_disable(imx_pcie->vpcie);
}
-static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
- .init = imx6_pcie_host_init,
- .deinit = imx6_pcie_host_exit,
+static const struct dw_pcie_host_ops imx_pcie_host_ops = {
+ .init = imx_pcie_host_init,
+ .deinit = imx_pcie_host_exit,
};
static const struct dw_pcie_ops dw_pcie_ops = {
- .start_link = imx6_pcie_start_link,
- .stop_link = imx6_pcie_stop_link,
+ .start_link = imx_pcie_start_link,
+ .stop_link = imx_pcie_stop_link,
};
-static void imx6_pcie_ep_init(struct dw_pcie_ep *ep)
+static void imx_pcie_ep_init(struct dw_pcie_ep *ep)
{
enum pci_barno bar;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -1018,7 +1018,7 @@ static void imx6_pcie_ep_init(struct dw_pcie_ep *ep)
dw_pcie_ep_reset_bar(pci, bar);
}
-static int imx6_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
+static int imx_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
unsigned int type, u16 interrupt_num)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -1065,35 +1065,35 @@ static const struct pci_epc_features imx95_pcie_epc_features = {
};
static const struct pci_epc_features*
-imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
+imx_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
- return imx6_pcie->drvdata->epc_features;
+ return imx_pcie->drvdata->epc_features;
}
static const struct dw_pcie_ep_ops pcie_ep_ops = {
- .init = imx6_pcie_ep_init,
- .raise_irq = imx6_pcie_ep_raise_irq,
- .get_features = imx6_pcie_ep_get_features,
+ .init = imx_pcie_ep_init,
+ .raise_irq = imx_pcie_ep_raise_irq,
+ .get_features = imx_pcie_ep_get_features,
};
-static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
+static int imx_add_pcie_ep(struct imx_pcie *imx_pcie,
struct platform_device *pdev)
{
int ret;
unsigned int pcie_dbi2_offset;
struct dw_pcie_ep *ep;
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
struct dw_pcie_rp *pp = &pci->pp;
struct device *dev = pci->dev;
- imx6_pcie_host_init(pp);
+ imx_pcie_host_init(pp);
ep = &pci->ep;
ep->ops = &pcie_ep_ops;
- switch (imx6_pcie->drvdata->variant) {
+ switch (imx_pcie->drvdata->variant) {
case IMX8MQ_EP:
case IMX8MM_EP:
case IMX8MP_EP:
@@ -1115,10 +1115,10 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
if (device_property_match_string(dev, "reg-names", "dbi2") >= 0)
pci->dbi_base2 = NULL;
- if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
+ if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_SUPPORT_64BIT))
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
- ep->page_size = imx6_pcie->drvdata->epc_features->align;
+ ep->page_size = imx_pcie->drvdata->epc_features->align;
ret = dw_pcie_ep_init(ep);
if (ret) {
@@ -1126,30 +1126,30 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
return ret;
}
/* Start LTSSM. */
- imx6_pcie_ltssm_enable(dev);
+ imx_pcie_ltssm_enable(dev);
return 0;
}
-static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
+static void imx_pcie_pm_turnoff(struct imx_pcie *imx_pcie)
{
- struct device *dev = imx6_pcie->pci->dev;
+ struct device *dev = imx_pcie->pci->dev;
/* Some variants have a turnoff reset in DT */
- if (imx6_pcie->turnoff_reset) {
- reset_control_assert(imx6_pcie->turnoff_reset);
- reset_control_deassert(imx6_pcie->turnoff_reset);
+ if (imx_pcie->turnoff_reset) {
+ reset_control_assert(imx_pcie->turnoff_reset);
+ reset_control_deassert(imx_pcie->turnoff_reset);
goto pm_turnoff_sleep;
}
/* Others poke directly at IOMUXC registers */
- switch (imx6_pcie->drvdata->variant) {
+ switch (imx_pcie->drvdata->variant) {
case IMX6SX:
case IMX6QP:
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_PM_TURN_OFF,
IMX6SX_GPR12_PCIE_PM_TURN_OFF);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0);
break;
default:
@@ -1168,73 +1168,73 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
usleep_range(1000, 10000);
}
-static void imx6_pcie_msi_save_restore(struct imx6_pcie *imx6_pcie, bool save)
+static void imx_pcie_msi_save_restore(struct imx_pcie *imx_pcie, bool save)
{
u8 offset;
u16 val;
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct dw_pcie *pci = imx_pcie->pci;
if (pci_msi_enabled()) {
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
if (save) {
val = dw_pcie_readw_dbi(pci, offset + PCI_MSI_FLAGS);
- imx6_pcie->msi_ctrl = val;
+ imx_pcie->msi_ctrl = val;
} else {
dw_pcie_dbi_ro_wr_en(pci);
- val = imx6_pcie->msi_ctrl;
+ val = imx_pcie->msi_ctrl;
dw_pcie_writew_dbi(pci, offset + PCI_MSI_FLAGS, val);
dw_pcie_dbi_ro_wr_dis(pci);
}
}
}
-static int imx6_pcie_suspend_noirq(struct device *dev)
+static int imx_pcie_suspend_noirq(struct device *dev)
{
- struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
- struct dw_pcie_rp *pp = &imx6_pcie->pci->pp;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ struct dw_pcie_rp *pp = &imx_pcie->pci->pp;
- if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_SUSPEND))
+ if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_SUPPORTS_SUSPEND))
return 0;
- imx6_pcie_msi_save_restore(imx6_pcie, true);
- imx6_pcie_pm_turnoff(imx6_pcie);
- imx6_pcie_stop_link(imx6_pcie->pci);
- imx6_pcie_host_exit(pp);
+ imx_pcie_msi_save_restore(imx_pcie, true);
+ imx_pcie_pm_turnoff(imx_pcie);
+ imx_pcie_stop_link(imx_pcie->pci);
+ imx_pcie_host_exit(pp);
return 0;
}
-static int imx6_pcie_resume_noirq(struct device *dev)
+static int imx_pcie_resume_noirq(struct device *dev)
{
int ret;
- struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
- struct dw_pcie_rp *pp = &imx6_pcie->pci->pp;
+ struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+ struct dw_pcie_rp *pp = &imx_pcie->pci->pp;
- if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_SUSPEND))
+ if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_SUPPORTS_SUSPEND))
return 0;
- ret = imx6_pcie_host_init(pp);
+ ret = imx_pcie_host_init(pp);
if (ret)
return ret;
- imx6_pcie_msi_save_restore(imx6_pcie, false);
+ imx_pcie_msi_save_restore(imx_pcie, false);
dw_pcie_setup_rc(pp);
- if (imx6_pcie->link_is_up)
- imx6_pcie_start_link(imx6_pcie->pci);
+ if (imx_pcie->link_is_up)
+ imx_pcie_start_link(imx_pcie->pci);
return 0;
}
-static const struct dev_pm_ops imx6_pcie_pm_ops = {
- NOIRQ_SYSTEM_SLEEP_PM_OPS(imx6_pcie_suspend_noirq,
- imx6_pcie_resume_noirq)
+static const struct dev_pm_ops imx_pcie_pm_ops = {
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_pcie_suspend_noirq,
+ imx_pcie_resume_noirq)
};
-static int imx6_pcie_probe(struct platform_device *pdev)
+static int imx_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
- struct imx6_pcie *imx6_pcie;
+ struct imx_pcie *imx_pcie;
struct device_node *np;
struct resource *dbi_base;
struct device_node *node = dev->of_node;
@@ -1242,8 +1242,8 @@ static int imx6_pcie_probe(struct platform_device *pdev)
u16 val;
int i;
- imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
- if (!imx6_pcie)
+ imx_pcie = devm_kzalloc(dev, sizeof(*imx_pcie), GFP_KERNEL);
+ if (!imx_pcie)
return -ENOMEM;
pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
@@ -1252,10 +1252,10 @@ static int imx6_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &dw_pcie_ops;
- pci->pp.ops = &imx6_pcie_host_ops;
+ pci->pp.ops = &imx_pcie_host_ops;
- imx6_pcie->pci = pci;
- imx6_pcie->drvdata = of_device_get_match_data(dev);
+ imx_pcie->pci = pci;
+ imx_pcie->drvdata = of_device_get_match_data(dev);
/* Find the PHY if one is defined, only imx7d uses it */
np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
@@ -1267,9 +1267,9 @@ static int imx6_pcie_probe(struct platform_device *pdev)
dev_err(dev, "Unable to map PCIe PHY\n");
return ret;
}
- imx6_pcie->phy_base = devm_ioremap_resource(dev, &res);
- if (IS_ERR(imx6_pcie->phy_base))
- return PTR_ERR(imx6_pcie->phy_base);
+ imx_pcie->phy_base = devm_ioremap_resource(dev, &res);
+ if (IS_ERR(imx_pcie->phy_base))
+ return PTR_ERR(imx_pcie->phy_base);
}
pci->dbi_base = devm_platform_get_and_ioremap_resource(pdev, 0, &dbi_base);
@@ -1277,12 +1277,12 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(pci->dbi_base);
/* Fetch GPIOs */
- imx6_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
- imx6_pcie->gpio_active_high = of_property_read_bool(node,
+ imx_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
+ imx_pcie->gpio_active_high = of_property_read_bool(node,
"reset-gpio-active-high");
- if (gpio_is_valid(imx6_pcie->reset_gpio)) {
- ret = devm_gpio_request_one(dev, imx6_pcie->reset_gpio,
- imx6_pcie->gpio_active_high ?
+ if (gpio_is_valid(imx_pcie->reset_gpio)) {
+ ret = devm_gpio_request_one(dev, imx_pcie->reset_gpio,
+ imx_pcie->gpio_active_high ?
GPIOF_OUT_INIT_HIGH :
GPIOF_OUT_INIT_LOW,
"PCIe reset");
@@ -1290,70 +1290,70 @@ static int imx6_pcie_probe(struct platform_device *pdev)
dev_err(dev, "unable to get reset gpio\n");
return ret;
}
- } else if (imx6_pcie->reset_gpio == -EPROBE_DEFER) {
- return imx6_pcie->reset_gpio;
+ } else if (imx_pcie->reset_gpio == -EPROBE_DEFER) {
+ return imx_pcie->reset_gpio;
}
- if (imx6_pcie->drvdata->clks_cnt >= IMX6_PCIE_MAX_CLKS)
+ if (imx_pcie->drvdata->clks_cnt >= IMX_PCIE_MAX_CLKS)
return dev_err_probe(dev, -ENOMEM, "clks_cnt is too big\n");
- for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
- imx6_pcie->clks[i].id = imx6_pcie->drvdata->clk_names[i];
+ for (i = 0; i < imx_pcie->drvdata->clks_cnt; i++)
+ imx_pcie->clks[i].id = imx_pcie->drvdata->clk_names[i];
/* Fetch clocks */
- ret = devm_clk_bulk_get(dev, imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+ ret = devm_clk_bulk_get(dev, imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
if (ret)
return ret;
- if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHYDRV)) {
- imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
- if (IS_ERR(imx6_pcie->phy))
- return dev_err_probe(dev, PTR_ERR(imx6_pcie->phy),
+ if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_PHYDRV)) {
+ imx_pcie->phy = devm_phy_get(dev, "pcie-phy");
+ if (IS_ERR(imx_pcie->phy))
+ return dev_err_probe(dev, PTR_ERR(imx_pcie->phy),
"failed to get pcie phy\n");
}
- if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_APP_RESET)) {
- imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, "apps");
- if (IS_ERR(imx6_pcie->apps_reset))
- return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
+ if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_APP_RESET)) {
+ imx_pcie->apps_reset = devm_reset_control_get_exclusive(dev, "apps");
+ if (IS_ERR(imx_pcie->apps_reset))
+ return dev_err_probe(dev, PTR_ERR(imx_pcie->apps_reset),
"failed to get pcie apps reset control\n");
}
- if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHY_RESET)) {
- imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, "pciephy");
- if (IS_ERR(imx6_pcie->pciephy_reset))
- return dev_err_probe(dev, PTR_ERR(imx6_pcie->pciephy_reset),
+ if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_PHY_RESET)) {
+ imx_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, "pciephy");
+ if (IS_ERR(imx_pcie->pciephy_reset))
+ return dev_err_probe(dev, PTR_ERR(imx_pcie->pciephy_reset),
"Failed to get PCIEPHY reset control\n");
}
- switch (imx6_pcie->drvdata->variant) {
+ switch (imx_pcie->drvdata->variant) {
case IMX8MQ:
case IMX8MQ_EP:
case IMX7D:
if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
- imx6_pcie->controller_id = 1;
+ imx_pcie->controller_id = 1;
break;
default:
break;
}
/* Grab turnoff reset */
- imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
- if (IS_ERR(imx6_pcie->turnoff_reset)) {
+ imx_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
+ if (IS_ERR(imx_pcie->turnoff_reset)) {
dev_err(dev, "Failed to get TURNOFF reset control\n");
- return PTR_ERR(imx6_pcie->turnoff_reset);
+ return PTR_ERR(imx_pcie->turnoff_reset);
}
- if (imx6_pcie->drvdata->gpr) {
+ if (imx_pcie->drvdata->gpr) {
/* Grab GPR config register range */
- imx6_pcie->iomuxc_gpr =
- syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
- if (IS_ERR(imx6_pcie->iomuxc_gpr))
- return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
+ imx_pcie->iomuxc_gpr =
+ syscon_regmap_lookup_by_compatible(imx_pcie->drvdata->gpr);
+ if (IS_ERR(imx_pcie->iomuxc_gpr))
+ return dev_err_probe(dev, PTR_ERR(imx_pcie->iomuxc_gpr),
"unable to find iomuxc registers\n");
}
- if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_SERDES)) {
+ if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_SERDES)) {
void __iomem *off = devm_platform_ioremap_resource_byname(pdev, "app");
if (IS_ERR(off))
@@ -1366,59 +1366,59 @@ static int imx6_pcie_probe(struct platform_device *pdev)
.reg_stride = 4,
};
- imx6_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, ®map_config);
- if (IS_ERR(imx6_pcie->iomuxc_gpr))
- return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
+ imx_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, ®map_config);
+ if (IS_ERR(imx_pcie->iomuxc_gpr))
+ return dev_err_probe(dev, PTR_ERR(imx_pcie->iomuxc_gpr),
"unable to find iomuxc registers\n");
}
/* Grab PCIe PHY Tx Settings */
if (of_property_read_u32(node, "fsl,tx-deemph-gen1",
- &imx6_pcie->tx_deemph_gen1))
- imx6_pcie->tx_deemph_gen1 = 0;
+ &imx_pcie->tx_deemph_gen1))
+ imx_pcie->tx_deemph_gen1 = 0;
if (of_property_read_u32(node, "fsl,tx-deemph-gen2-3p5db",
- &imx6_pcie->tx_deemph_gen2_3p5db))
- imx6_pcie->tx_deemph_gen2_3p5db = 0;
+ &imx_pcie->tx_deemph_gen2_3p5db))
+ imx_pcie->tx_deemph_gen2_3p5db = 0;
if (of_property_read_u32(node, "fsl,tx-deemph-gen2-6db",
- &imx6_pcie->tx_deemph_gen2_6db))
- imx6_pcie->tx_deemph_gen2_6db = 20;
+ &imx_pcie->tx_deemph_gen2_6db))
+ imx_pcie->tx_deemph_gen2_6db = 20;
if (of_property_read_u32(node, "fsl,tx-swing-full",
- &imx6_pcie->tx_swing_full))
- imx6_pcie->tx_swing_full = 127;
+ &imx_pcie->tx_swing_full))
+ imx_pcie->tx_swing_full = 127;
if (of_property_read_u32(node, "fsl,tx-swing-low",
- &imx6_pcie->tx_swing_low))
- imx6_pcie->tx_swing_low = 127;
+ &imx_pcie->tx_swing_low))
+ imx_pcie->tx_swing_low = 127;
/* Limit link speed */
pci->link_gen = 1;
of_property_read_u32(node, "fsl,max-link-speed", &pci->link_gen);
- imx6_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");
- if (IS_ERR(imx6_pcie->vpcie)) {
- if (PTR_ERR(imx6_pcie->vpcie) != -ENODEV)
- return PTR_ERR(imx6_pcie->vpcie);
- imx6_pcie->vpcie = NULL;
+ imx_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");
+ if (IS_ERR(imx_pcie->vpcie)) {
+ if (PTR_ERR(imx_pcie->vpcie) != -ENODEV)
+ return PTR_ERR(imx_pcie->vpcie);
+ imx_pcie->vpcie = NULL;
}
- imx6_pcie->vph = devm_regulator_get_optional(&pdev->dev, "vph");
- if (IS_ERR(imx6_pcie->vph)) {
- if (PTR_ERR(imx6_pcie->vph) != -ENODEV)
- return PTR_ERR(imx6_pcie->vph);
- imx6_pcie->vph = NULL;
+ imx_pcie->vph = devm_regulator_get_optional(&pdev->dev, "vph");
+ if (IS_ERR(imx_pcie->vph)) {
+ if (PTR_ERR(imx_pcie->vph) != -ENODEV)
+ return PTR_ERR(imx_pcie->vph);
+ imx_pcie->vph = NULL;
}
- platform_set_drvdata(pdev, imx6_pcie);
+ platform_set_drvdata(pdev, imx_pcie);
- ret = imx6_pcie_attach_pd(dev);
+ ret = imx_pcie_attach_pd(dev);
if (ret)
return ret;
- if (imx6_pcie->drvdata->mode == DW_PCIE_EP_TYPE) {
- ret = imx6_add_pcie_ep(imx6_pcie, pdev);
+ if (imx_pcie->drvdata->mode == DW_PCIE_EP_TYPE) {
+ ret = imx_add_pcie_ep(imx_pcie, pdev);
if (ret < 0)
return ret;
} else {
@@ -1438,12 +1438,12 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return 0;
}
-static void imx6_pcie_shutdown(struct platform_device *pdev)
+static void imx_pcie_shutdown(struct platform_device *pdev)
{
- struct imx6_pcie *imx6_pcie = platform_get_drvdata(pdev);
+ struct imx_pcie *imx_pcie = platform_get_drvdata(pdev);
/* bring down link, so bootloader gets clean state in case of reboot */
- imx6_pcie_assert_core_reset(imx6_pcie);
+ imx_pcie_assert_core_reset(imx_pcie);
}
static const char * const imx6q_clks[] = {"pcie_bus", "pcie", "pcie_phy"};
@@ -1451,11 +1451,11 @@ static const char * const imx8mm_clks[] = {"pcie_bus", "pcie", "pcie_aux"};
static const char * const imx8mq_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux"};
static const char * const imx6sx_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_inbound_axi"};
-static const struct imx6_pcie_drvdata drvdata[] = {
+static const struct imx_pcie_drvdata drvdata[] = {
[IMX6Q] = {
.variant = IMX6Q,
- .flags = IMX6_PCIE_FLAG_IMX6_PHY |
- IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
+ .flags = IMX_PCIE_FLAG_IMX_PHY |
+ IMX_PCIE_FLAG_IMX_SPEED_CHANGE,
.dbi_length = 0x200,
.gpr = "fsl,imx6q-iomuxc-gpr",
.clk_names = imx6q_clks,
@@ -1464,13 +1464,13 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
.mode_off[0] = IOMUXC_GPR12,
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
- .init_phy = imx6_pcie_init_phy,
+ .init_phy = imx_pcie_init_phy,
},
[IMX6SX] = {
.variant = IMX6SX,
- .flags = IMX6_PCIE_FLAG_IMX6_PHY |
- IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
- IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+ .flags = IMX_PCIE_FLAG_IMX_PHY |
+ IMX_PCIE_FLAG_IMX_SPEED_CHANGE |
+ IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
.gpr = "fsl,imx6q-iomuxc-gpr",
.clk_names = imx6sx_clks,
.clks_cnt = ARRAY_SIZE(imx6sx_clks),
@@ -1482,9 +1482,9 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX6QP] = {
.variant = IMX6QP,
- .flags = IMX6_PCIE_FLAG_IMX6_PHY |
- IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
- IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+ .flags = IMX_PCIE_FLAG_IMX_PHY |
+ IMX_PCIE_FLAG_IMX_SPEED_CHANGE |
+ IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
.dbi_length = 0x200,
.gpr = "fsl,imx6q-iomuxc-gpr",
.clk_names = imx6q_clks,
@@ -1493,13 +1493,13 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
.mode_off[0] = IOMUXC_GPR12,
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
- .init_phy = imx6_pcie_init_phy,
+ .init_phy = imx_pcie_init_phy,
},
[IMX7D] = {
.variant = IMX7D,
- .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
- IMX6_PCIE_FLAG_HAS_APP_RESET |
- IMX6_PCIE_FLAG_HAS_PHY_RESET,
+ .flags = IMX_PCIE_FLAG_SUPPORTS_SUSPEND |
+ IMX_PCIE_FLAG_HAS_APP_RESET |
+ IMX_PCIE_FLAG_HAS_PHY_RESET,
.gpr = "fsl,imx7d-iomuxc-gpr",
.clk_names = imx6q_clks,
.clks_cnt = ARRAY_SIZE(imx6q_clks),
@@ -1509,8 +1509,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MQ] = {
.variant = IMX8MQ,
- .flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
- IMX6_PCIE_FLAG_HAS_PHY_RESET,
+ .flags = IMX_PCIE_FLAG_HAS_APP_RESET |
+ IMX_PCIE_FLAG_HAS_PHY_RESET,
.gpr = "fsl,imx8mq-iomuxc-gpr",
.clk_names = imx8mq_clks,
.clks_cnt = ARRAY_SIZE(imx8mq_clks),
@@ -1522,9 +1522,9 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MM] = {
.variant = IMX8MM,
- .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
- IMX6_PCIE_FLAG_HAS_PHYDRV |
- IMX6_PCIE_FLAG_HAS_APP_RESET,
+ .flags = IMX_PCIE_FLAG_SUPPORTS_SUSPEND |
+ IMX_PCIE_FLAG_HAS_PHYDRV |
+ IMX_PCIE_FLAG_HAS_APP_RESET,
.gpr = "fsl,imx8mm-iomuxc-gpr",
.clk_names = imx8mm_clks,
.clks_cnt = ARRAY_SIZE(imx8mm_clks),
@@ -1533,9 +1533,9 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MP] = {
.variant = IMX8MP,
- .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
- IMX6_PCIE_FLAG_HAS_PHYDRV |
- IMX6_PCIE_FLAG_HAS_APP_RESET,
+ .flags = IMX_PCIE_FLAG_SUPPORTS_SUSPEND |
+ IMX_PCIE_FLAG_HAS_PHYDRV |
+ IMX_PCIE_FLAG_HAS_APP_RESET,
.gpr = "fsl,imx8mp-iomuxc-gpr",
.clk_names = imx8mm_clks,
.clks_cnt = ARRAY_SIZE(imx8mm_clks),
@@ -1544,7 +1544,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX95] = {
.variant = IMX95,
- .flags = IMX6_PCIE_FLAG_HAS_SERDES,
+ .flags = IMX_PCIE_FLAG_HAS_SERDES,
.clk_names = imx8mq_clks,
.clks_cnt = ARRAY_SIZE(imx8mq_clks),
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
@@ -1555,8 +1555,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MQ_EP] = {
.variant = IMX8MQ_EP,
- .flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
- IMX6_PCIE_FLAG_HAS_PHY_RESET,
+ .flags = IMX_PCIE_FLAG_HAS_APP_RESET |
+ IMX_PCIE_FLAG_HAS_PHY_RESET,
.mode = DW_PCIE_EP_TYPE,
.gpr = "fsl,imx8mq-iomuxc-gpr",
.clk_names = imx8mq_clks,
@@ -1570,8 +1570,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MM_EP] = {
.variant = IMX8MM_EP,
- .flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
- IMX6_PCIE_FLAG_HAS_PHYDRV,
+ .flags = IMX_PCIE_FLAG_HAS_APP_RESET |
+ IMX_PCIE_FLAG_HAS_PHYDRV,
.mode = DW_PCIE_EP_TYPE,
.gpr = "fsl,imx8mm-iomuxc-gpr",
.clk_names = imx8mm_clks,
@@ -1582,8 +1582,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MP_EP] = {
.variant = IMX8MP_EP,
- .flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
- IMX6_PCIE_FLAG_HAS_PHYDRV,
+ .flags = IMX_PCIE_FLAG_HAS_APP_RESET |
+ IMX_PCIE_FLAG_HAS_PHYDRV,
.mode = DW_PCIE_EP_TYPE,
.gpr = "fsl,imx8mp-iomuxc-gpr",
.clk_names = imx8mm_clks,
@@ -1594,8 +1594,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX95_EP] = {
.variant = IMX95_EP,
- .flags = IMX6_PCIE_FLAG_HAS_SERDES |
- IMX6_PCIE_FLAG_SUPPORT_64BIT,
+ .flags = IMX_PCIE_FLAG_HAS_SERDES |
+ IMX_PCIE_FLAG_SUPPORT_64BIT,
.clk_names = imx8mq_clks,
.clks_cnt = ARRAY_SIZE(imx8mq_clks),
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
@@ -1608,7 +1608,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
};
-static const struct of_device_id imx6_pcie_of_match[] = {
+static const struct of_device_id imx_pcie_of_match[] = {
{ .compatible = "fsl,imx6q-pcie", .data = &drvdata[IMX6Q], },
{ .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
{ .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], },
@@ -1624,19 +1624,19 @@ static const struct of_device_id imx6_pcie_of_match[] = {
{},
};
-static struct platform_driver imx6_pcie_driver = {
+static struct platform_driver imx_pcie_driver = {
.driver = {
.name = "imx6q-pcie",
- .of_match_table = imx6_pcie_of_match,
+ .of_match_table = imx_pcie_of_match,
.suppress_bind_attrs = true,
- .pm = &imx6_pcie_pm_ops,
+ .pm = &imx_pcie_pm_ops,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
- .probe = imx6_pcie_probe,
- .shutdown = imx6_pcie_shutdown,
+ .probe = imx_pcie_probe,
+ .shutdown = imx_pcie_shutdown,
};
-static void imx6_pcie_quirk(struct pci_dev *dev)
+static void imx_pcie_quirk(struct pci_dev *dev)
{
struct pci_bus *bus = dev->bus;
struct dw_pcie_rp *pp = bus->sysdata;
@@ -1646,33 +1646,33 @@ static void imx6_pcie_quirk(struct pci_dev *dev)
return;
/* Make sure we only quirk devices associated with this driver */
- if (bus->dev.parent->parent->driver != &imx6_pcie_driver.driver)
+ if (bus->dev.parent->parent->driver != &imx_pcie_driver.driver)
return;
if (pci_is_root_bus(bus)) {
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+ struct imx_pcie *imx_pcie = to_imx_pcie(pci);
/*
* Limit config length to avoid the kernel reading beyond
* the register set and causing an abort on i.MX 6Quad
*/
- if (imx6_pcie->drvdata->dbi_length) {
- dev->cfg_size = imx6_pcie->drvdata->dbi_length;
+ if (imx_pcie->drvdata->dbi_length) {
+ dev->cfg_size = imx_pcie->drvdata->dbi_length;
dev_info(&dev->dev, "Limiting cfg_size to %d\n",
dev->cfg_size);
}
}
}
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd,
- PCI_CLASS_BRIDGE_PCI, 8, imx6_pcie_quirk);
+ PCI_CLASS_BRIDGE_PCI, 8, imx_pcie_quirk);
-static int __init imx6_pcie_init(void)
+static int __init imx_pcie_init(void)
{
#ifdef CONFIG_ARM
struct device_node *np;
- np = of_find_matching_node(NULL, imx6_pcie_of_match);
+ np = of_find_matching_node(NULL, imx_pcie_of_match);
if (!np)
return -ENODEV;
of_node_put(np);
@@ -1688,6 +1688,6 @@ static int __init imx6_pcie_init(void)
"external abort on non-linefetch");
#endif
- return platform_driver_register(&imx6_pcie_driver);
+ return platform_driver_register(&imx_pcie_driver);
}
-device_initcall(imx6_pcie_init);
+device_initcall(imx_pcie_init);
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 02/11] PCI: imx6: Fix i.MX8MP PCIe EP can not trigger MSI
From: Frank Li @ 2024-04-02 14:33 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Philipp Zabel, Liam Girdwood, Mark Brown,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, imx, linux-arm-kernel, linux-kernel, bpf, devicetree,
Frank Li, Jason Liu
In-Reply-To: <20240402-pci2_upstream-v3-0-803414bdb430@nxp.com>
From: Richard Zhu <hongxing.zhu@nxp.com>
Fix i.MX8MP PCIe EP can't trigger MSI issue.
There is one 64Kbytes minimal requirement on i.MX8M PCIe outbound
region configuration.
EP uses Bar0 to set the outboud region to configure the MSI setting.
Set the page_size to "epc_features->align" to meet the requirement,
let the MSI can be triggered successfully.
Fixes: 1bd0d43dcf3b ("PCI: imx6: Clean up addr_space retrieval code")
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Acked-by: Jason Liu <jason.hui.liu@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index e43eda6b33ca7..6c4d25b92225e 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1118,6 +1118,8 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+ ep->page_size = imx6_pcie->drvdata->epc_features->align;
+
ret = dw_pcie_ep_init(ep);
if (ret) {
dev_err(dev, "failed to initialize endpoint\n");
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 01/11] PCI: imx6: Fix PCIe link down when i.MX8MM and i.MX8MP PCIe is EP mode
From: Frank Li @ 2024-04-02 14:33 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Philipp Zabel, Liam Girdwood, Mark Brown,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, imx, linux-arm-kernel, linux-kernel, bpf, devicetree,
Frank Li
In-Reply-To: <20240402-pci2_upstream-v3-0-803414bdb430@nxp.com>
From: Richard Zhu <hongxing.zhu@nxp.com>
Both IMX8MM_EP and IMX8MP_EP have the "IMX6_PCIE_FLAG_HAS_APP_RESET"
set indeed. Otherwise, the LTSSM_EN bit wouldn't be asserted anymore.
That's the root cause that PCIe link is down when i.MX8MM and i.MX8MP
PCIe are in the EP mode.
Fixes: 0c9651c21f2a ("PCI: imx6: Simplify reset handling by using *_FLAG_HAS_*_RESET")
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 99a60270b26cd..e43eda6b33ca7 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1568,7 +1568,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MM_EP] = {
.variant = IMX8MM_EP,
- .flags = IMX6_PCIE_FLAG_HAS_PHYDRV,
+ .flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
+ IMX6_PCIE_FLAG_HAS_PHYDRV,
.mode = DW_PCIE_EP_TYPE,
.gpr = "fsl,imx8mm-iomuxc-gpr",
.clk_names = imx8mm_clks,
@@ -1579,7 +1580,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
},
[IMX8MP_EP] = {
.variant = IMX8MP_EP,
- .flags = IMX6_PCIE_FLAG_HAS_PHYDRV,
+ .flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
+ IMX6_PCIE_FLAG_HAS_PHYDRV,
.mode = DW_PCIE_EP_TYPE,
.gpr = "fsl,imx8mp-iomuxc-gpr",
.clk_names = imx8mm_clks,
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 00/11] PCI: imx6: Fix\rename\clean up and add lut information for imx95
From: Frank Li @ 2024-04-02 14:33 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Philipp Zabel, Liam Girdwood, Mark Brown,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, imx, linux-arm-kernel, linux-kernel, bpf, devicetree,
Frank Li, Jason Liu
Fixed 8mp EP mode problem.
imx6 actaully for all imx chips (imx6*, imx7*, imx8*, imx9*). To avoid
confuse, rename all imx6_* to imx_*, IMX6_* to IMX_*. pci-imx6.c to
pci-imx.c to avoid confuse.
Using callback to reduce switch case for core reset and refclk.
Add imx95 iommux and its stream id information.
Base on linux-pci/controller/imx
To: Richard Zhu <hongxing.zhu@nxp.com>
To: Lucas Stach <l.stach@pengutronix.de>
To: Lorenzo Pieralisi <lpieralisi@kernel.org>
To: Krzysztof Wilczyński <kw@linux.com>
To: Rob Herring <robh@kernel.org>
To: Bjorn Helgaas <bhelgaas@google.com>
To: Shawn Guo <shawnguo@kernel.org>
To: Sascha Hauer <s.hauer@pengutronix.de>
To: Pengutronix Kernel Team <kernel@pengutronix.de>
To: Fabio Estevam <festevam@gmail.com>
To: NXP Linux Team <linux-imx@nxp.com>
To: Philipp Zabel <p.zabel@pengutronix.de>
To: Liam Girdwood <lgirdwood@gmail.com>
To: Mark Brown <broonie@kernel.org>
To: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
To: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
To: Conor Dooley <conor+dt@kernel.org>
Cc: linux-pci@vger.kernel.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: bpf@vger.kernel.org
Cc: devicetree@vger.kernel.org
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Changes in v3:
- Add an EP fixed patch
PCI: imx6: Fix PCIe link down when i.MX8MM and i.MX8MP PCIe is EP mode
PCI: imx6: Fix i.MX8MP PCIe EP can not trigger MSI
- Add 8qxp rc support
dt-bing yaml pass binding check
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8 dt_binding_check DT_SCHEMA_FILES=fsl,imx6q-pcie.yaml
LINT Documentation/devicetree/bindings
DTEX Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.example.dts
CHKDT Documentation/devicetree/bindings/processed-schema.json
SCHEMA Documentation/devicetree/bindings/processed-schema.json
DTC_CHK Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.example.dtb
- Link to v2: https://lore.kernel.org/r/20240304-pci2_upstream-v2-0-ad07c5eb6d67@nxp.com
Changes in v2:
- remove file to 'pcie-imx.c'
- keep CONFIG unchange.
- Link to v1: https://lore.kernel.org/r/20240227-pci2_upstream-v1-0-b952f8333606@nxp.com
---
Frank Li (7):
PCI: imx6: Rename imx6_* with imx_*
PCI: imx6: Rename pci-imx6.c to pcie-imx.c
MAINTAINERS: pci: imx: update imx6* to imx* since rename driver file
PCI: imx: Simplify switch-case logic by involve set_ref_clk callback
PCI: imx: Simplify switch-case logic by involve core_reset callback
PCI: imx: Config look up table(LUT) to support MSI ITS and IOMMU for i.MX95
PCI: imx: Consolidate redundant if-checks
Richard Zhu (4):
PCI: imx6: Fix PCIe link down when i.MX8MM and i.MX8MP PCIe is EP mode
PCI: imx6: Fix i.MX8MP PCIe EP can not trigger MSI
dt-bindings: imx6q-pcie: Add i.MX8Q pcie compatible string
PCI: imx6: Add i.MX8Q PCIe support
.../bindings/pci/fsl,imx6q-pcie-common.yaml | 5 +
.../devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 18 +
MAINTAINERS | 4 +-
drivers/pci/controller/dwc/Makefile | 2 +-
.../pci/controller/dwc/{pci-imx6.c => pcie-imx.c} | 1173 ++++++++++++--------
5 files changed, 727 insertions(+), 475 deletions(-)
---
base-commit: 2e45e73eebd43365cb585c49b3a671dcfae6b5b5
change-id: 20240227-pci2_upstream-0cdd19a15163
Best regards,
---
Frank Li <Frank.Li@nxp.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2] remoteproc: mediatek: Don't parse extraneous subnodes for multi-core
From: AngeloGioacchino Del Regno @ 2024-04-02 14:33 UTC (permalink / raw)
To: Mathieu Poirier
Cc: andersson, matthias.bgg, tzungbi, tinghan.shen, linux-remoteproc,
linux-kernel, linux-arm-kernel, linux-mediatek, wenst, kernel
In-Reply-To: <CANLsYkyu69Pwv094XGfVomuu1Oixw3vxr42q6WOE4F3snATygw@mail.gmail.com>
Il 02/04/24 16:23, Mathieu Poirier ha scritto:
> On Tue, 2 Apr 2024 at 03:56, AngeloGioacchino Del Regno
> <angelogioacchino.delregno@collabora.com> wrote:
>>
>> Il 28/03/24 15:38, Mathieu Poirier ha scritto:
>>> On Wed, Mar 27, 2024 at 01:49:58PM +0100, AngeloGioacchino Del Regno wrote:
>>>> Il 21/03/24 16:27, Mathieu Poirier ha scritto:
>>>>> On Thu, Mar 21, 2024 at 09:46:14AM +0100, AngeloGioacchino Del Regno wrote:
>>>>>> When probing multi-core SCP, this driver is parsing all sub-nodes of
>>>>>> the scp-cluster node, but one of those could be not an actual SCP core
>>>>>> and that would make the entire SCP cluster to fail probing for no good
>>>>>> reason.
>>>>>>
>>>>>> To fix that, in scp_add_multi_core() treat a subnode as a SCP Core by
>>>>>> parsing only available subnodes having compatible "mediatek,scp-core".
>>>>>>
>>>>>> Fixes: 1fdbf0cdde98 ("remoteproc: mediatek: Probe SCP cluster on multi-core SCP")
>>>>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>>>>>> ---
>>>>>> drivers/remoteproc/mtk_scp.c | 3 +++
>>>>>> 1 file changed, 3 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
>>>>>> index 67518291a8ad..fbe1c232dae7 100644
>>>>>> --- a/drivers/remoteproc/mtk_scp.c
>>>>>> +++ b/drivers/remoteproc/mtk_scp.c
>>>>>> @@ -1096,6 +1096,9 @@ static int scp_add_multi_core(struct platform_device *pdev,
>>>>>> cluster_of_data = (const struct mtk_scp_of_data **)of_device_get_match_data(dev);
>>>>>> for_each_available_child_of_node(np, child) {
>>>>>> + if (!of_device_is_compatible(child, "mediatek,scp-core"))
>>>>>> + continue;
>>>>>> +
>>>>>
>>>>> Interesting - what else gets stashed under the remote processor node? I don't
>>>>> see anything specified in the bindings.
>>>>>
>>>>
>>>> Sorry for the late reply - well, in this precise moment in time, upstream,
>>>> nothing yet.
>>>>
>>>> I have noticed this while debugging some lockups and wanted to move the scp_adsp
>>>> clock controller node as child of the SCP node (as some of those clocks are located
>>>> *into the SCP's CFG register space*, and it's correct for that to be a child as one
>>>> of those do depend on the SCP being up - and I'll spare you the rest) and noticed
>>>> the unexpected behavior, as the SCP driver was treating those as an SCP core.
>>>>
>>>> There was no kernel panic, but the SCP would fail probing.
>>>>
>>>> This is anyway a missed requirement ... for platforms that want *both* two SCP
>>>> cores *and* the AudioDSP, as that'd at least be two nodes with the same iostart
>>>> (scp@1072000, clock-controller@1072000), other than the reasons I explained some
>>>> lines back.
>>>>
>>>> ...and that's why this commit was sent :-)
>>>>
>>>
>>> Please update the bindings with the extra clock requirement in your next
>>> revision.
>>>
>>
>> Ok.
>>
>> Can you please take only patch 1/2 of this series so that I can delay this one
>> for a bit? I don't have time to work on that exactly right now.
>>
>
> It was added to rproc-next last week.
>
Ah, sorry, didn't notice that.
Thanks again!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v1 2/6] clk: meson: a1: pll: support 'syspll' general-purpose PLL for CPU clock
From: Jerome Brunet @ 2024-04-02 14:27 UTC (permalink / raw)
To: Dmitry Rokosov
Cc: Jerome Brunet, neil.armstrong, mturquette, sboyd, robh+dt,
krzysztof.kozlowski+dt, khilman, martin.blumenstingl, kernel,
rockosov, linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20240402121546.qrrc7r5un75464pb@CAB-WSD-L081021>
On Tue 02 Apr 2024 at 15:15, Dmitry Rokosov <ddrokosov@salutedevices.com> wrote:
> On Tue, Apr 02, 2024 at 11:00:42AM +0200, Jerome Brunet wrote:
>>
>> On Fri 29 Mar 2024 at 23:58, Dmitry Rokosov <ddrokosov@salutedevices.com> wrote:
>>
>> > The 'syspll' PLL, also known as the system PLL, is a general and
>> > essential PLL responsible for generating the CPU clock frequency.
>> > With its wide-ranging capabilities, it is designed to accommodate
>> > frequencies within the range of 768MHz to 1536MHz.
>> >
>> > Signed-off-by: Dmitry Rokosov <ddrokosov@salutedevices.com>
>> > ---
>> > drivers/clk/meson/a1-pll.c | 78 ++++++++++++++++++++++++++++++++++++++
>> > drivers/clk/meson/a1-pll.h | 6 +++
>> > 2 files changed, 84 insertions(+)
>> >
>> > diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c
>> > index 60b2e53e7e51..02fd2d325cc6 100644
>> > --- a/drivers/clk/meson/a1-pll.c
>> > +++ b/drivers/clk/meson/a1-pll.c
>> > @@ -138,6 +138,81 @@ static struct clk_regmap hifi_pll = {
>> > },
>> > };
>> >
>> > +static const struct pll_mult_range sys_pll_mult_range = {
>> > + .min = 32,
>> > + .max = 64,
>> > +};
>> > +
>> > +/*
>> > + * We assume that the sys_pll_clk has already been set up by the low-level
>> > + * bootloaders as the main CPU PLL source. Therefore, it is not necessary to
>> > + * run the initialization sequence.
>> > + */
>>
>> I see no reason to make such assumption.
>> This clock is no read-only, it apparently is able to re-lock so assuming
>> anything from the bootloader is just asking from trouble
>>
>
> Indeed, I have implemented the following initialization sequence. I have
> dumped the bootloader setup and included it in the definition of my
> sys_pll. However, I have encountered an issue with the enable bit. If I
> leave the enable bit switched on by default, there is a possibility that
> the bootloader selects a fixed CPU clock while the sys_pll should be
> switched off. On the other hand, if I keep the enable bit switched off
> by default, the bootloader might configure the CPU clock to use sys_pll,
> resulting in the execution halting when the initialization sequence is
> run. This situation has led me to assume that we should place our trust
> in the bootloader setup.
>
> If you believe it is necessary to include the initialization sequence, I
> can prepare it with the sys_pll enabled by default.
I just noted your initial comment is misleading.
You could submit a patch to apply the init sequence only if the PLL is
not already enabled. Maybe even condition that to flag in the pll data
to avoid applying it to the other platforms for now.
>
>> > +static struct clk_regmap sys_pll = {
>> > + .data = &(struct meson_clk_pll_data){
>> > + .en = {
>> > + .reg_off = ANACTRL_SYSPLL_CTRL0,
>> > + .shift = 28,
>> > + .width = 1,
>> > + },
>> > + .m = {
>> > + .reg_off = ANACTRL_SYSPLL_CTRL0,
>> > + .shift = 0,
>> > + .width = 8,
>> > + },
>> > + .n = {
>> > + .reg_off = ANACTRL_SYSPLL_CTRL0,
>> > + .shift = 10,
>> > + .width = 5,
>> > + },
>> > + .frac = {
>> > + .reg_off = ANACTRL_SYSPLL_CTRL1,
>> > + .shift = 0,
>> > + .width = 19,
>> > + },
>> > + .l = {
>> > + .reg_off = ANACTRL_SYSPLL_STS,
>> > + .shift = 31,
>> > + .width = 1,
>> > + },
>> > + .current_en = {
>> > + .reg_off = ANACTRL_SYSPLL_CTRL0,
>> > + .shift = 26,
>> > + .width = 1,
>> > + },
>> > + .l_detect = {
>> > + .reg_off = ANACTRL_SYSPLL_CTRL2,
>> > + .shift = 6,
>> > + .width = 1,
>> > + },
>> > + .range = &sys_pll_mult_range,
>> > + },
>> > + .hw.init = &(struct clk_init_data){
>> > + .name = "sys_pll",
>> > + .ops = &meson_clk_pll_ops,
>> > + .parent_names = (const char *[]){ "syspll_in" },
>> > + .num_parents = 1,
>> > + /*
>> > + * This clock is used as the main CPU PLL source in low-level
>> > + * bootloaders, and it is necessary to mark it as critical.
>> > + */
>> > + .flags = CLK_IS_CRITICAL,
>>
>> No I don't think so. Downstream consumer maybe critical but that one is
>> not, unless it is read-only.
>>
>> A CPU pll, like on the g12 family, is unlikely to be read-only since the
>> PLL will need to relock to change rates. During this phase, there will
>> be no reate coming from the PLL so the PLL is not critical and you must
>> be able to "park" your CPU an another clock while poking this one
>>
>
> Initially, I tagged it with CLK_IS_CRITICAL because I observed in the
> kernel start that CCF disables it.
> However, upon further understanding,
> I realized that this happened due to other reasons. I believe that if I
> provide an init sequence where sys_pll is enabled by default, CCF will
> not disable this clock.
>
>> > + },
>> > +};
>> > +
>> > +static struct clk_fixed_factor sys_pll_div16 = {
>> > + .mult = 1,
>> > + .div = 16,
>> > + .hw.init = &(struct clk_init_data){
>> > + .name = "sys_pll_div16",
>> > + .ops = &clk_fixed_factor_ops,
>> > + .parent_hws = (const struct clk_hw *[]) {
>> > + &sys_pll.hw
>> > + },
>> > + .num_parents = 1,
>> > + },
>> > +};
>> > +
>> > static struct clk_fixed_factor fclk_div2_div = {
>> > .mult = 1,
>> > .div = 2,
>> > @@ -283,6 +358,8 @@ static struct clk_hw *a1_pll_hw_clks[] = {
>> > [CLKID_FCLK_DIV5] = &fclk_div5.hw,
>> > [CLKID_FCLK_DIV7] = &fclk_div7.hw,
>> > [CLKID_HIFI_PLL] = &hifi_pll.hw,
>> > + [CLKID_SYS_PLL] = &sys_pll.hw,
>> > + [CLKID_SYS_PLL_DIV16] = &sys_pll_div16.hw,
>> > };
>> >
>> > static struct clk_regmap *const a1_pll_regmaps[] = {
>> > @@ -293,6 +370,7 @@ static struct clk_regmap *const a1_pll_regmaps[] = {
>> > &fclk_div5,
>> > &fclk_div7,
>> > &hifi_pll,
>> > + &sys_pll,
>> > };
>> >
>> > static struct regmap_config a1_pll_regmap_cfg = {
>> > diff --git a/drivers/clk/meson/a1-pll.h b/drivers/clk/meson/a1-pll.h
>> > index 4be17b2bf383..666d9b2137e9 100644
>> > --- a/drivers/clk/meson/a1-pll.h
>> > +++ b/drivers/clk/meson/a1-pll.h
>> > @@ -18,6 +18,12 @@
>> > #define ANACTRL_FIXPLL_CTRL0 0x0
>> > #define ANACTRL_FIXPLL_CTRL1 0x4
>> > #define ANACTRL_FIXPLL_STS 0x14
>> > +#define ANACTRL_SYSPLL_CTRL0 0x80
>> > +#define ANACTRL_SYSPLL_CTRL1 0x84
>> > +#define ANACTRL_SYSPLL_CTRL2 0x88
>> > +#define ANACTRL_SYSPLL_CTRL3 0x8c
>> > +#define ANACTRL_SYSPLL_CTRL4 0x90
>> > +#define ANACTRL_SYSPLL_STS 0x94
>> > #define ANACTRL_HIFIPLL_CTRL0 0xc0
>> > #define ANACTRL_HIFIPLL_CTRL1 0xc4
>> > #define ANACTRL_HIFIPLL_CTRL2 0xc8
--
Jerome
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 22/23] drivers: media: i2c: imx258: Add support for powerdown gpio
From: Dan Carpenter @ 2024-04-02 14:28 UTC (permalink / raw)
To: oe-kbuild, git, linux-media
Cc: lkp, oe-kbuild-all, dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, Luigi311, Ondrej Jirman
In-Reply-To: <20240327231710.53188-23-git@luigi311.com>
Hi,
kernel test robot noticed the following build warnings:
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/git-luigi311-com/media-i2c-imx258-Remove-unused-defines/20240328-072629
base: git://linuxtv.org/media_tree.git master
patch link: https://lore.kernel.org/r/20240327231710.53188-23-git%40luigi311.com
patch subject: [PATCH 22/23] drivers: media: i2c: imx258: Add support for powerdown gpio
config: x86_64-randconfig-161-20240331 (https://download.01.org/0day-ci/archive/20240401/202404011425.PVKV9Lf1-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202404011425.PVKV9Lf1-lkp@intel.com/
smatch warnings:
drivers/media/i2c/imx258.c:1562 imx258_probe() warn: missing unwind goto?
vim +1562 drivers/media/i2c/imx258.c
d3773094af21c9 Dave Stevenson 2024-03-27 1476
e4802cb00bfe3d Jason Chen 2018-05-02 1477 static int imx258_probe(struct i2c_client *client)
e4802cb00bfe3d Jason Chen 2018-05-02 1478 {
e4802cb00bfe3d Jason Chen 2018-05-02 1479 struct imx258 *imx258;
786d2ad50b9b49 Dave Stevenson 2024-03-27 1480 struct fwnode_handle *endpoint;
786d2ad50b9b49 Dave Stevenson 2024-03-27 1481 struct v4l2_fwnode_endpoint ep = {
786d2ad50b9b49 Dave Stevenson 2024-03-27 1482 .bus_type = V4L2_MBUS_CSI2_DPHY
786d2ad50b9b49 Dave Stevenson 2024-03-27 1483 };
e4802cb00bfe3d Jason Chen 2018-05-02 1484 int ret;
e4802cb00bfe3d Jason Chen 2018-05-02 1485 u32 val = 0;
e4802cb00bfe3d Jason Chen 2018-05-02 1486
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1487 imx258 = devm_kzalloc(&client->dev, sizeof(*imx258), GFP_KERNEL);
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1488 if (!imx258)
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1489 return -ENOMEM;
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1490
d3773094af21c9 Dave Stevenson 2024-03-27 1491 ret = imx258_get_regulators(imx258, client);
d3773094af21c9 Dave Stevenson 2024-03-27 1492 if (ret)
d3773094af21c9 Dave Stevenson 2024-03-27 1493 return dev_err_probe(&client->dev, ret,
d3773094af21c9 Dave Stevenson 2024-03-27 1494 "failed to get regulators\n");
d3773094af21c9 Dave Stevenson 2024-03-27 1495
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1496 imx258->clk = devm_clk_get_optional(&client->dev, NULL);
d170b0ea176098 Sakari Ailus 2021-08-16 1497 if (IS_ERR(imx258->clk))
d170b0ea176098 Sakari Ailus 2021-08-16 1498 return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),
d170b0ea176098 Sakari Ailus 2021-08-16 1499 "error getting clock\n");
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1500 if (!imx258->clk) {
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1501 dev_dbg(&client->dev,
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1502 "no clock provided, using clock-frequency property\n");
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1503
e4802cb00bfe3d Jason Chen 2018-05-02 1504 device_property_read_u32(&client->dev, "clock-frequency", &val);
d170b0ea176098 Sakari Ailus 2021-08-16 1505 } else {
d170b0ea176098 Sakari Ailus 2021-08-16 1506 val = clk_get_rate(imx258->clk);
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1507 }
8bde18cb296d0e Dave Stevenson 2024-03-27 1508
8bde18cb296d0e Dave Stevenson 2024-03-27 1509 switch (val) {
8bde18cb296d0e Dave Stevenson 2024-03-27 1510 case 19200000:
8bde18cb296d0e Dave Stevenson 2024-03-27 1511 imx258->link_freq_configs = link_freq_configs_19_2;
8bde18cb296d0e Dave Stevenson 2024-03-27 1512 imx258->link_freq_menu_items = link_freq_menu_items_19_2;
8bde18cb296d0e Dave Stevenson 2024-03-27 1513 break;
8bde18cb296d0e Dave Stevenson 2024-03-27 1514 case 24000000:
8bde18cb296d0e Dave Stevenson 2024-03-27 1515 imx258->link_freq_configs = link_freq_configs_24;
8bde18cb296d0e Dave Stevenson 2024-03-27 1516 imx258->link_freq_menu_items = link_freq_menu_items_24;
8bde18cb296d0e Dave Stevenson 2024-03-27 1517 break;
8bde18cb296d0e Dave Stevenson 2024-03-27 1518 default:
8bde18cb296d0e Dave Stevenson 2024-03-27 1519 dev_err(&client->dev, "input clock frequency of %u not supported\n",
8bde18cb296d0e Dave Stevenson 2024-03-27 1520 val);
e4802cb00bfe3d Jason Chen 2018-05-02 1521 return -EINVAL;
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1522 }
e4802cb00bfe3d Jason Chen 2018-05-02 1523
786d2ad50b9b49 Dave Stevenson 2024-03-27 1524 endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
786d2ad50b9b49 Dave Stevenson 2024-03-27 1525 if (!endpoint) {
786d2ad50b9b49 Dave Stevenson 2024-03-27 1526 dev_err(&client->dev, "Endpoint node not found\n");
786d2ad50b9b49 Dave Stevenson 2024-03-27 1527 return -EINVAL;
786d2ad50b9b49 Dave Stevenson 2024-03-27 1528 }
786d2ad50b9b49 Dave Stevenson 2024-03-27 1529
786d2ad50b9b49 Dave Stevenson 2024-03-27 1530 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
786d2ad50b9b49 Dave Stevenson 2024-03-27 1531 fwnode_handle_put(endpoint);
786d2ad50b9b49 Dave Stevenson 2024-03-27 1532 if (ret) {
786d2ad50b9b49 Dave Stevenson 2024-03-27 1533 dev_err(&client->dev, "Parsing endpoint node failed\n");
786d2ad50b9b49 Dave Stevenson 2024-03-27 1534 return ret;
786d2ad50b9b49 Dave Stevenson 2024-03-27 1535 }
786d2ad50b9b49 Dave Stevenson 2024-03-27 1536
786d2ad50b9b49 Dave Stevenson 2024-03-27 1537 /* Get number of data lanes */
a42d61a239fac8 Dave Stevenson 2024-03-27 1538 switch (ep.bus.mipi_csi2.num_data_lanes) {
a42d61a239fac8 Dave Stevenson 2024-03-27 1539 case 2:
a42d61a239fac8 Dave Stevenson 2024-03-27 1540 imx258->lane_mode_idx = IMX258_2_LANE_MODE;
a42d61a239fac8 Dave Stevenson 2024-03-27 1541 break;
a42d61a239fac8 Dave Stevenson 2024-03-27 1542 case 4:
a42d61a239fac8 Dave Stevenson 2024-03-27 1543 imx258->lane_mode_idx = IMX258_4_LANE_MODE;
a42d61a239fac8 Dave Stevenson 2024-03-27 1544 break;
a42d61a239fac8 Dave Stevenson 2024-03-27 1545 default:
786d2ad50b9b49 Dave Stevenson 2024-03-27 1546 dev_err(&client->dev, "Invalid data lanes: %u\n",
a42d61a239fac8 Dave Stevenson 2024-03-27 1547 ep.bus.mipi_csi2.num_data_lanes);
786d2ad50b9b49 Dave Stevenson 2024-03-27 1548 ret = -EINVAL;
786d2ad50b9b49 Dave Stevenson 2024-03-27 1549 goto error_endpoint_free;
786d2ad50b9b49 Dave Stevenson 2024-03-27 1550 }
786d2ad50b9b49 Dave Stevenson 2024-03-27 1551
7db096053387db Dave Stevenson 2024-03-27 1552 imx258->csi2_flags = ep.bus.mipi_csi2.flags;
7db096053387db Dave Stevenson 2024-03-27 1553
a8bb93eeccfa73 Dave Stevenson 2024-03-27 1554 imx258->variant_cfg = of_device_get_match_data(&client->dev);
a8bb93eeccfa73 Dave Stevenson 2024-03-27 1555 if (!imx258->variant_cfg)
a8bb93eeccfa73 Dave Stevenson 2024-03-27 1556 imx258->variant_cfg = &imx258_cfg;
a8bb93eeccfa73 Dave Stevenson 2024-03-27 1557
8a1906e91c0093 Luigi311 2024-03-27 1558 /* request optional power down pin */
8a1906e91c0093 Luigi311 2024-03-27 1559 imx258->powerdown_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
8a1906e91c0093 Luigi311 2024-03-27 1560 GPIOD_OUT_HIGH);
8a1906e91c0093 Luigi311 2024-03-27 1561 if (IS_ERR(imx258->powerdown_gpio))
8a1906e91c0093 Luigi311 2024-03-27 @1562 return PTR_ERR(imx258->powerdown_gpio);
ret = PTR_ERR(imx258->powerdown_gpio);
goto error_endpoint_free;
8a1906e91c0093 Luigi311 2024-03-27 1563
e4802cb00bfe3d Jason Chen 2018-05-02 1564 /* Initialize subdev */
e4802cb00bfe3d Jason Chen 2018-05-02 1565 v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
e4802cb00bfe3d Jason Chen 2018-05-02 1566
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1567 /* Will be powered off via pm_runtime_idle */
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1568 ret = imx258_power_on(&client->dev);
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1569 if (ret)
786d2ad50b9b49 Dave Stevenson 2024-03-27 1570 goto error_endpoint_free;
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1571
e4802cb00bfe3d Jason Chen 2018-05-02 1572 /* Check module identity */
e4802cb00bfe3d Jason Chen 2018-05-02 1573 ret = imx258_identify_module(imx258);
e4802cb00bfe3d Jason Chen 2018-05-02 1574 if (ret)
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1575 goto error_identify;
e4802cb00bfe3d Jason Chen 2018-05-02 1576
e4802cb00bfe3d Jason Chen 2018-05-02 1577 /* Set default mode to max resolution */
e4802cb00bfe3d Jason Chen 2018-05-02 1578 imx258->cur_mode = &supported_modes[0];
e4802cb00bfe3d Jason Chen 2018-05-02 1579
e4802cb00bfe3d Jason Chen 2018-05-02 1580 ret = imx258_init_controls(imx258);
e4802cb00bfe3d Jason Chen 2018-05-02 1581 if (ret)
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1582 goto error_identify;
e4802cb00bfe3d Jason Chen 2018-05-02 1583
e4802cb00bfe3d Jason Chen 2018-05-02 1584 /* Initialize subdev */
e4802cb00bfe3d Jason Chen 2018-05-02 1585 imx258->sd.internal_ops = &imx258_internal_ops;
e4802cb00bfe3d Jason Chen 2018-05-02 1586 imx258->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
e4802cb00bfe3d Jason Chen 2018-05-02 1587 imx258->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
e4802cb00bfe3d Jason Chen 2018-05-02 1588
e4802cb00bfe3d Jason Chen 2018-05-02 1589 /* Initialize source pad */
e4802cb00bfe3d Jason Chen 2018-05-02 1590 imx258->pad.flags = MEDIA_PAD_FL_SOURCE;
e4802cb00bfe3d Jason Chen 2018-05-02 1591
e4802cb00bfe3d Jason Chen 2018-05-02 1592 ret = media_entity_pads_init(&imx258->sd.entity, 1, &imx258->pad);
e4802cb00bfe3d Jason Chen 2018-05-02 1593 if (ret)
e4802cb00bfe3d Jason Chen 2018-05-02 1594 goto error_handler_free;
e4802cb00bfe3d Jason Chen 2018-05-02 1595
15786f7b564eff Sakari Ailus 2021-03-05 1596 ret = v4l2_async_register_subdev_sensor(&imx258->sd);
e4802cb00bfe3d Jason Chen 2018-05-02 1597 if (ret < 0)
e4802cb00bfe3d Jason Chen 2018-05-02 1598 goto error_media_entity;
e4802cb00bfe3d Jason Chen 2018-05-02 1599
e4802cb00bfe3d Jason Chen 2018-05-02 1600 pm_runtime_set_active(&client->dev);
e4802cb00bfe3d Jason Chen 2018-05-02 1601 pm_runtime_enable(&client->dev);
e4802cb00bfe3d Jason Chen 2018-05-02 1602 pm_runtime_idle(&client->dev);
786d2ad50b9b49 Dave Stevenson 2024-03-27 1603 v4l2_fwnode_endpoint_free(&ep);
e4802cb00bfe3d Jason Chen 2018-05-02 1604
e4802cb00bfe3d Jason Chen 2018-05-02 1605 return 0;
e4802cb00bfe3d Jason Chen 2018-05-02 1606
e4802cb00bfe3d Jason Chen 2018-05-02 1607 error_media_entity:
e4802cb00bfe3d Jason Chen 2018-05-02 1608 media_entity_cleanup(&imx258->sd.entity);
e4802cb00bfe3d Jason Chen 2018-05-02 1609
e4802cb00bfe3d Jason Chen 2018-05-02 1610 error_handler_free:
e4802cb00bfe3d Jason Chen 2018-05-02 1611 imx258_free_controls(imx258);
e4802cb00bfe3d Jason Chen 2018-05-02 1612
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1613 error_identify:
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1614 imx258_power_off(&client->dev);
9fda25332c4b9e Krzysztof Kozlowski 2021-01-27 1615
786d2ad50b9b49 Dave Stevenson 2024-03-27 1616 error_endpoint_free:
786d2ad50b9b49 Dave Stevenson 2024-03-27 1617 v4l2_fwnode_endpoint_free(&ep);
786d2ad50b9b49 Dave Stevenson 2024-03-27 1618
e4802cb00bfe3d Jason Chen 2018-05-02 1619 return ret;
e4802cb00bfe3d Jason Chen 2018-05-02 1620 }
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v1 6/6] clk: meson: a1: add Amlogic A1 CPU clock controller driver
From: Jerome Brunet @ 2024-04-02 14:11 UTC (permalink / raw)
To: Dmitry Rokosov
Cc: Jerome Brunet, neil.armstrong, mturquette, sboyd, robh+dt,
krzysztof.kozlowski+dt, khilman, martin.blumenstingl, kernel,
rockosov, linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20240402110538.ayectwxnhlu6o65d@CAB-WSD-L081021>
On Tue 02 Apr 2024 at 14:05, Dmitry Rokosov <ddrokosov@salutedevices.com> wrote:
> Hello Jerome,
>
> On Tue, Apr 02, 2024 at 11:35:49AM +0200, Jerome Brunet wrote:
>>
>> On Fri 29 Mar 2024 at 23:58, Dmitry Rokosov <ddrokosov@salutedevices.com> wrote:
>>
>> > The CPU clock controller plays a general role in the Amlogic A1 SoC
>> > family by generating CPU clocks. As an APB slave module, it offers the
>> > capability to inherit the CPU clock from two sources: the internal fixed
>> > clock known as 'cpu fixed clock' and the external input provided by the
>> > A1 PLL clock controller, referred to as 'syspll'.
>> >
>> > It is important for the driver to handle cpu_clk rate switching
>> > effectively by transitioning to the CPU fixed clock to avoid any
>> > potential execution freezes.
>> >
>> > Signed-off-by: Dmitry Rokosov <ddrokosov@salutedevices.com>
>> > ---
>> > drivers/clk/meson/Kconfig | 10 ++
>> > drivers/clk/meson/Makefile | 1 +
>> > drivers/clk/meson/a1-cpu.c | 324 +++++++++++++++++++++++++++++++++++++
>> > drivers/clk/meson/a1-cpu.h | 16 ++
>> > 4 files changed, 351 insertions(+)
>> > create mode 100644 drivers/clk/meson/a1-cpu.c
>> > create mode 100644 drivers/clk/meson/a1-cpu.h
>> >
>> > diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> > index 80c4a18c83d2..148d4495eee3 100644
>> > --- a/drivers/clk/meson/Kconfig
>> > +++ b/drivers/clk/meson/Kconfig
>> > @@ -111,6 +111,16 @@ config COMMON_CLK_AXG_AUDIO
>> > Support for the audio clock controller on AmLogic A113D devices,
>> > aka axg, Say Y if you want audio subsystem to work.
>> >
>> > +config COMMON_CLK_A1_CPU
>> > + tristate "Amlogic A1 SoC CPU controller support"
>> > + depends on ARM64
>> > + select COMMON_CLK_MESON_REGMAP
>> > + select COMMON_CLK_MESON_CLKC_UTILS
>> > + help
>> > + Support for the CPU clock controller on Amlogic A113L based
>> > + device, A1 SoC Family. Say Y if you want A1 CPU clock controller
>> > + to work.
>> > +
>> > config COMMON_CLK_A1_PLL
>> > tristate "Amlogic A1 SoC PLL controller support"
>> > depends on ARM64
>> > diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> > index 4968fc7ad555..2a06eb0303d6 100644
>> > --- a/drivers/clk/meson/Makefile
>> > +++ b/drivers/clk/meson/Makefile
>> > @@ -18,6 +18,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_AUDIO_RSTC) += meson-audio-rstc.o
>> >
>> > obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
>> > obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
>> > +obj-$(CONFIG_COMMON_CLK_A1_CPU) += a1-cpu.o
>> > obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
>> > obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
>> > obj-$(CONFIG_COMMON_CLK_A1_AUDIO) += a1-audio.o
>> > diff --git a/drivers/clk/meson/a1-cpu.c b/drivers/clk/meson/a1-cpu.c
>> > new file mode 100644
>> > index 000000000000..5f5d8ae112e5
>> > --- /dev/null
>> > +++ b/drivers/clk/meson/a1-cpu.c
>> > @@ -0,0 +1,324 @@
>> > +// SPDX-License-Identifier: GPL-2.0+
>> > +/*
>> > + * Amlogic A1 SoC family CPU Clock Controller driver.
>> > + *
>> > + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> > + * Author: Dmitry Rokosov <ddrokosov@salutedevices.com>
>> > + */
>> > +
>> > +#include <linux/clk.h>
>> > +#include <linux/clk-provider.h>
>> > +#include <linux/mod_devicetable.h>
>> > +#include <linux/platform_device.h>
>> > +#include "a1-cpu.h"
>> > +#include "clk-regmap.h"
>> > +#include "meson-clkc-utils.h"
>> > +
>> > +#include <dt-bindings/clock/amlogic,a1-cpu-clkc.h>
>> > +
>> > +static u32 cpu_fsource_sel_table[] = { 0, 1, 2 };
>> > +static const struct clk_parent_data cpu_fsource_sel_parents[] = {
>> > + { .fw_name = "xtal" },
>> > + { .fw_name = "fclk_div2" },
>> > + { .fw_name = "fclk_div3" },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_fsource_sel0 = {
>> > + .data = &(struct clk_regmap_mux_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .mask = 0x3,
>> > + .shift = 0,
>> > + .table = cpu_fsource_sel_table,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_fsource_sel0",
>> > + .ops = &clk_regmap_mux_ops,
>> > + .parent_data = cpu_fsource_sel_parents,
>> > + .num_parents = ARRAY_SIZE(cpu_fsource_sel_parents),
>> > + .flags = CLK_SET_RATE_PARENT,
>> > + },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_fsource_div0 = {
>> > + .data = &(struct clk_regmap_div_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .shift = 4,
>> > + .width = 6,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_fsource_div0",
>> > + .ops = &clk_regmap_divider_ops,
>> > + .parent_hws = (const struct clk_hw *[]) {
>> > + &cpu_fsource_sel0.hw
>> > + },
>> > + .num_parents = 1,
>> > + .flags = CLK_SET_RATE_PARENT,
>> > + },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_fsel0 = {
>> > + .data = &(struct clk_regmap_mux_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .mask = 0x1,
>> > + .shift = 2,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_fsel0",
>> > + .ops = &clk_regmap_mux_ops,
>> > + .parent_hws = (const struct clk_hw *[]) {
>> > + &cpu_fsource_sel0.hw,
>> > + &cpu_fsource_div0.hw,
>> > + },
>> > + .num_parents = 2,
>> > + .flags = CLK_SET_RATE_PARENT,
>> > + },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_fsource_sel1 = {
>> > + .data = &(struct clk_regmap_mux_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .mask = 0x3,
>> > + .shift = 16,
>> > + .table = cpu_fsource_sel_table,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_fsource_sel1",
>> > + .ops = &clk_regmap_mux_ops,
>> > + .parent_data = cpu_fsource_sel_parents,
>> > + .num_parents = ARRAY_SIZE(cpu_fsource_sel_parents),
>> > + .flags = CLK_SET_RATE_PARENT,
>> > + },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_fsource_div1 = {
>> > + .data = &(struct clk_regmap_div_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .shift = 20,
>> > + .width = 6,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_fsource_div1",
>> > + .ops = &clk_regmap_divider_ops,
>> > + .parent_hws = (const struct clk_hw *[]) {
>> > + &cpu_fsource_sel1.hw
>> > + },
>> > + .num_parents = 1,
>> > + .flags = CLK_SET_RATE_PARENT,
>> > + },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_fsel1 = {
>> > + .data = &(struct clk_regmap_mux_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .mask = 0x1,
>> > + .shift = 18,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_fsel1",
>> > + .ops = &clk_regmap_mux_ops,
>> > + .parent_hws = (const struct clk_hw *[]) {
>> > + &cpu_fsource_sel1.hw,
>> > + &cpu_fsource_div1.hw,
>> > + },
>> > + .num_parents = 2,
>> > + .flags = CLK_SET_RATE_PARENT,
>> > + },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_fclk = {
>> > + .data = &(struct clk_regmap_mux_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .mask = 0x1,
>> > + .shift = 10,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_fclk",
>> > + .ops = &clk_regmap_mux_ops,
>> > + .parent_hws = (const struct clk_hw *[]) {
>> > + &cpu_fsel0.hw,
>> > + &cpu_fsel1.hw,
>> > + },
>> > + .num_parents = 2,
>> > + .flags = CLK_SET_RATE_PARENT,
>> > + },
>> > +};
>> > +
>> > +static struct clk_regmap cpu_clk = {
>> > + .data = &(struct clk_regmap_mux_data) {
>> > + .offset = CPUCTRL_CLK_CTRL0,
>> > + .mask = 0x1,
>> > + .shift = 11,
>> > + },
>> > + .hw.init = &(struct clk_init_data) {
>> > + .name = "cpu_clk",
>> > + .ops = &clk_regmap_mux_ops,
>> > + .parent_data = (const struct clk_parent_data []) {
>> > + { .hw = &cpu_fclk.hw },
>> > + { .fw_name = "sys_pll", },
>> > + },
>> > + .num_parents = 2,
>> > + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
>> > + },
>> > +};
>> > +
>> > +/* Array of all clocks registered by this provider */
>> > +static struct clk_hw *a1_cpu_hw_clks[] = {
>> > + [CLKID_CPU_FSOURCE_SEL0] = &cpu_fsource_sel0.hw,
>> > + [CLKID_CPU_FSOURCE_DIV0] = &cpu_fsource_div0.hw,
>> > + [CLKID_CPU_FSEL0] = &cpu_fsel0.hw,
>> > + [CLKID_CPU_FSOURCE_SEL1] = &cpu_fsource_sel1.hw,
>> > + [CLKID_CPU_FSOURCE_DIV1] = &cpu_fsource_div1.hw,
>> > + [CLKID_CPU_FSEL1] = &cpu_fsel1.hw,
>> > + [CLKID_CPU_FCLK] = &cpu_fclk.hw,
>> > + [CLKID_CPU_CLK] = &cpu_clk.hw,
>> > +};
>> > +
>> > +static struct clk_regmap *const a1_cpu_regmaps[] = {
>> > + &cpu_fsource_sel0,
>> > + &cpu_fsource_div0,
>> > + &cpu_fsel0,
>> > + &cpu_fsource_sel1,
>> > + &cpu_fsource_div1,
>> > + &cpu_fsel1,
>> > + &cpu_fclk,
>> > + &cpu_clk,
>> > +};
>> > +
>> > +static struct regmap_config a1_cpu_regmap_cfg = {
>> > + .reg_bits = 32,
>> > + .val_bits = 32,
>> > + .reg_stride = 4,
>> > + .max_register = CPUCTRL_CLK_CTRL1,
>> > +};
>> > +
>> > +static struct meson_clk_hw_data a1_cpu_clks = {
>> > + .hws = a1_cpu_hw_clks,
>> > + .num = ARRAY_SIZE(a1_cpu_hw_clks),
>> > +};
>> > +
>> > +struct a1_cpu_clk_nb_data {
>> > + const struct clk_ops *mux_ops;
>>
>> That's fishy ...
>>
>> > + struct clk_hw *cpu_clk;
>> > + struct notifier_block nb;
>> > + u8 parent;
>> > +};
>> > +
>> > +#define MESON_A1_CPU_CLK_GET_PARENT(nbd) \
>> > + ((nbd)->mux_ops->get_parent((nbd)->cpu_clk))
>> > +#define MESON_A1_CPU_CLK_SET_PARENT(nbd, index) \
>> > + ((nbd)->mux_ops->set_parent((nbd)->cpu_clk, index))
>>
>> ... Directly going for the mux ops ??!?? No way !
>>
>> We have a framework to handle the clocks, the whole point is to use it,
>> not bypass it !
>>
>
> I suppose you understand my approach, which is quite similar to what is
> happening in the Mediatek driver:
>
> https://elixir.bootlin.com/linux/latest/source/drivers/clk/mediatek/clk-mux.c#L295
>
> Initially, I attempted to set the parent using the clk_set_parent() API.
> However, I encountered a problem with recursive calling of the
> notifier_block. This issue arises because the parent triggers
> notifications for its children, leading to repeated calls to the
> notifier_block.
>
> I find it puzzling why I cannot call an internal function or callback
> within the internal driver context. After all, the notifier block is
> just a part of the set_rate() flow. From a global Clock Control
> Framework perspective, the context should not change.
I don't care what MTK is doing TBH. Forcefully calling ops on a clock,
hoping they are going to match with the clock type is wrong.
There is a clk_hw API. Please it.
>
>> > +
>> > +static int meson_a1_cpu_clk_notifier_cb(struct notifier_block *nb,
>> > + unsigned long event, void *data)
>> > +{
>> > + struct a1_cpu_clk_nb_data *nbd;
>> > + int ret = 0;
>> > +
>> > + nbd = container_of(nb, struct a1_cpu_clk_nb_data, nb);
>> > +
>> > + switch (event) {
>> > + case PRE_RATE_CHANGE:
>> > + nbd->parent = MESON_A1_CPU_CLK_GET_PARENT(nbd);
>> > + /* Fallback to the CPU fixed clock */
>> > + ret = MESON_A1_CPU_CLK_SET_PARENT(nbd, 0);
>> > + /* Wait for clock propagation */
>> > + udelay(100);
>> > + break;
>> > +
>> > + case POST_RATE_CHANGE:
>> > + case ABORT_RATE_CHANGE:
>> > + /* Back to the original parent clock */
>> > + ret = MESON_A1_CPU_CLK_SET_PARENT(nbd, nbd->parent);
>> > + /* Wait for clock propagation */
>> > + udelay(100);
>> > + break;
>> > +
>> > + default:
>> > + pr_warn("Unknown event %lu for %s notifier block\n",
>> > + event, clk_hw_get_name(nbd->cpu_clk));
>> > + break;
>> > + }
>> > +
>> > + return notifier_from_errno(ret);
>> > +}
>> > +
>> > +static struct a1_cpu_clk_nb_data a1_cpu_clk_nb_data = {
>> > + .mux_ops = &clk_regmap_mux_ops,
>> > + .cpu_clk = &cpu_clk.hw,
>> > + .nb.notifier_call = meson_a1_cpu_clk_notifier_cb,
>> > +};
>> > +
>> > +static int meson_a1_dvfs_setup(struct platform_device *pdev)
>> > +{
>> > + struct device *dev = &pdev->dev;
>> > + struct clk *notifier_clk;
>> > + int ret;
>> > +
>> > + /* Setup clock notifier for cpu_clk */
>> > + notifier_clk = devm_clk_hw_get_clk(dev, &cpu_clk.hw, "dvfs");
>> > + if (IS_ERR(notifier_clk))
>> > + return dev_err_probe(dev, PTR_ERR(notifier_clk),
>> > + "can't get cpu_clk as notifier clock\n");
>> > +
>> > + ret = devm_clk_notifier_register(dev, notifier_clk,
>> > + &a1_cpu_clk_nb_data.nb);
>> > + if (ret)
>> > + return dev_err_probe(dev, ret,
>> > + "can't register cpu_clk notifier\n");
>> > +
>> > + return ret;
>> > +}
>> > +
>> > +static int meson_a1_cpu_probe(struct platform_device *pdev)
>> > +{
>> > + struct device *dev = &pdev->dev;
>> > + void __iomem *base;
>> > + struct regmap *map;
>> > + int clkid, i, err;
>> > +
>> > + base = devm_platform_ioremap_resource(pdev, 0);
>> > + if (IS_ERR(base))
>> > + return dev_err_probe(dev, PTR_ERR(base),
>> > + "can't ioremap resource\n");
>> > +
>> > + map = devm_regmap_init_mmio(dev, base, &a1_cpu_regmap_cfg);
>> > + if (IS_ERR(map))
>> > + return dev_err_probe(dev, PTR_ERR(map),
>> > + "can't init regmap mmio region\n");
>> > +
>> > + /* Populate regmap for the regmap backed clocks */
>> > + for (i = 0; i < ARRAY_SIZE(a1_cpu_regmaps); i++)
>> > + a1_cpu_regmaps[i]->map = map;
>> > +
>> > + for (clkid = 0; clkid < a1_cpu_clks.num; clkid++) {
>> > + err = devm_clk_hw_register(dev, a1_cpu_clks.hws[clkid]);
>> > + if (err)
>> > + return dev_err_probe(dev, err,
>> > + "clock[%d] registration failed\n",
>> > + clkid);
>> > + }
>> > +
>> > + err = devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &a1_cpu_clks);
>> > + if (err)
>> > + return dev_err_probe(dev, err, "can't add clk hw provider\n");
>>
>> I wonder if there is a window of opportunity to poke the syspll without
>> your notifier here. That being said, the situation would be similar on g12.
>>
>
> Yes, I have taken into account what you did in the G12A CPU clock
> relations. My thoughts were that it might not be applicable for the A1
> case. This is because the sys_pll should be located in a different
> driver from a logical perspective. Consequently, we cannot configure the
> sys_pll notifier block to manage the cpu_clk from a different driver.
> However, if I were to move the sys_pll clock object to the A1 CPU clock
> controller, I believe the g12a sys_pll notifier approach would work.
>
I fail to see the connection between the number of device and the
approach you took.
>> > +
>> > + return meson_a1_dvfs_setup(pdev);
>>
>>
>>
>> > +}
>> > +
>> > +static const struct of_device_id a1_cpu_clkc_match_table[] = {
>> > + { .compatible = "amlogic,a1-cpu-clkc", },
>> > + {}
>> > +};
>> > +MODULE_DEVICE_TABLE(of, a1_cpu_clkc_match_table);
>> > +
>> > +static struct platform_driver a1_cpu_clkc_driver = {
>> > + .probe = meson_a1_cpu_probe,
>> > + .driver = {
>> > + .name = "a1-cpu-clkc",
>> > + .of_match_table = a1_cpu_clkc_match_table,
>> > + },
>> > +};
>> > +
>> > +module_platform_driver(a1_cpu_clkc_driver);
>> > +MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@salutedevices.com>");
>> > +MODULE_LICENSE("GPL");
>> > diff --git a/drivers/clk/meson/a1-cpu.h b/drivers/clk/meson/a1-cpu.h
>> > new file mode 100644
>> > index 000000000000..e9af4117e26f
>> > --- /dev/null
>> > +++ b/drivers/clk/meson/a1-cpu.h
>>
>> There is not point putting the definition here in a header
>> These are clearly not going to be shared with another driver.
>>
>> Please drop this file
>>
>
> The same approach was applied to the Peripherals and PLL A1 drivers.
> Honestly, I am not a fan of having different file organization within a
> single logical code folder.
>
> Please refer to:
>
> drivers/clk/meson/a1-peripherals.h
> drivers/clk/meson/a1-pll.h
I understand. There was a time where it made sense, some definition
could have been shared back then. This is no longer the case and it
would probably welcome a rework.
... and again, just pointing to another code does really invalidate my
point.
>
>> > @@ -0,0 +1,16 @@
>> > +/* SPDX-License-Identifier: GPL-2.0+ */
>> > +/*
>> > + * Amlogic A1 CPU Clock Controller internals
>> > + *
>> > + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> > + * Author: Dmitry Rokosov <ddrokosov@salutedevices.com>
>> > + */
>> > +
>> > +#ifndef __A1_CPU_H
>> > +#define __A1_CPU_H
>> > +
>> > +/* cpu clock controller register offset */
>> > +#define CPUCTRL_CLK_CTRL0 0x80
>> > +#define CPUCTRL_CLK_CTRL1 0x84
>>
>> You are claiming the registers from 0x00 to 0x84 (included), but only
>> using these 2 registers ? What is the rest ? Are you sure there is only
>> clocks in there ?
>>
>
> Yes, unfortunately, the register map for this IP is not described in the
> A1 Datasheet. The only available information about it can be found in
> the vendor clock driver, which provides details for only two registers
> used to configure the CPU clock.
>
> From vendor kernel dtsi:
>
> clkc: clock-controller {
> compatible = "amlogic,a1-clkc";
> #clock-cells = <1>;
> reg = <0x0 0xfe000800 0x0 0x100>,
> <0x0 0xfe007c00 0x0 0x21c>,
> <0x0 0xfd000000 0x0 0x88>; <==== CPU clock regmap
> reg-names = "basic", "pll",
> "cpu_clk";
> clocks = <&xtal>;
> clock-names = "core";
> status = "okay";
> };
>
> From vendor clkc driver:
>
> /*
> * CPU clok register offset
> * APB_BASE: APB1_BASE_ADDR = 0xfd000000
> */
>
> #define CPUCTRL_CLK_CTRL0 0x80
> #define CPUCTRL_CLK_CTRL1 0x84
If you had clock in 0x0 and 0x80, then I would agree claiming 0x0-0x88
is reasonable, even if you don't really know what is in between. It
would be a fair assumption.
It is not the case here.
For all we know it could resets, power domains, etc ...
>
> [...]
--
Jerome
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 2/3] dt-bindings: phy: Add i.MX8Q HSIO SerDes PHY binding
From: Frank Li @ 2024-04-02 14:23 UTC (permalink / raw)
To: Richard Zhu
Cc: vkoul, kishon, robh+dt, krzysztof.kozlowski+dt, conor+dt,
linux-phy, devicetree, linux-arm-kernel, linux-kernel, kernel,
imx
In-Reply-To: <1712036704-21064-3-git-send-email-hongxing.zhu@nxp.com>
On Tue, Apr 02, 2024 at 01:45:03PM +0800, Richard Zhu wrote:
> Add i.MX8QM and i.MX8QXP HSIO SerDes PHY binding.
> - Use the controller ID to specify which controller is binded to the
> PHY.
> - Introduce one HSIO configuration, mandatory required to set
> "PCIE_AB_SELECT" and "PHY_X1_EPCS_SEL" during the initialization.
>
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
You missed all conor's comments.
Please double check v1's comments.
Frank
> ---
> .../bindings/phy/fsl,imx8q-hsio.yaml | 143 ++++++++++++++++++
> 1 file changed, 143 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml
>
> diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml
> new file mode 100644
> index 000000000000..506551d4d94a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml
> @@ -0,0 +1,143 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/fsl,imx8q-hsio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8Q SoC series HSIO SERDES PHY
> +
> +maintainers:
> + - Richard Zhu <hongxing.zhu@nxp.com>
> +
> +properties:
> + compatible:
> + enum:
> + - fsl,imx8qxp-serdes
> + - fsl,imx8qm-serdes
> + reg:
> + minItems: 4
> + maxItems: 4
> +
> + "#phy-cells":
> + const: 3
> + description: |
> + The first number defines the ID of the PHY contained in the HSIO macro.
> + The second defines controller ID binded to the PHY. The third defines the
> + HSIO configuratons refer to the different use cases. They are defined in
> + dt-bindings/phy/phy-imx8-pcie.h
> +
> + reg-names:
> + items:
> + - const: reg
> + - const: phy
> + - const: ctrl
> + - const: misc
> +
> + clocks:
> + minItems: 5
> + maxItems: 14
> +
> + clock-names:
> + minItems: 5
> + maxItems: 14
> +
> + fsl,refclk-pad-mode:
> + description: |
> + Specifies the mode of the refclk pad used. It can be UNUSED(PHY
> + refclock is derived from SoC internal source), INPUT(PHY refclock
> + is provided externally via the refclk pad) or OUTPUT(PHY refclock
> + is derived from SoC internal source and provided on the refclk pad).
> + Refer include/dt-bindings/phy/phy-imx8-pcie.h for the constants
> + to be used.
> + $ref: /schemas/types.yaml#/definitions/uint32
> + enum: [ 0, 1, 2 ]
I remember needn't enum because there are header file.
> +
> + power-domains:
> + description: |
> + i.MX8Q HSIO SerDes power domains. i.MX8QXP has one SerDes power domains.
> + And i.MX8QM has two.
> + minItems: 1
> + maxItems: 2
> +
> +required:
> + - compatible
> + - reg
> + - "#phy-cells"
> + - clocks
> + - clock-names
> + - fsl,refclk-pad-mode
> +
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - fsl,imx8qxp-serdes
> + then:
> + properties:
> + clock-names:
> + items:
> + - const: apb_pclk0
> + - const: pclk0
> + - const: phy0_crr
> + - const: ctl0_crr
> + - const: misc_crr
> + power-domains:
> + minItems: 1
> +
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - fsl,imx8qm-serdes
> + then:
> + properties:
> + clock-names:
> + items:
> + - const: pclk0
> + - const: pclk1
> + - const: apb_pclk0
> + - const: apb_pclk1
> + - const: pclk2
> + - const: epcs_tx
> + - const: epcs_rx
> + - const: apb_pclk2
> + - const: phy0_crr
> + - const: phy1_crr
> + - const: ctl0_crr
> + - const: ctl1_crr
> + - const: ctl2_crr
> + - const: misc_crr
> + power-domains:
> + minItems: 2
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/imx8-clock.h>
> + #include <dt-bindings/clock/imx8-lpcg.h>
> + #include <dt-bindings/firmware/imx/rsrc.h>
> + #include <dt-bindings/phy/phy-imx8-pcie.h>
> +
> + serdes: phy@5f1a0000 {
No "serdes".
> + compatible = "fsl,imx8qxp-serdes";
> + reg = <0x5f1a0000 0x10000>,
> + <0x5f120000 0x10000>,
> + <0x5f140000 0x10000>,
> + <0x5f160000 0x10000>;
> + reg-names = "reg", "phy", "ctrl", "misc";
> + clocks = <&phyx1_lpcg IMX_LPCG_CLK_0>,
> + <&phyx1_lpcg IMX_LPCG_CLK_4>,
> + <&phyx1_crr1_lpcg IMX_LPCG_CLK_4>,
> + <&pcieb_crr3_lpcg IMX_LPCG_CLK_4>,
> + <&misc_crr5_lpcg IMX_LPCG_CLK_4>;
> + clock-names = "apb_pclk0", "pclk0", "phy0_crr", "ctl0_crr",
> + "misc_crr";
> + power-domains = <&pd IMX_SC_R_SERDES_1>;
> + #phy-cells = <3>;
> + status = "disabled";
needn't status = "disabled".
> + };
> +...
> --
> 2.37.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2] remoteproc: mediatek: Don't parse extraneous subnodes for multi-core
From: Mathieu Poirier @ 2024-04-02 14:23 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: andersson, matthias.bgg, tzungbi, tinghan.shen, linux-remoteproc,
linux-kernel, linux-arm-kernel, linux-mediatek, wenst, kernel
In-Reply-To: <b6ed8710-1608-4343-8a58-5f8e0e16d10d@collabora.com>
On Tue, 2 Apr 2024 at 03:56, AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> Il 28/03/24 15:38, Mathieu Poirier ha scritto:
> > On Wed, Mar 27, 2024 at 01:49:58PM +0100, AngeloGioacchino Del Regno wrote:
> >> Il 21/03/24 16:27, Mathieu Poirier ha scritto:
> >>> On Thu, Mar 21, 2024 at 09:46:14AM +0100, AngeloGioacchino Del Regno wrote:
> >>>> When probing multi-core SCP, this driver is parsing all sub-nodes of
> >>>> the scp-cluster node, but one of those could be not an actual SCP core
> >>>> and that would make the entire SCP cluster to fail probing for no good
> >>>> reason.
> >>>>
> >>>> To fix that, in scp_add_multi_core() treat a subnode as a SCP Core by
> >>>> parsing only available subnodes having compatible "mediatek,scp-core".
> >>>>
> >>>> Fixes: 1fdbf0cdde98 ("remoteproc: mediatek: Probe SCP cluster on multi-core SCP")
> >>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> >>>> ---
> >>>> drivers/remoteproc/mtk_scp.c | 3 +++
> >>>> 1 file changed, 3 insertions(+)
> >>>>
> >>>> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> >>>> index 67518291a8ad..fbe1c232dae7 100644
> >>>> --- a/drivers/remoteproc/mtk_scp.c
> >>>> +++ b/drivers/remoteproc/mtk_scp.c
> >>>> @@ -1096,6 +1096,9 @@ static int scp_add_multi_core(struct platform_device *pdev,
> >>>> cluster_of_data = (const struct mtk_scp_of_data **)of_device_get_match_data(dev);
> >>>> for_each_available_child_of_node(np, child) {
> >>>> + if (!of_device_is_compatible(child, "mediatek,scp-core"))
> >>>> + continue;
> >>>> +
> >>>
> >>> Interesting - what else gets stashed under the remote processor node? I don't
> >>> see anything specified in the bindings.
> >>>
> >>
> >> Sorry for the late reply - well, in this precise moment in time, upstream,
> >> nothing yet.
> >>
> >> I have noticed this while debugging some lockups and wanted to move the scp_adsp
> >> clock controller node as child of the SCP node (as some of those clocks are located
> >> *into the SCP's CFG register space*, and it's correct for that to be a child as one
> >> of those do depend on the SCP being up - and I'll spare you the rest) and noticed
> >> the unexpected behavior, as the SCP driver was treating those as an SCP core.
> >>
> >> There was no kernel panic, but the SCP would fail probing.
> >>
> >> This is anyway a missed requirement ... for platforms that want *both* two SCP
> >> cores *and* the AudioDSP, as that'd at least be two nodes with the same iostart
> >> (scp@1072000, clock-controller@1072000), other than the reasons I explained some
> >> lines back.
> >>
> >> ...and that's why this commit was sent :-)
> >>
> >
> > Please update the bindings with the extra clock requirement in your next
> > revision.
> >
>
> Ok.
>
> Can you please take only patch 1/2 of this series so that I can delay this one
> for a bit? I don't have time to work on that exactly right now.
>
It was added to rproc-next last week.
> Thanks,
> Angelo
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 0/3] media: i2c: Add imx283 camera sensor driver
From: Konstantin Ryabitsev @ 2024-04-02 14:15 UTC (permalink / raw)
To: Umang Jain
Cc: Kieran Bingham, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
Sakari Ailus, linux-media, devicetree, linux-arm-kernel,
linux-kernel, Rob Herring, Laurent Pinchart
In-Reply-To: <d46380d7-e296-445b-a294-b0231ea45518@ideasonboard.com>
On Tue, Apr 02, 2024 at 02:01:19PM +0530, Umang Jain wrote:
> Hi all,
>
> PLease ignore the series, I was testing/learning the b4 tool.
>
> I did pass --offline-mode but it has sent the patches anyway :-//
Hm... I see why this would be confusing and I will try to fix this.
(the --offline-mode flag is to prevent b4 from querying lore.kernel.org, but
it should also bubble up to other functionality that calls remote services,
like b4 send).
-K
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2] arm64: acpi: Honour firmware_signature field of FACS, if it exists
From: Sudeep Holla @ 2024-04-02 14:12 UTC (permalink / raw)
To: Mediouni, Mohamed
Cc: David Woodhouse, linux-arm-kernel@lists.infradead.org,
Catalin Marinas, Sudeep Holla, Will Deacon, Robert Moore,
Rafael J. Wysocki, Len Brown, Saidi, Ali,
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
acpica-devel@lists.linux.dev, Saket Dumbre
In-Reply-To: <70B4B352-08A5-4922-93A0-7F420374A831@amazon.de>
On Tue, Apr 02, 2024 at 12:17:22PM +0000, Mediouni, Mohamed wrote:
>
> > On 2. Apr 2024, at 12:29, Sudeep Holla <sudeep.holla@arm.com> wrote:
> >
> > I think it is OK as a temporary solution for now. But there was some
> > investigation last year as part of some work in Linaro to enable
> > "drivers/acpi/sleep.c" into the build cleaning up some x86-ness in there.
> > acpi_sleep_hibernate_setup() already does this but enabling sleep.c need
> > some careful investigation so that it doesn't break any existing arm64/x86
> > platforms and made need some wordings clarification in the ACPI spec.
> > Today system suspend work via psci std path bypassing the ACPI paths which
> > may not be ideal as none of the ACPI methods are honoured. Some arm64
> > platforms may implement them and expect to be executed in the future,
> > maybe ?
> Current Windows on Arm platforms (seen on SC8280XP) don’t have _GTS
> or _PTS methods, and don’t have sleeping objects either.
>
IMO, SC8280XP is not a very good model platform for ACPI firmware reference.
It uses PEP which Linux doesn't support for good reason and that make it
hard to follow everything on that platform.
> As such, I don’t expect any users for that potential functionality.
I am not 100% sure
> Am I missing something or hibernation signalling to firmware (on ARM64)
> can be made PSCI only indefinitely?
Also bypassing certain operation taken care in sleep.c might result in
missing certain features. Few things IIRC(might be missing things myself
or misunderstood as it has been a while since I looked at the code in
detail): handing of GPE for wakeup, power resource handling during the
resume, power button event to mention few.
--
Regards,
Sudeep
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v7 4/4] pinctrl: Implementation of the generic scmi-pinctrl driver
From: Dan Carpenter @ 2024-04-02 14:09 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Peng Fan (OSS), Sudeep Holla, Cristian Marussi, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Linus Walleij,
linux-arm-kernel, linux-kernel, devicetree, linux-gpio, Peng Fan,
Oleksii Moisieiev
In-Reply-To: <ZgwGpZ6S13vjk8jh@smile.fi.intel.com>
On Tue, Apr 02, 2024 at 04:22:45PM +0300, Andy Shevchenko wrote:
> On Tue, Apr 02, 2024 at 10:22:24AM +0800, Peng Fan (OSS) wrote:
> > +static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
> > + struct pinctrl_desc *desc)
> > +{
> > + struct pinctrl_pin_desc *pins;
> > + unsigned int npins;
> > + int ret, i;
> > +
> > + npins = pinctrl_ops->count_get(pmx->ph, PIN_TYPE);
> > + /*
> > + * npins will never be zero, the scmi pinctrl driver has bailed out
> > + * if npins is zero.
> > + */
>
> This is fragile, but at least it is documented.
>
It was never clear to me where the crash would happen if npins was zero.
Does some part of pinctrl internals assume we have at least one pin?
It's nice to be able to allocate zero element arrays and generally it
works well in the kernel. The one common bug with zero element arrays
has to do with strings. Something like this (garbage) example:
str = kmalloc(n_char, GFP_KERNEL);
copy_from_user(str, user_ptr, n_char);
str[n_char - 1] = '\0';
If the str is zero bytes long it will lead to an Oops when we add a NUL
terminator.
regards,
dan carpenter
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v7 4/4] pinctrl: Implementation of the generic scmi-pinctrl driver
From: Andy Shevchenko @ 2024-04-02 14:09 UTC (permalink / raw)
To: Peng Fan
Cc: Peng Fan (OSS), Sudeep Holla, Cristian Marussi, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Linus Walleij, Dan Carpenter,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, Oleksii Moisieiev
In-Reply-To: <DU0PR04MB9417D0D33573E99D440D7BD7883E2@DU0PR04MB9417.eurprd04.prod.outlook.com>
On Tue, Apr 02, 2024 at 01:59:19PM +0000, Peng Fan wrote:
> > On Tue, Apr 02, 2024 at 10:22:24AM +0800, Peng Fan (OSS) wrote:
...
> > > +#include <linux/device.h>
> > > +#include <linux/err.h>
> > > +#include <linux/module.h>
> > > +#include <linux/seq_file.h>
> > > +#include <linux/scmi_protocol.h>
> > > +#include <linux/slab.h>
> >
> > Missing headers.
>
> Not sure there is an easy way to filter out what is missed.
And?..
You are the author, not me. You know your code much better and
it will be quite easy to perform. I may miss things, but reading
briefly the 1000 lines and get what headers are required takes
no more than half an hour.
(Tools that help me, in case I don't remember by heart, are
`cscope` and `git grep ...`.)
...
> > > + ret = pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE,
> > &pins[i].name);
> > > + if (ret)
> >
> > How does the cleanup work for the previously assigned pin names? Is it
> > needed?
>
> No need. The "name" memory region is allocated in firmware pinctrl
> Protocol init phase.
>
> > Maybe a comment?
>
> ok. As below.
> /*
> * The region for name is handled by the scmi firmware driver,
> * no need free here
> */
LGTM.
> > > + return dev_err_probe(pmx->dev, ret,
> > > + "Can't get name for pin %d", i);
--
With Best Regards,
Andy Shevchenko
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v7 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support
From: Andy Shevchenko @ 2024-04-02 14:05 UTC (permalink / raw)
To: Peng Fan
Cc: Peng Fan (OSS), Sudeep Holla, Cristian Marussi, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Linus Walleij, Dan Carpenter,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, Oleksii Moisieiev
In-Reply-To: <DU0PR04MB941780B4C28DB353C64966F8883E2@DU0PR04MB9417.eurprd04.prod.outlook.com>
On Tue, Apr 02, 2024 at 01:27:19PM +0000, Peng Fan wrote:
> > On Tue, Apr 02, 2024 at 10:22:23AM +0800, Peng Fan (OSS) wrote:
...
> > > +#include <linux/module.h>
> > > +#include <linux/scmi_protocol.h>
> > > +#include <linux/slab.h>
> >
> > Please, follow IWYU principle, a lot of headers are missed.
>
> ok. I will try to figure out. BTW, is there an easy way to filter
> out what is missed?
For you is much easier than to me as I'm not familiar with the code.
Basically you should know what you wrote :-)
But if you are asking about tooling, we would appreciate when somebody comes
with a such.
> > > +#include "common.h"
> > > +#include "protocols.h"
...
> > > + ret = scmi_pinctrl_get_pin_info(ph, selector,
> > > + &pi->pins[selector]);
> >
> > It's netter as a single line.
>
> I try to follow 80 max chars per SCMI coding style. If Sudeep and Cristian
> is ok, I could use a single line.
It's minor, but even before relaxation of 80 limit it was and is mentioned
in the documentation that you may go over if it increases readability.
> > > + if (ret)
> > > + return ret;
> > > + }
...
> > > +static int scmi_pinctrl_protocol_init(const struct
> > > +scmi_protocol_handle *ph) {
> > > + int ret;
> > > + u32 version;
> > > + struct scmi_pinctrl_info *pinfo;
> > > +
> > > + ret = ph->xops->version_get(ph, &version);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + dev_dbg(ph->dev, "Pinctrl Version %d.%d\n",
> > > + PROTOCOL_REV_MAJOR(version),
> > PROTOCOL_REV_MINOR(version));
> > > +
> > > + pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL);
> > > + if (!pinfo)
> > > + return -ENOMEM;
> > > +
> > > + ret = scmi_pinctrl_attributes_get(ph, pinfo);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + pinfo->pins = devm_kcalloc(ph->dev, pinfo->nr_pins,
> > > + sizeof(*pinfo->pins), GFP_KERNEL);
> > > + if (!pinfo->pins)
> > > + return -ENOMEM;
> > > +
> > > + pinfo->groups = devm_kcalloc(ph->dev, pinfo->nr_groups,
> > > + sizeof(*pinfo->groups), GFP_KERNEL);
> > > + if (!pinfo->groups)
> > > + return -ENOMEM;
> > > +
> > > + pinfo->functions = devm_kcalloc(ph->dev, pinfo->nr_functions,
> > > + sizeof(*pinfo->functions),
> > GFP_KERNEL);
> > > + if (!pinfo->functions)
> > > + return -ENOMEM;
> > > +
> > > + pinfo->version = version;
> > > +
> > > + return ph->set_priv(ph, pinfo, version);
> >
> > Same comments as per previous version. devm_ here is simply wrong.
> > It breaks the order of freeing resources.
> >
> > I.o.w. I see *no guarantee* that these init-deinit functions will be properly
> > called from the respective probe-remove. Moreover the latter one may also
> > have its own devm allocations (which are rightfully placed) and you get
> > completely out of control the resource management.
>
> I see an old thread.
> https://lore.kernel.org/linux-arm-kernel/ZJ78hBcjAhiU+ZBO@e120937-lin/#t
>
> The free in deinit is not to free the ones alloced in init, it is to free the ones
> alloced such as in scmi_pinctrl_get_function_info
Even messier than I thought. For bare minimum these two should be documented
and renamed accordingly that no-one will think that deinit is a counter part
of init.
--
With Best Regards,
Andy Shevchenko
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v7 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support
From: Peng Fan @ 2024-04-02 14:04 UTC (permalink / raw)
To: Cristian Marussi, Peng Fan (OSS)
Cc: Sudeep Holla, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Dan Carpenter,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, Oleksii Moisieiev
In-Reply-To: <Zgvd7npz1jdJSu-b@pluto>
> Subject: Re: [PATCH v7 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> protocol basic support
>
> On Tue, Apr 02, 2024 at 10:22:23AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan@nxp.com>
> >
> > Add basic implementation of the SCMI v3.2 pincontrol protocol.
> >
>
> Hi,
>
>
> > Co-developed-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
> > Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > ---
>
> [snip]
>
>
> > +struct scmi_settings_get_ipriv {
> > + u32 selector;
> > + enum scmi_pinctrl_selector_type type;
> > + bool get_all;
> > + enum scmi_pinctrl_conf_type *config_types;
> > + u32 *config_values;
> > +};
> > +
> > +static void
> > +iter_pinctrl_settings_get_prepare_message(void *message, u32 desc_index,
> > + const void *priv)
> > +{
> > + struct scmi_msg_settings_get *msg = message;
> > + const struct scmi_settings_get_ipriv *p = priv;
> > + u32 attributes;
> > +
> > + attributes = FIELD_PREP(SELECTOR_MASK, p->type);
> > +
> > + if (p->get_all) {
> > + attributes |= FIELD_PREP(CONFIG_FLAG_MASK, 1) |
> > + FIELD_PREP(SKIP_CONFIGS_MASK, desc_index);
> > + } else {
> > + attributes |= FIELD_PREP(CONFIG_TYPE_MASK, p-
> >config_types[0]);
> > + }
> > +
> > + msg->attributes = cpu_to_le32(attributes);
> > + msg->identifier = cpu_to_le32(p->selector); }
> > +
> > +static int
> > +iter_pinctrl_settings_get_update_state(struct scmi_iterator_state *st,
> > + const void *response, void *priv) {
> > + const struct scmi_resp_settings_get *r = response;
> > + struct scmi_settings_get_ipriv *p = priv;
> > +
> > + if (p->get_all) {
> > + st->num_returned = le32_get_bits(r->num_configs,
> GENMASK(7, 0));
> > + st->num_remaining = le32_get_bits(r->num_configs,
> GENMASK(31, 24));
> > + } else {
> > + st->num_returned = 1;
> > + st->num_remaining = 0;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int
> > +iter_pinctrl_settings_get_process_response(const struct
> scmi_protocol_handle *ph,
> > + const void *response,
> > + struct scmi_iterator_state *st,
> > + void *priv)
> > +{
> > + const struct scmi_resp_settings_get *r = response;
> > + struct scmi_settings_get_ipriv *p = priv;
> > + u32 type = le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7,
> 0));
> > + u32 val = le32_to_cpu(r->configs[st->loop_idx * 2 + 1]);
> > +
> > + if (p->get_all) {
> > + p->config_types[st->desc_index + st->loop_idx] = type;
> > + } else {
> > + if (p->config_types[0] != type)
> > + return -EINVAL;
> > + }
> > +
> > + p->config_values[st->desc_index + st->loop_idx] = val;
> > +
> > + return 0;
> > +}
> > +
> > +static int
> > +scmi_pinctrl_settings_get(const struct scmi_protocol_handle *ph, u32
> selector,
> > + enum scmi_pinctrl_selector_type type,
> > + enum scmi_pinctrl_conf_type config_type,
> > + u32 *config_value, bool get_all) {
> > + int ret;
> > + void *iter;
> > + struct scmi_iterator_ops ops = {
> > + .prepare_message =
> iter_pinctrl_settings_get_prepare_message,
> > + .update_state = iter_pinctrl_settings_get_update_state,
> > + .process_response =
> iter_pinctrl_settings_get_process_response,
> > + };
> > + struct scmi_settings_get_ipriv ipriv = {
> > + .selector = selector,
> > + .type = type,
> > + .get_all = get_all,
> > + .config_types = &config_type,
> > + .config_values = config_value,
> > + };
> > +
> > + if (!config_value || type == FUNCTION_TYPE)
> > + return -EINVAL;
> > +
> > + ret = scmi_pinctrl_validate_id(ph, selector, type);
> > + if (ret)
> > + return ret;
> > +
> > + iter = ph->hops->iter_response_init(ph, &ops, SCMI_PIN_OEM_END,
> > + PINCTRL_SETTINGS_GET,
> > + sizeof(struct
> scmi_msg_settings_get),
> > + &ipriv);
> > + if (IS_ERR(iter))
> > + return PTR_ERR(iter);
> > +
> > + return ph->hops->iter_response_run(iter);
> > +}
> > +
> > +static int scmi_pinctrl_settings_get_one(const struct scmi_protocol_handle
> *ph,
> > + u32 selector,
> > + enum scmi_pinctrl_selector_type
> type,
> > + enum scmi_pinctrl_conf_type
> config_type,
> > + u32 *config_value)
> > +{
> > + return scmi_pinctrl_settings_get(ph, selector, type, config_type,
> > + config_value, false);
> > +}
> > +
> > +static int scmi_pinctrl_settings_get_all(const struct scmi_protocol_handle
> *ph,
> > + u32 selector,
> > + enum scmi_pinctrl_selector_type
> type,
> > + enum scmi_pinctrl_conf_type
> config_type,
> > + u32 *config_value)
> > +{
> > + return scmi_pinctrl_settings_get(ph, selector, type, config_type,
> > + config_value, true);
> > +}
> > +
>
> If you generalize the scmi_pinctrl_settings_get() and reintroduce a
> .settings_get_all() ops (even though unused by pinctrl driver, I am fine with
> this..), you should take care to pass as an input parameter NOT only the array
> of config_values BUT also an array of config_types since you could get back
> up to 256 OEM types: for this reason you will need also to pass to
> scmi_pinctrl_settings_get() an input param that specifies the sizes of the
> 2 array input params (in order to avoid oveflows) AND use that same inout
> param also as an output param to report at the end how many OEM types
> were effectively found and returned....
>
> IOW, I did this on top of your V7 to make the settings_get_all work:
>
> ---8<---
> diff --git a/drivers/firmware/arm_scmi/pinctrl.c
> b/drivers/firmware/arm_scmi/pinctrl.c
> index b75af1dd75fa..f4937af66c4d 100644
> --- a/drivers/firmware/arm_scmi/pinctrl.c
> +++ b/drivers/firmware/arm_scmi/pinctrl.c
> @@ -317,6 +317,7 @@ struct scmi_settings_get_ipriv {
> u32 selector;
> enum scmi_pinctrl_selector_type type;
> bool get_all;
> + unsigned int *nr_configs;
> enum scmi_pinctrl_conf_type *config_types;
> u32 *config_values;
> };
> @@ -379,6 +380,7 @@ iter_pinctrl_settings_get_process_response(const
> struct scmi_protocol_handle *ph
> }
>
> p->config_values[st->desc_index + st->loop_idx] = val;
> + ++*p->nr_configs;
>
> return 0;
> }
> @@ -386,11 +388,13 @@ iter_pinctrl_settings_get_process_response(const
> struct scmi_protocol_handle *ph static int scmi_pinctrl_settings_get(const
> struct scmi_protocol_handle *ph, u32 selector,
> enum scmi_pinctrl_selector_type type,
> - enum scmi_pinctrl_conf_type config_type,
> - u32 *config_value, bool get_all)
> + unsigned int *nr_configs,
> + enum scmi_pinctrl_conf_type *config_types,
> + u32 *config_values)
> {
> int ret;
> void *iter;
> + unsigned int max_configs = *nr_configs;
> struct scmi_iterator_ops ops = {
> .prepare_message =
> iter_pinctrl_settings_get_prepare_message,
> .update_state = iter_pinctrl_settings_get_update_state,
> @@ -399,19 +403,22 @@ scmi_pinctrl_settings_get(const struct
> scmi_protocol_handle *ph, u32 selector,
> struct scmi_settings_get_ipriv ipriv = {
> .selector = selector,
> .type = type,
> - .get_all = get_all,
> - .config_types = &config_type,
> - .config_values = config_value,
> + .get_all = (max_configs > 1),
> + .nr_configs = nr_configs,
> + .config_types = config_types,
> + .config_values = config_values,
> };
>
> - if (!config_value || type == FUNCTION_TYPE)
> + if (!config_types || !config_values || type == FUNCTION_TYPE)
> return -EINVAL;
>
> ret = scmi_pinctrl_validate_id(ph, selector, type);
> if (ret)
> return ret;
>
> - iter = ph->hops->iter_response_init(ph, &ops, SCMI_PIN_OEM_END,
> + /* Prepare to count returned configs */
> + *nr_configs = 0;
> + iter = ph->hops->iter_response_init(ph, &ops, max_configs,
> PINCTRL_SETTINGS_GET,
> sizeof(struct
> scmi_msg_settings_get),
> &ipriv);
> @@ -427,18 +434,24 @@ static int scmi_pinctrl_settings_get_one(const
> struct scmi_protocol_handle *ph,
> enum scmi_pinctrl_conf_type
> config_type,
> u32 *config_value)
> {
> - return scmi_pinctrl_settings_get(ph, selector, type, config_type,
> - config_value, false);
> + unsigned int nr_configs = 1;
> +
> + return scmi_pinctrl_settings_get(ph, selector, type, &nr_configs,
> + &config_type, config_value);
> }
>
> static int scmi_pinctrl_settings_get_all(const struct scmi_protocol_handle
> *ph,
> u32 selector,
> enum scmi_pinctrl_selector_type
> type,
> - enum scmi_pinctrl_conf_type
> config_type,
> - u32 *config_value)
> + unsigned int *nr_configs,
> + enum scmi_pinctrl_conf_type
> *config_types,
> + u32 *config_values)
> {
> - return scmi_pinctrl_settings_get(ph, selector, type, config_type,
> - config_value, true);
> + if (!nr_configs || *nr_configs == 0)
> + return -EINVAL;
> +
> + return scmi_pinctrl_settings_get(ph, selector, type, nr_configs,
> + config_types, config_values);
> }
>
> static int
> diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
> index abaf6122ea37..7915792efd81 100644
> --- a/include/linux/scmi_protocol.h
> +++ b/include/linux/scmi_protocol.h
> @@ -882,8 +882,9 @@ struct scmi_pinctrl_proto_ops {
> int (*settings_get_all)(const struct scmi_protocol_handle *ph,
> u32 selector,
> enum scmi_pinctrl_selector_type type,
> - enum scmi_pinctrl_conf_type config_type,
> - u32 *config_value);
> + unsigned int *nr_configs,
> + enum scmi_pinctrl_conf_type *config_types,
> + u32 *config_values);
> int (*settings_conf)(const struct scmi_protocol_handle *ph,
> u32 selector, enum scmi_pinctrl_selector_type
> type,
> unsigned int nr_configs,
> --->8-----
>
> Please check if this addition sounds good to you and integrate into v8
> eventually...
Thanks for helping on this, I will included your changes, and your
Co-developed-by tag if you not mind.
Thanks,
Peng.
>
> Thanks,
> Cristian
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v1 0/3] mm/gup: consistently call it GUP-fast
From: David Hildenbrand @ 2024-04-02 12:55 UTC (permalink / raw)
To: linux-kernel
Cc: linux-mm, David Hildenbrand, Andrew Morton, Mike Rapoport,
Jason Gunthorpe, John Hubbard, Peter Xu, linux-arm-kernel,
loongarch, linux-mips, linuxppc-dev, linux-s390, linux-sh,
linux-perf-users, linux-fsdevel, linux-riscv, x86
Some cleanups around function names, comments and the config option of
"GUP-fast" -- GUP without "lock" safety belts on.
With this cleanup it's easy to judge which functions are GUP-fast specific.
We now consistently call it "GUP-fast", avoiding mixing it with "fast GUP",
"lockless", or simply "gup" (which I always considered confusing in the
ode).
So the magic now happens in functions that contain "gup_fast", whereby
gup_fast() is the entry point into that magic. Comments consistently
reference either "GUP-fast" or "gup_fast()".
Based on mm-unstable from today. I won't CC arch maintainers, but only
arch mailing lists, to reduce noise.
Tested on x86_64, cross compiled on a bunch of archs.
RFC -> v1:
* Rebased on latest mm/mm-unstable
* "mm/gup: consistently name GUP-fast functions"
-> "internal_get_user_pages_fast()" -> "gup_fast_fallback()"
-> "undo_dev_pagemap()" -> "gup_fast_undo_dev_pagemap()"
-> Fixup a bunch more comments
* "mm/treewide: rename CONFIG_HAVE_FAST_GUP to CONFIG_HAVE_GUP_FAST"
-> Take care of RISCV
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mike Rapoport (IBM) <rppt@kernel.org>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: loongarch@lists.linux.dev
Cc: linux-mips@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-perf-users@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-riscv@lists.infradead.org
Cc: x86@kernel.org
David Hildenbrand (3):
mm/gup: consistently name GUP-fast functions
mm/treewide: rename CONFIG_HAVE_FAST_GUP to CONFIG_HAVE_GUP_FAST
mm: use "GUP-fast" instead "fast GUP" in remaining comments
arch/arm/Kconfig | 2 +-
arch/arm64/Kconfig | 2 +-
arch/loongarch/Kconfig | 2 +-
arch/mips/Kconfig | 2 +-
arch/powerpc/Kconfig | 2 +-
arch/riscv/Kconfig | 2 +-
arch/s390/Kconfig | 2 +-
arch/sh/Kconfig | 2 +-
arch/x86/Kconfig | 2 +-
include/linux/rmap.h | 8 +-
kernel/events/core.c | 4 +-
mm/Kconfig | 2 +-
mm/filemap.c | 2 +-
mm/gup.c | 215 +++++++++++++++++++++--------------------
mm/internal.h | 2 +-
mm/khugepaged.c | 2 +-
16 files changed, 127 insertions(+), 126 deletions(-)
--
2.44.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v6 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support
From: Peng Fan @ 2024-04-02 14:01 UTC (permalink / raw)
To: Andy Shevchenko, Cristian Marussi
Cc: Peng Fan (OSS), Sudeep Holla, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Dan Carpenter,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, Oleksii Moisieiev
In-Reply-To: <CAHp75VdAaTeQ_Ag3gd0s9UfT=kAT2hwibeJ9-YFXJx4z=R3e+g@mail.gmail.com>
> Subject: Re: [PATCH v6 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> protocol basic support
>
> On Tue, Apr 2, 2024 at 10:48 AM Cristian Marussi
> <cristian.marussi@arm.com> wrote:
> > On Sun, Mar 31, 2024 at 01:44:28PM +0000, Peng Fan wrote:
> > > > Sat, Mar 23, 2024 at 08:15:16PM +0800, Peng Fan (OSS) kirjoitti:
>
> ...
>
> > > > > +#include <linux/module.h>
> > > > > +#include <linux/scmi_protocol.h> #include <linux/slab.h>
> > > >
> > > > This is semi-random list of headers. Please, follow IWYU principle
> > > > (include what you use). There are a lot of inclusions I see
> > > > missing (just in the context of this page I see bits.h, types.h, and
> asm/byteorder.h).
> > >
> > > Is there any documentation about this requirement?
> > > Some headers are already included by others.
>
> The documentation here is called "a common sense".
> The C language is built like this and we expect that nobody will invest into the
> dependency hell that we have already, that's why IWYU principle, please
> follow it.
>
> > Andy made (mostly) the same remarks on this same patch ~1-year ago on
> > this same patch while it was posted by Oleksii.
> >
> > And I told that time that most of the remarks around devm_ usage were
> > wrong due to how the SCMI core handles protocol initialization (using
> > a devres group transparently).
> >
> > This is what I answered that time.
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore
> > .kernel.org%2Flinux-arm-kernel%2FZJ78hBcjAhiU%2BZBO%40e120937-
> lin%2F%2
> >
> 3t&data=05%7C02%7Cpeng.fan%40nxp.com%7C3f8c12062db048608e2a08d
> c5315bed
> >
> 0%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6384766000583
> 40430%7CUn
> >
> known%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6I
> k1haW
> >
> wiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=Whn3ehZjXy%2BcKG4irlWjQ6
> K3HF%2FofD
> > Yu7j0Lrm8dN5k%3D&reserved=0
> >
> > I wont repeat myself, but, in a nutshell the memory allocation like it
> > is now is fine: a bit happens via devm_ at protocol initialization,
> > the other is doe via explicit kmalloc at runtime and freed via kfree
> > at remove time (if needed...i.e. checking the present flag of some
> > structs)
>
> This sounds like a mess. devm_ is expected to be used only for the
> ->probe() stage, otherwise you may consider cleanup.h (__free() macro)
> to have automatic free at the paths where memory is not needed.
>
> And the function naming doesn't suggest that you have a probe-remove pair.
> Moreover, if the init-deinit part is called in the probe-remove, the devm_
> must not be mixed with non-devm ones, as it breaks the order and leads to
> subtle mistakes.
I am new to __free() honestly. I'll let Cristian and Sudeep to comment on
what should I do for v8.
Thanks,
Peng.
>
> > I'll made further remarks on v7 that you just posted.
>
> --
> With Best Regards,
> Andy Shevchenko
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH RFT 01/10] arm64: dts: microchip: sparx5: fix mdio reg
From: Steen Hegelund @ 2024-04-02 14:00 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rob Herring, Daniel Machon, Bjarni Jonasson, linux-kernel,
Conor Dooley, Claudiu Beznea, devicetree, linux-arm-kernel,
Krzysztof Kozlowski, UNGLinuxDriver, David S. Miller,
Lars Povlsen
In-Reply-To: <20240401153740.123978-1-krzk@kernel.org>
Hi Krzysztof,
On Mon, 2024-04-01 at 17:37 +0200, Krzysztof Kozlowski wrote:
> [Some people who received this message don't often get email from
> krzk@kernel.org. Learn why this is important at
> https://aka.ms/LearnAboutSenderIdentification ]
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you
> know the content is safe
>
> Correct the reg address of mdio node to match unit address. Assume
> the
> reg is not correct and unit address was correct, because there is
> alerady node using the existing reg 0x110102d4.
>
> sparx5.dtsi:443.25-451.5: Warning (simple_bus_reg):
> /axi@600000000/mdio@6110102f8: simple-bus unit address format error,
> expected "6110102d4"
>
> Fixes: d0f482bb06f9 ("arm64: dts: sparx5: Add the Sparx5 switch
> node")
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
>
> ---
>
> Not tested on hardware
> ---
> arch/arm64/boot/dts/microchip/sparx5.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi
> b/arch/arm64/boot/dts/microchip/sparx5.dtsi
> index 24075cd91420..5d820da8c69d 100644
> --- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
> +++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
> @@ -447,7 +447,7 @@ mdio2: mdio@6110102f8 {
> pinctrl-names = "default";
> #address-cells = <1>;
> #size-cells = <0>;
> - reg = <0x6 0x110102d4 0x24>;
> + reg = <0x6 0x110102f8 0x24>;
> };
>
> mdio3: mdio@61101031c {
> --
> 2.34.1
>
I did a check of our current Sparx5 EVBs and none of them uses
controller 2 in any revision, so this is probably why it has not come
up before, so as it stands we have no platform to test this change on
currently.
Besides that the change looks good to me.
Best Regards
Steen
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v7 4/4] pinctrl: Implementation of the generic scmi-pinctrl driver
From: Peng Fan @ 2024-04-02 13:59 UTC (permalink / raw)
To: Andy Shevchenko, Peng Fan (OSS)
Cc: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Dan Carpenter,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, Oleksii Moisieiev
In-Reply-To: <ZgwGpZ6S13vjk8jh@smile.fi.intel.com>
> Subject: Re: [PATCH v7 4/4] pinctrl: Implementation of the generic scmi-
> pinctrl driver
>
> On Tue, Apr 02, 2024 at 10:22:24AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan@nxp.com>
> >
> > scmi-pinctrl driver implements pinctrl driver interface and using SCMI
> > protocol to redirect messages from pinctrl subsystem SDK to SCMI
> > platform firmware, which does the changes in HW.
>
> ...
>
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/module.h>
> > +#include <linux/seq_file.h>
> > +#include <linux/scmi_protocol.h>
> > +#include <linux/slab.h>
>
> Missing headers.
Not sure there is an easy way to filter out what is missed.
>
> ...
>
> > + *p_groups = (const char * const *)func->groups;
>
> Is this casting needed?
This is no needed.
>
> ...
>
> > +static int pinctrl_scmi_pinconf_get(struct pinctrl_dev *pctldev,
> > + unsigned int _pin, unsigned long *config)
>
> Why underscored parameter name?
Underscore could be dropped.
>
> ...
>
> > +static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
> > + struct pinctrl_desc *desc)
> > +{
> > + struct pinctrl_pin_desc *pins;
> > + unsigned int npins;
> > + int ret, i;
> > +
> > + npins = pinctrl_ops->count_get(pmx->ph, PIN_TYPE);
> > + /*
> > + * npins will never be zero, the scmi pinctrl driver has bailed out
> > + * if npins is zero.
> > + */
>
> This is fragile, but at least it is documented.
>
> > + pins = devm_kmalloc_array(pmx->dev, npins, sizeof(*pins),
> GFP_KERNEL);
> > + if (!pins)
> > + return -ENOMEM;
> > +
> > + for (i = 0; i < npins; i++) {
> > + pins[i].number = i;
> > + ret = pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE,
> &pins[i].name);
> > + if (ret)
>
> How does the cleanup work for the previously assigned pin names? Is it
> needed?
No need. The "name" memory region is allocated in firmware pinctrl
Protocol init phase.
> Maybe a comment?
ok. As below.
/*
* The region for name is handled by the scmi firmware driver,
* no need free here
*/
>
> > + return dev_err_probe(pmx->dev, ret,
> > + "Can't get name for pin %d", i);
> > + }
> > +
> > + desc->npins = npins;
> > + desc->pins = pins;
> > + dev_dbg(pmx->dev, "got pins %u", npins);
> > +
> > + return 0;
> > +}
>
> ...
>
> > +static const struct scmi_device_id scmi_id_table[] = {
> > + { SCMI_PROTOCOL_PINCTRL, "pinctrl" },
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(scmi, scmi_id_table);
>
> Move this closer to the user.
ok. Fix in v8.
Thanks,
Peng.
>
> --
> With Best Regards,
> Andy Shevchenko
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6 0/4] fpga: xilinx-selectmap: add new driver
From: Charles Perry @ 2024-04-02 13:57 UTC (permalink / raw)
To: Xu Yilun
Cc: mdf, Allen VANDIVER, Brian CODY, hao wu, yilun xu, Tom Rix,
Rob Herring, krzysztof kozlowski+dt, Conor Dooley, Michal Simek,
linux-fpga, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <Zgl4I6rykg7shI2K@yilunxu-OptiPlex-7050>
On Mar 31, 2024, at 10:50 AM, Xu Yilun yilun.xu@linux.intel.com wrote:
> On Thu, Mar 21, 2024 at 06:04:32PM -0400, Charles Perry wrote:
>> Hello,
>>
>> This patchset adds a new driver for the 7 series FPGA's SelectMAP
>> interface.
>>
>> The SelectMAP interface shares a common GPIO protocol with the SPI
>> interface which is already in the kernel (drivers/fpga/xilinx-spi.c).
>> The approach proposed in this patchset is to refactor xilinx-spi.c into
>> xilinx-core.c which would handle the common GPIO protocol. This is then
>> used to build two drivers, the already existing xilinx-spi.c driver and
>> a newly added xilinx-selectmap.c driver.
>>
>> The SelectMAP driver proposed only supports 8 bit mode. This is because
>> the 16 and 32 bits mode have limitations with regards to compressed
>> bitstream support as well as introducing endianness considerations.
>>
>> I'm testing xilinx-selectmap.c on a custom i.MX6 board connected to an
>> Artix 7 FPGA. Flashing a 913K bitstream takes 0.44 seconds.
>>
>> Changes since v5: (from Yilun review)
>> * xilinx-core.h: remove private fields kernel-doc
>> * xilinx-spi.c: rename conf into core in xilinx_spi_probe
>> * xilinx-core.c: introduce the new gpio names in patch 4/4
>> * xilinx-core.c: remove kernel-doc on xilinx_core_devm_gpiod_get()
>> * xilinx-selectmap.c:
>> * reorder includes in alphabetical order
>> * xilinx_selectmap_probe(): remove unused resource *r variable
>> * xilinx_selectmap_probe(): use a single gpio_desc* temporary
>> * xilinx_selectmap_probe(): declare variables in reverse xmas tree
>>
>> Changes since v4: (from Yilun and Krzysztof review)
>> * xilinx-core: use sizeof() instead of hardcoded immediate
>> * xilinx-core: fix module compilation (EXPORT_SYMBOL_GPL, MODULE_LICENSE,
>> MODULE_AUTHOR, MODULE_DESCRIPTION)
>> * xilinx-core: add private/public qualifiers for struct xilinx_fpga_core
>> * xilinx-spi: remove struct xilinx_spi_conf. This struct isn't needed as
>> the struct spi_device* can be retrieved from the struct device*.
>> * dt-bindings: remove usage of "_b" and "-b" for the new driver. We
>> agreed that the spi and selectmap driver will use different bindings
>> which will be handled by the driver core and that the legacy names will
>> be used only for the spi compatible.
>> * xilinx-core: select between prog/init and prog_b/init-b
>>
>> Changes since v3: (from Rob Herring review)
>> * Fix an error in the DT binding example compatible.
>> * Drop the renaming of "prog_b" to "prog" and "init-b" to "init".
>> Patches 2 and 3 are removed.
>>
>> Changes since v2:
>> * Inserted patch 2 and 3 which rename "prog_b" and "init-b" into "prog"
>> and "init" for the SPI driver.
>> * From Krzysztof Kozlowski review's:
>> * Use more specific compatible names
>> * Remove other missing occurences of the slave word missed in v2.
>> * From Xu Yilun review's:
>> * Fix vertical whitespace in get_done_gpio().
>> * Combine write() and write_one_dummy_byte() together.
>> * Eliminate most of the xilinx_core_probe() arguments, the driver
>> needs to populate those directly into the xilinx_fpga_core struct.
>> Added some documentation to struct xilinx_fpga_core to clarify
>> this.
>> * Removed typedefs from xilinx-core.h.
>> * Moved null checks in xilinx_core_probe() to first patch.
>> * Move csi_b and rdwr_b out of xilinx_selectmap_conf as they are not
>> used out of the probe function.
>>
>> Changes since v1: (from Krzysztof Kozlowski review's)
>> * Use more conventional names for gpio DT bindings
>> * fix example in DT bindings
>> * add mc-peripheral-props.yaml to DT bindings
>> * fix various formatting mistakes
>> * Remove all occurences of the "slave" word.
>>
>> Charles Perry (4):
>> fpga: xilinx-spi: extract a common driver core
>> dt-bindings: fpga: xlnx,fpga-selectmap: add DT schema
>> fpga: xilinx-selectmap: add new driver
>> xilinx-core: add new gpio names for prog and init
>>
>> .../bindings/fpga/xlnx,fpga-selectmap.yaml | 86 +++++++
>> drivers/fpga/Kconfig | 12 +
>> drivers/fpga/Makefile | 2 +
>> drivers/fpga/xilinx-core.c | 229 ++++++++++++++++++
>> drivers/fpga/xilinx-core.h | 27 +++
>> drivers/fpga/xilinx-selectmap.c | 95 ++++++++
>> drivers/fpga/xilinx-spi.c | 224 ++---------------
>> 7 files changed, 466 insertions(+), 209 deletions(-)
>> create mode 100644
>> Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>> create mode 100644 drivers/fpga/xilinx-core.c
>> create mode 100644 drivers/fpga/xilinx-core.h
>> create mode 100644 drivers/fpga/xilinx-selectmap.c
>
> Applied this series to for-next with a nit.
>
> Thanks,
> Yilun
>
Thanks again for all the good reviews Yilun.
Regards,
Charles
>>
>> --
>> 2.43.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH net-next 1/3] dt-bindings: net: renesas,rzn1-gmac: Document RZ/N1 GMAC support
From: Geert Uytterhoeven @ 2024-04-02 13:43 UTC (permalink / raw)
To: Romain Gantois
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Alexandre Torgue, Jose Abreu,
Maxime Coquelin, Russell King, Clément Léger,
Thomas Petazzoni, netdev, devicetree, linux-kernel,
linux-renesas-soc, linux-stm32, linux-arm-kernel
In-Reply-To: <20240402-rzn1-gmac1-v1-1-5be2b2894d8c@bootlin.com>
Hi Romain,
On Tue, Apr 2, 2024 at 2:36 PM Romain Gantois
<romain.gantois@bootlin.com> wrote:
> From: Clément Léger <clement.leger@bootlin.com>
>
> The RZ/N1 series of MPUs feature up to two Gigabit Ethernet controllers.
> These controllers are based on Synopsys IPs. They can be connected to
> RZ/N1 RGMII/RMII converters.
>
> Add a binding that describes these GMAC devices.
>
> Signed-off-by: "Clément Léger" <clement.leger@bootlin.com>
> [rgantois: commit log]
> Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
Thanks for your patch!
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
> +examples:
> + - |
> + #include <dt-bindings/clock/r9a06g032-sysctrl.h>
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> + ethernet@44000000 {
> + compatible = "renesas,r9a06g032-gmac", "renesas,rzn1-gmac", "snps,dwmac";
> + reg = <0x44000000 0x2000>;
> + interrupt-parent = <&gic>;
There is no need to use interrupt-parent in examples.
> + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
> + clock-names = "stmmaceth";
> + clocks = <&sysctrl R9A06G032_HCLK_GMAC0>;
If you want this to be a real example, you should add power-domains.
> + snps,multicast-filter-bins = <256>;
> + snps,perfect-filter-entries = <128>;
> + tx-fifo-depth = <2048>;
> + rx-fifo-depth = <4096>;
> + pcs-handle = <&mii_conv1>;
> + phy-mode = "mii";
> + };
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 00/18] Improve PCI memory mapping API
From: Rick Wertenbroek @ 2024-04-02 12:36 UTC (permalink / raw)
To: Damien Le Moal
Cc: Manivannan Sadhasivam, Lorenzo Pieralisi, Kishon Vijay Abraham I,
Shawn Lin, Krzysztof Wilczyński, Bjorn Helgaas,
Heiko Stuebner, linux-pci, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, devicetree, linux-rockchip, linux-arm-kernel,
Wilfred Mallawa, Niklas Cassel
In-Reply-To: <20240330041928.1555578-1-dlemoal@kernel.org>
On Sat, Mar 30, 2024 at 5:19 AM Damien Le Moal <dlemoal@kernel.org> wrote:
>
> This series introduces the new functions pci_epc_map_align(),
> pci_epc_mem_map() and pci_epc_mem_unmap() to improve handling of the
> PCI address mapping alignment constraints of endpoint controllers in a
> controller independent manner.
>
> The issue fixed is that the fixed alignment defined by the "align" field
> of struct pci_epc_features assumes that the alignment of the endpoint
> memory used to map a RC PCI address range is independent of the PCI
> address being mapped. But that is not the case for the rk3399 SoC
> controller: in endpoint mode, this controller uses the lower bits of the
> local endpoint memory address as the lower bits for the PCI addresses
> for data transfers. That is, when mapping local memory, one must take
> into account the number of bits of the RC PCI address that change from
> the start address of the mapping.
>
> To fix this, the new endpoint controller method .map_align is introduced
> and called from pci_epc_map_align(). This method is optional and for
> controllers that do not define it, the mapping information returned
> is based of the fixed alignment constraint as defined by the align
> feature.
>
> The functions pci_epc_mem_map() is a helper function which obtains
> mapping information, allocates endpoint controller memory according to
> the mapping size obtained and maps the memory. pci_epc_mem_map() unmaps
> and frees the endpoint memory.
This way of mapping is not only useful for the RK3399 but would also
help for the addition of other future PCI endpoint controller drivers.
For example, on several FPGA PCI endpoint IPs the window mapping is
also done by passing N bits from the mapped address and M bits from
the window mapping address (where N+M=bus width, e.g., 32 or 64).
Using AND/OR masks/operations to combine the bits for the hardware
address from the mapped address and map base uses less resources than
using add/subtract to get the hardware address from an unaligned map
base and offset. So I guess that more than a few IPs, being hard or
soft IPs, use this kind of mapping (to reduce size, logic, improve max
operating frequency, improve efficiency etc.)
Two major examples come to mind :
1) The AMD/Xilinx PCIe endpoint IP. The mapping is documentented in
"AXI Bridge for PCI Express Gen3 Subsystem Product Guide (PG194)" [1]
section BAR and Address Translation (Figure AXI to PCIe Address
Translation).
2) The Intel/Altera PCIe endpoint IP. The mapping is documented in
"Multi Channel DMA Intel® FPGA IP for PCI Express* User Guide" [2]
section 3.6. Root Port Address Translation Table Enablement.
Both those IPs don't have mainline support yet as PCIe endpoint
controllers but also use a similar kind of mapping as suggested here
for the RK3399. So these changes would also make the addition of these
controller drivers easier.
The new mapping scheme also makes it much clearer in the PCI endpoint
framework. Because without it some mapping operation would fail
because of alignment requirements in the controller, this requires
extra code and checks in the drivers that implement the endpoint
functions. With the current state of the PCI endpoint controller
framework there is no good way to express that the controller does an
AND/OR mask combination to create the hardware address and therefore
requires the map to be aligned to the window size, rather than doing a
window base addition with an offset (subtraction) in the mapping. This
could benefit from further clarification in the endpoint framework.
Best regards,
Rick
[1] https://docs.amd.com/r/en-US/pg194-axi-bridge-pcie-gen3/Address-Translation
[2] https://www.intel.com/content/www/us/en/docs/programmable/683821/23-4/
>
> This series is organized as follows:
> - Patch 1 tidy up the epc core code
> - Patch 2 and 3 introduce the new map_align endpoint controller method
> and related epc functions.
> - Patch 4 to 6 modify the test endpoint driver to use these new
> functions and improve the code of this driver.
> - Finally, Patch 7 to 18 fix the rk3399 endpoint driver, defining a
> .map_align method for it and improving its overall code readability
> and features.
>
> Changes from v1:
> - Changed pci_epc_check_func() to pci_epc_function_is_valid() in patch
> 1.
> - Removed patch "PCI: endpoint: Improve pci_epc_mem_alloc_addr()"
> (former patch 2 of v1)
> - Various typos cleanups all over. Also fixed some blank space
> indentation.
> - Added review tags
>
> Damien Le Moal (17):
> PCI: endpoint: Introduce pci_epc_function_is_valid()
> PCI: endpoint: Introduce pci_epc_map_align()
> PCI: endpoint: Introduce pci_epc_mem_map()/unmap()
> PCI: endpoint: test: Use pci_epc_mem_map/unmap()
> PCI: endpoint: test: Synchronously cancel command handler work
> PCI: endpoint: test: Implement link_down event operation
> PCI: rockchip-ep: Fix address translation unit programming
> PCI: rockchip-ep: Use a macro to define EP controller .align feature
> PCI: rockchip-ep: Improve rockchip_pcie_ep_unmap_addr()
> PCI: rockchip-ep: Improve rockchip_pcie_ep_map_addr()
> PCI: rockchip-ep: Implement the map_align endpoint controller operation
> PCI: rockchip-ep: Refactor rockchip_pcie_ep_probe() memory allocations
> PCI: rockchip-ep: Refactor rockchip_pcie_ep_probe() MSI-X hiding
> PCI: rockchip-ep: Refactor endpoint link training enable
> PCI: rockship-ep: Introduce rockchip_pcie_ep_stop()
> PCI: rockchip-ep: Improve link training
> PCI: rockchip-ep: Handle PERST# signal in endpoint mode
>
> Wilfred Mallawa (1):
> dt-bindings: pci: rockchip,rk3399-pcie-ep: Add ep-gpios property
>
> .../bindings/pci/rockchip,rk3399-pcie-ep.yaml | 3 +
> drivers/pci/controller/pcie-rockchip-ep.c | 393 ++++++++++++++----
> drivers/pci/controller/pcie-rockchip.c | 17 +-
> drivers/pci/controller/pcie-rockchip.h | 22 +
> drivers/pci/endpoint/functions/pci-epf-test.c | 390 +++++++++--------
> drivers/pci/endpoint/pci-epc-core.c | 213 +++++++---
> include/linux/pci-epc.h | 39 ++
> 7 files changed, 768 insertions(+), 309 deletions(-)
>
> --
> 2.44.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
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