[PATCH 2/2] usb: dwc3: xilinx: Remove the extra freeing of clocks
The clocks are configured by devm_clk_bulk_get_all() in this driver. In case of any error the clocks freeing will be handled automatically. There is no need to explicitly free the clocks. Fix the same. Fixes: 84770f028fab ("usb: dwc3: Add driver for Xilinx platforms") Signed-off-by: Manish Narani --- drivers/usb/dwc3/dwc3-xilinx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index f42f4cb..9cc3ad7 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -271,7 +271,6 @@ static int dwc3_xlnx_probe(struct platform_device *pdev) err_clk_put: clk_bulk_disable_unprepare(priv_data->num_clocks, priv_data->clks); - clk_bulk_put_all(priv_data->num_clocks, priv_data->clks); return ret; } @@ -284,7 +283,6 @@ static int dwc3_xlnx_remove(struct platform_device *pdev) of_platform_depopulate(dev); clk_bulk_disable_unprepare(priv_data->num_clocks, priv_data->clks); - clk_bulk_put_all(priv_data->num_clocks, priv_data->clks); priv_data->num_clocks = 0; pm_runtime_disable(dev); -- 2.1.1
[PATCH 1/2] usb: dwc3: Resolve kernel-doc warning for Xilinx DWC3 driver
The kernel-doc run gave a warning for Xilinx DWC3 driver: drivers/usb/dwc3/dwc3-xilinx.c:27: warning: expecting prototype for dwc3(). Prototype was for XLNX_USB_PHY_RST_EN() instead Basically it was due to an extra '*' in line:2. This patch fixes the same. Signed-off-by: Manish Narani Reported-by: kernel test robot --- drivers/usb/dwc3/dwc3-xilinx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index a59e149..f42f4cb 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/** +/* * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver * * Authors: Manish Narani -- 2.1.1
[PATCH 0/2] Fix for a bug and a kernel-doc warning in Xilinx DWC3
This patch series resolves a kernel-doc warning and a clk freeing bug that was causing a crash. This patch series is on top of: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/usb/dwc3?id=84770f028fabab4cb66188d583ed12652f30576b Manish Narani (2): usb: dwc3: Resolve kernel-doc warning for Xilinx DWC3 driver usb: dwc3: xilinx: Remove the extra freeing of clocks drivers/usb/dwc3/dwc3-xilinx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) -- 2.1.1
RE: [PATCH v3] phy: zynqmp: Handle the clock enable/disable properly
Hi Laurent, Thank you so much for the review. > -Original Message- > From: Laurent Pinchart > Sent: Wednesday, March 24, 2021 8:38 AM > To: Manish Narani > Cc: kis...@ti.com; vk...@kernel.org; Michal Simek ; > linux-kernel@vger.kernel.org; linux-arm-ker...@lists.infradead.org; git > > Subject: Re: [PATCH v3] phy: zynqmp: Handle the clock enable/disable > properly > > Hi Manish, > > Thank you for the patch. > > On Tue, Mar 23, 2021 at 07:49:47PM +0530, Manish Narani wrote: > > The current driver is not handling the clock enable/disable operations > > properly. The clocks need to be handled correctly by enabling or > > disabling at appropriate places. This patch adds code to handle the > > same. > > > > Signed-off-by: Manish Narani > > This looks good to me. > > Reviewed-by: Laurent Pinchart > > However, it would be really nice to make clock handling dynamic, to only > enable clocks that are needed by active PHYs. Keeping them enabled at > all times will waste power. It can be done on top of this patch. Is it > something you could work on ? Sure. I'll plan to work on that. I have sent v4 for this with Michal's input. Thanks, Manish
[PATCH v4] phy: zynqmp: Handle the clock enable/disable properly
The current driver is not handling the clock enable/disable operations properly. The clocks need to be handled correctly by enabling or disabling at appropriate places. This patch adds code to handle the same. Signed-off-by: Manish Narani Reviewed-by: Laurent Pinchart --- drivers/phy/xilinx/phy-zynqmp.c | 58 - 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index 2b65f84..3565215 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -208,6 +208,7 @@ struct xpsgtr_phy { * @gtr_mutex: mutex for locking * @phys: PHY lanes * @refclk_sscs: spread spectrum settings for the reference clocks + * @clk: reference clocks * @tx_term_fix: fix for GT issue * @saved_icm_cfg0: stored value of ICM CFG0 register * @saved_icm_cfg1: stored value of ICM CFG1 register @@ -219,6 +220,7 @@ struct xpsgtr_dev { struct mutex gtr_mutex; /* mutex for locking */ struct xpsgtr_phy phys[NUM_LANES]; const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; + struct clk *clk[NUM_LANES]; bool tx_term_fix; unsigned int saved_icm_cfg0; unsigned int saved_icm_cfg1; @@ -818,11 +820,15 @@ static struct phy *xpsgtr_xlate(struct device *dev, static int __maybe_unused xpsgtr_suspend(struct device *dev) { struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); + unsigned int i; /* Save the snapshot ICM_CFG registers. */ gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) + clk_disable_unprepare(gtr_dev->clk[i]); + return 0; } @@ -832,6 +838,13 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) unsigned int icm_cfg0, icm_cfg1; unsigned int i; bool skip_phy_init; + int err; + + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) { + err = clk_prepare_enable(gtr_dev->clk[i]); + if (err) + goto err_clk_put; + } icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); @@ -852,6 +865,12 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) gtr_dev->phys[i].skip_phy_init = skip_phy_init; return 0; + +err_clk_put: + while (i--) + clk_disable_unprepare(gtr_dev->clk[i]); + + return err; } static const struct dev_pm_ops xpsgtr_pm_ops = { @@ -865,6 +884,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = { static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) { unsigned int refclk; + int ret; for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { unsigned long rate; @@ -874,14 +894,22 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) snprintf(name, sizeof(name), "ref%u", refclk); clk = devm_clk_get_optional(gtr_dev->dev, name); - if (IS_ERR(clk)) - return dev_err_probe(gtr_dev->dev, PTR_ERR(clk), -"Failed to get reference clock %u\n", -refclk); + if (IS_ERR(clk)) { + ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk), + "Failed to get reference clock %u\n", + refclk); + goto err_clk_put; + } if (!clk) continue; + ret = clk_prepare_enable(clk); + if (ret) + goto err_clk_put; + + gtr_dev->clk[refclk] = clk; + /* * Get the spread spectrum (SSC) settings for the reference * clock rate. @@ -899,11 +927,18 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) dev_err(gtr_dev->dev, "Invalid rate %lu for reference clock %u\n", rate, refclk); - return -EINVAL; + ret = -EINVAL; + goto err_clk_put; } } return 0; + +err_clk_put: + while (refclk--) + clk_disable_unprepare(gtr_dev->clk[refclk]); + + return ret; } static int xpsgtr_probe(struct platform_device *pdev) @@ -912,6 +947,7 @@ static int xpsgtr_probe(struct platform_device *pdev) struct xpsgtr_dev *gtr_dev; struct phy_provider *provider; unsigned int port; + unsigned int i; int ret; gtr_dev = devm_k
[PATCH v3] phy: zynqmp: Handle the clock enable/disable properly
The current driver is not handling the clock enable/disable operations properly. The clocks need to be handled correctly by enabling or disabling at appropriate places. This patch adds code to handle the same. Signed-off-by: Manish Narani --- drivers/phy/xilinx/phy-zynqmp.c | 57 - 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index 2b65f84..69492a5 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -219,6 +219,7 @@ struct xpsgtr_dev { struct mutex gtr_mutex; /* mutex for locking */ struct xpsgtr_phy phys[NUM_LANES]; const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; + struct clk *clk[NUM_LANES]; bool tx_term_fix; unsigned int saved_icm_cfg0; unsigned int saved_icm_cfg1; @@ -818,11 +819,15 @@ static struct phy *xpsgtr_xlate(struct device *dev, static int __maybe_unused xpsgtr_suspend(struct device *dev) { struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); + unsigned int i; /* Save the snapshot ICM_CFG registers. */ gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) + clk_disable_unprepare(gtr_dev->clk[i]); + return 0; } @@ -832,6 +837,13 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) unsigned int icm_cfg0, icm_cfg1; unsigned int i; bool skip_phy_init; + int err; + + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) { + err = clk_prepare_enable(gtr_dev->clk[i]); + if (err) + goto err_clk_put; + } icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); @@ -852,6 +864,12 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) gtr_dev->phys[i].skip_phy_init = skip_phy_init; return 0; + +err_clk_put: + while (i--) + clk_disable_unprepare(gtr_dev->clk[i]); + + return err; } static const struct dev_pm_ops xpsgtr_pm_ops = { @@ -865,6 +883,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = { static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) { unsigned int refclk; + int ret; for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { unsigned long rate; @@ -874,14 +893,22 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) snprintf(name, sizeof(name), "ref%u", refclk); clk = devm_clk_get_optional(gtr_dev->dev, name); - if (IS_ERR(clk)) - return dev_err_probe(gtr_dev->dev, PTR_ERR(clk), -"Failed to get reference clock %u\n", -refclk); + if (IS_ERR(clk)) { + ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk), + "Failed to get reference clock %u\n", + refclk); + goto err_clk_put; + } if (!clk) continue; + ret = clk_prepare_enable(clk); + if (ret) + goto err_clk_put; + + gtr_dev->clk[refclk] = clk; + /* * Get the spread spectrum (SSC) settings for the reference * clock rate. @@ -899,11 +926,18 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) dev_err(gtr_dev->dev, "Invalid rate %lu for reference clock %u\n", rate, refclk); - return -EINVAL; + ret = -EINVAL; + goto err_clk_put; } } return 0; + +err_clk_put: + while (refclk--) + clk_disable_unprepare(gtr_dev->clk[refclk]); + + return ret; } static int xpsgtr_probe(struct platform_device *pdev) @@ -912,6 +946,7 @@ static int xpsgtr_probe(struct platform_device *pdev) struct xpsgtr_dev *gtr_dev; struct phy_provider *provider; unsigned int port; + unsigned int i; int ret; gtr_dev = devm_kzalloc(>dev, sizeof(*gtr_dev), GFP_KERNEL); @@ -951,7 +986,8 @@ static int xpsgtr_probe(struct platform_device *pdev) phy = devm_phy_create(>dev, np, _phyops); if (IS_ERR(phy)) { dev_err(>dev, "failed to create PHY\n"); - return PTR_ERR(phy); + ret = PTR_ERR(
RE: [PATCH v2] phy: zynqmp: Handle the clock enable/disable properly
Gentle Ping! > -Original Message- > From: Manish Narani > Sent: Tuesday, March 9, 2021 4:48 PM > To: laurent.pinch...@ideasonboard.com; kis...@ti.com; vk...@kernel.org; > Michal Simek > Cc: linux-kernel@vger.kernel.org; linux-arm-ker...@lists.infradead.org; git > ; Manish Narani > Subject: [PATCH v2] phy: zynqmp: Handle the clock enable/disable properly > > The current driver is not handling the clock enable/disable operations > properly. The clocks need to be handled correctly by enabling or > disabling at appropriate places. This patch adds code to handle the > same. > > Signed-off-by: Manish Narani > --- > drivers/phy/xilinx/phy-zynqmp.c | 57 > - > 1 file changed, 50 insertions(+), 7 deletions(-) > > diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy- > zynqmp.c > index 2b65f84..37fcecf 100644 > --- a/drivers/phy/xilinx/phy-zynqmp.c > +++ b/drivers/phy/xilinx/phy-zynqmp.c > @@ -219,6 +219,7 @@ struct xpsgtr_dev { > struct mutex gtr_mutex; /* mutex for locking */ > struct xpsgtr_phy phys[NUM_LANES]; > const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; > + struct clk *clk[NUM_LANES]; > bool tx_term_fix; > unsigned int saved_icm_cfg0; > unsigned int saved_icm_cfg1; > @@ -818,11 +819,15 @@ static struct phy *xpsgtr_xlate(struct device *dev, > static int __maybe_unused xpsgtr_suspend(struct device *dev) > { > struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); > + unsigned int i; > > /* Save the snapshot ICM_CFG registers. */ > gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); > gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); > > + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) > + clk_disable_unprepare(gtr_dev->clk[i]); > + > return 0; > } > > @@ -832,6 +837,13 @@ static int __maybe_unused xpsgtr_resume(struct > device *dev) > unsigned int icm_cfg0, icm_cfg1; > unsigned int i; > bool skip_phy_init; > + int err; > + > + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) { > + err = clk_prepare_enable(gtr_dev->clk[i]); > + if (err) > + goto err_clk_put; > + } > > icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); > icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); > @@ -852,6 +864,12 @@ static int __maybe_unused xpsgtr_resume(struct > device *dev) > gtr_dev->phys[i].skip_phy_init = skip_phy_init; > > return 0; > + > +err_clk_put: > + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) > + clk_disable_unprepare(gtr_dev->clk[i]); > + > + return err; > } > > static const struct dev_pm_ops xpsgtr_pm_ops = { > @@ -865,6 +883,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = { > static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) > { > unsigned int refclk; > + int ret; > > for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { > unsigned long rate; > @@ -874,14 +893,22 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev > *gtr_dev) > > snprintf(name, sizeof(name), "ref%u", refclk); > clk = devm_clk_get_optional(gtr_dev->dev, name); > - if (IS_ERR(clk)) > - return dev_err_probe(gtr_dev->dev, PTR_ERR(clk), > - "Failed to get reference clock > %u\n", > - refclk); > + if (IS_ERR(clk)) { > + ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk), > + "Failed to get reference clock > %u\n", > + refclk); > + goto err_clk_put; > + } > > if (!clk) > continue; > > + gtr_dev->clk[refclk] = clk; > + > + ret = clk_prepare_enable(gtr_dev->clk[refclk]); > + if (ret) > + goto err_clk_put; > + > /* >* Get the spread spectrum (SSC) settings for the reference >* clock rate. > @@ -899,11 +926,18 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev > *gtr_dev) > dev_err(gtr_dev->dev, > "Invalid rate %lu for reference clock %u\n", > rate, refclk); > - return -EINVAL; > + ret = -EINVAL; &
[PATCH v4 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Add documentation for Versal DWC3 controller. Add required property 'reg' for the same. Also add optional properties for snps,dwc3. Signed-off-by: Manish Narani Reviewed-by: Rob Herring --- .../devicetree/bindings/usb/dwc3-xilinx.txt| 28 -- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index a668f43..04813a4 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -1,32 +1,56 @@ Xilinx SuperSpeed DWC3 USB SoC controller Required properties: -- compatible: Should contain "xlnx,zynqmp-dwc3" +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal-dwc3" +- reg: Base address and length of the register control block - clocks: A list of phandles for the clocks listed in clock-names - clock-names: Should contain the following: "bus_clk" Master/Core clock, have to be >= 125 MHz for SS operation and >= 60MHz for HS operation "ref_clk" Clock source to core during PHY power down +- resets: A list of phandles for resets listed in reset-names +- reset-names: + "usb_crst"USB core reset + "usb_hibrst" USB hibernation reset + "usb_apbrst" USB APB reset Required child node: A child node must exist to represent the core DWC3 IP block. The name of the node is not important. The content of the node is defined in dwc3.txt. +Optional properties for snps,dwc3: +- dma-coherent:Enable this flag if CCI is enabled in design. Adding this + flag configures Global SoC bus Configuration Register and + Xilinx USB 3.0 IP - USB coherency register to enable CCI. +- interrupt-names: Should contain the following: + "dwc_usb3" USB gadget mode interrupts + "otg"USB OTG mode interrupts + "hiber" USB hibernation interrupts + Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; compatible = "xlnx,zynqmp-dwc3"; + reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk", "ref_clk"; clocks = <>, <>; + resets = <_reset ZYNQMP_RESET_USB1_CORERESET>, +<_reset ZYNQMP_RESET_USB1_HIBERRESET>, +<_reset ZYNQMP_RESET_USB1_APB>; + reset-names = "usb_crst", "usb_hibrst", "usb_apbrst"; ranges; dwc3@fe20 { compatible = "snps,dwc3"; reg = <0x0 0xfe20 0x4>; - interrupts = <0x0 0x41 0x4>; + interrupt-names = "dwc_usb3", "otg", "hiber"; + interrupts = <0 65 4>, <0 69 4>, <0 75 4>; + phys = < 2 PHY_TYPE_USB3 0 2>; + phy-names = "usb3-phy"; dr_mode = "host"; + dma-coherent; }; }; -- 2.1.1
[PATCH v4 2/2] usb: dwc3: Add driver for Xilinx platforms
Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 339 ++ 4 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 2133acf..66b1454 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -149,4 +149,13 @@ config USB_DWC3_IMX8MP functionality. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 2259f88..2d499de 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index e62ecd2..71fd620 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index 000..a59e149 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST_EN0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define XLNX_USB_FPD_PIPE_CLK 0x7c +#define PIPE_CLK_DESELECT 1 +#define PIPE_CLK_SELECT0 +#define XLNX_USB_FPD_POWER_PRSNT 0x80 +#define FPD_POWER_PRSNT_OPTION BIT(0) + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device *dev; + void __iomem*regs; + int (*pltfm_init)(struct dwc3_xlnx *data); +}; + +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) +{ + u32 reg; + + /* +* Enable or disable ULPI PHY reset from USB Controller. +* This does not actually reset the phy, but just controls +* whether USB controller can or cannot reset ULPI PHY. +*/ + reg = readl(priv_data->regs + XLNX_USB_PHY_RST_EN); + + if (mask) + reg &= ~XLNX_PHY_RST_MASK; + else + reg |= XLNX_PHY_RST_MASK; + + writel(reg, priv_data->regs + XLNX_USB_PHY_RST_EN); +} + +static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) +{ + struct device *dev = priv_data->dev; + int ret; + + dwc3_xlnx_mask_phy_rst(priv_data, false); + + /* Assert and De-assert reset */ + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_ID, +PM_RESET_ACTION_ASSERT); +
[PATCH v4 0/2] Add a separate DWC3 OF driver for Xilinx platforms
This patch series documents the Xilinx Versal DWC3 controller. This also adds a new Xilinx specific driver for adding new features in the future. Changes in v2: - Addressed review comments from v1 - merged normal and runtime suspend resume functions as they are same - Improved description of some register operations to avoid confusion - Updated commit log for patch 2/2 for better clarity. Changes in v3: - Removed snps,enable-hibernation property from the devicetree binding. Changes in v4: - Error checking added for devm_phy_get - Documented resets in dt-bindings Manish Narani (2): dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller usb: dwc3: Add driver for Xilinx platforms .../devicetree/bindings/usb/dwc3-xilinx.txt| 28 +- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c | 339 + 5 files changed, 375 insertions(+), 3 deletions(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c -- 2.1.1
[PATCH v2] phy: zynqmp: Handle the clock enable/disable properly
The current driver is not handling the clock enable/disable operations properly. The clocks need to be handled correctly by enabling or disabling at appropriate places. This patch adds code to handle the same. Signed-off-by: Manish Narani --- drivers/phy/xilinx/phy-zynqmp.c | 57 - 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index 2b65f84..37fcecf 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -219,6 +219,7 @@ struct xpsgtr_dev { struct mutex gtr_mutex; /* mutex for locking */ struct xpsgtr_phy phys[NUM_LANES]; const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; + struct clk *clk[NUM_LANES]; bool tx_term_fix; unsigned int saved_icm_cfg0; unsigned int saved_icm_cfg1; @@ -818,11 +819,15 @@ static struct phy *xpsgtr_xlate(struct device *dev, static int __maybe_unused xpsgtr_suspend(struct device *dev) { struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); + unsigned int i; /* Save the snapshot ICM_CFG registers. */ gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) + clk_disable_unprepare(gtr_dev->clk[i]); + return 0; } @@ -832,6 +837,13 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) unsigned int icm_cfg0, icm_cfg1; unsigned int i; bool skip_phy_init; + int err; + + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) { + err = clk_prepare_enable(gtr_dev->clk[i]); + if (err) + goto err_clk_put; + } icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); @@ -852,6 +864,12 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) gtr_dev->phys[i].skip_phy_init = skip_phy_init; return 0; + +err_clk_put: + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) + clk_disable_unprepare(gtr_dev->clk[i]); + + return err; } static const struct dev_pm_ops xpsgtr_pm_ops = { @@ -865,6 +883,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = { static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) { unsigned int refclk; + int ret; for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { unsigned long rate; @@ -874,14 +893,22 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) snprintf(name, sizeof(name), "ref%u", refclk); clk = devm_clk_get_optional(gtr_dev->dev, name); - if (IS_ERR(clk)) - return dev_err_probe(gtr_dev->dev, PTR_ERR(clk), -"Failed to get reference clock %u\n", -refclk); + if (IS_ERR(clk)) { + ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk), + "Failed to get reference clock %u\n", + refclk); + goto err_clk_put; + } if (!clk) continue; + gtr_dev->clk[refclk] = clk; + + ret = clk_prepare_enable(gtr_dev->clk[refclk]); + if (ret) + goto err_clk_put; + /* * Get the spread spectrum (SSC) settings for the reference * clock rate. @@ -899,11 +926,18 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) dev_err(gtr_dev->dev, "Invalid rate %lu for reference clock %u\n", rate, refclk); - return -EINVAL; + ret = -EINVAL; + goto err_clk_put; } } return 0; + +err_clk_put: + for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->clk); refclk++) + clk_disable_unprepare(gtr_dev->clk[refclk]); + + return ret; } static int xpsgtr_probe(struct platform_device *pdev) @@ -912,6 +946,7 @@ static int xpsgtr_probe(struct platform_device *pdev) struct xpsgtr_dev *gtr_dev; struct phy_provider *provider; unsigned int port; + unsigned int i; int ret; gtr_dev = devm_kzalloc(>dev, sizeof(*gtr_dev), GFP_KERNEL); @@ -951,7 +986,8 @@ static int xpsgtr_probe(struct platform_device *pdev) phy = devm_phy_create(>dev, np, _phyops); if (IS_ERR(phy)) { dev_err(>
RE: [PATCH] phy: zynqmp: Handle the clock enable/disable properly
Hi Laurent, Thank you for the review. > -Original Message- > From: Laurent Pinchart > Sent: Tuesday, March 9, 2021 1:37 AM > To: Manish Narani > Cc: Anurag Kumar Vulisha ; kis...@ti.com; > vk...@kernel.org; Michal Simek ; linux- > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org > Subject: Re: [PATCH] phy: zynqmp: Handle the clock enable/disable properly > > Hi Manish, > > Thank you for the patch. > > On Tue, Mar 09, 2021 at 12:19:16AM +0530, Manish Narani wrote: > > The current driver is not handling the clock enable/disable operations > > properly. The clocks need to be handled correctly by enabling or > > disabling at appropriate places. This patch adds code to handle the > > same. > > > > Signed-off-by: Manish Narani > > --- > > drivers/phy/xilinx/phy-zynqmp.c | 40 > +--- > > 1 file changed, 37 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy- > zynqmp.c > > index 2b65f84..0ec534e 100644 > > --- a/drivers/phy/xilinx/phy-zynqmp.c > > +++ b/drivers/phy/xilinx/phy-zynqmp.c > > @@ -219,6 +219,7 @@ struct xpsgtr_dev { > > struct mutex gtr_mutex; /* mutex for locking */ > > struct xpsgtr_phy phys[NUM_LANES]; > > const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; > > + struct clk *clk[NUM_LANES]; > > bool tx_term_fix; > > unsigned int saved_icm_cfg0; > > unsigned int saved_icm_cfg1; > > @@ -818,11 +819,15 @@ static struct phy *xpsgtr_xlate(struct device *dev, > > static int __maybe_unused xpsgtr_suspend(struct device *dev) > > { > > struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); > > + int i; > > i is never negative, so you can make it an unsigned int. OK. Will update in v2. > > > > > /* Save the snapshot ICM_CFG registers. */ > > gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); > > gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); > > > > + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) > > + clk_disable(gtr_dev->clk[i]); > > Why is this only clk_disable(), and not clk_disable_unprepare() ? Same > question for xpsgtr_resume(). It can be clk_disable_unprepare() and clk_prepare_enable in suspend() and resume() respectively, will update in v2. > > > + > > return 0; > > } > > > > @@ -832,6 +837,13 @@ static int __maybe_unused xpsgtr_resume(struct > device *dev) > > unsigned int icm_cfg0, icm_cfg1; > > unsigned int i; > > bool skip_phy_init; > > + int err; > > + > > + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) { > > + err = clk_enable(gtr_dev->clk[i]); > > + if (err) > > + return err; > > In case of error we need to disable the clocks that have been > successfully enabled already. Thanks for bringing this. Will be updated in v2. > > > + } > > > > icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); > > icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); > > @@ -865,6 +877,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = { > > static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) > > { > > unsigned int refclk; > > + int ret; > > > > for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { > > unsigned long rate; > > @@ -882,6 +895,12 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev > *gtr_dev) > > There's an error check above that needs to jump to err_clk_put too. > > > if (!clk) > > continue; > > > > + gtr_dev->clk[refclk] = clk; > > + > > + ret = clk_prepare_enable(gtr_dev->clk[refclk]); > > + if (ret) > > + return ret; > > It would be nice to move the driver to runtime PM to keep the clocks > disabled when the PHY isn't in use. It can be done in a separate patch. Sure thanks. I will plan for that as well. Thanks, Manish > > > + > > /* > > * Get the spread spectrum (SSC) settings for the reference > > * clock rate. > > @@ -899,11 +918,17 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev > *gtr_dev) > > dev_err(gtr_dev->dev, > > "Invalid rate %lu for reference clock %u\n", > > rate, refclk); > > - return -EINVAL; > > + goto err_clk
[PATCH] phy: zynqmp: Handle the clock enable/disable properly
The current driver is not handling the clock enable/disable operations properly. The clocks need to be handled correctly by enabling or disabling at appropriate places. This patch adds code to handle the same. Signed-off-by: Manish Narani --- drivers/phy/xilinx/phy-zynqmp.c | 40 +--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index 2b65f84..0ec534e 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -219,6 +219,7 @@ struct xpsgtr_dev { struct mutex gtr_mutex; /* mutex for locking */ struct xpsgtr_phy phys[NUM_LANES]; const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; + struct clk *clk[NUM_LANES]; bool tx_term_fix; unsigned int saved_icm_cfg0; unsigned int saved_icm_cfg1; @@ -818,11 +819,15 @@ static struct phy *xpsgtr_xlate(struct device *dev, static int __maybe_unused xpsgtr_suspend(struct device *dev) { struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); + int i; /* Save the snapshot ICM_CFG registers. */ gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) + clk_disable(gtr_dev->clk[i]); + return 0; } @@ -832,6 +837,13 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) unsigned int icm_cfg0, icm_cfg1; unsigned int i; bool skip_phy_init; + int err; + + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) { + err = clk_enable(gtr_dev->clk[i]); + if (err) + return err; + } icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); @@ -865,6 +877,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = { static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) { unsigned int refclk; + int ret; for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { unsigned long rate; @@ -882,6 +895,12 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) if (!clk) continue; + gtr_dev->clk[refclk] = clk; + + ret = clk_prepare_enable(gtr_dev->clk[refclk]); + if (ret) + return ret; + /* * Get the spread spectrum (SSC) settings for the reference * clock rate. @@ -899,11 +918,17 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) dev_err(gtr_dev->dev, "Invalid rate %lu for reference clock %u\n", rate, refclk); - return -EINVAL; + goto err_clk_put; } } return 0; + +err_clk_put: + for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->clk); refclk++) + clk_disable_unprepare(gtr_dev->clk[refclk]); + + return -EINVAL; } static int xpsgtr_probe(struct platform_device *pdev) @@ -913,6 +938,7 @@ static int xpsgtr_probe(struct platform_device *pdev) struct phy_provider *provider; unsigned int port; int ret; + int i; gtr_dev = devm_kzalloc(>dev, sizeof(*gtr_dev), GFP_KERNEL); if (!gtr_dev) @@ -951,7 +977,8 @@ static int xpsgtr_probe(struct platform_device *pdev) phy = devm_phy_create(>dev, np, _phyops); if (IS_ERR(phy)) { dev_err(>dev, "failed to create PHY\n"); - return PTR_ERR(phy); + ret = PTR_ERR(phy); + goto err_clk_put; } gtr_phy->phy = phy; @@ -962,9 +989,16 @@ static int xpsgtr_probe(struct platform_device *pdev) provider = devm_of_phy_provider_register(>dev, xpsgtr_xlate); if (IS_ERR(provider)) { dev_err(>dev, "registering provider failed\n"); - return PTR_ERR(provider); + ret = PTR_ERR(provider); + goto err_clk_put; } return 0; + +err_clk_put: + for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) + clk_disable_unprepare(gtr_dev->clk[i]); + + return ret; } static const struct of_device_id xpsgtr_of_match[] = { -- 2.1.1
RE: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
HI Michael, > -Original Message- > From: Michael Grzeschik > Sent: Monday, February 22, 2021 9:01 PM > To: Manish Narani > Cc: gre...@linuxfoundation.org; robh...@kernel.org; Michal Simek > ; ba...@kernel.org; p.za...@pengutronix.de; > devicet...@vger.kernel.org; linux-...@vger.kernel.org; linux- > ker...@vger.kernel.org; git ; linux-arm- > ker...@lists.infradead.org > Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx > platforms > > Hi Manish! > > On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: > >Add a new driver for supporting Xilinx platforms. This driver is used > >for some sequence of operations required for Xilinx USB controllers. > >This driver is also used to choose between PIPE clock coming from SerDes > >and the Suspend Clock. Before the controller is out of reset, the clock > >selection should be changed to PIPE clock in order to make the USB > >controller work. There is a register added in Xilinx USB controller > >register space for the same. > > > >Signed-off-by: Manish Narani > >--- > > drivers/usb/dwc3/Kconfig | 9 + > > drivers/usb/dwc3/Makefile | 1 + > > drivers/usb/dwc3/dwc3-of-simple.c | 1 - > > drivers/usb/dwc3/dwc3-xilinx.c| 334 > ++ > > 4 files changed, 344 insertions(+), 1 deletion(-) > > create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c > > > >diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig > >index 7a2304565a73..0e00e6dfccd8 100644 > >--- a/drivers/usb/dwc3/Kconfig > >+++ b/drivers/usb/dwc3/Kconfig > >@@ -139,4 +139,13 @@ config USB_DWC3_QCOM > > for peripheral mode support. > > Say 'Y' or 'M' if you have one such device. > > > >+config USB_DWC3_XILINX > >+tristate "Xilinx Platforms" > >+depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF > >+default USB_DWC3 > >+help > >+ Support Xilinx SoCs with DesignWare Core USB3 IP. > >+ This driver handles both ZynqMP and Versal SoC operations. > >+ Say 'Y' or 'M' if you have one such device. > >+ > > endif > >diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile > >index ae86da0dc5bd..add567578b1f 100644 > >--- a/drivers/usb/dwc3/Makefile > >+++ b/drivers/usb/dwc3/Makefile > >@@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += > dwc3-meson-g12a.o > > obj-$(CONFIG_USB_DWC3_OF_SIMPLE)+= dwc3-of-simple.o > > obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o > > obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o > >+obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o > >diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3- > of-simple.c > >index e62ecd22b3ed..71fd620c5161 100644 > >--- a/drivers/usb/dwc3/dwc3-of-simple.c > >+++ b/drivers/usb/dwc3/dwc3-of-simple.c > >@@ -172,7 +172,6 @@ static const struct dev_pm_ops > dwc3_of_simple_dev_pm_ops = { > > > > static const struct of_device_id of_dwc3_simple_match[] = { > > { .compatible = "rockchip,rk3399-dwc3" }, > >-{ .compatible = "xlnx,zynqmp-dwc3" }, > > { .compatible = "cavium,octeon-7130-usb-uctl" }, > > { .compatible = "sprd,sc9860-dwc3" }, > > { .compatible = "allwinner,sun50i-h6-dwc3" }, > >diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3- > xilinx.c > >new file mode 100644 > >index ..7e485951d2f7 > >--- /dev/null > >+++ b/drivers/usb/dwc3/dwc3-xilinx.c > >@@ -0,0 +1,334 @@ > >+// SPDX-License-Identifier: GPL-2.0 > >+/** > >+ * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver > >+ * > >+ * Authors: Manish Narani > >+ * Anurag Kumar Vulisha > >+ */ > >+ > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+#include > >+ > >+#include > >+ > >+/* USB phy reset mask register */ > >+#define XLNX_USB_PHY_RST_EN 0x001C > >+#define XLNX_PHY_RST_MASK 0x1 > >+ > >+/* Xilinx USB 3.0 IP Register */ > >+#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C > >+#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 > >+ > >+/* Versal USB Reset ID */ > >+#define VERSAL_USB_RESET_ID 0xC104036 > >+ > >+#define XLNX_USB_FPD_PIPE
RE: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Michael, > -Original Message- > From: Michael Grzeschik > Sent: Tuesday, February 9, 2021 5:26 AM > To: Manish Narani > Cc: devicet...@vger.kernel.org; p.za...@pengutronix.de; ba...@kernel.org; > gre...@linuxfoundation.org; linux-...@vger.kernel.org; linux- > ker...@vger.kernel.org; robh...@kernel.org; Michal Simek > ; git ; ker...@pengutronix.de; linux- > arm-ker...@lists.infradead.org > Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx > platforms > > Hi Manish! > > On Thu, Jan 28, 2021 at 12:36:07AM +0100, Michael Grzeschik wrote: > >On Fri, Jan 22, 2021 at 02:34:52PM +0100, Michael Grzeschik wrote: > >>On Fri, Jan 22, 2021 at 01:06:22PM +, Manish Narani wrote: > >>>Hi Michael, > >>> > >>>>-Original Message- > >>>>From: Michael Grzeschik > >>>>Sent: Friday, January 22, 2021 1:39 PM > >>>>To: Manish Narani > >>>>Cc: devicet...@vger.kernel.org; ker...@pengutronix.de; > ba...@kernel.org; > >>>>gre...@linuxfoundation.org; linux-...@vger.kernel.org; Michal Simek > >>>>; linux-kernel@vger.kernel.org; > robh...@kernel.org; > >>>>git ; p.za...@pengutronix.de; linux-arm- > >>>>ker...@lists.infradead.org > >>>>Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx > >>>>platforms > >>>> > >>>>Hello! > >>>> > >>>>On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: > >>>>>Hi! > >>>>> > >>>>>On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: > >>>>>>Add a new driver for supporting Xilinx platforms. This driver is used > >>>>>>for some sequence of operations required for Xilinx USB controllers. > >>>>>>This driver is also used to choose between PIPE clock coming from > SerDes > >>>>>>and the Suspend Clock. Before the controller is out of reset, the clock > >>>>>>selection should be changed to PIPE clock in order to make the USB > >>>>>>controller work. There is a register added in Xilinx USB controller > >>>>>>register space for the same. > >>>>> > >>>>>I tried out this driver with the vanilla kernel on an zynqmp. Without > >>>>>this patch the USB-Gadget is already acting buggy. In the gadget mode, > >>>>>some iterations of plug/unplug results to an stalled gadget which will > >>>>>never come back without a reboot. > >>>>> > >>>>>With the corresponding code of this driver (reset assert, clk modify, > >>>>>reset deassert) in the downstream kernels phy driver we found out it is > >>>>>totaly stable. But using this exact glue driver which should do the same > >>>>>as the downstream code, the gadget still was buggy the way described > >>>>>above. > >>>>> > >>>>>I suspect the difference lays in the different order of operations. > >>>>>While the downstream code is runing the resets inside the phy driver > >>>>>which is powered and initialized in the dwc3-core itself. With this glue > >>>>>layser approach of this patch the whole phy init is done before even > >>>>>touching dwc3-core in any way. It seems not to have the same effect, > >>>>>though. > >>>>> > >>>>>If really the order of operations is limiting us, we probably need > >>>>>another solution than this glue layer. Any Ideas? > >>>> > >>>>I found out what the difference between the Downstream and this > >>>>Glue is. When using vanilla with this Glue code we may not set > >>>>the following bit: > >>>> > >>>>https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq- > >>>>ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html > >>>> > >>>>>>+ /* Set PIPE Power Present signal in FPD Power Present > Register*/ > >>>>>>+ writel(PIPE_POWER_ON, priv_data->regs + > >>>>XLNX_USB_FPD_POWER_PRSNT); > >>>> > >>>>When I comment this out, the link stays stable. This is different in > >>>>the Downstream Xilinx Kernel, where the bit is also set but has no > >>>>negativ effect. > >>>> > >>>>Manish, can you give me a po
RE: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Michael, > -Original Message- > From: Michael Grzeschik > Sent: Friday, January 22, 2021 1:39 PM > To: Manish Narani > Cc: devicet...@vger.kernel.org; ker...@pengutronix.de; ba...@kernel.org; > gre...@linuxfoundation.org; linux-...@vger.kernel.org; Michal Simek > ; linux-kernel@vger.kernel.org; robh...@kernel.org; > git ; p.za...@pengutronix.de; linux-arm- > ker...@lists.infradead.org > Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx > platforms > > Hello! > > On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: > >Hi! > > > >On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: > >>Add a new driver for supporting Xilinx platforms. This driver is used > >>for some sequence of operations required for Xilinx USB controllers. > >>This driver is also used to choose between PIPE clock coming from SerDes > >>and the Suspend Clock. Before the controller is out of reset, the clock > >>selection should be changed to PIPE clock in order to make the USB > >>controller work. There is a register added in Xilinx USB controller > >>register space for the same. > > > >I tried out this driver with the vanilla kernel on an zynqmp. Without > >this patch the USB-Gadget is already acting buggy. In the gadget mode, > >some iterations of plug/unplug results to an stalled gadget which will > >never come back without a reboot. > > > >With the corresponding code of this driver (reset assert, clk modify, > >reset deassert) in the downstream kernels phy driver we found out it is > >totaly stable. But using this exact glue driver which should do the same > >as the downstream code, the gadget still was buggy the way described > >above. > > > >I suspect the difference lays in the different order of operations. > >While the downstream code is runing the resets inside the phy driver > >which is powered and initialized in the dwc3-core itself. With this glue > >layser approach of this patch the whole phy init is done before even > >touching dwc3-core in any way. It seems not to have the same effect, > >though. > > > >If really the order of operations is limiting us, we probably need > >another solution than this glue layer. Any Ideas? > > I found out what the difference between the Downstream and this > Glue is. When using vanilla with this Glue code we may not set > the following bit: > > https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq- > ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html > > >>+ /* Set PIPE Power Present signal in FPD Power Present Register*/ > >>+ writel(PIPE_POWER_ON, priv_data->regs + > XLNX_USB_FPD_POWER_PRSNT); > > When I comment this out, the link stays stable. This is different in > the Downstream Xilinx Kernel, where the bit is also set but has no > negativ effect. > > Manish, can you give me a pointer what to look for? > So setting this will also work with mainline? I am looking further on this but from what I see here is that, In order to make USB function properly, there are some dt changes needed in mainline for USB node which include defining clocks coming from serdes. The DT changes are pending to be sent to mainline. Can you share the DT settings for USB node on your side? Meanwhile I will keep updating on the same. Thanks, Manish > > Regards, > Michael > > >> > >>Signed-off-by: Manish Narani > >>--- > >>drivers/usb/dwc3/Kconfig | 9 + > >>drivers/usb/dwc3/Makefile | 1 + > >>drivers/usb/dwc3/dwc3-of-simple.c | 1 - > >>drivers/usb/dwc3/dwc3-xilinx.c| 334 > ++ > >>4 files changed, 344 insertions(+), 1 deletion(-) > >>create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c > >> > >>diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig > >>index 7a2304565a73..0e00e6dfccd8 100644 > >>--- a/drivers/usb/dwc3/Kconfig > >>+++ b/drivers/usb/dwc3/Kconfig > >>@@ -139,4 +139,13 @@ config USB_DWC3_QCOM > >> for peripheral mode support. > >> Say 'Y' or 'M' if you have one such device. > >> > >>+config USB_DWC3_XILINX > >>+ tristate "Xilinx Platforms" > >>+ depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF > >>+ default USB_DWC3 > >>+ help > >>+ Support Xilinx SoCs with DesignWare Core USB3 IP. > >>+ This driver handles both ZynqMP and Versal SoC operations. > >>+ Say 'Y' or 'M' if you have one such device. > >>+ > >>endif > >>diff --git a/
[RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 7a2304565a73..0e00e6dfccd8 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -139,4 +139,13 @@ config USB_DWC3_QCOM for peripheral mode support. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index ae86da0dc5bd..add567578b1f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index e62ecd22b3ed..71fd620c5161 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index ..7e485951d2f7 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST_EN0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define XLNX_USB_FPD_PIPE_CLK 0x7c +#define PIPE_CLK_DESELECT 1 +#define PIPE_CLK_SELECT0 +#define XLNX_USB_FPD_POWER_PRSNT 0x80 +#define PIPE_POWER_ON 1 +#define PIPE_POWER_OFF 0 + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device *dev; + void __iomem*regs; + int (*pltfm_init)(struct dwc3_xlnx *data); +}; + +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) +{ + u32 reg; + + /* +* Enable or disable ULPI PHY reset from USB Controller. +* This does not actually reset the phy, but just controls +* whether USB controller can or cannot reset ULPI PHY. +*/ + reg = readl(priv_data->regs + XLNX_USB_PHY_RST_EN); + + if (mask) + reg &= ~XLNX_PHY_RST_MASK; + else + reg |= XLNX_PHY_RST_MASK; + + writel(reg, priv_data->regs + XLNX_USB_PHY_RST_EN); +} + +static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) +{ + struct device *dev = priv_data->dev; + int ret; + + dwc3_xlnx_mask_phy_rst(priv_data, false); + + /* Assert and De-assert reset */ + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_
[RESEND PATCH v3 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Add documentation for Versal DWC3 controller. Add required property 'reg' for the same. Also add optional properties for snps,dwc3. Signed-off-by: Manish Narani Reviewed-by: Rob Herring --- .../devicetree/bindings/usb/dwc3-xilinx.txt | 17 +++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index 4aae5b2cef56..0629f48cc807 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -1,7 +1,8 @@ Xilinx SuperSpeed DWC3 USB SoC controller Required properties: -- compatible: Should contain "xlnx,zynqmp-dwc3" +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal-dwc3" +- reg: Base address and length of the register control block - clocks: A list of phandles for the clocks listed in clock-names - clock-names: Should contain the following: "bus_clk" Master/Core clock, have to be >= 125 MHz for SS @@ -13,12 +14,22 @@ Required child node: A child node must exist to represent the core DWC3 IP block. The name of the node is not important. The content of the node is defined in dwc3.txt. +Optional properties for snps,dwc3: +- dma-coherent:Enable this flag if CCI is enabled in design. Adding this + flag configures Global SoC bus Configuration Register and + Xilinx USB 3.0 IP - USB coherency register to enable CCI. +- interrupt-names: Should contain the following: + "dwc_usb3" USB gadget mode interrupts + "otg"USB OTG mode interrupts + "hiber" USB hibernation interrupts + Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; compatible = "xlnx,zynqmp-dwc3"; + reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk" "ref_clk"; clocks = <>, <>; ranges; @@ -26,7 +37,9 @@ Example device node: dwc3@fe20 { compatible = "snps,dwc3"; reg = <0x0 0xfe20 0x4>; - interrupts = <0x0 0x41 0x4>; + interrupt-names = "dwc_usb3", "otg", "hiber"; + interrupts = <0 65 4>, <0 69 4>, <0 75 4>; dr_mode = "host"; + dma-coherent; }; }; -- 2.17.1
[RESEND PATCH v3 0/2] Add a separate DWC3 OF driver for Xilinx platforms
This patch series documents the Xilinx Versal DWC3 controller. This also adds a new Xilinx specific driver for adding new features in the future. Changes in v2: - Addressed review comments from v1 - merged normal and runtime suspend resume functions as they are same - Improved description of some register operations to avoid confusion - Updated commit log for patch 2/2 for better clarity. Changes in v3: - Removed snps,enable-hibernation property from the devicetree binding. Manish Narani (2): dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller usb: dwc3: Add driver for Xilinx platforms .../devicetree/bindings/usb/dwc3-xilinx.txt | 17 +- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 5 files changed, 359 insertions(+), 3 deletions(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c -- 2.17.1
RE: [PATCH] mmc: sdhci-of-arasan: Add pinctrl support to the driver
Hi Uffe/Michal, > -Original Message- > From: Michal Simek > Sent: Wednesday, November 18, 2020 11:54 PM > To: Ulf Hansson ; Manish Narani > > Cc: Michal Simek ; Adrian Hunter > ; Linux ARM ker...@lists.infradead.org>; linux-...@vger.kernel.org; Linux Kernel > Mailing List ; git > Subject: Re: [PATCH] mmc: sdhci-of-arasan: Add pinctrl support to the driver > > > > On 18. 11. 20 16:43, Ulf Hansson wrote: > > On Wed, 18 Nov 2020 at 07:22, Manish Narani > wrote: > >> > >> Driver should be able to handle optional pinctrl setting. > >> > >> Signed-off-by: Michal Simek > >> Signed-off-by: Manish Narani > >> --- > >> drivers/mmc/host/sdhci-of-arasan.c | 24 > >> 1 file changed, 24 insertions(+) > >> > >> diff --git a/drivers/mmc/host/sdhci-of-arasan.c > b/drivers/mmc/host/sdhci-of-arasan.c > >> index 829ccef87426..f788cc9d5914 100644 > >> --- a/drivers/mmc/host/sdhci-of-arasan.c > >> +++ b/drivers/mmc/host/sdhci-of-arasan.c > >> @@ -23,6 +23,7 @@ > >> #include > >> #include > >> #include > >> +#include > >> > >> #include "cqhci.h" > >> #include "sdhci-pltfm.h" > >> @@ -135,6 +136,8 @@ struct sdhci_arasan_clk_data { > >> * @clk_ops: Struct for the Arasan Controller Clock Operations. > >> * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers. > >> * @soc_ctl_map: Map to get offsets into soc_ctl registers. > >> + * @pinctrl: Per-device pin control state holder. > >> + * @pins_default: Pinctrl state for a device. > >> * @quirks:Arasan deviations from spec. > >> */ > >> struct sdhci_arasan_data { > >> @@ -149,6 +152,8 @@ struct sdhci_arasan_data { > >> > >> struct regmap *soc_ctl_base; > >> const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; > >> + struct pinctrl *pinctrl; > >> + struct pinctrl_state *pins_default; > >> unsigned intquirks; > >> > >> /* Controller does not have CD wired and will not function normally > without */ > >> @@ -1619,6 +1624,25 @@ static int sdhci_arasan_probe(struct > platform_device *pdev) > >> goto unreg_clk; > >> } > >> > >> + sdhci_arasan->pinctrl = devm_pinctrl_get(>dev); > >> + if (!IS_ERR(sdhci_arasan->pinctrl)) { > >> + sdhci_arasan->pins_default = > >> + pinctrl_lookup_state(sdhci_arasan->pinctrl, > >> +PINCTRL_STATE_DEFAULT); > >> + if (IS_ERR(sdhci_arasan->pins_default)) { > >> + dev_err(>dev, "Missing default pinctrl > >> config\n"); > >> + ret = PTR_ERR(sdhci_arasan->pins_default); > >> + goto unreg_clk; > >> + } > >> + > >> + ret = pinctrl_select_state(sdhci_arasan->pinctrl, > >> + sdhci_arasan->pins_default); > >> + if (ret) { > >> + dev_err(>dev, "could not select default > >> state\n"); > >> + goto unreg_clk; > >> + } > >> + } > > > > Isn't all this already taken care of via pinctrl_bind_pins() called by > > driver core during probe? > > > > Thanks for the hint. > Manish: Can you please check it? Thanks Uffe. Yes, this is already taken care of via pinctrl_bind_pins() called during probe. This patch is not required to be merged. Thanks, Manish
[PATCH] mmc: sdhci-of-arasan: Add pinctrl support to the driver
Driver should be able to handle optional pinctrl setting. Signed-off-by: Michal Simek Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 829ccef87426..f788cc9d5914 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "cqhci.h" #include "sdhci-pltfm.h" @@ -135,6 +136,8 @@ struct sdhci_arasan_clk_data { * @clk_ops: Struct for the Arasan Controller Clock Operations. * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers. * @soc_ctl_map: Map to get offsets into soc_ctl registers. + * @pinctrl: Per-device pin control state holder. + * @pins_default: Pinctrl state for a device. * @quirks:Arasan deviations from spec. */ struct sdhci_arasan_data { @@ -149,6 +152,8 @@ struct sdhci_arasan_data { struct regmap *soc_ctl_base; const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; unsigned intquirks; /* Controller does not have CD wired and will not function normally without */ @@ -1619,6 +1624,25 @@ static int sdhci_arasan_probe(struct platform_device *pdev) goto unreg_clk; } + sdhci_arasan->pinctrl = devm_pinctrl_get(>dev); + if (!IS_ERR(sdhci_arasan->pinctrl)) { + sdhci_arasan->pins_default = + pinctrl_lookup_state(sdhci_arasan->pinctrl, +PINCTRL_STATE_DEFAULT); + if (IS_ERR(sdhci_arasan->pins_default)) { + dev_err(>dev, "Missing default pinctrl config\n"); + ret = PTR_ERR(sdhci_arasan->pins_default); + goto unreg_clk; + } + + ret = pinctrl_select_state(sdhci_arasan->pinctrl, + sdhci_arasan->pins_default); + if (ret) { + dev_err(>dev, "could not select default state\n"); + goto unreg_clk; + } + } + sdhci_arasan->phy = ERR_PTR(-ENODEV); if (of_device_is_compatible(pdev->dev.of_node, "arasan,sdhci-5.1")) { -- 2.17.1
[PATCH] usb: gadget: u_ether: Fix MTU size mismatch with RX packet size
Fix the MTU size issue with RX packet size as the host sends the packet with extra bytes containing ethernet header. This causes failure when user sets the MTU size to the maximum i.e. 15412. In this case the ethernet packet received will be of length 15412 plus the ethernet header length. This patch fixes the issue where there is a check that RX packet length must not be more than max packet length. Fixes: bba787a860fa ("usb: gadget: ether: Allow jumbo frames") Signed-off-by: Manish Narani --- drivers/usb/gadget/function/u_ether.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 31ea76adcc0d..c019f2b0c0af 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -45,9 +45,10 @@ #define UETH__VERSION "29-May-2008" /* Experiments show that both Linux and Windows hosts allow up to 16k - * frame sizes. Set the max size to 15k+52 to prevent allocating 32k + * frame sizes. Set the max MTU size to 15k+52 to prevent allocating 32k * blocks and still have efficient handling. */ -#define GETHER_MAX_ETH_FRAME_LEN 15412 +#define GETHER_MAX_MTU_SIZE 15412 +#define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN) struct eth_dev { /* lock is held while accessing port_usb @@ -786,7 +787,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, /* MTU range: 14 - 15412 */ net->min_mtu = ETH_HLEN; - net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; + net->max_mtu = GETHER_MAX_MTU_SIZE; dev->gadget = g; SET_NETDEV_DEV(net, >dev); @@ -848,7 +849,7 @@ struct net_device *gether_setup_name_default(const char *netname) /* MTU range: 14 - 15412 */ net->min_mtu = ETH_HLEN; - net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; + net->max_mtu = GETHER_MAX_MTU_SIZE; return net; } -- 2.17.1
[PATCH] firmware: xilinx: Fix SD DLL node reset issue
Fix the SD DLL node reset issue where incorrect node is being referenced instead of SD DLL node. Fixes: 426c8d85df7a ("firmware: xilinx: Use APIs instead of IOCTLs") Signed-off-by: Manish Narani --- drivers/firmware/xilinx/zynqmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 8d1ff2454e2e..7696bd24f182 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -612,7 +612,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay); */ int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) { - return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SET_SD_TAPDELAY, + return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SD_DLL_RESET, type, 0, NULL); } EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset); -- 2.17.1
RE: [PATCH] mmc: sdhci-of-arasan: Allow configuring zero tap values
Hi, > -Original Message- > From: Manish Narani > Sent: Tuesday, November 10, 2020 11:12 PM > To: Michal Simek ; adrian.hun...@intel.com; > ulf.hans...@linaro.org > Cc: linux-arm-ker...@lists.infradead.org; linux-...@vger.kernel.org; linux- > ker...@vger.kernel.org; git ; Manish Narani > ; Sai Krishna Potthuri > Subject: [PATCH] mmc: sdhci-of-arasan: Allow configuring zero tap values > > Allow configuring the Output and Input tap values with zero to avoid > failures in some cases (one of them is SD boot mode) where the output > and input tap values may be already set to non-zero. > > Signed-off-by: Sai Krishna Potthuri > Signed-off-by: Manish Narani > --- > drivers/mmc/host/sdhci-of-arasan.c | 40 ++ > 1 file changed, 8 insertions(+), 32 deletions(-) > This patch, with "Fixes" tag added in commit, is included along with the v2 patch series for couple of bug fixes in https://lkml.org/lkml/2020/11/16/142 . Please review this patch series. Thanks, Manish
[PATCH v2 2/3] mmc: sdhci-of-arasan: Use Mask writes for Tap delays
Mask the ITAP and OTAP delay bits before updating with the new tap value for Versal platform. Fixes: 1a470721c8f5 ("sdhci: arasan: Add support for Versal Tap Delays") Signed-off-by: Sai Krishna Potthuri Signed-off-by: Manish Narani Acked-by: Michal Simek --- drivers/mmc/host/sdhci-of-arasan.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 100621e55427..3ec5ecad637c 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -30,7 +30,10 @@ #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 #define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 +#define SDHCI_ARASAN_ITAPDLY_SEL_MASK 0xFF + #define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC +#define SDHCI_ARASAN_OTAPDLY_SEL_MASK 0x3F #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 #define VENDOR_ENHANCED_STROBE BIT(0) @@ -755,6 +758,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees) regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); regval |= SDHCI_OTAPDLY_ENABLE; sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); + regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK; regval |= tap_delay; sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); } @@ -822,6 +826,7 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); regval |= SDHCI_ITAPDLY_ENABLE; sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); + regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK; regval |= tap_delay; sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); regval &= ~SDHCI_ITAPDLY_CHGWIN; -- 2.17.1
[PATCH v2 1/3] mmc: sdhci-of-arasan: Allow configuring zero tap values
Allow configuring the Output and Input tap values with zero to avoid failures in some cases (one of them is SD boot mode) where the output and input tap values may be already set to non-zero. Fixes: a5c8b2ae2e51 ("mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup") Signed-off-by: Sai Krishna Potthuri Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 40 ++ 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 829ccef87426..100621e55427 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -600,14 +600,8 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) u8 tap_delay, tap_max = 0; int ret; - /* -* This is applicable for SDHCI_SPEC_300 and above -* ZynqMP does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { @@ -668,14 +662,8 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees) u8 tap_delay, tap_max = 0; int ret; - /* -* This is applicable for SDHCI_SPEC_300 and above -* ZynqMP does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { @@ -733,14 +721,8 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees) struct sdhci_host *host = sdhci_arasan->host; u8 tap_delay, tap_max = 0; - /* -* This is applicable for SDHCI_SPEC_300 and above -* Versal does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { @@ -804,14 +786,8 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) struct sdhci_host *host = sdhci_arasan->host; u8 tap_delay, tap_max = 0; - /* -* This is applicable for SDHCI_SPEC_300 and above -* Versal does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { -- 2.17.1
[PATCH v2 3/3] mmc: sdhci-of-arasan: Issue DLL reset explicitly
In the current implementation DLL reset will be issued for each ITAP and OTAP setting inside ATF, this is creating issues in some scenarios and this sequence is not inline with the TRM. To fix the issue, DLL reset should be removed from the ATF and host driver will request it explicitly. This patch update host driver to explicitly request for DLL reset before ITAP (assert DLL) and after OTAP (release DLL) settings. Fixes: a5c8b2ae2e51 ("mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup") Signed-off-by: Sai Krishna Potthuri Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 3ec5ecad637c..d25a4b50c2f3 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -635,6 +635,9 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) if (ret) pr_err("Error setting Output Tap Delay\n"); + /* Release DLL Reset */ + zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_RELEASE); + return ret; } @@ -669,6 +672,9 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees) if (host->version < SDHCI_SPEC_300) return 0; + /* Assert DLL Reset */ + zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_ASSERT); + switch (host->timing) { case MMC_TIMING_MMC_HS: case MMC_TIMING_SD_HS: -- 2.17.1
[PATCH v2 0/3] Bug Fixes to Tap Delay code in SDHCI Arasan driver
This patch set consists a couple of minor bug fixes for SDHCI Arasan driver. The fixes are for tap delay programming where in some cases tuning is failing for some of the SD cards. Changes in v2: - Fixed the eemi_ops call issue by replacing to an API call directly - Merged https://lore.kernel.org/patchwork/patch/1336342/ with this series of patches Manish Narani (3): mmc: sdhci-of-arasan: Allow configuring zero tap values mmc: sdhci-of-arasan: Use Mask writes for Tap delays mmc: sdhci-of-arasan: Issue DLL reset explicitly drivers/mmc/host/sdhci-of-arasan.c | 51 +++--- 1 file changed, 19 insertions(+), 32 deletions(-) -- 2.17.1
RE: [PATCH] mmc: sdhci-of-arasan: Allow configuring zero tap values
Hi, > -Original Message- > From: Manish Narani > Sent: Tuesday, November 10, 2020 11:12 PM > To: Michal Simek ; adrian.hun...@intel.com; > ulf.hans...@linaro.org > Cc: linux-arm-ker...@lists.infradead.org; linux-...@vger.kernel.org; linux- > ker...@vger.kernel.org; git ; Manish Narani > ; Sai Krishna Potthuri > Subject: [PATCH] mmc: sdhci-of-arasan: Allow configuring zero tap values > > Allow configuring the Output and Input tap values with zero to avoid > failures in some cases (one of them is SD boot mode) where the output > and input tap values may be already set to non-zero. > Fixes: a5c8b2ae2e51 ("mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup") > Signed-off-by: Sai Krishna Potthuri > Signed-off-by: Manish Narani > --- > drivers/mmc/host/sdhci-of-arasan.c | 40 ++ > 1 file changed, 8 insertions(+), 32 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci- > of-arasan.c > index 829ccef87426..100621e55427 100644 > --- a/drivers/mmc/host/sdhci-of-arasan.c > +++ b/drivers/mmc/host/sdhci-of-arasan.c > @@ -600,14 +600,8 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct > clk_hw *hw, int degrees) > u8 tap_delay, tap_max = 0; > int ret; > > - /* > - * This is applicable for SDHCI_SPEC_300 and above > - * ZynqMP does not set phase for <=25MHz clock. > - * If degrees is zero, no need to do anything. > - */ > - if (host->version < SDHCI_SPEC_300 || > - host->timing == MMC_TIMING_LEGACY || > - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) > + /* This is applicable for SDHCI_SPEC_300 and above */ > + if (host->version < SDHCI_SPEC_300) > return 0; > > switch (host->timing) { > @@ -668,14 +662,8 @@ static int > sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees) > u8 tap_delay, tap_max = 0; > int ret; > > - /* > - * This is applicable for SDHCI_SPEC_300 and above > - * ZynqMP does not set phase for <=25MHz clock. > - * If degrees is zero, no need to do anything. > - */ > - if (host->version < SDHCI_SPEC_300 || > - host->timing == MMC_TIMING_LEGACY || > - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) > + /* This is applicable for SDHCI_SPEC_300 and above */ > + if (host->version < SDHCI_SPEC_300) > return 0; > > switch (host->timing) { > @@ -733,14 +721,8 @@ static int sdhci_versal_sdcardclk_set_phase(struct > clk_hw *hw, int degrees) > struct sdhci_host *host = sdhci_arasan->host; > u8 tap_delay, tap_max = 0; > > - /* > - * This is applicable for SDHCI_SPEC_300 and above > - * Versal does not set phase for <=25MHz clock. > - * If degrees is zero, no need to do anything. > - */ > - if (host->version < SDHCI_SPEC_300 || > - host->timing == MMC_TIMING_LEGACY || > - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) > + /* This is applicable for SDHCI_SPEC_300 and above */ > + if (host->version < SDHCI_SPEC_300) > return 0; > > switch (host->timing) { > @@ -804,14 +786,8 @@ static int sdhci_versal_sampleclk_set_phase(struct > clk_hw *hw, int degrees) > struct sdhci_host *host = sdhci_arasan->host; > u8 tap_delay, tap_max = 0; > > - /* > - * This is applicable for SDHCI_SPEC_300 and above > - * Versal does not set phase for <=25MHz clock. > - * If degrees is zero, no need to do anything. > - */ > - if (host->version < SDHCI_SPEC_300 || > - host->timing == MMC_TIMING_LEGACY || > - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) > + /* This is applicable for SDHCI_SPEC_300 and above */ > + if (host->version < SDHCI_SPEC_300) > return 0; > > switch (host->timing) { > -- > 2.17.1 Thanks, Manish
[PATCH 0/2] Bug Fixes to Tap Delay code in SDHCI Arasan driver
This patch set consists a couple of minor bug fixes for SDHCI Arasan driver. The fixes are for tap delay programming where in some cases tuning is failing for some of the SD cards. Manish Narani (2): mmc: sdhci-of-arasan: Use Mask writes for Tap delays mmc: sdhci-of-arasan: Issue DLL reset explicitly drivers/mmc/host/sdhci-of-arasan.c | 11 +++ 1 file changed, 11 insertions(+) -- 2.17.1
[PATCH 2/2] mmc: sdhci-of-arasan: Issue DLL reset explicitly
In the current implementation DLL reset will be issued for each ITAP and OTAP setting inside ATF, this is creating issues in some scenarios and this sequence is not inline with the TRM. To fix the issue, DLL reset should be removed from the ATF and host driver will request it explicitly. This patch update host driver to explicitly request for DLL reset before ITAP (assert DLL) and after OTAP (release DLL) settings. Fixes: a5c8b2ae2e51 ("mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup") Signed-off-by: Sai Krishna Potthuri Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 3ec5ecad637c..e066d8f51954 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -635,6 +635,9 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) if (ret) pr_err("Error setting Output Tap Delay\n"); + eemi_ops->ioctl(node_id, IOCTL_SD_DLL_RESET, + PM_DLL_RESET_RELEASE, 0, NULL); + return ret; } @@ -794,6 +797,9 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) if (host->version < SDHCI_SPEC_300) return 0; + eemi_ops->ioctl(node_id, IOCTL_SD_DLL_RESET, + PM_DLL_RESET_ASSERT, 0, NULL); + switch (host->timing) { case MMC_TIMING_MMC_HS: case MMC_TIMING_SD_HS: -- 2.17.1
[PATCH 1/2] mmc: sdhci-of-arasan: Use Mask writes for Tap delays
Mask the ITAP and OTAP delay bits before updating with the new tap value for Versal platform. Fixes: 1a470721c8f5 ("sdhci: arasan: Add support for Versal Tap Delays") Signed-off-by: Sai Krishna Potthuri Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 100621e55427..3ec5ecad637c 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -30,7 +30,10 @@ #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 #define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 +#define SDHCI_ARASAN_ITAPDLY_SEL_MASK 0xFF + #define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC +#define SDHCI_ARASAN_OTAPDLY_SEL_MASK 0x3F #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 #define VENDOR_ENHANCED_STROBE BIT(0) @@ -755,6 +758,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees) regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); regval |= SDHCI_OTAPDLY_ENABLE; sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); + regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK; regval |= tap_delay; sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); } @@ -822,6 +826,7 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); regval |= SDHCI_ITAPDLY_ENABLE; sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); + regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK; regval |= tap_delay; sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); regval &= ~SDHCI_ITAPDLY_CHGWIN; -- 2.17.1
[PATCH] mmc: sdhci-of-arasan: Allow configuring zero tap values
Allow configuring the Output and Input tap values with zero to avoid failures in some cases (one of them is SD boot mode) where the output and input tap values may be already set to non-zero. Signed-off-by: Sai Krishna Potthuri Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 40 ++ 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 829ccef87426..100621e55427 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -600,14 +600,8 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) u8 tap_delay, tap_max = 0; int ret; - /* -* This is applicable for SDHCI_SPEC_300 and above -* ZynqMP does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { @@ -668,14 +662,8 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees) u8 tap_delay, tap_max = 0; int ret; - /* -* This is applicable for SDHCI_SPEC_300 and above -* ZynqMP does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { @@ -733,14 +721,8 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees) struct sdhci_host *host = sdhci_arasan->host; u8 tap_delay, tap_max = 0; - /* -* This is applicable for SDHCI_SPEC_300 and above -* Versal does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { @@ -804,14 +786,8 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) struct sdhci_host *host = sdhci_arasan->host; u8 tap_delay, tap_max = 0; - /* -* This is applicable for SDHCI_SPEC_300 and above -* Versal does not set phase for <=25MHz clock. -* If degrees is zero, no need to do anything. -*/ - if (host->version < SDHCI_SPEC_300 || - host->timing == MMC_TIMING_LEGACY || - host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + /* This is applicable for SDHCI_SPEC_300 and above */ + if (host->version < SDHCI_SPEC_300) return 0; switch (host->timing) { -- 2.17.1
RE: [PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Ping! > -Original Message- > From: Manish Narani > Sent: Thursday, October 8, 2020 6:37 PM > To: gre...@linuxfoundation.org; robh...@kernel.org; Michal Simek > ; ba...@kernel.org; p.za...@pengutronix.de > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-kernel@vger.kernel.org; git > ; > Manish Narani > Subject: [PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms > > Add a new driver for supporting Xilinx platforms. This driver is used > for some sequence of operations required for Xilinx USB controllers. > This driver is also used to choose between PIPE clock coming from SerDes > and the Suspend Clock. Before the controller is out of reset, the clock > selection should be changed to PIPE clock in order to make the USB > controller work. There is a register added in Xilinx USB controller > register space for the same. > > Signed-off-by: Manish Narani > --- > drivers/usb/dwc3/Kconfig | 9 + > drivers/usb/dwc3/Makefile | 1 + > drivers/usb/dwc3/dwc3-of-simple.c | 1 - > drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ > 4 files changed, 344 insertions(+), 1 deletion(-) > create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c > > diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig > index 7a2304565a73..0e00e6dfccd8 100644 > --- a/drivers/usb/dwc3/Kconfig > +++ b/drivers/usb/dwc3/Kconfig > @@ -139,4 +139,13 @@ config USB_DWC3_QCOM > for peripheral mode support. > Say 'Y' or 'M' if you have one such device. > > +config USB_DWC3_XILINX > + tristate "Xilinx Platforms" > + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF > + default USB_DWC3 > + help > + Support Xilinx SoCs with DesignWare Core USB3 IP. > + This driver handles both ZynqMP and Versal SoC operations. > + Say 'Y' or 'M' if you have one such device. > + > endif > diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile > index ae86da0dc5bd..add567578b1f 100644 > --- a/drivers/usb/dwc3/Makefile > +++ b/drivers/usb/dwc3/Makefile > @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3- > meson-g12a.o > obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o > obj-$(CONFIG_USB_DWC3_ST)+= dwc3-st.o > obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o > +obj-$(CONFIG_USB_DWC3_XILINX)+= dwc3-xilinx.o > diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of- > simple.c > index 7df115012935..e3a485b76818 100644 > --- a/drivers/usb/dwc3/dwc3-of-simple.c > +++ b/drivers/usb/dwc3/dwc3-of-simple.c > @@ -172,7 +172,6 @@ static const struct dev_pm_ops > dwc3_of_simple_dev_pm_ops = { > > static const struct of_device_id of_dwc3_simple_match[] = { > { .compatible = "rockchip,rk3399-dwc3" }, > - { .compatible = "xlnx,zynqmp-dwc3" }, > { .compatible = "cavium,octeon-7130-usb-uctl" }, > { .compatible = "sprd,sc9860-dwc3" }, > { .compatible = "allwinner,sun50i-h6-dwc3" }, > diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c > new file mode 100644 > index ..7e485951d2f7 > --- /dev/null > +++ b/drivers/usb/dwc3/dwc3-xilinx.c > @@ -0,0 +1,334 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/** > + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver > + * > + * Authors: Manish Narani > + * Anurag Kumar Vulisha > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +/* USB phy reset mask register */ > +#define XLNX_USB_PHY_RST_EN 0x001C > +#define XLNX_PHY_RST_MASK0x1 > + > +/* Xilinx USB 3.0 IP Register */ > +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG0x005C > +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 > + > +/* Versal USB Reset ID */ > +#define VERSAL_USB_RESET_ID 0xC104036 > + > +#define XLNX_USB_FPD_PIPE_CLK0x7c > +#define PIPE_CLK_DESELECT1 > +#define PIPE_CLK_SELECT 0 > +#define XLNX_USB_FPD_POWER_PRSNT 0x80 > +#define PIPE_POWER_ON1 > +#define PIPE_POWER_OFF 0 > + > +struct dwc3_xlnx { > + int num_clocks; > + struct clk_bulk_data*clks; > + struct device *dev; > +
[PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 7a2304565a73..0e00e6dfccd8 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -139,4 +139,13 @@ config USB_DWC3_QCOM for peripheral mode support. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index ae86da0dc5bd..add567578b1f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 7df115012935..e3a485b76818 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index ..7e485951d2f7 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST_EN0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define XLNX_USB_FPD_PIPE_CLK 0x7c +#define PIPE_CLK_DESELECT 1 +#define PIPE_CLK_SELECT0 +#define XLNX_USB_FPD_POWER_PRSNT 0x80 +#define PIPE_POWER_ON 1 +#define PIPE_POWER_OFF 0 + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device *dev; + void __iomem*regs; + int (*pltfm_init)(struct dwc3_xlnx *data); +}; + +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) +{ + u32 reg; + + /* +* Enable or disable ULPI PHY reset from USB Controller. +* This does not actually reset the phy, but just controls +* whether USB controller can or cannot reset ULPI PHY. +*/ + reg = readl(priv_data->regs + XLNX_USB_PHY_RST_EN); + + if (mask) + reg &= ~XLNX_PHY_RST_MASK; + else + reg |= XLNX_PHY_RST_MASK; + + writel(reg, priv_data->regs + XLNX_USB_PHY_RST_EN); +} + +static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) +{ + struct device *dev = priv_data->dev; + int ret; + + dwc3_xlnx_mask_phy_rst(priv_data, false); + + /* Assert and De-assert reset */ + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_
[PATCH v3 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Add documentation for Versal DWC3 controller. Add required property 'reg' for the same. Also add optional properties for snps,dwc3. Signed-off-by: Manish Narani --- .../devicetree/bindings/usb/dwc3-xilinx.txt | 17 +++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index 4aae5b2cef56..0629f48cc807 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -1,7 +1,8 @@ Xilinx SuperSpeed DWC3 USB SoC controller Required properties: -- compatible: Should contain "xlnx,zynqmp-dwc3" +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal-dwc3" +- reg: Base address and length of the register control block - clocks: A list of phandles for the clocks listed in clock-names - clock-names: Should contain the following: "bus_clk" Master/Core clock, have to be >= 125 MHz for SS @@ -13,12 +14,22 @@ Required child node: A child node must exist to represent the core DWC3 IP block. The name of the node is not important. The content of the node is defined in dwc3.txt. +Optional properties for snps,dwc3: +- dma-coherent:Enable this flag if CCI is enabled in design. Adding this + flag configures Global SoC bus Configuration Register and + Xilinx USB 3.0 IP - USB coherency register to enable CCI. +- interrupt-names: Should contain the following: + "dwc_usb3" USB gadget mode interrupts + "otg"USB OTG mode interrupts + "hiber" USB hibernation interrupts + Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; compatible = "xlnx,zynqmp-dwc3"; + reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk" "ref_clk"; clocks = <>, <>; ranges; @@ -26,7 +37,9 @@ Example device node: dwc3@fe20 { compatible = "snps,dwc3"; reg = <0x0 0xfe20 0x4>; - interrupts = <0x0 0x41 0x4>; + interrupt-names = "dwc_usb3", "otg", "hiber"; + interrupts = <0 65 4>, <0 69 4>, <0 75 4>; dr_mode = "host"; + dma-coherent; }; }; -- 2.17.1
[PATCH v3 0/2] Add a separate DWC3 OF driver for Xilinx platforms
This patch series documents the Xilinx Versal DWC3 controller. This also adds a new Xilinx specific driver for adding new features in the future. Changes in v2: - Addressed review comments from v1 - merged normal and runtime suspend resume functions as they are same - Improved description of some register operations to avoid confusion - Updated commit log for patch 2/2 for better clarity. Changes in v3: - Removed snps,enable-hibernation property from the devicetree binding. Manish Narani (2): dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller usb: dwc3: Add driver for Xilinx platforms .../devicetree/bindings/usb/dwc3-xilinx.txt | 17 +- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 5 files changed, 359 insertions(+), 3 deletions(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c -- 2.17.1
RE: [PATCH v2 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Felipe, Would you please review this patch? So that in v3, I can include the changes in the driver if any, along with the binding corrections. Thanks, Manish > -Original Message- > From: Manish Narani > Sent: Thursday, September 10, 2020 12:33 AM > To: gre...@linuxfoundation.org; robh...@kernel.org; Michal Simek > ; ba...@kernel.org; p.za...@pengutronix.de > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-kernel@vger.kernel.org; git > ; Manish Narani > Subject: [PATCH v2 2/2] usb: dwc3: Add driver for Xilinx platforms > > Add a new driver for supporting Xilinx platforms. This driver is used > for some sequence of operations required for Xilinx USB controllers. > This driver is also used to choose between PIPE clock coming from SerDes > and the Suspend Clock. Before the controller is out of reset, the clock > selection should be changed to PIPE clock in order to make the USB > controller work. There is a register added in Xilinx USB controller > register space for the same. > > Signed-off-by: Manish Narani > --- > drivers/usb/dwc3/Kconfig | 9 + > drivers/usb/dwc3/Makefile | 1 + > drivers/usb/dwc3/dwc3-of-simple.c | 1 - > drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ > 4 files changed, 344 insertions(+), 1 deletion(-) > create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c > > diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig > index 7a2304565a73..0e00e6dfccd8 100644 > --- a/drivers/usb/dwc3/Kconfig > +++ b/drivers/usb/dwc3/Kconfig > @@ -139,4 +139,13 @@ config USB_DWC3_QCOM > for peripheral mode support. > Say 'Y' or 'M' if you have one such device. > > +config USB_DWC3_XILINX > + tristate "Xilinx Platforms" > + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF > + default USB_DWC3 > + help > + Support Xilinx SoCs with DesignWare Core USB3 IP. > + This driver handles both ZynqMP and Versal SoC operations. > + Say 'Y' or 'M' if you have one such device. > + > endif > diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile > index ae86da0dc5bd..add567578b1f 100644 > --- a/drivers/usb/dwc3/Makefile > +++ b/drivers/usb/dwc3/Makefile > @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += > dwc3-meson-g12a.o > obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o > obj-$(CONFIG_USB_DWC3_ST)+= dwc3-st.o > obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o > +obj-$(CONFIG_USB_DWC3_XILINX)+= dwc3-xilinx.o > diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of- > simple.c > index 7df115012935..e3a485b76818 100644 > --- a/drivers/usb/dwc3/dwc3-of-simple.c > +++ b/drivers/usb/dwc3/dwc3-of-simple.c > @@ -172,7 +172,6 @@ static const struct dev_pm_ops > dwc3_of_simple_dev_pm_ops = { > > static const struct of_device_id of_dwc3_simple_match[] = { > { .compatible = "rockchip,rk3399-dwc3" }, > - { .compatible = "xlnx,zynqmp-dwc3" }, > { .compatible = "cavium,octeon-7130-usb-uctl" }, > { .compatible = "sprd,sc9860-dwc3" }, > { .compatible = "allwinner,sun50i-h6-dwc3" }, > diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c > new file mode 100644 > index ..7e485951d2f7 > --- /dev/null > +++ b/drivers/usb/dwc3/dwc3-xilinx.c > @@ -0,0 +1,334 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/** > + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver > + * > + * Authors: Manish Narani > + * Anurag Kumar Vulisha > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +/* USB phy reset mask register */ > +#define XLNX_USB_PHY_RST_EN 0x001C > +#define XLNX_PHY_RST_MASK0x1 > + > +/* Xilinx USB 3.0 IP Register */ > +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG0x005C > +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 > + > +/* Versal USB Reset ID */ > +#define VERSAL_USB_RESET_ID 0xC104036 > + > +#define XLNX_USB_FPD_PIPE_CLK0x7c > +#define PIPE_CLK_DESELECT1 > +#define PIPE_CLK_SELECT 0 > +#define XLNX_USB_FPD_POWER_PRSNT 0x80 > +#define PIPE_POWER_ON1 > +#define PIPE_POWER_OFF 0 > + > +struct dwc3_xlnx { > +
RE: [PATCH v2 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Hi Felipe, > -Original Message- > From: Felipe Balbi > Sent: Friday, September 25, 2020 12:42 PM > To: Manish Narani ; Rob Herring > Cc: gre...@linuxfoundation.org; Michal Simek ; > p.za...@pengutronix.de; linux-...@vger.kernel.org; > devicet...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > ker...@vger.kernel.org; git > Subject: RE: [PATCH v2 1/2] dt-bindings: usb: dwc3-xilinx: Add > documentation for Versal DWC3 Controller > > > Hi, > > Manish Narani writes: > > Hi Rob/Felipe, > > > > Thanks for the review. > > > >> -Original Message- > >> From: Felipe Balbi > >> Sent: Thursday, September 24, 2020 12:47 PM > >> To: Rob Herring ; Manish Narani > > >> Cc: gre...@linuxfoundation.org; Michal Simek ; > >> p.za...@pengutronix.de; linux-...@vger.kernel.org; > >> devicet...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > >> ker...@vger.kernel.org; git > >> Subject: Re: [PATCH v2 1/2] dt-bindings: usb: dwc3-xilinx: Add > >> documentation for Versal DWC3 Controller > >> > >> Rob Herring writes: > >> > >> > On Thu, Sep 10, 2020 at 12:33:04AM +0530, Manish Narani wrote: > >> >> Add documentation for Versal DWC3 controller. Add required property > >> >> 'reg' for the same. Also add optional properties for snps,dwc3. > >> >> > >> >> Signed-off-by: Manish Narani > >> >> --- > >> >> .../devicetree/bindings/usb/dwc3-xilinx.txt | 20 +- > - > >> >> 1 file changed, 18 insertions(+), 2 deletions(-) > >> >> > >> >> diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > >> b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > >> >> index 4aae5b2cef56..219b5780dbee 100644 > >> >> --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > >> >> +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > >> >> @@ -1,7 +1,8 @@ > >> >> Xilinx SuperSpeed DWC3 USB SoC controller > >> >> > >> >> Required properties: > >> >> -- compatible: Should contain "xlnx,zynqmp-dwc3" > >> >> +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal- > >> dwc3" > >> >> +- reg: Base address and length of the register control block > >> >> - clocks: A list of phandles for the clocks listed in clock-names > >> >> - clock-names: Should contain the following: > >> >>"bus_clk" Master/Core clock, have to be >= 125 MHz for SS > >> >> @@ -13,12 +14,24 @@ Required child node: > >> >> A child node must exist to represent the core DWC3 IP block. The > name of > >> >> the node is not important. The content of the node is defined in > dwc3.txt. > >> >> > >> >> +Optional properties for snps,dwc3: > >> >> +- dma-coherent:Enable this flag if CCI is enabled in design. > >> >> Adding this > >> >> + flag configures Global SoC bus Configuration Register > >> >> and > >> >> + Xilinx USB 3.0 IP - USB coherency register to enable > >> >> CCI. > >> >> +- snps,enable-hibernation: Add this flag to enable hibernation support > >> for > >> >> + peripheral mode. > >> > > >> > This belongs in the DWC3 binding. It also implies that hibernation is > >> > not supported by any other DWC3 based platform. Can't this be implied > by > >> > the compatible string (in the parent)? > > > > Rob, We can move this to dwc3 bindings. If Felipe is okay with below > response. > > > >> > >> hibernation support is detectable in runtime, and we've been using that. > > > > Felipe, Yes, this flag is to control the enable/disable hibernation. > > I did not see has_hibernation flag being set anywhere in the driver. > > Can we control the hibernation enable/disable through DT entry? See > below: > > - > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > > index 2eb34c8b4065..1baf44d8d566 100644 > > --- a/drivers/usb/dwc3/core.c > > +++ b/drivers/usb/dwc3/core.c > > @@ -769,8 +769,15 @@ static void dwc3_core_setup_global_control(struct > dwc3 *dwc) > > reg &= ~DWC3_GCTL_DSBLCLKGTNG; > > break; &g
RE: [PATCH v2 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Hi Rob/Felipe, Thanks for the review. > -Original Message- > From: Felipe Balbi > Sent: Thursday, September 24, 2020 12:47 PM > To: Rob Herring ; Manish Narani > Cc: gre...@linuxfoundation.org; Michal Simek ; > p.za...@pengutronix.de; linux-...@vger.kernel.org; > devicet...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > ker...@vger.kernel.org; git > Subject: Re: [PATCH v2 1/2] dt-bindings: usb: dwc3-xilinx: Add > documentation for Versal DWC3 Controller > > Rob Herring writes: > > > On Thu, Sep 10, 2020 at 12:33:04AM +0530, Manish Narani wrote: > >> Add documentation for Versal DWC3 controller. Add required property > >> 'reg' for the same. Also add optional properties for snps,dwc3. > >> > >> Signed-off-by: Manish Narani > >> --- > >> .../devicetree/bindings/usb/dwc3-xilinx.txt | 20 +-- > >> 1 file changed, 18 insertions(+), 2 deletions(-) > >> > >> diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > >> index 4aae5b2cef56..219b5780dbee 100644 > >> --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > >> +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > >> @@ -1,7 +1,8 @@ > >> Xilinx SuperSpeed DWC3 USB SoC controller > >> > >> Required properties: > >> -- compatible: Should contain "xlnx,zynqmp-dwc3" > >> +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal- > dwc3" > >> +- reg:Base address and length of the register control block > >> - clocks: A list of phandles for the clocks listed in clock-names > >> - clock-names:Should contain the following: > >>"bus_clk"Master/Core clock, have to be >= 125 MHz for SS > >> @@ -13,12 +14,24 @@ Required child node: > >> A child node must exist to represent the core DWC3 IP block. The name of > >> the node is not important. The content of the node is defined in dwc3.txt. > >> > >> +Optional properties for snps,dwc3: > >> +- dma-coherent: Enable this flag if CCI is enabled in design. Adding > >> this > >> + flag configures Global SoC bus Configuration Register and > >> + Xilinx USB 3.0 IP - USB coherency register to enable CCI. > >> +- snps,enable-hibernation: Add this flag to enable hibernation support > for > >> + peripheral mode. > > > > This belongs in the DWC3 binding. It also implies that hibernation is > > not supported by any other DWC3 based platform. Can't this be implied by > > the compatible string (in the parent)? Rob, We can move this to dwc3 bindings. If Felipe is okay with below response. > > hibernation support is detectable in runtime, and we've been using that. Felipe, Yes, this flag is to control the enable/disable hibernation. I did not see has_hibernation flag being set anywhere in the driver. Can we control the hibernation enable/disable through DT entry? See below: - diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 2eb34c8b4065..1baf44d8d566 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -769,8 +769,15 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc) reg &= ~DWC3_GCTL_DSBLCLKGTNG; break; case DWC3_GHWPARAMS1_EN_PWROPT_HIB: - /* enable hibernation here */ - dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4); + if (!device_property_read_bool(dwc->dev, + "snps,enable-hibernation")) { + dev_dbg(dwc->dev, "Hibernation not enabled\n"); + } else { + /* enable hibernation here */ + dwc->nr_scratch = + DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4); + dwc->has_hibernation = 1; + } /* * REVISIT Enabling this bit so that host-mode hibernation - Please provide your inputs. Thanks, Manish
[PATCH v2 2/2] usb: dwc3: Add driver for Xilinx platforms
Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 7a2304565a73..0e00e6dfccd8 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -139,4 +139,13 @@ config USB_DWC3_QCOM for peripheral mode support. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index ae86da0dc5bd..add567578b1f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 7df115012935..e3a485b76818 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index ..7e485951d2f7 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST_EN0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define XLNX_USB_FPD_PIPE_CLK 0x7c +#define PIPE_CLK_DESELECT 1 +#define PIPE_CLK_SELECT0 +#define XLNX_USB_FPD_POWER_PRSNT 0x80 +#define PIPE_POWER_ON 1 +#define PIPE_POWER_OFF 0 + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device *dev; + void __iomem*regs; + int (*pltfm_init)(struct dwc3_xlnx *data); +}; + +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) +{ + u32 reg; + + /* +* Enable or disable ULPI PHY reset from USB Controller. +* This does not actually reset the phy, but just controls +* whether USB controller can or cannot reset ULPI PHY. +*/ + reg = readl(priv_data->regs + XLNX_USB_PHY_RST_EN); + + if (mask) + reg &= ~XLNX_PHY_RST_MASK; + else + reg |= XLNX_PHY_RST_MASK; + + writel(reg, priv_data->regs + XLNX_USB_PHY_RST_EN); +} + +static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) +{ + struct device *dev = priv_data->dev; + int ret; + + dwc3_xlnx_mask_phy_rst(priv_data, false); + + /* Assert and De-assert reset */ + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_
[PATCH v2 0/2] Add a separate DWC3 OF driver for Xilinx platforms
This patch series documents the Xilinx Versal DWC3 controller. This also adds a new Xilinx specific driver for adding new features in the future. Changes in v2: - Addressed review comments from v1 - merged normal and runtime suspend resume functions as they are same - Improved description of some register operations to avoid confusion - Updated commit log for patch 2/2 for better clarity. Manish Narani (2): dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller usb: dwc3: Add driver for Xilinx platforms .../devicetree/bindings/usb/dwc3-xilinx.txt | 20 +- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 5 files changed, 362 insertions(+), 3 deletions(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c -- 2.17.1
[PATCH v2 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Add documentation for Versal DWC3 controller. Add required property 'reg' for the same. Also add optional properties for snps,dwc3. Signed-off-by: Manish Narani --- .../devicetree/bindings/usb/dwc3-xilinx.txt | 20 +-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index 4aae5b2cef56..219b5780dbee 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -1,7 +1,8 @@ Xilinx SuperSpeed DWC3 USB SoC controller Required properties: -- compatible: Should contain "xlnx,zynqmp-dwc3" +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal-dwc3" +- reg: Base address and length of the register control block - clocks: A list of phandles for the clocks listed in clock-names - clock-names: Should contain the following: "bus_clk" Master/Core clock, have to be >= 125 MHz for SS @@ -13,12 +14,24 @@ Required child node: A child node must exist to represent the core DWC3 IP block. The name of the node is not important. The content of the node is defined in dwc3.txt. +Optional properties for snps,dwc3: +- dma-coherent:Enable this flag if CCI is enabled in design. Adding this + flag configures Global SoC bus Configuration Register and + Xilinx USB 3.0 IP - USB coherency register to enable CCI. +- snps,enable-hibernation: Add this flag to enable hibernation support for + peripheral mode. +- interrupt-names: Should contain the following: + "dwc_usb3" USB gadget mode interrupts + "otg"USB OTG mode interrupts + "hiber" USB hibernation interrupts + Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; compatible = "xlnx,zynqmp-dwc3"; + reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk" "ref_clk"; clocks = <>, <>; ranges; @@ -26,7 +39,10 @@ Example device node: dwc3@fe20 { compatible = "snps,dwc3"; reg = <0x0 0xfe20 0x4>; - interrupts = <0x0 0x41 0x4>; + interrupt-names = "dwc_usb3", "otg", "hiber"; + interrupts = <0 65 4>, <0 69 4>, <0 75 4>; dr_mode = "host"; + dma-coherent; + snps,enable-hibernation; }; }; -- 2.17.1
RE: [PATCH 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Hi Rob, Thanks for the review. > -Original Message- > From: Rob Herring > Sent: Wednesday, September 9, 2020 4:35 AM > To: Manish Narani > Cc: gre...@linuxfoundation.org; Michal Simek ; > ba...@kernel.org; p.za...@pengutronix.de; linux-...@vger.kernel.org; > devicet...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > ker...@vger.kernel.org; git > Subject: Re: [PATCH 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for > Versal DWC3 Controller > > On Thu, Aug 27, 2020 at 12:14:00AM +0530, Manish Narani wrote: > > Add documentation for Versal DWC3 controller. Add required property > > 'reg' for the same. Also add optional properties for snps,dwc3. > > > > Signed-off-by: Manish Narani > > --- > > .../devicetree/bindings/usb/dwc3-xilinx.txt | 12 +++- > > 1 file changed, 11 insertions(+), 1 deletion(-) > > > > diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > > index 4aae5b2cef56..dd41ed831411 100644 > > --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > > +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt > > @@ -1,7 +1,8 @@ > > Xilinx SuperSpeed DWC3 USB SoC controller > > > > Required properties: > > -- compatible: Should contain "xlnx,zynqmp-dwc3" > > +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal- > dwc3" > > +- reg: Base address and length of the register control block > > - clocks: A list of phandles for the clocks listed in clock-names > > - clock-names: Should contain the following: > >"bus_clk" Master/Core clock, have to be >= 125 MHz for SS > > @@ -13,12 +14,19 @@ Required child node: > > A child node must exist to represent the core DWC3 IP block. The name of > > the node is not important. The content of the node is defined in dwc3.txt. > > > > +Optional properties for snps,dwc3: > > +- dma-coherent:Enable this flag if CCI is enabled in design. Adding > > this > > + flag configures Global SoC bus Configuration Register and > > + Xilinx USB 3.0 IP - USB coherency register to enable CCI. > > +- interrupt-names: This property provides the names of the interrupt ids > used > > You have to define what the names are. 'dwc_usb3' seems pretty pointless > if only 1 name. OK. I am planning to add more interrupt ids going ahead. For now I will remove this interrupt name in v2. The interrupt name will be added along with other interrupt names. Thanks, Manish
RE: [PATCH 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Felipe, Thanks for the response. > -Original Message- > From: Felipe Balbi > Sent: Tuesday, September 1, 2020 5:45 PM > > >> > +goto err; > >> > +} > >> > + > >> > +ret = dwc3_xlnx_rst_assert(priv_data->apbrst); > >> > +if (ret < 0) { > >> > +dev_err(dev, "%s: %d: Failed to assert reset\n", > >> > +__func__, __LINE__); > >> > >>dev_err(dev, "Failed to assert APB reset\n"); > >> > >> > +goto err; > >> > +} > >> > + > >> > +ret = phy_init(priv_data->usb3_phy); > >> > >> dwc3 core should be handling this already > > > > The USB controller used in Xilinx ZynqMP platform uses xilinx GT phy > > which has 4 GT lanes and can used by 4 peripherals at a time. > > At the same time or are they mutually exclusive? The lanes are mutually exclusive. [...] > >> > +if (ret < 0) { > >> > +dev_err(dev, "%s: %d: Failed to release reset\n", > >> > +__func__, __LINE__); > >> > +goto err; > >> > +} > >> > + > >> > +/* Set PIPE power present signal */ > >> > +writel(PIPE_POWER_ON, priv_data->regs + PIPE_POWER_OFFSET); > >> > + > >> > +/* Clear PIPE CLK signal */ > >> > +writel(PIPE_CLK_OFF, priv_data->regs + PIPE_CLK_OFFSET); > >> > >> shouldn't this be hidden under clk_enable()? > > > > Though its naming suggests something related to clock framework, it is > > a register in the Xilinx USB controller space which configures the > > PIPE clock coming from Serdes. > > PIPE clock is a clock. It just so happens that the source is the PHY > itself. This bit is used to choose between PIPE clock coming from SerDes and the Suspend Clock. When the controller is out of reset, this bit needs to be reset in order to make the USB controller work. This register is added in Xilinx USB controller register space. I will add more description about the same in v2. Thanks, Manish
RE: [PATCH 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Robin, Thanks for the review. Please find my comment below inline. > -Original Message- > From: Robin Murphy > Sent: Friday, August 28, 2020 12:17 AM > To: Manish Narani ; gre...@linuxfoundation.org; > robh...@kernel.org; Michal Simek ; ba...@kernel.org; > p.za...@pengutronix.de > Cc: devicet...@vger.kernel.org; linux-...@vger.kernel.org; linux- > ker...@vger.kernel.org; git ; linux-arm- > ker...@lists.infradead.org > Subject: Re: [PATCH 2/2] usb: dwc3: Add driver for Xilinx platforms > > On 2020-08-26 19:44, Manish Narani wrote: > [...] > > + /* > > +* This routes the usb dma traffic to go through CCI path instead > > +* of reaching DDR directly. This traffic routing is needed to > > +* make SMMU and CCI work with USB dma. > > +*/ > > + if (of_dma_is_coherent(dev->of_node) || dev->iommu_group) { > > + reg = readl(priv_data->regs + XLNX_USB_COHERENCY); > > + reg |= XLNX_USB_COHERENCY_ENABLE; > > + writel(reg, priv_data->regs + XLNX_USB_COHERENCY); > > + } > > This looks rather suspect - coherency should be based on coherency, not > on whether an IOMMU group is present. If the device isn't described as > coherent in the DT, then any SMMU mappings will end up using attributes > that will downgrade traffic to be non-snooping anyway. And if the SMMU > is enabled but not translating (e.g. "iommu.passthrough=1") then > enabling hardware coherency when the DMA layer hasn't been told about it > can potentially lead to nasty subtle problems and data loss. May be the description needs to be updated in this. This is not the actual coherency enabling bit, but this is needed when coherency is enabled. This is a register inside Xilinx USB controller which handles USB (which is in LPD) traffic route switching from LPD (Low Power Domain) to FPD (Full Power Domain) path in the Xilinx SoC in either of the below scenarios: 1. Device is described coherent in DT. 2. SMMU is enabled. I will update the same in v2. Thanks, Manish
RE: [PATCH 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Felipe, Thanks for the review. Please find my comments below inline. > -Original Message- > From: Felipe Balbi > Sent: Thursday, August 27, 2020 12:02 PM > To: Manish Narani ; gre...@linuxfoundation.org; > robh...@kernel.org; Michal Simek ; > p.za...@pengutronix.de > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-kernel@vger.kernel.org; git > ; > Manish Narani > Subject: Re: [PATCH 2/2] usb: dwc3: Add driver for Xilinx platforms > > Manish Narani writes: > > > Add a new driver for supporting Xilinx platforms. This driver handles > > the USB 3.0 PHY initialization and PIPE control & reset operations for > > PHY initialization should be done as part of a drivers/phy driver. Yes. This driver calls those APIs present in the Xilinx PHY driver (drivers/phy/xilinx/phy-zynqmp.c) for initializing the PHY. May be I can optimize this commit message a bit. > > > ZynqMP platforms. This also handles the USB 2.0 PHY initialization and > > reset operations for Versal platforms. > > similarly for USB2 PHYs > > > diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c > > new file mode 100644 > > index ..272906797a7a > > --- /dev/null > > +++ b/drivers/usb/dwc3/dwc3-xilinx.c > > @@ -0,0 +1,416 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/** > > + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver > > + * > > + * Authors: Anurag Kumar Vulisha > > + * Manish Narani > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > + > > +/* USB phy reset mask register */ > > +#define XLNX_USB_PHY_RST 0x001C > > +#define XLNX_PHY_RST_MASK 0x1 > > + > > +/* Xilinx USB 3.0 IP Register */ > > +#define XLNX_USB_COHERENCY 0x005C > > +#define XLNX_USB_COHERENCY_ENABLE 0x1 > > + > > +/* Versal USB Reset ID */ > > +#define VERSAL_USB_RESET_ID0xC104036 > > + > > +#define PIPE_CLK_OFFSET0x7c > > +#define PIPE_CLK_ON1 > > +#define PIPE_CLK_OFF 0 > > +#define PIPE_POWER_OFFSET 0x80 > > +#define PIPE_POWER_ON 1 > > +#define PIPE_POWER_OFF 0 > > + > > +#define RST_TIMEOUT1000 > > + > > +struct dwc3_xlnx { > > + int num_clocks; > > + struct clk_bulk_data*clks; > > + struct device *dev; > > + void __iomem*regs; > > + struct dwc3 *dwc; > > + struct phy *phy; > > + struct phy *usb3_phy; > > + struct reset_control*crst; > > + struct reset_control*hibrst; > > + struct reset_control*apbrst; > > +}; > > + > > +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool > mask) > > +{ > > + u32 reg; > > + > > + reg = readl(priv_data->regs + XLNX_USB_PHY_RST); > > + > > + if (mask) > > + /* > > +* Mask the phy reset signal from comtroller > > s/comtroller/controller > > But really, the comments don't bring any extra information. I'd say > remove the comments as the code speaks for itself very clearly in this > case. > > > +static int dwc3_xlnx_rst_assert(struct reset_control *rstc) > > this looks like it should be an actual reset controller driver. > > > +static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) > > +{ > > + struct device *dev = priv_data->dev; > > + int ret; > > + > > + dwc3_xlnx_mask_phy_rst(priv_data, false); > > + > > + /* Assert and De-assert reset */ > > + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_ID, > > +PM_RESET_ACTION_ASSERT); > > + if (ret < 0) { > > + dev_err(dev, "failed to assert Reset\n"); > > + return ret; > > + } > > + > > + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_ID, > > +PM_RESET_ACTION_RELEASE); > > + if (ret < 0) { > > + dev_err(dev, "failed to De-assert Reset\
[PATCH 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Add documentation for Versal DWC3 controller. Add required property 'reg' for the same. Also add optional properties for snps,dwc3. Signed-off-by: Manish Narani --- .../devicetree/bindings/usb/dwc3-xilinx.txt | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index 4aae5b2cef56..dd41ed831411 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -1,7 +1,8 @@ Xilinx SuperSpeed DWC3 USB SoC controller Required properties: -- compatible: Should contain "xlnx,zynqmp-dwc3" +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal-dwc3" +- reg: Base address and length of the register control block - clocks: A list of phandles for the clocks listed in clock-names - clock-names: Should contain the following: "bus_clk" Master/Core clock, have to be >= 125 MHz for SS @@ -13,12 +14,19 @@ Required child node: A child node must exist to represent the core DWC3 IP block. The name of the node is not important. The content of the node is defined in dwc3.txt. +Optional properties for snps,dwc3: +- dma-coherent:Enable this flag if CCI is enabled in design. Adding this + flag configures Global SoC bus Configuration Register and + Xilinx USB 3.0 IP - USB coherency register to enable CCI. +- interrupt-names: This property provides the names of the interrupt ids used + Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; compatible = "xlnx,zynqmp-dwc3"; + reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk" "ref_clk"; clocks = <>, <>; ranges; @@ -26,7 +34,9 @@ Example device node: dwc3@fe20 { compatible = "snps,dwc3"; reg = <0x0 0xfe20 0x4>; + interrupt-name = "dwc_usb3"; interrupts = <0x0 0x41 0x4>; dr_mode = "host"; + dma-coherent; }; }; -- 2.17.1
[PATCH 0/2] Add a separate DWC3 OF driver for Xilinx platforms
This patch series documents the Xilinx Versal DWC3 controller. This also adds a new Xilinx specific driver for adding new features in the future. Manish Narani (2): dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller usb: dwc3: Add driver for Xilinx platforms .../devicetree/bindings/usb/dwc3-xilinx.txt | 12 +- drivers/usb/dwc3/Kconfig | 8 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 416 ++ 5 files changed, 436 insertions(+), 2 deletions(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c -- 2.17.1
[PATCH 2/2] usb: dwc3: Add driver for Xilinx platforms
Add a new driver for supporting Xilinx platforms. This driver handles the USB 3.0 PHY initialization and PIPE control & reset operations for ZynqMP platforms. This also handles the USB 2.0 PHY initialization and reset operations for Versal platforms. Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 8 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 416 ++ 4 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 7a2304565a73..416063ee9d05 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -139,4 +139,12 @@ config USB_DWC3_QCOM for peripheral mode support. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. +Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index ae86da0dc5bd..add567578b1f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 7df115012935..e3a485b76818 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index ..272906797a7a --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Anurag Kumar Vulisha + * Manish Narani + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST 0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_COHERENCY 0x005C +#define XLNX_USB_COHERENCY_ENABLE 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define PIPE_CLK_OFFSET0x7c +#define PIPE_CLK_ON1 +#define PIPE_CLK_OFF 0 +#define PIPE_POWER_OFFSET 0x80 +#define PIPE_POWER_ON 1 +#define PIPE_POWER_OFF 0 + +#define RST_TIMEOUT1000 + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device *dev; + void __iomem*regs; + struct dwc3 *dwc; + struct phy *phy; + struct phy *usb3_phy; + struct reset_control*crst; + struct reset_control*hibrst; + struct reset_control*apbrst; +}; + +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) +{ + u32 reg; + + reg = readl(priv_data->regs + XLNX_USB_PHY_RST); + + if (mask) + /* +* Mask the phy reset signal from comtroller +* reaching ULPI phy. This can be done by +* writing 0 into usb2_phy_reset register +*/ + reg &= ~XLNX_PHY_RST_MASK; + else + /* +* Allow phy reset signal from controller to +* reset ULPI phy. This can be done by writing +* 0x1 into usb2_phy_reset register +*/ + reg |= XLNX_PHY_RST_MASK; + + writel(reg, priv_data->regs + XLNX_USB_PHY_RST); +} + +static int dwc3_xlnx_rst_assert(struct reset_control *rstc) +{ + unsigned long loop_time = msecs_to_jiffies(RST_TIMEOUT); + unsigned long timeout; + + reset_control_assert(rstc);
RE: [PATCH] dt-bindings: mmc: Add missing description for clk_in/out_sd1
> -Original Message- > From: Michal Simek On Behalf Of Michal Simek > Sent: Monday, August 24, 2020 1:55 PM > To: linux-kernel@vger.kernel.org; mon...@monstr.eu; Michal Simek > ; git ; Manish Narani > > Cc: Adrian Hunter ; Rob Herring > ; Ulf Hansson ; Wan Ahmad > Zainie ; > devicet...@vger.kernel.org; linux-...@vger.kernel.org > Subject: [PATCH] dt-bindings: mmc: Add missing description for clk_in/out_sd1 > > The commit a8fdb80f4d47 ("arm64: zynqmp: Add ZynqMP SDHCI compatible > string") added clock-output-names for both SDHCIs before DT binding yaml > conversion. But only clk_in/out_sd0 clock names have been covered by > DT binding which ends up with dt yaml checking warnings as: > From schema: .../Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml > ... mmc@ff17: clock-output-names:0: 'clk_out_sd0' was expected > ... mmc@ff17: clock-output-names:1: 'clk_in_sd0' was expected > > Fixes: 16ecd8f33c6e ("dt-bindings: mmc: convert arasan sdhci bindings to > yaml") > Signed-off-by: Michal Simek Reviewed-by: Manish Narani
[PATCH] mmc: host: sdhci-of-arasan: fix timings allocation code
The initial code that was adding delays was doing a cast over undefined memory. This meant that the delays would be all gibberish. This change, allocates all delays on the stack, and assigns them from the ZynqMP & Versal macros/phase-list. And then finally copies them over the common iclk_phase & oclk_phase variables. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 25 ++--- 1 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index db9b544..90e42d1 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -1025,7 +1025,6 @@ static void arasan_dt_read_clk_phase(struct device *dev, static void arasan_dt_parse_clk_phases(struct device *dev, struct sdhci_arasan_clk_data *clk_data) { - int *iclk_phase, *oclk_phase; u32 mio_bank = 0; int i; @@ -1037,28 +1036,32 @@ static void arasan_dt_parse_clk_phases(struct device *dev, clk_data->set_clk_delays = sdhci_arasan_set_clk_delays; if (of_device_is_compatible(dev->of_node, "xlnx,zynqmp-8.9a")) { - iclk_phase = (int [MMC_TIMING_MMC_HS400 + 1]) ZYNQMP_ICLK_PHASE; - oclk_phase = (int [MMC_TIMING_MMC_HS400 + 1]) ZYNQMP_OCLK_PHASE; + u32 zynqmp_iclk_phase[MMC_TIMING_MMC_HS400 + 1] = + ZYNQMP_ICLK_PHASE; + u32 zynqmp_oclk_phase[MMC_TIMING_MMC_HS400 + 1] = + ZYNQMP_OCLK_PHASE; of_property_read_u32(dev->of_node, "xlnx,mio-bank", _bank); if (mio_bank == 2) { - oclk_phase[MMC_TIMING_UHS_SDR104] = 90; - oclk_phase[MMC_TIMING_MMC_HS200] = 90; + zynqmp_oclk_phase[MMC_TIMING_UHS_SDR104] = 90; + zynqmp_oclk_phase[MMC_TIMING_MMC_HS200] = 90; } for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) { - clk_data->clk_phase_in[i] = iclk_phase[i]; - clk_data->clk_phase_out[i] = oclk_phase[i]; + clk_data->clk_phase_in[i] = zynqmp_iclk_phase[i]; + clk_data->clk_phase_out[i] = zynqmp_oclk_phase[i]; } } if (of_device_is_compatible(dev->of_node, "xlnx,versal-8.9a")) { - iclk_phase = (int [MMC_TIMING_MMC_HS400 + 1]) VERSAL_ICLK_PHASE; - oclk_phase = (int [MMC_TIMING_MMC_HS400 + 1]) VERSAL_OCLK_PHASE; + u32 versal_iclk_phase[MMC_TIMING_MMC_HS400 + 1] = + VERSAL_ICLK_PHASE; + u32 versal_oclk_phase[MMC_TIMING_MMC_HS400 + 1] = + VERSAL_OCLK_PHASE; for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) { - clk_data->clk_phase_in[i] = iclk_phase[i]; - clk_data->clk_phase_out[i] = oclk_phase[i]; + clk_data->clk_phase_in[i] = versal_iclk_phase[i]; + clk_data->clk_phase_out[i] = versal_oclk_phase[i]; } } -- 1.7.1
RE: [PATCH v3 4/8] dt-bindings: mmc: arasan: Add optional properties for Arasan SDHCI
Hi Rob, Thank you so much for the review. Please find my comments inline below. Thanks, Manish > -Original Message- > From: Rob Herring > Sent: Thursday, October 17, 2019 11:53 PM > To: Manish Narani > Cc: ulf.hans...@linaro.org; mark.rutl...@arm.com; adrian.hun...@intel.com; > Michal Simek ; Jolly Shah ; Rajan > Vaja ; Nava kishore Manne ; > m...@kernel.org; linux-...@vger.kernel.org; devicet...@vger.kernel.org; > linux-kernel@vger.kernel.org; linux-arm-ker...@lists.infradead.org; git > > Subject: Re: [PATCH v3 4/8] dt-bindings: mmc: arasan: Add optional properties > for Arasan SDHCI > > On Thu, Oct 17, 2019 at 11:51:46AM +0530, Manish Narani wrote: > > Add optional propeties for Arasan SDHCI which are used to set clk delays > > properties > > > for different speed modes in the controller. > > > > Signed-off-by: Manish Narani > > --- > > .../devicetree/bindings/mmc/arasan,sdhci.txt | 15 +++ > > 1 file changed, 15 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > index b51e40b2e0c5..e0369dd7fb18 100644 > > --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > @@ -46,6 +46,21 @@ Optional Properties: > > properly. Test mode can be used to force the controller to function. > >- xlnx,int-clock-stable-broken: when present, the controller always > > reports > > that the internal clock is stable even when it is not. > > + - clk-phase-legacy: Input/Output Clock Delay pair in degrees for Legacy > Mode. > > + - clk-phase-mmc-hs: Input/Output Clock Delay pair degrees for MMC HS. > > + - clk-phase-sd-hs: Input/Output Clock Delay pair in degrees for SD HS. > > + - clk-phase-uhs-sdr12: Input/Output Clock Delay pair in degrees for > > SDR12. > > + - clk-phase-uhs-sdr25: Input/Output Clock Delay pair in degrees for > > SDR25. > > + - clk-phase-uhs-sdr50: Input/Output Clock Delay pair in degrees for > > SDR50. > > + - clk-phase-uhs-sdr104: Input/Output Clock Delay pair in degrees for > SDR104. > > + - clk-phase-uhs-ddr50: Input/Output Clock Delay pair in degrees for SD > DDR50. > > + - clk-phase-mmc-ddr52: Input/Output Clock Delay pair in degrees for MMC > DDR52. > > + - clk-phase-mmc-hs200: Input/Output Clock Delay pair in degrees for MMC > HS200. > > + - clk-phase-mmc-hs400: Input/Output Clock Delay pair in degrees for MMC > HS400. > > Should be common? Yes, these properties should be common. > > Range of values? As these values are in degrees, the range of values is 0 to 359 degrees. Thanks, Manish
[PATCH v3] arm64: zynqmp: Add ZynqMP SDHCI compatible string
Add the new compatible string for ZynqMP SD Host Controller for its use in the Arasan SDHCI driver for some of the ZynqMP specific operations. Add required properties for the same. Signed-off-by: Manish Narani --- This patch depends on the below series of patches: https://lkml.org/lkml/2019/10/17/37 Changes in v2: - Added clock-names for SD card clocks for getting clocks in the driver Changes in v3: - Reverted "Added clock-names for SD card clocks for getting clocks in the driver" --- arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 9aa67340a4d8..c7b8c3c28aa7 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -494,20 +494,26 @@ sdhci0: mmc@ff16 { compatible = "arasan,sdhci-8.9a"; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; interrupt-parent = <>; interrupts = <0 48 4>; reg = <0x0 0xff16 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; + #clock-cells = <1>; + clock-output-names = "clk_out_sd0", "clk_in_sd0"; }; sdhci1: mmc@ff17 { compatible = "arasan,sdhci-8.9a"; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; interrupt-parent = <>; interrupts = <0 49 4>; reg = <0x0 0xff17 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; + #clock-cells = <1>; + clock-output-names = "clk_out_sd1", "clk_in_sd1"; }; smmu: smmu@fd80 { -- 2.17.1
[PATCH v3 7/8] dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller
dd documentation for 'xlnx,zynqmp-8.9a' SDHCI controller and optional properties followed by example. Signed-off-by: Manish Narani Reviewed-by: Rob Herring --- .../devicetree/bindings/mmc/arasan,sdhci.txt | 19 +++ 1 file changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index e0369dd7fb18..c3ee86b819f3 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -15,6 +15,9 @@ Required Properties: - "arasan,sdhci-5.1": generic Arasan SDHCI 5.1 PHY - "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1": rk3399 eMMC PHY For this device it is strongly suggested to include arasan,soc-ctl-syscon. +- "xlnx,zynqmp-8.9a": ZynqMP SDHCI 8.9a PHY + For this device it is strongly suggested to include clock-output-names and + #clock-cells. - "ti,am654-sdhci-5.1", "arasan,sdhci-5.1": TI AM654 MMC PHY Note: This binding has been deprecated and moved to [5]. - "intel,lgm-sdhci-5.1-emmc", "arasan,sdhci-5.1": Intel LGM eMMC PHY @@ -62,6 +65,10 @@ Optional Properties: controller while switching to particular speed mode. If not specified, driver will configure the default value defined for particular mode in it. + - xlnx,mio-bank: When specified, this will indicate the MIO bank number in +which the command and data lines are configured. If not specified, driver +will assume this as 0. + Example: sdhci@e010 { compatible = "arasan,sdhci-8.9a"; @@ -98,6 +105,18 @@ Example: #clock-cells = <0>; }; + sdhci: mmc@ff16 { + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; + interrupt-parent = <>; + interrupts = <0 48 4>; + reg = <0x0 0xff16 0x0 0x1000>; + clocks = <>, <>; + clock-names = "clk_xin", "clk_ahb"; + clock-output-names = "clk_out_sd0", "clk_in_sd0"; + #clock-cells = <1>; + clk-phase-sd-hs = <63>, <72>; + }; + emmc: sdhci@ec70 { compatible = "intel,lgm-sdhci-5.1-emmc", "arasan,sdhci-5.1"; reg = <0xec70 0x300>; -- 2.17.1
[PATCH v3 6/8] firmware: xilinx: Add SDIO Tap Delay nodes
Add tap delay nodes for setting SDIO Tap Delays on ZynqMP platform. Signed-off-by: Manish Narani --- include/linux/firmware/xlnx-zynqmp.h | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 778abbbc7d94..df366f1a4cb4 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -91,7 +91,8 @@ enum pm_ret_status { }; enum pm_ioctl_id { - IOCTL_SET_PLL_FRAC_MODE = 8, + IOCTL_SET_SD_TAPDELAY = 7, + IOCTL_SET_PLL_FRAC_MODE, IOCTL_GET_PLL_FRAC_MODE, IOCTL_SET_PLL_FRAC_DATA, IOCTL_GET_PLL_FRAC_DATA, @@ -250,6 +251,16 @@ enum zynqmp_pm_request_ack { ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING, }; +enum pm_node_id { + NODE_SD_0 = 39, + NODE_SD_1, +}; + +enum tap_delay_type { + PM_TAPDELAY_INPUT = 0, + PM_TAPDELAY_OUTPUT, +}; + /** * struct zynqmp_pm_query_data - PM query data * @qid: query ID -- 2.17.1
[PATCH v3 4/8] dt-bindings: mmc: arasan: Add optional properties for Arasan SDHCI
Add optional propeties for Arasan SDHCI which are used to set clk delays for different speed modes in the controller. Signed-off-by: Manish Narani --- .../devicetree/bindings/mmc/arasan,sdhci.txt | 15 +++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index b51e40b2e0c5..e0369dd7fb18 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -46,6 +46,21 @@ Optional Properties: properly. Test mode can be used to force the controller to function. - xlnx,int-clock-stable-broken: when present, the controller always reports that the internal clock is stable even when it is not. + - clk-phase-legacy: Input/Output Clock Delay pair in degrees for Legacy Mode. + - clk-phase-mmc-hs: Input/Output Clock Delay pair degrees for MMC HS. + - clk-phase-sd-hs: Input/Output Clock Delay pair in degrees for SD HS. + - clk-phase-uhs-sdr12: Input/Output Clock Delay pair in degrees for SDR12. + - clk-phase-uhs-sdr25: Input/Output Clock Delay pair in degrees for SDR25. + - clk-phase-uhs-sdr50: Input/Output Clock Delay pair in degrees for SDR50. + - clk-phase-uhs-sdr104: Input/Output Clock Delay pair in degrees for SDR104. + - clk-phase-uhs-ddr50: Input/Output Clock Delay pair in degrees for SD DDR50. + - clk-phase-mmc-ddr52: Input/Output Clock Delay pair in degrees for MMC DDR52. + - clk-phase-mmc-hs200: Input/Output Clock Delay pair in degrees for MMC HS200. + - clk-phase-mmc-hs400: Input/Output Clock Delay pair in degrees for MMC HS400. + + Above mentioned are the clock (phase) delays which are to be configured in the + controller while switching to particular speed mode. If not specified, driver + will configure the default value defined for particular mode in it. Example: sdhci@e010 { -- 2.17.1
[PATCH v3 2/8] dt-bindings: mmc: arasan: Update Documentation for the input clock
Add documentation for an optional input clock which is essentially used in sampling the input data coming from the card. Signed-off-by: Manish Narani --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 7ca0aa7ccc0b..b51e40b2e0c5 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -38,9 +38,9 @@ Optional Properties: - clock-output-names: If specified, this will be the name of the card clock which will be exposed by this device. Required if #clock-cells is specified. - - #clock-cells: If specified this should be the value <0>. With this property -in place we will export a clock representing the Card Clock. This clock -is expected to be consumed by our PHY. You must also specify + - #clock-cells: If specified this should be the value <0> or <1>. With this +property in place we will export one or two clocks representing the Card +Clock. These clocks are expected to be consumed by our PHY. - xlnx,fails-without-test-cd: when present, the controller doesn't work when the CD line is not connected properly, and the line is not connected properly. Test mode can be used to force the controller to function. -- 2.17.1
[PATCH v3 3/8] mmc: sdhci-of-arasan: Add sampling clock for a phy to use
There are some operations like setting the clock delays may need to have two clocks, one for output path and one for input path. Adding input path clock for some phys to use. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 151 + 1 file changed, 134 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 701b6cc0f9a3..f77f884f44a4 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -75,10 +75,14 @@ struct sdhci_arasan_soc_ctl_map { * struct sdhci_arasan_clk_data * @sdcardclk_hw: Struct for the clock we might provide to a PHY. * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. + * @sampleclk_hw: Struct for the clock we might provide to a PHY. + * @sampleclk: Pointer to normal 'struct clock' for sampleclk_hw. */ struct sdhci_arasan_clk_data { struct clk_hw sdcardclk_hw; struct clk *sdcardclk; + struct clk_hw sampleclk_hw; + struct clk *sampleclk; }; /** @@ -541,6 +545,33 @@ static const struct clk_ops arasan_sdcardclk_ops = { .recalc_rate = sdhci_arasan_sdcardclk_recalc_rate, }; +/** + * sdhci_arasan_sampleclk_recalc_rate - Return the sampling clock rate + * + * Return the current actual rate of the sampling clock. This can be used + * to communicate with out PHY. + * + * @hw:Pointer to the hardware clock structure. + * @parent_rateThe parent rate (should be rate of clk_xin). + * Returns the sample clock rate. + */ +static unsigned long sdhci_arasan_sampleclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) + +{ + struct sdhci_arasan_clk_data *clk_data = + container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw); + struct sdhci_arasan_data *sdhci_arasan = + container_of(clk_data, struct sdhci_arasan_data, clk_data); + struct sdhci_host *host = sdhci_arasan->host; + + return host->mmc->actual_clock; +} + +static const struct clk_ops arasan_sampleclk_ops = { + .recalc_rate = sdhci_arasan_sampleclk_recalc_rate, +}; + /** * sdhci_arasan_update_clockmultiplier - Set corecfg_clockmultiplier * @@ -620,28 +651,21 @@ static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host) } /** - * sdhci_arasan_register_sdclk - Register the sdclk for a PHY to use + * sdhci_arasan_register_sdcardclk - Register the sdcardclk for a PHY to use * * Some PHY devices need to know what the actual card clock is. In order for * them to find out, we'll provide a clock through the common clock framework * for them to query. * - * Note: without seriously re-architecting SDHCI's clock code and testing on - * all platforms, there's no way to create a totally beautiful clock here - * with all clock ops implemented. Instead, we'll just create a clock that can - * be queried and set the CLK_GET_RATE_NOCACHE attribute to tell common clock - * framework that we're doing things behind its back. This should be sufficient - * to create nice clean device tree bindings and later (if needed) we can try - * re-architecting SDHCI if we see some benefit to it. - * * @sdhci_arasan: Our private data structure. * @clk_xin: Pointer to the functional clock * @dev: Pointer to our struct device. * Returns 0 on success and error value on error */ -static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, - struct clk *clk_xin, - struct device *dev) +static int +sdhci_arasan_register_sdcardclk(struct sdhci_arasan_data *sdhci_arasan, + struct clk *clk_xin, + struct device *dev) { struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; struct device_node *np = dev->of_node; @@ -649,10 +673,6 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, const char *parent_clk_name; int ret; - /* Providing a clock to the PHY is optional; no error if missing */ - if (!of_find_property(np, "#clock-cells", NULL)) - return 0; - ret = of_property_read_string_index(np, "clock-output-names", 0, _init.name); if (ret) { @@ -674,7 +694,56 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, ret = of_clk_add_provider(np, of_clk_src_simple_get, clk_data->sdcardclk); if (ret) - dev_err(dev, "Failed to add clock provider\n"); + dev_err(dev, "Failed to add sdcard clock provider\n"); + + return ret; +} + +/** + * sdhci_ar
[PATCH v3 1/8] mmc: sdhci-of-arasan: Separate out clk related data to another structure
To improve the code readability, use two different structs, one for clock provider data and one for mmc platform data. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 31 -- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 7023cbec4017..701b6cc0f9a3 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -71,14 +71,23 @@ struct sdhci_arasan_soc_ctl_map { boolhiword_update; }; +/** + * struct sdhci_arasan_clk_data + * @sdcardclk_hw: Struct for the clock we might provide to a PHY. + * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. + */ +struct sdhci_arasan_clk_data { + struct clk_hw sdcardclk_hw; + struct clk *sdcardclk; +}; + /** * struct sdhci_arasan_data * @host: Pointer to the main SDHCI host structure. * @clk_ahb: Pointer to the AHB clock * @phy: Pointer to the generic phy * @is_phy_on: True if the PHY is on; false if not. - * @sdcardclk_hw: Struct for the clock we might provide to a PHY. - * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. + * @clk_data: Struct for the Arasan Controller Clock Data. * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers. * @soc_ctl_map: Map to get offsets into soc_ctl registers. */ @@ -89,8 +98,7 @@ struct sdhci_arasan_data { boolis_phy_on; boolhas_cqe; - struct clk_hw sdcardclk_hw; - struct clk *sdcardclk; + struct sdhci_arasan_clk_data clk_data; struct regmap *soc_ctl_base; const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; @@ -520,8 +528,10 @@ static unsigned long sdhci_arasan_sdcardclk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { + struct sdhci_arasan_clk_data *clk_data = + container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); struct sdhci_arasan_data *sdhci_arasan = - container_of(hw, struct sdhci_arasan_data, sdcardclk_hw); + container_of(clk_data, struct sdhci_arasan_data, clk_data); struct sdhci_host *host = sdhci_arasan->host; return host->mmc->actual_clock; @@ -633,6 +643,7 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, struct clk *clk_xin, struct device *dev) { + struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; struct device_node *np = dev->of_node; struct clk_init_data sdcardclk_init; const char *parent_clk_name; @@ -655,13 +666,13 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, sdcardclk_init.flags = CLK_GET_RATE_NOCACHE; sdcardclk_init.ops = _sdcardclk_ops; - sdhci_arasan->sdcardclk_hw.init = _init; - sdhci_arasan->sdcardclk = - devm_clk_register(dev, _arasan->sdcardclk_hw); - sdhci_arasan->sdcardclk_hw.init = NULL; + clk_data->sdcardclk_hw.init = _init; + clk_data->sdcardclk = + devm_clk_register(dev, _data->sdcardclk_hw); + clk_data->sdcardclk_hw.init = NULL; ret = of_clk_add_provider(np, of_clk_src_simple_get, - sdhci_arasan->sdcardclk); + clk_data->sdcardclk); if (ret) dev_err(dev, "Failed to add clock provider\n"); -- 2.17.1
[PATCH v3 8/8] mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup
Apart from taps set by auto tuning, ZynqMP platform has feature to set the tap values manually. Add support to set tap delay values in HW via ZynqMP SoC framework. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 206 - 1 file changed, 204 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 9b2b7b6399b3..45cde17da5a2 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "cqhci.h" #include "sdhci-pltfm.h" @@ -32,6 +33,10 @@ #define PHY_CLK_TOO_SLOW_HZ40 +/* Default settings for ZynqMP Clock Phases */ +#define ZYNQMP_ICLK_PHASE {0, 63, 63, 0, 63, 0, 0, 183, 54, 0, 0} +#define ZYNQMP_OCLK_PHASE {0, 60, 72, 0, 60, 72, 135, 180, 72, 36, 0} + /* * On some SoCs the syscon area has a feature where the upper 16-bits of * each 32-bit register act as a write mask for the lower 16-bits. This allows @@ -80,6 +85,7 @@ struct sdhci_arasan_soc_ctl_map { * @clk_phase_in: Array of Input Clock Phase Delays for all speed modes * @clk_phase_out: Array of Output Clock Phase Delays for all speed modes * @set_clk_delays:Function pointer for setting Clock Delays + * @clk_of_data: Platform specific runtime clock data storage pointer */ struct sdhci_arasan_clk_data { struct clk_hw sdcardclk_hw; @@ -89,6 +95,11 @@ struct sdhci_arasan_clk_data { int clk_phase_in[MMC_TIMING_MMC_HS400 + 1]; int clk_phase_out[MMC_TIMING_MMC_HS400 + 1]; void(*set_clk_delays)(struct sdhci_host *host); + void*clk_of_data; +}; + +struct sdhci_arasan_zynqmp_clk_data { + const struct zynqmp_eemi_ops *eemi_ops; }; /** @@ -525,6 +536,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = { .compatible = "arasan,sdhci-4.9a", .data = _arasan_data, }, + { + .compatible = "xlnx,zynqmp-8.9a", + .data = _arasan_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match); @@ -583,6 +598,150 @@ static const struct clk_ops arasan_sampleclk_ops = { .recalc_rate = sdhci_arasan_sampleclk_recalc_rate, }; +/** + * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays + * + * Set the SD Output Clock Tap Delays for Output path + * + * @hw:Pointer to the hardware clock structure. + * @degreesThe clock phase shift between 0 - 359. + * Return: 0 on success and error value on error + */ +static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) + +{ + struct sdhci_arasan_clk_data *clk_data = + container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); + struct sdhci_arasan_data *sdhci_arasan = + container_of(clk_data, struct sdhci_arasan_data, clk_data); + struct sdhci_host *host = sdhci_arasan->host; + struct sdhci_arasan_zynqmp_clk_data *zynqmp_clk_data = + clk_data->clk_of_data; + const struct zynqmp_eemi_ops *eemi_ops = zynqmp_clk_data->eemi_ops; + const char *clk_name = clk_hw_get_name(hw); + u32 node_id = !strcmp(clk_name, "clk_out_sd0") ? NODE_SD_0 : NODE_SD_1; + u8 tap_delay, tap_max = 0; + int ret; + + /* +* This is applicable for SDHCI_SPEC_300 and above +* ZynqMP does not set phase for <=25MHz clock. +* If degrees is zero, no need to do anything. +*/ + if (host->version < SDHCI_SPEC_300 || + host->timing == MMC_TIMING_LEGACY || + host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + return 0; + + switch (host->timing) { + case MMC_TIMING_MMC_HS: + case MMC_TIMING_SD_HS: + case MMC_TIMING_UHS_SDR25: + case MMC_TIMING_UHS_DDR50: + case MMC_TIMING_MMC_DDR52: + /* For 50MHz clock, 30 Taps are available */ + tap_max = 30; + break; + case MMC_TIMING_UHS_SDR50: + /* For 100MHz clock, 15 Taps are available */ + tap_max = 15; + break; + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_MMC_HS200: + /* For 200MHz clock, 8 Taps are available */ + tap_max = 8; + default: + break; + } + + tap_delay = (degrees * tap_max) / 360; + + /* Set the Clock Phase */ + ret = eemi_ops->ioctl(node_id, IOCTL_SET_SD_TAPDELAY, + PM_TAPDELAY_OUTPUT, tap_delay, NULL); + if (ret) + pr_err("Error setting Output Tap Delay\n"); + + return ret; +} + +static const struct clk_ops zynqmp_sdcar
[PATCH v3 5/8] mmc: sdhci-of-arasan: Add support to set clock phase delays for SD
Add support to read Clock Phase Delays from the DT and set it via clk_set_phase() API from clock framework. Some of the controllers might have their own handling of setting clock delays, for this keep the set_clk_delays as function pointer which can be assigned controller specific handling of the same. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 91 ++ 1 file changed, 91 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index f77f884f44a4..9b2b7b6399b3 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -77,12 +77,18 @@ struct sdhci_arasan_soc_ctl_map { * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. * @sampleclk_hw: Struct for the clock we might provide to a PHY. * @sampleclk: Pointer to normal 'struct clock' for sampleclk_hw. + * @clk_phase_in: Array of Input Clock Phase Delays for all speed modes + * @clk_phase_out: Array of Output Clock Phase Delays for all speed modes + * @set_clk_delays:Function pointer for setting Clock Delays */ struct sdhci_arasan_clk_data { struct clk_hw sdcardclk_hw; struct clk *sdcardclk; struct clk_hw sampleclk_hw; struct clk *sampleclk; + int clk_phase_in[MMC_TIMING_MMC_HS400 + 1]; + int clk_phase_out[MMC_TIMING_MMC_HS400 + 1]; + void(*set_clk_delays)(struct sdhci_host *host); }; /** @@ -186,6 +192,7 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); + struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; bool ctrl_phy = false; if (!IS_ERR(sdhci_arasan->phy)) { @@ -227,6 +234,10 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_arasan->is_phy_on = false; } + /* Set the Input and Output Clock Phase Delays */ + if (clk_data->set_clk_delays) + clk_data->set_clk_delays(host); + sdhci_set_clock(host, clock); if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE) @@ -650,6 +661,84 @@ static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host) sdhci_arasan_syscon_write(host, _ctl_map->baseclkfreq, mhz); } +static void sdhci_arasan_set_clk_delays(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); + struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; + + clk_set_phase(clk_data->sampleclk, + clk_data->clk_phase_in[host->timing]); + clk_set_phase(clk_data->sdcardclk, + clk_data->clk_phase_out[host->timing]); +} + +static void arasan_dt_read_clk_phase(struct device *dev, +struct sdhci_arasan_clk_data *clk_data, +unsigned int timing, const char *prop) +{ + struct device_node *np = dev->of_node; + + int clk_phase[2] = {0}; + + /* +* Read Tap Delay values from DT, if the DT does not contain the +* Tap Values then use the pre-defined values. +*/ + if (of_property_read_variable_u32_array(np, prop, _phase[0], + 2, 0)) { + dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n", + prop, clk_data->clk_phase_in[timing], + clk_data->clk_phase_out[timing]); + return; + } + + /* The values read are Input and Output Clock Delays in order */ + clk_data->clk_phase_in[timing] = clk_phase[0]; + clk_data->clk_phase_out[timing] = clk_phase[1]; +} + +/** + * arasan_dt_parse_clk_phases - Read Clock Delay values from DT + * + * Called at initialization to parse the values of Clock Delays. + * + * @dev: Pointer to our struct device. + */ +static void arasan_dt_parse_clk_phases(struct device *dev, + struct sdhci_arasan_clk_data *clk_data) +{ + /* +* This has been kept as a pointer and is assigned a function here. +* So that different controller variants can assign their own handling +* function. +*/ + clk_data->set_clk_delays = sdhci_arasan_set_clk_delays; + + arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_LEGACY, +"clk-phase-legacy"); + arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_HS, +"clk-phase-mmc-hs"); + arasan_dt_rea
[PATCH v3 0/8] Arasan SDHCI enhancements and ZynqMP Tap Delays Handling
This patch series does the following: - Reorganize the Clock Handling in Arasan SD driver - Adds new sampling clock in Arasan SD driver - Adds support to set Clock Delays in SD Arasan Driver - Add SDIO Tap Delay handling in ZynqMP firmware driver - Add support for ZynqMP Tap Delays setting in Arasan SD driver Changes in v2: - Replaced the deprecated calls to clock framework APIs - Added support for dev_clk_get() call to work for SD card clock - Separated the clock data struct - Fragmented the patch series in smaller patches to make it more readable Changes in v3: - Reverted "Replaced the deprecated calls to clock framework APIs" - Removed devm_clk_get() call which was added in v2 Manish Narani (8): mmc: sdhci-of-arasan: Separate out clk related data to another structure dt-bindings: mmc: arasan: Update Documentation for the input clock mmc: sdhci-of-arasan: Add sampling clock for a phy to use dt-bindings: mmc: arasan: Add optional properties for Arasan SDHCI mmc: sdhci-of-arasan: Add support to set clock phase delays for SD firmware: xilinx: Add SDIO Tap Delay nodes dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup .../devicetree/bindings/mmc/arasan,sdhci.txt | 40 +- drivers/mmc/host/sdhci-of-arasan.c| 477 +- include/linux/firmware/xlnx-zynqmp.h | 13 +- 3 files changed, 498 insertions(+), 32 deletions(-) -- 2.17.1
RE: [PATCH v2 01/11] dt-bindings: mmc: arasan: Update documentation for SD Card Clock
Hi Heiko/Uffe, > -Original Message- > From: Heiko Stuebner > Sent: Thursday, August 22, 2019 11:53 PM > To: Ulf Hansson ; linux-...@vger.kernel.org > Cc: Manish Narani ; Rob Herring ; > mark.rutl...@arm.com; Michal Simek ; > adrian.hun...@intel.com; christoph.muell...@theobroma-systems.com; > philipp.toms...@theobroma-systems.com; viresh.ku...@linaro.org; > scott.bran...@broadcom.com; ay...@soulik.info; ker...@esmil.dk; > tony@rock-chips.com; Rajan Vaja ; > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-rockc...@lists.infradead.org > Subject: Re: [PATCH v2 01/11] dt-bindings: mmc: arasan: Update > documentation for SD Card Clock > > Am Donnerstag, 22. August 2019, 15:38:26 CEST schrieb Ulf Hansson: > > [...] > > > > > > > > > --- > > > > > > > Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 15 > > > > ++- > > > > > > > > > > > > > 1 file changed, 10 insertions(+), 5 deletions(-) > > > > > > > > > > > > > > diff --git > a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > > > > b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > > > > > index 1edbb04..15c6397 100644 > > > > > > > --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > > > > > +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > > > > > @@ -23,6 +23,10 @@ Required Properties: > > > > > > >- reg: From mmc bindings: Register location and length. > > > > > > >- clocks: From clock bindings: Handles to clock inputs. > > > > > > >- clock-names: From clock bindings: Tuple including "clk_xin" > > > > > > > and > > > > "clk_ahb" > > > > > > > +Apart from these two there is one more optional clock > which > > > > > > > +is "clk_sdcard". This clock represents output clock > > > > > > > from > > > > > > > +controller and card. This must be specified when > > > > > > > #clock- > cells > > > > > > > +is specified. > > > > > > >- interrupts: Interrupt specifier > > > > > > > > > > > > > > Required Properties for "arasan,sdhci-5.1": > > > > > > > @@ -36,9 +40,10 @@ Optional Properties: > > > > > > >- clock-output-names: If specified, this will be the name of > > > > > > > the card > > > > clock > > > > > > > which will be exposed by this device. Required if > > > > > > > #clock-cells is > > > > > > > specified. > > > > > > > - - #clock-cells: If specified this should be the value <0>. > > > > > > > With this > > > > property > > > > > > > -in place we will export a clock representing the Card Clock. > > > > > > > This > clock > > > > > > > -is expected to be consumed by our PHY. You must also specify > > > > > > > + - #clock-cells: If specified this should be the value <0>. > > > > > > > With this > > > > > > > +property in place we will export one clock representing the > > > > > > > Card > > > > > > > +Clock. This clock is expected to be consumed by our PHY. You > must > > > > also > > > > > > > +specify > > > > > > > > > > > > specify what? > > > > > I think this line was already there, I missed to correct it, Will > > > > > update in > v3. > > > > > > > > > > > > > > > > > The 3rd clock input I assume? This statement means any existing > > > > > > users > > > > > > with 2 clock inputs and #clock-cells are in error now. Is that > > > > > > correct? > > > > > Yes, this is correct. So far there was only one vendor using > > > > > '#clock-cells' > > > > which is Rockchip. I have sent DT patch (02/11) for that also. > > > > > Here this is needed as earlier implementation isn't correct as > > > > > suggested > by > > > > Uffe. (https://lkml.org/lkml/2019/6/20/486) . > > > > > > > > I am not sure how big of a problem the backwards compatible thingy > > > > with DT is, in general we must not break it. What do you say Manish? > > > > > > Though I agree with Uffe on this, there is no other way from my > understanding. Please suggest. > > > > > > > > > > > As a workaround, would it be possible to use > > > > of_clk_get_from_provider() somehow to address the compatibility issue? > > > > > > For this to be used we have to parse 'clkspec' from the DT node and pass > the same as an argument to this function. In this case also the DT node needs > to > be updated, which is same as we have done in this series. > > > > Alright. I guess breaking DTBs for Rockchip platforms isn't > > acceptable, especially if those are already widely deployed, which I > > have no idea of > > The arasan sdhci is part of the rk3399, so every SBC using that SoC, but > also the whole Gru series of ChromeOS devices (Samsung Chromebook Plus > among them) would be affected. Thanks for confirming. This will be taken care of. I will go back to v1 changes and will send v3. Thanks, Manish
RE: [PATCH v2 01/11] dt-bindings: mmc: arasan: Update documentation for SD Card Clock
Hi Uffe, > -Original Message- > From: Ulf Hansson > Sent: Thursday, July 25, 2019 6:31 PM > To: Manish Narani > Cc: Rob Herring ; mark.rutl...@arm.com; > he...@sntech.de; Michal Simek ; > adrian.hun...@intel.com; christoph.muell...@theobroma-systems.com; > philipp.toms...@theobroma-systems.com; viresh.ku...@linaro.org; > scott.bran...@broadcom.com; ay...@soulik.info; ker...@esmil.dk; > tony@rock-chips.com; Rajan Vaja ; Jolly Shah > ; Nava kishore Manne ; > m...@kernel.org; o...@lixom.net; linux-...@vger.kernel.org; > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-rockc...@lists.infradead.org > Subject: Re: [PATCH v2 01/11] dt-bindings: mmc: arasan: Update > documentation for SD Card Clock > > On Tue, 23 Jul 2019 at 10:23, Manish Narani wrote: > > > > Hi Rob, > > > > Thanks a lot for the review! > > > > > > > -Original Message- > > > From: Rob Herring > > > Sent: Tuesday, July 23, 2019 3:24 AM > > > To: Manish Narani > > > Cc: ulf.hans...@linaro.org; mark.rutl...@arm.com; he...@sntech.de; > Michal > > > Simek ; adrian.hun...@intel.com; > > > christoph.muell...@theobroma-systems.com; philipp.tomsich@theobroma- > > > systems.com; viresh.ku...@linaro.org; scott.bran...@broadcom.com; > > > ay...@soulik.info; ker...@esmil.dk; tony@rock-chips.com; Rajan Vaja > > > ; Jolly Shah ; Nava kishore > Manne > > > ; m...@kernel.org; o...@lixom.net; linux- > > > m...@vger.kernel.org; devicet...@vger.kernel.org; linux- > > > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > > > rockc...@lists.infradead.org > > > Subject: Re: [PATCH v2 01/11] dt-bindings: mmc: arasan: Update > > > documentation for SD Card Clock > > > > > > On Mon, Jul 01, 2019 at 10:59:41AM +0530, Manish Narani wrote: > > > > The clock handling is to be updated in the Arasan SDHCI. As the > > > > 'devm_clk_register' is deprecated in the clock framework, this needs to > > > > specify one more clock named 'clk_sdcard' to get the clock in the driver > > > > via 'devm_clk_get()'. This clock represents the clock from controller to > > > > the card. > > > > > > Please explain why in terms of the binding, not some driver calls. > > Okay. > > > > > > > > > > > > Signed-off-by: Manish Narani > > > > --- > > > > Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 15 > ++- > > > > > > > 1 file changed, 10 insertions(+), 5 deletions(-) > > > > > > > > diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > > index 1edbb04..15c6397 100644 > > > > --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > > +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > > @@ -23,6 +23,10 @@ Required Properties: > > > >- reg: From mmc bindings: Register location and length. > > > >- clocks: From clock bindings: Handles to clock inputs. > > > >- clock-names: From clock bindings: Tuple including "clk_xin" and > "clk_ahb" > > > > +Apart from these two there is one more optional clock which > > > > +is "clk_sdcard". This clock represents output clock from > > > > +controller and card. This must be specified when > > > > #clock-cells > > > > +is specified. > > > >- interrupts: Interrupt specifier > > > > > > > > Required Properties for "arasan,sdhci-5.1": > > > > @@ -36,9 +40,10 @@ Optional Properties: > > > >- clock-output-names: If specified, this will be the name of the card > clock > > > > which will be exposed by this device. Required if #clock-cells is > > > > specified. > > > > - - #clock-cells: If specified this should be the value <0>. With this > property > > > > -in place we will export a clock representing the Card Clock. This > > > > clock > > > > -is expected to be consumed by our PHY. You must also specify > > > > + - #clock-cells: If specified this should be the value <0>. With this > > > > +property in place we will export one clock representing the Card > > > > +Clock. This clock is expected to be consumed by our
RE: [PATCH v2 01/11] dt-bindings: mmc: arasan: Update documentation for SD Card Clock
Hi Rob, Thanks a lot for the review! > -Original Message- > From: Rob Herring > Sent: Tuesday, July 23, 2019 3:24 AM > To: Manish Narani > Cc: ulf.hans...@linaro.org; mark.rutl...@arm.com; he...@sntech.de; Michal > Simek ; adrian.hun...@intel.com; > christoph.muell...@theobroma-systems.com; philipp.tomsich@theobroma- > systems.com; viresh.ku...@linaro.org; scott.bran...@broadcom.com; > ay...@soulik.info; ker...@esmil.dk; tony@rock-chips.com; Rajan Vaja > ; Jolly Shah ; Nava kishore Manne > ; m...@kernel.org; o...@lixom.net; linux- > m...@vger.kernel.org; devicet...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > rockc...@lists.infradead.org > Subject: Re: [PATCH v2 01/11] dt-bindings: mmc: arasan: Update > documentation for SD Card Clock > > On Mon, Jul 01, 2019 at 10:59:41AM +0530, Manish Narani wrote: > > The clock handling is to be updated in the Arasan SDHCI. As the > > 'devm_clk_register' is deprecated in the clock framework, this needs to > > specify one more clock named 'clk_sdcard' to get the clock in the driver > > via 'devm_clk_get()'. This clock represents the clock from controller to > > the card. > > Please explain why in terms of the binding, not some driver calls. Okay. > > > > Signed-off-by: Manish Narani > > --- > > Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 15 ++- > > > 1 file changed, 10 insertions(+), 5 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > index 1edbb04..15c6397 100644 > > --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > @@ -23,6 +23,10 @@ Required Properties: > >- reg: From mmc bindings: Register location and length. > >- clocks: From clock bindings: Handles to clock inputs. > >- clock-names: From clock bindings: Tuple including "clk_xin" and > > "clk_ahb" > > +Apart from these two there is one more optional clock which > > +is "clk_sdcard". This clock represents output clock from > > +controller and card. This must be specified when #clock-cells > > +is specified. > >- interrupts: Interrupt specifier > > > > Required Properties for "arasan,sdhci-5.1": > > @@ -36,9 +40,10 @@ Optional Properties: > >- clock-output-names: If specified, this will be the name of the card > > clock > > which will be exposed by this device. Required if #clock-cells is > > specified. > > - - #clock-cells: If specified this should be the value <0>. With this > > property > > -in place we will export a clock representing the Card Clock. This > > clock > > -is expected to be consumed by our PHY. You must also specify > > + - #clock-cells: If specified this should be the value <0>. With this > > +property in place we will export one clock representing the Card > > +Clock. This clock is expected to be consumed by our PHY. You must also > > +specify > > specify what? I think this line was already there, I missed to correct it, Will update in v3. > > The 3rd clock input I assume? This statement means any existing users > with 2 clock inputs and #clock-cells are in error now. Is that correct? Yes, this is correct. So far there was only one vendor using '#clock-cells' which is Rockchip. I have sent DT patch (02/11) for that also. Here this is needed as earlier implementation isn't correct as suggested by Uffe. (https://lkml.org/lkml/2019/6/20/486) . Thanks, Manish
RE: [PATCH v2 00/11] Arasan SDHCI enhancements and ZynqMP Tap Delays Handling
Gentle Ping! > -Original Message- > From: Manish Narani > Sent: Monday, July 15, 2019 12:46 PM > To: Manish Narani ; ulf.hans...@linaro.org; > robh...@kernel.org; mark.rutl...@arm.com; he...@sntech.de; Michal Simek > ; adrian.hun...@intel.com; > christoph.muell...@theobroma-systems.com; philipp.tomsich@theobroma- > systems.com; viresh.ku...@linaro.org; scott.bran...@broadcom.com; > ay...@soulik.info; ker...@esmil.dk; tony@rock-chips.com; > m...@kernel.org; o...@lixom.net > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > rockc...@lists.infradead.org > Subject: RE: [PATCH v2 00/11] Arasan SDHCI enhancements and ZynqMP Tap > Delays Handling > > Ping! > > > -Original Message- > > From: Manish Narani > > Sent: Monday, July 1, 2019 11:00 AM > > To: ulf.hans...@linaro.org; robh...@kernel.org; mark.rutl...@arm.com; > > he...@sntech.de; Michal Simek ; > > adrian.hun...@intel.com; christoph.muell...@theobroma-systems.com; > > philipp.toms...@theobroma-systems.com; viresh.ku...@linaro.org; > > scott.bran...@broadcom.com; ay...@soulik.info; ker...@esmil.dk; > > tony@rock-chips.com; Rajan Vaja ; Jolly Shah > > ; Nava kishore Manne ; > > m...@kernel.org; Manish Narani ; o...@lixom.net > > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux- > > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > > rockc...@lists.infradead.org > > Subject: [PATCH v2 00/11] Arasan SDHCI enhancements and ZynqMP Tap > > Delays Handling > > > > This patch series does the following: > > - Reorganize the Clock Handling in Arasan SD driver > > - Adds new sampling clock in Arasan SD driver > > - Adds support to set Clock Delays in SD Arasan Driver > > - Add SDIO Tap Delay handling in ZynqMP firmware driver > > - Add support for ZynqMP Tap Delays setting in Arasan SD driver > > > > Changes in v2: > > - Replaced the deprecated calls to clock framework APIs > > - Added support for dev_clk_get() call to work for SD card clock > > - Separated the clock data struct > > - Fragmented the patch series in smaller patches to make it more > > readable > > > > This patch series contains a DT patch, which I think should be there to > > maintain the order of commits. > > > > Manish Narani (11): > > dt-bindings: mmc: arasan: Update documentation for SD Card Clock > > arm64: dts: rockchip: Add optional clock property indicating sdcard > > clock > > mmc: sdhci-of-arasan: Replace deprecated clk API calls > > mmc: sdhci-of-arasan: Separate out clk related data to another > > structure > > dt-bindings: mmc: arasan: Update Documentation for the input clock > > mmc: sdhci-of-arasan: Add sampling clock for a phy to use > > dt-bindings: mmc: arasan: Add optional properties for Arasan SDHCI > > mmc: sdhci-of-arasan: Add support to set clock phase delays for SD > > firmware: xilinx: Add SDIO Tap Delay APIs > > dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller > > mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup > > > > .../devicetree/bindings/mmc/arasan,sdhci.txt | 49 ++- > > arch/arm64/boot/dts/rockchip/rk3399.dtsi | 4 +- > > drivers/firmware/xilinx/zynqmp.c | 48 +++ > > drivers/mmc/host/sdhci-of-arasan.c | 453 > - > > include/linux/firmware/xlnx-zynqmp.h | 15 +- > > 5 files changed, 540 insertions(+), 29 deletions(-) > > > > -- > > 2.1.1
RE: [PATCH v2 00/11] Arasan SDHCI enhancements and ZynqMP Tap Delays Handling
Ping! > -Original Message- > From: Manish Narani > Sent: Monday, July 1, 2019 11:00 AM > To: ulf.hans...@linaro.org; robh...@kernel.org; mark.rutl...@arm.com; > he...@sntech.de; Michal Simek ; > adrian.hun...@intel.com; christoph.muell...@theobroma-systems.com; > philipp.toms...@theobroma-systems.com; viresh.ku...@linaro.org; > scott.bran...@broadcom.com; ay...@soulik.info; ker...@esmil.dk; > tony@rock-chips.com; Rajan Vaja ; Jolly Shah > ; Nava kishore Manne ; > m...@kernel.org; Manish Narani ; o...@lixom.net > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > rockc...@lists.infradead.org > Subject: [PATCH v2 00/11] Arasan SDHCI enhancements and ZynqMP Tap > Delays Handling > > This patch series does the following: > - Reorganize the Clock Handling in Arasan SD driver > - Adds new sampling clock in Arasan SD driver > - Adds support to set Clock Delays in SD Arasan Driver > - Add SDIO Tap Delay handling in ZynqMP firmware driver > - Add support for ZynqMP Tap Delays setting in Arasan SD driver > > Changes in v2: > - Replaced the deprecated calls to clock framework APIs > - Added support for dev_clk_get() call to work for SD card clock > - Separated the clock data struct > - Fragmented the patch series in smaller patches to make it more > readable > > This patch series contains a DT patch, which I think should be there to > maintain the order of commits. > > Manish Narani (11): > dt-bindings: mmc: arasan: Update documentation for SD Card Clock > arm64: dts: rockchip: Add optional clock property indicating sdcard > clock > mmc: sdhci-of-arasan: Replace deprecated clk API calls > mmc: sdhci-of-arasan: Separate out clk related data to another > structure > dt-bindings: mmc: arasan: Update Documentation for the input clock > mmc: sdhci-of-arasan: Add sampling clock for a phy to use > dt-bindings: mmc: arasan: Add optional properties for Arasan SDHCI > mmc: sdhci-of-arasan: Add support to set clock phase delays for SD > firmware: xilinx: Add SDIO Tap Delay APIs > dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller > mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup > > .../devicetree/bindings/mmc/arasan,sdhci.txt | 49 ++- > arch/arm64/boot/dts/rockchip/rk3399.dtsi | 4 +- > drivers/firmware/xilinx/zynqmp.c | 48 +++ > drivers/mmc/host/sdhci-of-arasan.c | 453 > - > include/linux/firmware/xlnx-zynqmp.h | 15 +- > 5 files changed, 540 insertions(+), 29 deletions(-) > > -- > 2.1.1
RE: [PATCH v2 09/11] firmware: xilinx: Add SDIO Tap Delay APIs
Hi Jolly, > -Original Message- > From: Jolly Shah > Sent: Monday, July 1, 2019 11:36 PM > To: Manish Narani ; ulf.hans...@linaro.org; > robh...@kernel.org; mark.rutl...@arm.com; he...@sntech.de; Michal Simek > ; adrian.hun...@intel.com; > christoph.muell...@theobroma-systems.com; philipp.tomsich@theobroma- > systems.com; viresh.ku...@linaro.org; scott.bran...@broadcom.com; > ay...@soulik.info; ker...@esmil.dk; tony@rock-chips.com; Rajan Vaja > ; Nava kishore Manne ; > m...@kernel.org; Manish Narani ; o...@lixom.net > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > rockc...@lists.infradead.org > Subject: RE: [PATCH v2 09/11] firmware: xilinx: Add SDIO Tap Delay APIs > > Hi Manish, > > > -Original Message- > > From: Manish Narani > > Sent: Sunday, June 30, 2019 10:30 PM > > To: ulf.hans...@linaro.org; robh...@kernel.org; mark.rutl...@arm.com; > > he...@sntech.de; Michal Simek ; > > adrian.hun...@intel.com; christoph.muell...@theobroma-systems.com; > > philipp.toms...@theobroma-systems.com; viresh.ku...@linaro.org; > > scott.bran...@broadcom.com; ay...@soulik.info; ker...@esmil.dk; > > tony@rock-chips.com; Rajan Vaja ; Jolly Shah > > ; Nava kishore Manne ; > > m...@kernel.org; Manish Narani ; o...@lixom.net > > Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org; linux- > > ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > > rockc...@lists.infradead.org > > Subject: [PATCH v2 09/11] firmware: xilinx: Add SDIO Tap Delay APIs > > > > Add APIs for setting SDIO Tap Delays on ZynqMP platform. > > > > Signed-off-by: Manish Narani > > --- > > drivers/firmware/xilinx/zynqmp.c | 48 > > > > include/linux/firmware/xlnx-zynqmp.h | 15 ++- > > 2 files changed, 62 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/firmware/xilinx/zynqmp.c > b/drivers/firmware/xilinx/zynqmp.c > > index fd3d837..b81f1be 100644 > > --- a/drivers/firmware/xilinx/zynqmp.c > > +++ b/drivers/firmware/xilinx/zynqmp.c > > @@ -664,6 +664,52 @@ static int zynqmp_pm_set_requirement(const u32 > > node, const u32 capabilities, > >qos, ack, NULL); > > } > > > > +/** > > + * zynqmp_pm_sdio_out_setphase() - PM call to set clock output delays for > SD > > + * @device_id: Device ID of the SD controller > > + * @tap_delay: Tap Delay value for output clock > > + * > > + * This API function is to be used for setting the clock output delays for > > SD > > + * clock. > > + * > > + * Return: Returns status, either success or error+reason > > + */ > > +static int zynqmp_pm_sdio_out_setphase(u32 device_id, u8 tap_delay) > > +{ > > + u32 node_id = (!device_id) ? NODE_SD_0 : NODE_SD_1; > > + int ret; > > + > > + ret = zynqmp_pm_ioctl(node_id, IOCTL_SET_SD_TAPDELAY, > > + PM_TAPDELAY_OUTPUT, tap_delay, NULL); > > + if (ret) > > + pr_err("Error setting Output Tap Delay\n"); > > + > > + return ret; > > +} > > + > > +/** > > + * zynqmp_pm_sdio_in_setphase() - PM call to set clock input delays for SD > > + * @device_id: Device ID of the SD controller > > + * @tap_delay: Tap Delay value for input clock > > + * > > + * This API function is to be used for setting the clock input delays for > > SD > > + * clock. > > + * > > + * Return: Returns status, either success or error+reason > > + */ > > +static int zynqmp_pm_sdio_in_setphase(u32 device_id, u8 tap_delay) > > +{ > > + u32 node_id = (!device_id) ? NODE_SD_0 : NODE_SD_1; > > + int ret; > > + > > + ret = zynqmp_pm_ioctl(node_id, IOCTL_SET_SD_TAPDELAY, > > + PM_TAPDELAY_INPUT, tap_delay, NULL); > > + if (ret) > > + pr_err("Error setting Input Tap Delay\n"); > > + > > + return ret; > > +} > > + > > static const struct zynqmp_eemi_ops eemi_ops = { > > .get_api_version = zynqmp_pm_get_api_version, > > .get_chipid = zynqmp_pm_get_chipid, > > @@ -687,6 +733,8 @@ static const struct zynqmp_eemi_ops eemi_ops = { > > .set_requirement = zynqmp_pm_set_requirement, > > .fpga_load = zynqmp_pm_fpga_load, > > .fpga_get_status = zynqmp_pm_fpga_get_status, > > + .sdio_out_setphase = zynqmp_pm_sdio_out_setphase, > > + .sdio_in_setphase = zynqmp_pm_sdio_in_setphase, > > Are these eemi APIs? You are using ioctl eemi api to set the delay. Yes, I am making these eemi APIs and calling ioctl API from these. This is to make the SD driver code more readable. Thanks, Manish
[PATCH v2] arm64: zynqmp: Add ZynqMP SDHCI compatible string
Add the new compatible string for ZynqMP SD Host Controller for its use in the Arasan SDHCI driver for some of the ZynqMP specific operations. Add required properties for the same. Signed-off-by: Manish Narani --- This patch depends on the below series of patches: https://lkml.org/lkml/2019/7/1/25 Changes in v2: - Added clock-names for SD card clocks for getting clocks in the driver --- arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi | 4 ++-- arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 14 ++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi index 306ad21..24c04a1 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi @@ -177,11 +177,11 @@ }; { - clocks = < >; + clocks = <>, <>, < 0>, < 1>; }; { - clocks = < >; + clocks = <>, <>, < 0>, < 1>; }; { diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 9aa6734..4c21346 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -493,21 +493,27 @@ }; sdhci0: mmc@ff16 { - compatible = "arasan,sdhci-8.9a"; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; interrupt-parent = <>; interrupts = <0 48 4>; reg = <0x0 0xff16 0x0 0x1000>; - clock-names = "clk_xin", "clk_ahb"; + clock-names = "clk_xin", "clk_ahb", + "clk_sdcard", "clk_sample"; + #clock-cells = <1>; + clock-output-names = "clk_out_sd0", "clk_in_sd0"; }; sdhci1: mmc@ff17 { - compatible = "arasan,sdhci-8.9a"; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; interrupt-parent = <>; interrupts = <0 49 4>; reg = <0x0 0xff17 0x0 0x1000>; - clock-names = "clk_xin", "clk_ahb"; + clock-names = "clk_xin", "clk_ahb", + "clk_sdcard", "clk_sample"; + #clock-cells = <1>; + clock-output-names = "clk_out_sd1", "clk_in_sd1"; }; smmu: smmu@fd80 { -- 2.1.1
[PATCH v2 07/11] dt-bindings: mmc: arasan: Add optional properties for Arasan SDHCI
Add optional propeties for Arasan SDHCI which are used to set clk delays for different speed modes in the controller. Signed-off-by: Manish Narani --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 15 +++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 7c79496..7425d52 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -49,6 +49,21 @@ Optional Properties: properly. Test mode can be used to force the controller to function. - xlnx,int-clock-stable-broken: when present, the controller always reports that the internal clock is stable even when it is not. + - clk-phase-legacy: Input/Output Clock Delay pair in degrees for Legacy Mode. + - clk-phase-mmc-hs: Input/Output Clock Delay pair degrees for MMC HS. + - clk-phase-sd-hs: Input/Output Clock Delay pair in degrees for SD HS. + - clk-phase-uhs-sdr12: Input/Output Clock Delay pair in degrees for SDR12. + - clk-phase-uhs-sdr25: Input/Output Clock Delay pair in degrees for SDR25. + - clk-phase-uhs-sdr50: Input/Output Clock Delay pair in degrees for SDR50. + - clk-phase-uhs-sdr104: Input/Output Clock Delay pair in degrees for SDR104. + - clk-phase-uhs-ddr50: Input/Output Clock Delay pair in degrees for SD DDR50. + - clk-phase-mmc-ddr52: Input/Output Clock Delay pair in degrees for MMC DDR52. + - clk-phase-mmc-hs200: Input/Output Clock Delay pair in degrees for MMC HS200. + - clk-phase-mmc-hs400: Input/Output Clock Delay pair in degrees for MMC HS400. + + Above mentioned are the clock (phase) delays which are to be configured in the + controller while switching to particular speed mode. If not specified, driver + will configure the default value defined for particular mode in it. Example: sdhci@e010 { -- 2.1.1
[PATCH v2 05/11] dt-bindings: mmc: arasan: Update Documentation for the input clock
Add documentation for an optional input clock which is essentially used in sampling the input data coming from the card. Signed-off-by: Manish Narani --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 15c6397..7c79496 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -23,10 +23,10 @@ Required Properties: - reg: From mmc bindings: Register location and length. - clocks: From clock bindings: Handles to clock inputs. - clock-names: From clock bindings: Tuple including "clk_xin" and "clk_ahb" -Apart from these two there is one more optional clock which -is "clk_sdcard". This clock represents output clock from -controller and card. This must be specified when #clock-cells -is specified. +Apart from these two there are two more optional clocks which +are "clk_sdcard" and "clk_sample". These two clocks represent +output and input clocks between controller and card. These +must be specified when #clock-cells is specified. - interrupts: Interrupt specifier Required Properties for "arasan,sdhci-5.1": @@ -40,9 +40,9 @@ Optional Properties: - clock-output-names: If specified, this will be the name of the card clock which will be exposed by this device. Required if #clock-cells is specified. - - #clock-cells: If specified this should be the value <0>. With this -property in place we will export one clock representing the Card -Clock. This clock is expected to be consumed by our PHY. You must also + - #clock-cells: If specified this should be the value <0> or <1>. With this +property in place we will export one or two clocks representing the Card +Clock. These clocks are expected to be consumed by our PHY. You must also specify - xlnx,fails-without-test-cd: when present, the controller doesn't work when the CD line is not connected properly, and the line is not connected -- 2.1.1
[PATCH v2 06/11] mmc: sdhci-of-arasan: Add sampling clock for a phy to use
There are some operations like setting the clock delays may need to have two clocks, one for output path and one for input path. Adding input path clock for some phys to use. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 118 ++--- 1 file changed, 110 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index c7586f5..9513813 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -75,10 +75,14 @@ struct sdhci_arasan_soc_ctl_map { * struct sdhci_arasan_clk_data * @sdcardclk_hw: Struct for the clock we might provide to a PHY. * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. + * @sampleclk_hw: Struct for the clock we might provide to a PHY. + * @sampleclk: Pointer to normal 'struct clock' for sampleclk_hw. */ struct sdhci_arasan_clk_data { struct clk_hw sdcardclk_hw; struct clk *sdcardclk; + struct clk_hw sampleclk_hw; + struct clk *sampleclk; }; /** @@ -527,6 +531,33 @@ static const struct clk_ops arasan_sdcardclk_ops = { }; /** + * sdhci_arasan_sampleclk_recalc_rate - Return the sampling clock rate + * + * Return the current actual rate of the sampling clock. This can be used + * to communicate with out PHY. + * + * @hw:Pointer to the hardware clock structure. + * @parent_rateThe parent rate (should be rate of clk_xin). + * Returns the sample clock rate. + */ +static unsigned long sdhci_arasan_sampleclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) + +{ + struct sdhci_arasan_clk_data *clk_data = + container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw); + struct sdhci_arasan_data *sdhci_arasan = + container_of(clk_data, struct sdhci_arasan_data, clk_data); + struct sdhci_host *host = sdhci_arasan->host; + + return host->mmc->actual_clock; +} + +static const struct clk_ops arasan_sampleclk_ops = { + .recalc_rate = sdhci_arasan_sampleclk_recalc_rate, +}; + +/** * sdhci_arasan_update_clockmultiplier - Set corecfg_clockmultiplier * * The corecfg_clockmultiplier is supposed to contain clock multiplier @@ -605,7 +636,7 @@ static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host) } /** - * sdhci_arasan_register_sdclk - Register the sdclk for a PHY to use + * sdhci_arasan_register_sdcardclk - Register the sdcardclk for a PHY to use * * Some PHY devices need to know what the actual card clock is. In order for * them to find out, we'll provide a clock through the common clock framework @@ -624,9 +655,10 @@ static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host) * @dev: Pointer to our struct device. * Returns 0 on success and error value on error */ -static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, - struct clk *clk_xin, - struct device *dev) +static int +sdhci_arasan_register_sdcardclk(struct sdhci_arasan_data *sdhci_arasan, + struct clk *clk_xin, + struct device *dev) { struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; struct device_node *np = dev->of_node; @@ -662,7 +694,7 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, _data->sdcardclk_hw); if (ret) { - dev_err(dev, "Failed to add clock provider\n"); + dev_err(dev, "Failed to add sdcard clock provider\n"); return ret; } @@ -676,10 +708,74 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, } /** + * sdhci_arasan_register_sampleclk - Register the sampleclk for a PHY to use + * + * Some PHY devices need to know what the actual card clock is. In order for + * them to find out, we'll provide a clock through the common clock framework + * for them to query. + * + * @sdhci_arasan: Our private data structure. + * @clk_xin: Pointer to the functional clock + * @dev: Pointer to our struct device. + * Returns 0 on success and error value on error + */ +static int +sdhci_arasan_register_sampleclk(struct sdhci_arasan_data *sdhci_arasan, + struct clk *clk_xin, + struct device *dev) +{ + struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; + struct device_node *np = dev->of_node; + struct clk_init_data sampleclk_init; + const char *parent_clk_name; + int ret; + + /* Providing a clock
[PATCH v2 00/11] Arasan SDHCI enhancements and ZynqMP Tap Delays Handling
This patch series does the following: - Reorganize the Clock Handling in Arasan SD driver - Adds new sampling clock in Arasan SD driver - Adds support to set Clock Delays in SD Arasan Driver - Add SDIO Tap Delay handling in ZynqMP firmware driver - Add support for ZynqMP Tap Delays setting in Arasan SD driver Changes in v2: - Replaced the deprecated calls to clock framework APIs - Added support for dev_clk_get() call to work for SD card clock - Separated the clock data struct - Fragmented the patch series in smaller patches to make it more readable This patch series contains a DT patch, which I think should be there to maintain the order of commits. Manish Narani (11): dt-bindings: mmc: arasan: Update documentation for SD Card Clock arm64: dts: rockchip: Add optional clock property indicating sdcard clock mmc: sdhci-of-arasan: Replace deprecated clk API calls mmc: sdhci-of-arasan: Separate out clk related data to another structure dt-bindings: mmc: arasan: Update Documentation for the input clock mmc: sdhci-of-arasan: Add sampling clock for a phy to use dt-bindings: mmc: arasan: Add optional properties for Arasan SDHCI mmc: sdhci-of-arasan: Add support to set clock phase delays for SD firmware: xilinx: Add SDIO Tap Delay APIs dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup .../devicetree/bindings/mmc/arasan,sdhci.txt | 49 ++- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 4 +- drivers/firmware/xilinx/zynqmp.c | 48 +++ drivers/mmc/host/sdhci-of-arasan.c | 453 - include/linux/firmware/xlnx-zynqmp.h | 15 +- 5 files changed, 540 insertions(+), 29 deletions(-) -- 2.1.1
[PATCH v2 01/11] dt-bindings: mmc: arasan: Update documentation for SD Card Clock
The clock handling is to be updated in the Arasan SDHCI. As the 'devm_clk_register' is deprecated in the clock framework, this needs to specify one more clock named 'clk_sdcard' to get the clock in the driver via 'devm_clk_get()'. This clock represents the clock from controller to the card. Signed-off-by: Manish Narani --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 1edbb04..15c6397 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -23,6 +23,10 @@ Required Properties: - reg: From mmc bindings: Register location and length. - clocks: From clock bindings: Handles to clock inputs. - clock-names: From clock bindings: Tuple including "clk_xin" and "clk_ahb" +Apart from these two there is one more optional clock which +is "clk_sdcard". This clock represents output clock from +controller and card. This must be specified when #clock-cells +is specified. - interrupts: Interrupt specifier Required Properties for "arasan,sdhci-5.1": @@ -36,9 +40,10 @@ Optional Properties: - clock-output-names: If specified, this will be the name of the card clock which will be exposed by this device. Required if #clock-cells is specified. - - #clock-cells: If specified this should be the value <0>. With this property -in place we will export a clock representing the Card Clock. This clock -is expected to be consumed by our PHY. You must also specify + - #clock-cells: If specified this should be the value <0>. With this +property in place we will export one clock representing the Card +Clock. This clock is expected to be consumed by our PHY. You must also +specify - xlnx,fails-without-test-cd: when present, the controller doesn't work when the CD line is not connected properly, and the line is not connected properly. Test mode can be used to force the controller to function. @@ -70,8 +75,8 @@ Example: compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1"; reg = <0x0 0xfe33 0x0 0x1>; interrupts = ; - clocks = < SCLK_EMMC>, < ACLK_EMMC>; - clock-names = "clk_xin", "clk_ahb"; + clocks = < SCLK_EMMC>, < ACLK_EMMC>, < 0>; + clock-names = "clk_xin", "clk_ahb", "clk_sdcard"; arasan,soc-ctl-syscon = <>; assigned-clocks = < SCLK_EMMC>; assigned-clock-rates = <2>; -- 2.1.1
[PATCH v2 08/11] mmc: sdhci-of-arasan: Add support to set clock phase delays for SD
Add support to read Clock Phase Delays from the DT and set it via clk_set_phase() API from clock framework. Some of the controllers might have their own handling of setting clock delays, for this keep the set_clk_delays as function pointer which can be assigned controller specific handling of the same. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 91 ++ 1 file changed, 91 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 9513813..a545221 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -77,12 +77,18 @@ struct sdhci_arasan_soc_ctl_map { * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. * @sampleclk_hw: Struct for the clock we might provide to a PHY. * @sampleclk: Pointer to normal 'struct clock' for sampleclk_hw. + * @clk_phase_in: Array of Input Clock Phase Delays for all speed modes + * @clk_phase_out: Array of Output Clock Phase Delays for all speed modes + * @set_clk_delays:Function pointer for setting Clock Delays */ struct sdhci_arasan_clk_data { struct clk_hw sdcardclk_hw; struct clk *sdcardclk; struct clk_hw sampleclk_hw; struct clk *sampleclk; + int clk_phase_in[MMC_TIMING_MMC_HS400 + 1]; + int clk_phase_out[MMC_TIMING_MMC_HS400 + 1]; + void(*set_clk_delays)(struct sdhci_host *host); }; /** @@ -180,6 +186,7 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); + struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; bool ctrl_phy = false; if (!IS_ERR(sdhci_arasan->phy)) { @@ -221,6 +228,10 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_arasan->is_phy_on = false; } + /* Set the Input and Output Clock Phase Delays */ + if (clk_data->set_clk_delays) + clk_data->set_clk_delays(host); + sdhci_set_clock(host, clock); if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE) @@ -635,6 +646,84 @@ static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host) sdhci_arasan_syscon_write(host, _ctl_map->baseclkfreq, mhz); } +static void sdhci_arasan_set_clk_delays(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); + struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; + + clk_set_phase(clk_data->sampleclk, + clk_data->clk_phase_in[host->timing]); + clk_set_phase(clk_data->sdcardclk, + clk_data->clk_phase_out[host->timing]); +} + +static void arasan_dt_read_clk_phase(struct device *dev, +struct sdhci_arasan_clk_data *clk_data, +unsigned int timing, const char *prop) +{ + struct device_node *np = dev->of_node; + + int clk_phase[2] = {0}; + + /* +* Read Tap Delay values from DT, if the DT does not contain the +* Tap Values then use the pre-defined values. +*/ + if (of_property_read_variable_u32_array(np, prop, _phase[0], + 2, 0)) { + dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n", + prop, clk_data->clk_phase_in[timing], + clk_data->clk_phase_out[timing]); + return; + } + + /* The values read are Input and Output Clock Delays in order */ + clk_data->clk_phase_in[timing] = clk_phase[0]; + clk_data->clk_phase_out[timing] = clk_phase[1]; +} + +/** + * arasan_dt_parse_clk_phases - Read Clock Delay values from DT + * + * Called at initialization to parse the values of Clock Delays. + * + * @dev: Pointer to our struct device. + */ +static void arasan_dt_parse_clk_phases(struct device *dev, + struct sdhci_arasan_clk_data *clk_data) +{ + /* +* This has been kept as a pointer and is assigned a function here. +* So that different controller variants can assign their own handling +* function. +*/ + clk_data->set_clk_delays = sdhci_arasan_set_clk_delays; + + arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_LEGACY, +"clk-phase-legacy"); + arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_HS, +"clk-phase-mmc-hs"); + arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_SD_HS, +
[PATCH v2 11/11] mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup
Apart from taps set by auto tuning, ZynqMP platform has feature to set the tap values manually. Add support to set tap delay values in HW via ZynqMP SoC framework. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 200 - 1 file changed, 198 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index a545221..508d942 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "cqhci.h" #include "sdhci-pltfm.h" @@ -32,6 +33,10 @@ #define PHY_CLK_TOO_SLOW_HZ40 +/* Default settings for ZynqMP Clock Phases */ +#define ZYNQMP_ICLK_PHASE {0, 63, 63, 0, 63, 0, 0, 183, 54, 0, 0} +#define ZYNQMP_OCLK_PHASE {0, 60, 72, 0, 60, 72, 135, 180, 72, 36, 0} + /* * On some SoCs the syscon area has a feature where the upper 16-bits of * each 32-bit register act as a write mask for the lower 16-bits. This allows @@ -80,6 +85,7 @@ struct sdhci_arasan_soc_ctl_map { * @clk_phase_in: Array of Input Clock Phase Delays for all speed modes * @clk_phase_out: Array of Output Clock Phase Delays for all speed modes * @set_clk_delays:Function pointer for setting Clock Delays + * @clk_of_data: Platform specific runtime clock data storage pointer */ struct sdhci_arasan_clk_data { struct clk_hw sdcardclk_hw; @@ -89,6 +95,11 @@ struct sdhci_arasan_clk_data { int clk_phase_in[MMC_TIMING_MMC_HS400 + 1]; int clk_phase_out[MMC_TIMING_MMC_HS400 + 1]; void(*set_clk_delays)(struct sdhci_host *host); + void*clk_of_data; +}; + +struct sdhci_arasan_zynqmp_clk_data { + const struct zynqmp_eemi_ops *eemi_ops; }; /** @@ -510,6 +521,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = { .compatible = "arasan,sdhci-4.9a", .data = _arasan_data, }, + { + .compatible = "xlnx,zynqmp-8.9a", + .data = _arasan_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match); @@ -569,6 +584,144 @@ static const struct clk_ops arasan_sampleclk_ops = { }; /** + * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays + * + * Set the SD Output Clock Tap Delays for Output path + * + * @hw:Pointer to the hardware clock structure. + * @degreesThe clock phase shift between 0 - 359. + * Return: 0 on success and error value on error + */ +static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) + +{ + struct sdhci_arasan_clk_data *clk_data = + container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); + struct sdhci_arasan_data *sdhci_arasan = + container_of(clk_data, struct sdhci_arasan_data, clk_data); + struct sdhci_host *host = sdhci_arasan->host; + struct sdhci_arasan_zynqmp_clk_data *zynqmp_clk_data = + clk_data->clk_of_data; + const struct zynqmp_eemi_ops *eemi_ops = zynqmp_clk_data->eemi_ops; + const char *clk_name = clk_hw_get_name(hw); + u32 device_id = !strcmp(clk_name, "clk_out_sd0") ? 0 : 1; + u8 tap_delay, tap_max = 0; + + if (!eemi_ops->sdio_out_setphase) + return -ENODEV; + + /* +* This is applicable for SDHCI_SPEC_300 and above +* ZynqMP does not set phase for <=25MHz clock. +* If degrees is zero, no need to do anything. +*/ + if (host->version < SDHCI_SPEC_300 || + host->timing == MMC_TIMING_LEGACY || + host->timing == MMC_TIMING_UHS_SDR12 || !degrees) + return 0; + + switch (host->timing) { + case MMC_TIMING_MMC_HS: + case MMC_TIMING_SD_HS: + case MMC_TIMING_UHS_SDR25: + case MMC_TIMING_UHS_DDR50: + case MMC_TIMING_MMC_DDR52: + /* For 50MHz clock, 30 Taps are available */ + tap_max = 30; + break; + case MMC_TIMING_UHS_SDR50: + /* For 100MHz clock, 15 Taps are available */ + tap_max = 15; + break; + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_MMC_HS200: + /* For 200MHz clock, 8 Taps are available */ + tap_max = 8; + default: + break; + } + + tap_delay = (degrees * tap_max) / 360; + + /* Set the Clock Phase */ + return eemi_ops->sdio_out_setphase(device_id, tap_delay); +} + +static const struct clk_ops zynqmp_sdcardclk_ops = { + .recalc_rate = sdhci_arasan_sdcardclk_recalc_rate, + .set_phase = sdhci_zynqmp_sdcardclk_set_phase, +}; + +/** + * sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Cl
[PATCH v2 02/11] arm64: dts: rockchip: Add optional clock property indicating sdcard clock
As devm_clk_register() is deprecated in the clock framework, it is mandatory to use devm_clk_get() for getting the clock. This patch adds sdcard clock which will be used for the same. Signed-off-by: Manish Narani --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 196ac9b..0b512f3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -332,8 +332,8 @@ arasan,soc-ctl-syscon = <>; assigned-clocks = < SCLK_EMMC>; assigned-clock-rates = <2>; - clocks = < SCLK_EMMC>, < ACLK_EMMC>; - clock-names = "clk_xin", "clk_ahb"; + clocks = < SCLK_EMMC>, < ACLK_EMMC>, < 0>; + clock-names = "clk_xin", "clk_ahb", "clk_sdcard"; clock-output-names = "emmc_cardclock"; #clock-cells = <0>; phys = <_phy>; -- 2.1.1
[PATCH v2 09/11] firmware: xilinx: Add SDIO Tap Delay APIs
Add APIs for setting SDIO Tap Delays on ZynqMP platform. Signed-off-by: Manish Narani --- drivers/firmware/xilinx/zynqmp.c | 48 include/linux/firmware/xlnx-zynqmp.h | 15 ++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index fd3d837..b81f1be 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -664,6 +664,52 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, qos, ack, NULL); } +/** + * zynqmp_pm_sdio_out_setphase() - PM call to set clock output delays for SD + * @device_id: Device ID of the SD controller + * @tap_delay: Tap Delay value for output clock + * + * This API function is to be used for setting the clock output delays for SD + * clock. + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_sdio_out_setphase(u32 device_id, u8 tap_delay) +{ + u32 node_id = (!device_id) ? NODE_SD_0 : NODE_SD_1; + int ret; + + ret = zynqmp_pm_ioctl(node_id, IOCTL_SET_SD_TAPDELAY, + PM_TAPDELAY_OUTPUT, tap_delay, NULL); + if (ret) + pr_err("Error setting Output Tap Delay\n"); + + return ret; +} + +/** + * zynqmp_pm_sdio_in_setphase() - PM call to set clock input delays for SD + * @device_id: Device ID of the SD controller + * @tap_delay: Tap Delay value for input clock + * + * This API function is to be used for setting the clock input delays for SD + * clock. + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_sdio_in_setphase(u32 device_id, u8 tap_delay) +{ + u32 node_id = (!device_id) ? NODE_SD_0 : NODE_SD_1; + int ret; + + ret = zynqmp_pm_ioctl(node_id, IOCTL_SET_SD_TAPDELAY, + PM_TAPDELAY_INPUT, tap_delay, NULL); + if (ret) + pr_err("Error setting Input Tap Delay\n"); + + return ret; +} + static const struct zynqmp_eemi_ops eemi_ops = { .get_api_version = zynqmp_pm_get_api_version, .get_chipid = zynqmp_pm_get_chipid, @@ -687,6 +733,8 @@ static const struct zynqmp_eemi_ops eemi_ops = { .set_requirement = zynqmp_pm_set_requirement, .fpga_load = zynqmp_pm_fpga_load, .fpga_get_status = zynqmp_pm_fpga_get_status, + .sdio_out_setphase = zynqmp_pm_sdio_out_setphase, + .sdio_in_setphase = zynqmp_pm_sdio_in_setphase, }; /** diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 1262ea6..d9b53e5 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -92,7 +92,8 @@ enum pm_ret_status { }; enum pm_ioctl_id { - IOCTL_SET_PLL_FRAC_MODE = 8, + IOCTL_SET_SD_TAPDELAY = 7, + IOCTL_SET_PLL_FRAC_MODE, IOCTL_GET_PLL_FRAC_MODE, IOCTL_SET_PLL_FRAC_DATA, IOCTL_GET_PLL_FRAC_DATA, @@ -251,6 +252,16 @@ enum zynqmp_pm_request_ack { ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING, }; +enum pm_node_id { + NODE_SD_0 = 39, + NODE_SD_1, +}; + +enum tap_delay_type { + PM_TAPDELAY_INPUT = 0, + PM_TAPDELAY_OUTPUT, +}; + /** * struct zynqmp_pm_query_data - PM query data * @qid: query ID @@ -295,6 +306,8 @@ struct zynqmp_eemi_ops { const u32 capabilities, const u32 qos, const enum zynqmp_pm_request_ack ack); + int (*sdio_out_setphase)(u32 device_id, u8 tap_delay); + int (*sdio_in_setphase)(u32 device_id, u8 tap_delay); }; int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1, -- 2.1.1
[PATCH v2 03/11] mmc: sdhci-of-arasan: Replace deprecated clk API calls
The clk framework APIs devm_clk_register and of_clk_add_provider, which are used here, are deprecated. Replace the calls with the new API calls. Also add an API call devm_clk_get() to get the clock from DT. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index b12abf9..d60a2e8 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -641,14 +641,25 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, sdcardclk_init.ops = _sdcardclk_ops; sdhci_arasan->sdcardclk_hw.init = _init; - sdhci_arasan->sdcardclk = - devm_clk_register(dev, _arasan->sdcardclk_hw); + ret = devm_clk_hw_register(dev, _arasan->sdcardclk_hw); + if (ret) { + dev_err(dev, "Failed to register SD clk_hw\n"); + return ret; + } sdhci_arasan->sdcardclk_hw.init = NULL; - ret = of_clk_add_provider(np, of_clk_src_simple_get, - sdhci_arasan->sdcardclk); - if (ret) + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, +_arasan->sdcardclk_hw); + if (ret) { dev_err(dev, "Failed to add clock provider\n"); + return ret; + } + + sdhci_arasan->sdcardclk = devm_clk_get(dev, "clk_sdcard"); + if (IS_ERR(sdhci_arasan->sdcardclk)) { + dev_err(dev, "sdcardclk clock not found.\n"); + ret = PTR_ERR(sdhci_arasan->sdcardclk); + } return ret; } -- 2.1.1
[PATCH v2 10/11] dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller
Add documentation for 'xlnx,zynqmp-8.9a' SDHCI controller and optional properties followed by example. Signed-off-by: Manish Narani --- .../devicetree/bindings/mmc/arasan,sdhci.txt | 19 +++ 1 file changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 7425d52..d2058ee 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -15,6 +15,9 @@ Required Properties: - "arasan,sdhci-5.1": generic Arasan SDHCI 5.1 PHY - "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1": rk3399 eMMC PHY For this device it is strongly suggested to include arasan,soc-ctl-syscon. +- "xlnx,zynqmp-8.9a": ZynqMP SDHCI 8.9a PHY + For this device it is strongly suggested to include clock-output-names and + #clock-cells. - "ti,am654-sdhci-5.1", "arasan,sdhci-5.1": TI AM654 MMC PHY Note: This binding has been deprecated and moved to [5]. @@ -65,6 +68,10 @@ Optional Properties: controller while switching to particular speed mode. If not specified, driver will configure the default value defined for particular mode in it. + - xlnx,mio-bank: When specified, this will indicate the MIO bank number in +which the command and data lines are configured. If not specified, driver +will assume this as 0. + Example: sdhci@e010 { compatible = "arasan,sdhci-8.9a"; @@ -100,3 +107,15 @@ Example: phy-names = "phy_arasan"; #clock-cells = <0>; }; + + sdhci: mmc@ff16 { + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; + interrupt-parent = <>; + interrupts = <0 48 4>; + reg = <0x0 0xff16 0x0 0x1000>; + clocks = <>, <>, < 0>, < 1>; + clock-names = "clk_xin", "clk_ahb", "clk_sdcard", "clk_sample"; + clock-output-names = "clk_out_sd0", "clk_in_sd0"; + #clock-cells = <1>; + clk-phase-sd-hs = <63>, <72>; + }; -- 2.1.1
[PATCH v2 04/11] mmc: sdhci-of-arasan: Separate out clk related data to another structure
To improve the code readability, use two different structs, one for clock provider data and one for mmc platform data. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 35 +++ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index d60a2e8..c7586f5 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -72,13 +72,22 @@ struct sdhci_arasan_soc_ctl_map { }; /** + * struct sdhci_arasan_clk_data + * @sdcardclk_hw: Struct for the clock we might provide to a PHY. + * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. + */ +struct sdhci_arasan_clk_data { + struct clk_hw sdcardclk_hw; + struct clk *sdcardclk; +}; + +/** * struct sdhci_arasan_data * @host: Pointer to the main SDHCI host structure. * @clk_ahb: Pointer to the AHB clock * @phy: Pointer to the generic phy + * @clk_data: Struct for the Arasan Controller Clock Data. * @is_phy_on: True if the PHY is on; false if not. - * @sdcardclk_hw: Struct for the clock we might provide to a PHY. - * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers. * @soc_ctl_map: Map to get offsets into soc_ctl registers. */ @@ -89,8 +98,7 @@ struct sdhci_arasan_data { boolis_phy_on; boolhas_cqe; - struct clk_hw sdcardclk_hw; - struct clk *sdcardclk; + struct sdhci_arasan_clk_data clk_data; struct regmap *soc_ctl_base; const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; @@ -505,8 +513,10 @@ static unsigned long sdhci_arasan_sdcardclk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { + struct sdhci_arasan_clk_data *clk_data = + container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); struct sdhci_arasan_data *sdhci_arasan = - container_of(hw, struct sdhci_arasan_data, sdcardclk_hw); + container_of(clk_data, struct sdhci_arasan_data, clk_data); struct sdhci_host *host = sdhci_arasan->host; return host->mmc->actual_clock; @@ -618,6 +628,7 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, struct clk *clk_xin, struct device *dev) { + struct sdhci_arasan_clk_data *clk_data = _arasan->clk_data; struct device_node *np = dev->of_node; struct clk_init_data sdcardclk_init; const char *parent_clk_name; @@ -640,25 +651,25 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, sdcardclk_init.flags = CLK_GET_RATE_NOCACHE; sdcardclk_init.ops = _sdcardclk_ops; - sdhci_arasan->sdcardclk_hw.init = _init; - ret = devm_clk_hw_register(dev, _arasan->sdcardclk_hw); + clk_data->sdcardclk_hw.init = _init; + ret = devm_clk_hw_register(dev, _data->sdcardclk_hw); if (ret) { dev_err(dev, "Failed to register SD clk_hw\n"); return ret; } - sdhci_arasan->sdcardclk_hw.init = NULL; + clk_data->sdcardclk_hw.init = NULL; ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, -_arasan->sdcardclk_hw); +_data->sdcardclk_hw); if (ret) { dev_err(dev, "Failed to add clock provider\n"); return ret; } - sdhci_arasan->sdcardclk = devm_clk_get(dev, "clk_sdcard"); - if (IS_ERR(sdhci_arasan->sdcardclk)) { + clk_data->sdcardclk = devm_clk_get(dev, "clk_sdcard"); + if (IS_ERR(clk_data->sdcardclk)) { dev_err(dev, "sdcardclk clock not found.\n"); - ret = PTR_ERR(sdhci_arasan->sdcardclk); + ret = PTR_ERR(clk_data->sdcardclk); } return ret; -- 2.1.1
RE: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup
Hi Uffe, > -Original Message- > From: Ulf Hansson > Sent: Wednesday, June 19, 2019 8:11 PM > To: Manish Narani > Cc: Michal Simek ; Rob Herring ; > Mark Rutland ; Adrian Hunter > ; Rajan Vaja ; Jolly Shah > ; Nava kishore Manne ; Olof > Johansson ; linux-...@vger.kernel.org; DTML > ; Linux Kernel Mailing List ker...@vger.kernel.org>; Linux ARM > Subject: Re: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP > Platform Tap Delays Setup > > On Tue, 18 Jun 2019 at 06:59, Manish Narani wrote: > > > > Hi Uffe, > > > > Thanks for the review. Please find my comments below. > > > > > -Original Message- > > > From: Ulf Hansson > > > Sent: Monday, June 17, 2019 8:29 PM > > > To: Michal Simek > > > Cc: Manish Narani ; Rob Herring > > > ; Mark Rutland ; Adrian > > > Hunter ; Rajan Vaja ; Jolly > > > Shah ; Nava kishore Manne ; > Olof > > > Johansson ; linux-...@vger.kernel.org; DTML > > > ; Linux Kernel Mailing List > > ker...@vger.kernel.org>; Linux ARM ker...@lists.infradead.org> > > > Subject: Re: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP > > > Platform Tap Delays Setup > > > > > > [...] > > > > > > > >> > > > > >> > > > > >>> In regards to the mmc data part, I suggest to drop the > > > > >>> ->set_tap_delay() callback, but rather use a boolean flag to > > > > >>> indicate > > > > >>> whether clock phases needs to be changed for the variant. > > > > >>> Potentially > > > > >>> that could even be skipped and instead call clk_set_phase() > > > > >>> unconditionally, as the clock core deals fine with clock providers > > > > >>> that doesn't support the ->set_phase() callback. > > > > In the current implementation, I am taking care of both the input and > > output clock delays with the single clock (which is output clock) > > registration > > and differentiating these tap delays based on their values > > (<256 then input delay and >= 256 then output delay), because that is > > zynqmp specific. If we want to make this generic, we may need to > > register 'another' clock which will be there as an input (sampling) clock > > and then we can make this 'clk_set_phase()' be called unconditionally > > each for both the clocks and let the platforms handle their clock part. > > What's your take on this? > > Not sure exactly what you are suggesting, but my gut feeling says it > sounds good. > > How is tap delays managed for both the input clock and the output > clock? Is some managed by the clock provider (which is probably > firmware in your case) and some managed by the MMC controller? Yes, for the existing "xlnx,zynqmp-8.9a" controller, the tap delays will be managed by the firmware, however in the upcoming "xlnx,versal-8.9a" variant the tap delays will be managed by the MMC controller itself. I will include the Versal one in the next series of patches. Thanks, Manish
RE: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup
Hi Uffe, > -Original Message- > From: Ulf Hansson > Sent: Wednesday, June 19, 2019 7:09 PM > To: Manish Narani > Cc: Michal Simek ; Rob Herring ; > Mark Rutland ; Adrian Hunter > ; Rajan Vaja ; Jolly Shah > ; Nava kishore Manne ; Olof > Johansson ; linux-...@vger.kernel.org; DTML > ; Linux Kernel Mailing List ker...@vger.kernel.org>; Linux ARM > Subject: Re: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP > Platform Tap Delays Setup > > On Wed, 19 Jun 2019 at 10:40, Manish Narani wrote: > > > > Hi Uffe, > > > > > > > -Original Message- > > > From: Ulf Hansson > > > Sent: Monday, June 17, 2019 5:51 PM > > [...] > > > > > > The "const struct zynqmp_eemi_ops *eemi_ops; should then be moved into > > > a clock provider specific struct, which is assigned when calling > > > sdhci_arasan_register_sdclk. I understand that all the clock data is > > > folded into struct sdhci_arasan_data today, but I think that should be > > > moved into a "sub-struct" for the clock specifics. > > > > > > Moreover, when registering the clock, we should convert from using > > > devm_clk_register() into devm_clk_hw_register() as the first one is > > > now deprecated. > > > > Just a query here: > > When we switch to using devm_clk_hw_register() here, it will register the > clk_hw and return int. > > Is there a way we can get the clk (related to the clk_hw registered) from > > the > > clock framework? > > I am asking this because we will need that clk pointer while calling > clk_set_phase() function. > > I assume devm_clk_get() should work fine? This clock does not come through ZynqMP Clock framework. We are initializing it in this 'sdhci-of-arasan' driver and getting only the clock name from "clock_output_names" property. So I think devm_clk_get() will not work here for our case. I have gone through the clock framework and I found one function which may be used to create clock from clock hw, that is ' clk_hw_create_clk()' which can be used from our driver, however this needs change in the clock framework as below : --- diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index aa51756..4dc69ff 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3420,6 +3420,7 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, return clk; } +EXPORT_SYMBOL_GPL(clk_hw_create_clk); static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist) { diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index d8400d6..2319899 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -22,17 +22,9 @@ static inline struct clk_hw *of_clk_get_hw(struct device_node *np, struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id); #ifdef CONFIG_COMMON_CLK -struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, - const char *dev_id, const char *con_id); void __clk_put(struct clk *clk); #else /* All these casts to avoid ifdefs in clkdev... */ -static inline struct clk * -clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, - const char *con_id) -{ - return (struct clk *)hw; -} static struct clk_hw *__clk_get_hw(struct clk *clk) { return (struct clk_hw *)clk; diff --git a/include/linux/clk.h b/include/linux/clk.h index f689fc5..d3f60fe 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -18,6 +18,7 @@ struct device; struct clk; +struct clk_hw; struct device_node; struct of_phandle_args; @@ -934,4 +935,15 @@ static inline struct clk *of_clk_get_from_provider(struct of_phandle_args *clksp } #endif +#ifdef CONFIG_COMMON_CLK +struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, + const char *dev_id, const char *con_id); +#else +static inline struct clk * +clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, + const char *con_id) +{ + return (struct clk *)hw; +} +#endif #endif --- This change should help other drivers (outside 'drivers/clk/') as well for getting the clock created from clk_hw. Is this fine to do? Thanks, Manish
RE: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup
Hi Uffe, > -Original Message- > From: Ulf Hansson > Sent: Monday, June 17, 2019 5:51 PM [...] > > The "const struct zynqmp_eemi_ops *eemi_ops; should then be moved into > a clock provider specific struct, which is assigned when calling > sdhci_arasan_register_sdclk. I understand that all the clock data is > folded into struct sdhci_arasan_data today, but I think that should be > moved into a "sub-struct" for the clock specifics. > > Moreover, when registering the clock, we should convert from using > devm_clk_register() into devm_clk_hw_register() as the first one is > now deprecated. Just a query here: When we switch to using devm_clk_hw_register() here, it will register the clk_hw and return int. Is there a way we can get the clk (related to the clk_hw registered) from the clock framework? I am asking this because we will need that clk pointer while calling clk_set_phase() function. Thanks, Manish
RE: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup
Hi Uffe, Thanks for the review. Please find my comments below. > -Original Message- > From: Ulf Hansson > Sent: Monday, June 17, 2019 8:29 PM > To: Michal Simek > Cc: Manish Narani ; Rob Herring > ; Mark Rutland ; Adrian > Hunter ; Rajan Vaja ; Jolly > Shah ; Nava kishore Manne ; Olof > Johansson ; linux-...@vger.kernel.org; DTML > ; Linux Kernel Mailing List ker...@vger.kernel.org>; Linux ARM > Subject: Re: [PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP > Platform Tap Delays Setup > > [...] > > > >> > > >> > > >>> In regards to the mmc data part, I suggest to drop the > > >>> ->set_tap_delay() callback, but rather use a boolean flag to indicate > > >>> whether clock phases needs to be changed for the variant. Potentially > > >>> that could even be skipped and instead call clk_set_phase() > > >>> unconditionally, as the clock core deals fine with clock providers > > >>> that doesn't support the ->set_phase() callback. In the current implementation, I am taking care of both the input and output clock delays with the single clock (which is output clock) registration and differentiating these tap delays based on their values (<256 then input delay and >= 256 then output delay), because that is zynqmp specific. If we want to make this generic, we may need to register 'another' clock which will be there as an input (sampling) clock and then we can make this 'clk_set_phase()' be called unconditionally each for both the clocks and let the platforms handle their clock part. What's your take on this? Thanks, Manish > > >> > > >> In connection to another version of this driver for latest Xilinx chip > > >> it would be better to keep set_tap_delay callback in the driver. The > > >> reason is that new chip/ip is capable to setup tap delays directly > > >> without asking firmware to do it. That's why for versal IP there is a > > >> need to call different setup_tap_delay function. > > > > > > The ->set_tap_delay() callback is for ZyncMp pointing to > > > sdhci_arasan_zynqmp_set_tap_delay(). This function calls the > > > clk_set_phase() API. > > > > > > What does ->set_tap_delay() do for the latest version? > > > > There is different set of default tap delays which should be programmed > > and it is done just via writing to registers which are the part of > > controller address space. > > Okay, I see. > > Not sure what makes most sense to do here, but it sounds to me like > another ->set_phase() callback should be implemented for the clock > provider. In other words, calling clk_set_phase() should continue to > works just fine for this case as well. If it turns out to be > inconvenient, we can always add the ->set_tap_delay() at a later point > when it makes more sense. > > [...] > > Kind regards > Uffe
[PATCH] arm64: zynqmp: Add ZynqMP SDHCI compatible string
Add the new compatible string for ZynqMP SD Host Controller for its use in the Arasan SDHCI driver for some of the ZynqMP specific operations. Add required properties for the same. Signed-off-by: Manish Narani --- This patch depends on the below series of patches: https://lkml.org/lkml/2019/6/11/286 --- arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 9aa6734..6da5b82 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -493,21 +493,25 @@ }; sdhci0: mmc@ff16 { - compatible = "arasan,sdhci-8.9a"; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; interrupt-parent = <>; interrupts = <0 48 4>; reg = <0x0 0xff16 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; + clock-output-names = "clk_sd0"; + #clock-cells = <0>; }; sdhci1: mmc@ff17 { - compatible = "arasan,sdhci-8.9a"; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; interrupt-parent = <>; interrupts = <0 49 4>; reg = <0x0 0xff17 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; + clock-output-names = "clk_sd1"; + #clock-cells = <0>; }; smmu: smmu@fd80 { -- 2.1.1
[PATCH 0/3] Add ZynqMP SD Clock Tap Delays configuration support
This patch series adds support to configure SD tap delays on ZynqMP platforms using Xilinx firmware driver and clock framework APIs. Manish Narani (3): firmware: xilinx: Add SDIO Tap Delay API dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup .../devicetree/bindings/mmc/arasan,sdhci.txt | 32 drivers/firmware/xilinx/zynqmp.c | 32 drivers/mmc/host/sdhci-of-arasan.c | 173 - include/linux/firmware/xlnx-zynqmp.h | 17 +- 4 files changed, 252 insertions(+), 2 deletions(-) -- 2.1.1
[PATCH 3/3] mmc: sdhci-of-arasan: Add support for ZynqMP Platform Tap Delays Setup
Apart from taps set by auto tuning, ZynqMP platform has feature to set the tap values manually. Add support to read tap delay values from DT and set the same in HW via ZynqMP SoC framework. Reading Tap Delays from DT is optional, if the property is not available in DT the driver will use the pre-defined Tap Delay Values. Signed-off-by: Manish Narani --- drivers/mmc/host/sdhci-of-arasan.c | 173 - 1 file changed, 172 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index b12abf9..7af6cec 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "cqhci.h" #include "sdhci-pltfm.h" @@ -32,6 +33,10 @@ #define PHY_CLK_TOO_SLOW_HZ40 +/* Default settings for ZynqMP Tap Delays */ +#define ZYNQMP_ITAP_DELAYS {0, 0x15, 0x15, 0, 0x15, 0, 0, 0x3D, 0x12, 0, 0} +#define ZYNQMP_OTAP_DELAYS {0, 0x5, 0x6, 0, 0x5, 0x3, 0x3, 0x4, 0x6, 0x3, 0} + /* * On some SoCs the syscon area has a feature where the upper 16-bits of * each 32-bit register act as a write mask for the lower 16-bits. This allows @@ -81,6 +86,7 @@ struct sdhci_arasan_soc_ctl_map { * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers. * @soc_ctl_map: Map to get offsets into soc_ctl registers. + * @of_data: Platform specific runtime data storage pointer */ struct sdhci_arasan_data { struct sdhci_host *host; @@ -101,6 +107,15 @@ struct sdhci_arasan_data { /* Controller immediately reports SDHCI_CLOCK_INT_STABLE after enabling the * internal clock even when the clock isn't stable */ #define SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE BIT(1) + + void *of_data; +}; + +struct sdhci_arasan_zynqmp_data { + void (*set_tap_delay)(struct sdhci_host *host); + const struct zynqmp_eemi_ops *eemi_ops; + u8 tapdly[MMC_TIMING_MMC_HS400 + 1][2]; /* [0] for input delay, */ + /* [1] for output delay */ }; struct sdhci_arasan_of_data { @@ -209,6 +224,16 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_arasan->is_phy_on = false; } + /* Set the Input and Output Tap Delays */ + if (host->version >= SDHCI_SPEC_300 && + host->timing != MMC_TIMING_LEGACY && + host->timing != MMC_TIMING_UHS_SDR12) { + struct sdhci_arasan_zynqmp_data *zynqmp_data = + sdhci_arasan->of_data; + if (zynqmp_data && zynqmp_data->set_tap_delay) + zynqmp_data->set_tap_delay(host); + } + sdhci_set_clock(host, clock); if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE) @@ -487,6 +512,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = { .compatible = "arasan,sdhci-4.9a", .data = _arasan_data, }, + { + .compatible = "xlnx,zynqmp-8.9a", + .data = _arasan_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match); @@ -517,6 +546,37 @@ static const struct clk_ops arasan_sdcardclk_ops = { }; /** + * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Clock Tap Delays + * + * Set the SD Clock Tap Delays for Input and Output paths + * + * @hw:Pointer to the hardware clock structure. + * @degreesThe clock phase shift between 0 - 359. + * Return: 0 on success and error value on error + */ +static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) + +{ + struct sdhci_arasan_data *sdhci_arasan = + container_of(hw, struct sdhci_arasan_data, sdcardclk_hw); + struct sdhci_arasan_zynqmp_data *zynqmp_data = sdhci_arasan->of_data; + const struct zynqmp_eemi_ops *eemi_ops = zynqmp_data->eemi_ops; + const char *clk_name = clk_hw_get_name(hw); + u32 device_id = !strcmp(clk_name, "clk_sd0") ? 0 : 1; + + if (!eemi_ops->sdio_setphase) + return -ENODEV; + + /* Set the Clock Phase */ + return eemi_ops->sdio_setphase(device_id, degrees); +} + +static const struct clk_ops zynqmp_sdcardclk_ops = { + .recalc_rate = sdhci_arasan_sdcardclk_recalc_rate, + .set_phase = sdhci_zynqmp_sdcardclk_set_phase, +}; + +/** * sdhci_arasan_update_clockmultiplier - Set corecfg_clockmultiplier * * The corecfg_clockmultiplier is supposed to contain clock multiplier @@ -638,7 +698,10 @@ static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, sdcardclk_init.parent_names = _clk_name; sdcardclk_i
[PATCH 2/3] dt-bindings: mmc: arasan: Document 'xlnx,zynqmp-8.9a' controller
Add documentation for 'xlnx,zynqmp-8.9a' SDHCI controller and optional properties followed by example. Signed-off-by: Manish Narani --- .../devicetree/bindings/mmc/arasan,sdhci.txt | 32 ++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 1edbb04..6945b3b 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -15,6 +15,9 @@ Required Properties: - "arasan,sdhci-5.1": generic Arasan SDHCI 5.1 PHY - "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1": rk3399 eMMC PHY For this device it is strongly suggested to include arasan,soc-ctl-syscon. +- "xlnx,zynqmp-8.9a": ZynqMP SDHCI 8.9a PHY + For this device it is strongly suggested to include clock-output-names and + #clock-cells. - "ti,am654-sdhci-5.1", "arasan,sdhci-5.1": TI AM654 MMC PHY Note: This binding has been deprecated and moved to [5]. @@ -45,6 +48,24 @@ Optional Properties: - xlnx,int-clock-stable-broken: when present, the controller always reports that the internal clock is stable even when it is not. +Optional Properties for "xlnx,zynqmp-8.9a": + - xlnx,tap-delay-mmc-hsd: Input/Output Tap Delays in degrees for MMC HS. + - xlnx,tap-delay-sd-hsd: Input/Output Tap Delays in degrees for SD HS. + - xlnx,tap-delay-sdr25: Input/Output Tap Delays in degrees for SDR25. + - xlnx,tap-delay-sdr50: Input/Output Tap Delays in degrees for SDR50. + - xlnx,tap-delay-sdr104: Input/Output Tap Delays in degrees for SDR104. + - xlnx,tap-delay-sd-ddr50: Input/Output Tap Delays in degrees for SD DDR50. + - xlnx,tap-delay-mmc-ddr52: Input/Output Tap Delays in degrees for MMC DDR52. + - xlnx,tap-delay-mmc-hs200: Input/Output Tap Delays in degrees for MMC HS200. + + Above mentioned are the clock (phase) delays which are to be configured in the + controller while switching to particular speed mode. If not specified, driver + will configure the default value defined for particular mode in it. + + - xlnx,mio-bank: When specified, this will indicate the MIO bank number in +which the command and data lines are configured. If not specified, driver +will assume this as 0. + Example: sdhci@e010 { compatible = "arasan,sdhci-8.9a"; @@ -80,3 +101,14 @@ Example: phy-names = "phy_arasan"; #clock-cells = <0>; }; + + sdhci: mmc@ff16 { + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; + interrupt-parent = <>; + interrupts = <0 48 4>; + reg = <0x0 0xff16 0x0 0x1000>; + clock-names = "clk_xin", "clk_ahb"; + clock-output-names = "clk_sd0"; + #clock-cells = <0>; + xlnx,tap-delay-sd-hsd = <21>, <6>; + }; -- 2.1.1
[PATCH 1/3] firmware: xilinx: Add SDIO Tap Delay API
Add API for setting SDIO Tap Delays on ZynqMP platforms. Signed-off-by: Manish Narani --- drivers/firmware/xilinx/zynqmp.c | 32 include/linux/firmware/xlnx-zynqmp.h | 17 - 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index fd3d837..c6f9e72 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -664,6 +664,37 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, qos, ack, NULL); } +/** + * zynqmp_pm_sdio_setphase() - PM call to set clock delays for SD clock + * @device_id: Device ID of the SD controller + * @degrees: Tap Delay value in degrees for Input/Output clocks + * + * This API function is to be used for setting the clock delays for SD + * clock. + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_sdio_setphase(u32 device_id, int degrees) +{ + u32 node_id = (!device_id) ? NODE_SD_0 : NODE_SD_1; + enum tap_delay_type tap_type; + int ret; + + if (degrees < INPUT_TAP_BOUNDARY) { + tap_type = PM_TAPDELAY_INPUT; + } else { + tap_type = PM_TAPDELAY_OUTPUT; + degrees -= INPUT_TAP_BOUNDARY; + } + + ret = zynqmp_pm_ioctl(node_id, IOCTL_SET_SD_TAPDELAY, tap_type, + degrees, NULL); + if (ret) + pr_err("Error setting Tap Delay\n"); + + return ret; +} + static const struct zynqmp_eemi_ops eemi_ops = { .get_api_version = zynqmp_pm_get_api_version, .get_chipid = zynqmp_pm_get_chipid, @@ -687,6 +718,7 @@ static const struct zynqmp_eemi_ops eemi_ops = { .set_requirement = zynqmp_pm_set_requirement, .fpga_load = zynqmp_pm_fpga_load, .fpga_get_status = zynqmp_pm_fpga_get_status, + .sdio_setphase = zynqmp_pm_sdio_setphase, }; /** diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 1262ea6..0fc4bf7 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -56,6 +56,9 @@ #define XILINX_ZYNQMP_PM_FPGA_FULL 0x0U #define XILINX_ZYNQMP_PM_FPGA_PARTIAL BIT(0) +/* Input Tap Delay Boundary Value */ +#define INPUT_TAP_BOUNDARY 0x100 + enum pm_api_id { PM_GET_API_VERSION = 1, PM_REQUEST_NODE = 13, @@ -92,7 +95,8 @@ enum pm_ret_status { }; enum pm_ioctl_id { - IOCTL_SET_PLL_FRAC_MODE = 8, + IOCTL_SET_SD_TAPDELAY = 7, + IOCTL_SET_PLL_FRAC_MODE, IOCTL_GET_PLL_FRAC_MODE, IOCTL_SET_PLL_FRAC_DATA, IOCTL_GET_PLL_FRAC_DATA, @@ -251,6 +255,16 @@ enum zynqmp_pm_request_ack { ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING, }; +enum pm_node_id { + NODE_SD_0 = 39, + NODE_SD_1, +}; + +enum tap_delay_type { + PM_TAPDELAY_INPUT = 0, + PM_TAPDELAY_OUTPUT, +}; + /** * struct zynqmp_pm_query_data - PM query data * @qid: query ID @@ -295,6 +309,7 @@ struct zynqmp_eemi_ops { const u32 capabilities, const u32 qos, const enum zynqmp_pm_request_ack ack); + int (*sdio_setphase)(u32 device_id, int degrees); }; int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1, -- 2.1.1
[PATCH v4 1/3] dt-bindings: iio: adc: Add Xilinx AMS binding documentation
Xilinx AMS have several ADC channels that can be used for measurement of different voltages and temperatures. Document the same in the bindings. Signed-off-by: Manish Narani --- .../devicetree/bindings/iio/adc/xilinx-ams.txt | 183 + 1 file changed, 183 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/xilinx-ams.txt diff --git a/Documentation/devicetree/bindings/iio/adc/xilinx-ams.txt b/Documentation/devicetree/bindings/iio/adc/xilinx-ams.txt new file mode 100644 index 000..cacb6d4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/xilinx-ams.txt @@ -0,0 +1,183 @@ +Xilinx AMS controller +` +The AMS (Analog Monitoring System) includes an ADC as well as on-chip sensors +that can be used to sample external voltages and monitor on-die operating +conditions, such as temperature and supply voltage levels. +The AMS has two SYSMON blocks which are PL (Programmable Logic) SYSMON and +PS (Processing System) SYSMON. +All designs should have AMS registers, but PS and PL are optional. The +AMS controller can work with only PS, only PL and both PS and PL +configurations. Please specify registers according to your design. Devicetree +should always have AMS module property. Providing PS & PL module is optional. + +Required properties: + - compatible: Should be "xlnx,zynqmp-ams" + - reg: Should specify AMS register space + - interrupts: Interrupt number for the AMS control interface + - interrupt-names: Interrupt name, must be "ams-irq" + - clocks: Should contain a clock specifier for the device + - ranges: keep the property empty to map child address space + (for PS and/or PL) nodes 1:1 onto the parent address + space + + AMS sub-nodes: + - ams-ps : Used as PS-SYSMON node + - ams-pl : Used as PL-SYSMON node + + + +AMS PS-SYSMON +` +PS (Processing System) SYSMON is memory mapped to PS. This block has built-in +alarm generation logic that is used to interrupt the processor based on +condition set. + +Required properties: + - compatible: Should be "xlnx,zynqmp-ams-ps" + - reg: Register space for PS-SYSMON + + + +AMS PL-SYSMON +` +PL-SYSMON is capable of monitoring off chip voltage and temperature. PL-SYSMON +block has DRP, JTAG and I2C interface to enable monitoring from external master. +Out of this interface currently only DRP is supported. This block has alarm +generation logic that is used to interrupt the processor based on condition set. + +Required properties: + - compatible: Should be "xlnx,zynqmp-ams-pl" + - reg: Register space for PL-SYSMON + +PL-SYSMON optional sub-nodes: + - xlnx,ext-channels: List of external channels that are connected to the +AMS PL module. + + The child nodes of PL-SYSMON represent the external channels which are + connected to this Module. If the property is not present + no external channels will be assumed to be connected. + + Each child node represents one channel and has the following + properties: + + Required properties: + * reg: Pair of pins the channel is connected to. This value is + same as Channel Number for particular channel. + + 'reg' value Channel Name + --- + 30 VP/VN + 31 VUSER0 + 32 VUSER1 + 33 VUSER3 + 34 VUSER4 + 35 VAUXP[0]/VAUXN[0] + 36 VAUXP[1]/VAUXN[1] + ... + 50 VAUXP[15]/VAUXN[15] + + Each channel number should only be used at most once. For + more details on channels, refer to the table given at the end. + + Optional properties: + * xlnx,bipolar: If set the channel is used in bipolar + mode. + + +Example: + xilinx_ams: ams@ffa5 { + compatible = "xlnx,zynqmp-ams"; + interrupt-parent = <>; + interrupts = <0 56 4>; + interrupt-names = "ams-irq"; + reg = <0x0 0xffa5 0x0 0x800>; + reg-names = "ams-base"; + #address-cells = <1>; + #size-cells = <1>; + #io-channel-cells = <1>; + ranges = <0 0 0xffa50800 0x800>; + + ams_ps: ams-ps@0,0 { + compatible = "xlnx,zynqmp-ams-ps"; + reg = <0 0x400>; + }; + + ams_pl: ams-pl@1,0 { +
[PATCH v4 2/3] iio: adc: Add Xilinx AMS driver
The AMS includes an ADC as well as on-chip sensors that can be used to sample external voltages and monitor on-die operating conditions, such as temperature and supply voltage levels. The AMS has two SYSMON blocks. PL-SYSMON block is capable of monitoring off chip voltage and temperature. PL-SYSMON block has DRP, JTAG and I2C interface to enable monitoring from external master. Out of these interface currently only DRP is supported. Other block PS-SYSMON is memory mapped to PS. The AMS can use internal channels to monitor voltage and temperature as well as one primary and up to 16 auxiliary channels for measuring external voltages. The voltage and temperature monitoring channels also have event capability which allows to generate an interrupt when their value falls below or raises above a set threshold. Signed-off-by: Manish Narani --- drivers/iio/adc/Kconfig | 10 + drivers/iio/adc/Makefile |1 + drivers/iio/adc/xilinx-ams.c | 1341 ++ 3 files changed, 1352 insertions(+) create mode 100644 drivers/iio/adc/xilinx-ams.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 76db6e5..d98e275 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1071,4 +1071,14 @@ config XILINX_XADC The driver can also be build as a module. If so, the module will be called xilinx-xadc. +config XILINX_AMS + tristate "Xilinx AMS driver" + depends on ARCH_ZYNQMP || COMPILE_TEST + depends on HAS_IOMEM + help + Say yes here to have support for the Xilinx AMS. + + The driver can also be built as a module. If so, the module will be called + xilinx-ams. + endmenu diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 6fcebd1..06bc6b3 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -97,4 +97,5 @@ obj-$(CONFIG_VF610_ADC) += vf610_adc.o obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o +obj-$(CONFIG_XILINX_AMS) += xilinx-ams.o obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c new file mode 100644 index 000..b0d79c0 --- /dev/null +++ b/drivers/iio/adc/xilinx-ams.c @@ -0,0 +1,1341 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx AMS driver + * + * Copyright (C) 2017-2018 Xilinx, Inc. + * + * Manish Narani + * Rajnikant Bhojani + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static const unsigned int AMS_UNMASK_TIMEOUT_MS = 500; + +/* AMS registers definitions */ +#define AMS_ISR_0 0x010 +#define AMS_ISR_1 0x014 +#define AMS_IER_0 0x020 +#define AMS_IER_1 0x024 +#define AMS_IDR_0 0x028 +#define AMS_IDR_1 0x02c +#define AMS_PS_CSTS0x040 +#define AMS_PL_CSTS0x044 + +#define AMS_VCC_PSPLL0 0x060 +#define AMS_VCC_PSPLL3 0x06C +#define AMS_VCCINT 0x078 +#define AMS_VCCBRAM0x07C +#define AMS_VCCAUX 0x080 +#define AMS_PSDDRPLL 0x084 +#define AMS_PSINTFPDDR 0x09C + +#define AMS_VCC_PSPLL0_CH 48 +#define AMS_VCC_PSPLL3_CH 51 +#define AMS_VCCINT_CH 54 +#define AMS_VCCBRAM_CH 55 +#define AMS_VCCAUX_CH 56 +#define AMS_PSDDRPLL_CH57 +#define AMS_PSINTFPDDR_CH 63 + +#define AMS_REG_CONFIG00x100 +#define AMS_REG_CONFIG10x104 +#define AMS_REG_CONFIG30x10C +#define AMS_REG_SEQ_CH00x120 +#define AMS_REG_SEQ_CH10x124 +#define AMS_REG_SEQ_CH20x118 + +#define AMS_TEMP 0x000 +#define AMS_SUPPLY10x004 +#define AMS_SUPPLY20x008 +#define AMS_VP_VN 0x00c +#define AMS_VREFP 0x010 +#define AMS_VREFN 0x014 +#define AMS_SUPPLY30x018 +#define AMS_SUPPLY40x034 +#define AMS_SUPPLY50x038 +#define AMS_SUPPLY60x03c +#define AMS_SUPPLY70x200 +#define AMS_SUPPLY80x204 +#define AMS_SUPPLY90x208 +#define AMS_SUPPLY10 0x20c +#define AMS_VCCAMS 0x210 +#define AMS_TEMP_REMOTE0x214 + +#define AMS_REG_VAUX(x)(0x40 + 4*(x)) + +#define AMS_PS_RESET_VALUE 0x +#define AMS_PL_R
[PATCH v4 3/3] arm64: zynqmp: DT: Add Xilinx AMS node
The Xilinx AMS includes an ADC as well as on-chip sensors that can be used to sample external and monitor on-die operating conditions, such as temperature and supply voltage levels. Signed-off-by: Manish Narani --- arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 26 ++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 9aa6734..f776913 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -625,5 +625,31 @@ reg = <0x0 0xfd4d 0x0 0x1000>; timeout-sec = <10>; }; + + xilinx_ams: ams@ffa5 { + compatible = "xlnx,zynqmp-ams"; + status = "disabled"; + interrupt-parent = <>; + interrupts = <0 56 4>; + interrupt-names = "ams-irq"; + reg = <0x0 0xffa5 0x0 0x800>; + reg-names = "ams-base"; + #address-cells = <1>; + #size-cells = <1>; + #io-channel-cells = <1>; + ranges = <0 0 0xffa50800 0x800>; + + ams_ps: ams-ps@0,0 { + compatible = "xlnx,zynqmp-ams-ps"; + status = "disabled"; + reg = <0 0x400>; + }; + + ams_pl: ams-pl@1,0 { + compatible = "xlnx,zynqmp-ams-pl"; + status = "disabled"; + reg = <0x400 0x400>; + }; + }; }; }; -- 2.1.1
[PATCH v4 0/3] Add Xilinx AMS Driver
Add Xilinx AMS driver which is used for Xilinx's ZynqMP AMS controller. This AMS driver is used to report various interface voltages and temperatures across the system. This driver will be used by iio-hwmon to repport voltages and temperatures across the system by using various channel interfaces. This driver handles AMS module including PS-Sysmon & PL-Sysmon. The binding documentation is added for understanding of AMS, PS, PL Sysmon Channels. Changes in v2: - Added documentation for sysfs (Patch-2) - Addressed code style review comments - Patch-2 (Now it is Patch-3) - Arranged the includes in alphabetical order - Removed the wrapper 'ams_pl_write_reg()' and used writel instead - Removed the unnecessary delay of 1ms and used polling of EOC instead - Removed spin_lock and used mutex only. - Used request_irq() instead of devm_request_irq() and handled respective error conditions - Moved contents of xilinx-ams.h to inline with xilinx-ams.c - Patch-1 - Addressed Documentation style comments Changes in v3: - Updated bindings document with the suggested modification in v2 review - Removed documentation for sysfs - Removed extended names for channels in the Xilinx AMS driver - Modified dts to use ranges for child nodes - Reduced address and size cells to 32-bit instead of 64-bit Changes in v4: - Updated bindings document with the suggested modification in v3 review - Changed the Device Tree property 'ranges' for child nodes - Used Channel Numbers as 'reg' value in DT to avoid confusion - Removed unused NULL arguments as suggested in v3 patch review - Addressed comments on Device Tree property naming Manish Narani (3): dt-bindings: iio: adc: Add Xilinx AMS binding documentation iio: adc: Add Xilinx AMS driver arm64: zynqmp: DT: Add Xilinx AMS node .../devicetree/bindings/iio/adc/xilinx-ams.txt | 183 +++ arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 26 + drivers/iio/adc/Kconfig| 10 + drivers/iio/adc/Makefile |1 + drivers/iio/adc/xilinx-ams.c | 1341 5 files changed, 1561 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/xilinx-ams.txt create mode 100644 drivers/iio/adc/xilinx-ams.c -- 2.1.1
RE: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver
Hi Boris, > -Original Message- > From: Borislav Petkov [mailto:b...@alien8.de] > Sent: Tuesday, November 6, 2018 3:34 PM > To: Manish Narani > Cc: robh...@kernel.org; mark.rutl...@arm.com; Michal Simek > ; mche...@kernel.org; amit.kuche...@linaro.org; > sudeep.ho...@arm.com; leoyang...@nxp.com; devicet...@vger.kernel.org; > linux-kernel@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > e...@vger.kernel.org > Subject: Re: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver > > On Thu, Oct 25, 2018 at 11:36:55AM +0530, Manish Narani wrote: > > Change in v10: > > - Moved the checking for ce_cnt and ue_cnt before the readl() call > > - Aligned arguments on the opening brace in setup_irq() > > > > Manish Narani (6): > > edac: synopsys: Add error handling for NULL in probe() > > dt: bindings: Document ZynqMP DDRC in Synopsys documentation > > edac: synopsys: Add macro defines for ZynqMP DDRC > > edac: synopsys: Add EDAC ECC support for ZynqMP DDRC > > arm64: zynqmp: Add DDRC node > > edac: synopsys: Add Error Injection support for ZynqMP DDRC > > > > .../bindings/memory-controllers/synopsys.txt | 27 +- > > arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 7 + > > drivers/edac/Kconfig | 2 +- > > drivers/edac/synopsys_edac.c | 911 > > - > > 4 files changed, 918 insertions(+), 29 deletions(-) > > Ok, patches pushed here: > > (minus https://lkml.kernel.org/r/1540447621-22870-6-git-send-email- > manish.nar...@xilinx.com) > > https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=edac-for-4.21- > synps > Thanks a lot for your support. > Please run this on the hw before I queue it for linux-next. I have tested this and verified as working fine on hardware. You can go ahead and queue it for linux-next. Thanks, Manish
RE: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver
Hi Boris, > -Original Message- > From: Borislav Petkov [mailto:b...@alien8.de] > Sent: Tuesday, November 6, 2018 3:34 PM > To: Manish Narani > Cc: robh...@kernel.org; mark.rutl...@arm.com; Michal Simek > ; mche...@kernel.org; amit.kuche...@linaro.org; > sudeep.ho...@arm.com; leoyang...@nxp.com; devicet...@vger.kernel.org; > linux-kernel@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linux- > e...@vger.kernel.org > Subject: Re: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver > > On Thu, Oct 25, 2018 at 11:36:55AM +0530, Manish Narani wrote: > > Change in v10: > > - Moved the checking for ce_cnt and ue_cnt before the readl() call > > - Aligned arguments on the opening brace in setup_irq() > > > > Manish Narani (6): > > edac: synopsys: Add error handling for NULL in probe() > > dt: bindings: Document ZynqMP DDRC in Synopsys documentation > > edac: synopsys: Add macro defines for ZynqMP DDRC > > edac: synopsys: Add EDAC ECC support for ZynqMP DDRC > > arm64: zynqmp: Add DDRC node > > edac: synopsys: Add Error Injection support for ZynqMP DDRC > > > > .../bindings/memory-controllers/synopsys.txt | 27 +- > > arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 7 + > > drivers/edac/Kconfig | 2 +- > > drivers/edac/synopsys_edac.c | 911 > > - > > 4 files changed, 918 insertions(+), 29 deletions(-) > > Ok, patches pushed here: > > (minus https://lkml.kernel.org/r/1540447621-22870-6-git-send-email- > manish.nar...@xilinx.com) > > https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=edac-for-4.21- > synps > Thanks a lot for your support. > Please run this on the hw before I queue it for linux-next. I have tested this and verified as working fine on hardware. You can go ahead and queue it for linux-next. Thanks, Manish
RE: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver
Ping! > -Original Message- > From: Manish Narani [mailto:manish.nar...@xilinx.com] > Sent: Thursday, October 25, 2018 11:37 AM > To: robh...@kernel.org; mark.rutl...@arm.com; Michal Simek > ; b...@alien8.de; mche...@kernel.org; Manish Narani > ; amit.kuche...@linaro.org; sudeep.ho...@arm.com; > leoyang...@nxp.com > Cc: devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-e...@vger.kernel.org > Subject: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver > > This patch series enhances the current EDAC driver to support different > platforms. This series adds support for ZynqMP DDRC controller in synopsys > EDAC driver. This series also adds Device tree properties and relevant binding > documentation. > > Changes in v2: > - Moved checking of DDR_ECC_INTR_SUPPORT from (1/4) to (3/4) as it > is > a feature of ZynqMP DDRC > - The Binding Documentation in (2/4) is modified as per the review > comments > > Changes in v3: > - The commit message in (2/4) is modified (Synopsys EDAC Driver --> > ZynqMP DDRC) > > Changes in v4: > - Updated the commit message in (1/4) > - Renamed function pointer names removing 'synps_' in (1/4) > - Shortened unnecessary long lines as per the review comment on (1/4) > > Changes in v5: > - Updated the commit message in (2/4) and (4/4). > - Removed the unnecessary check for match data in probe() in (1/4) > - Some Indentation changes for better readability in (1/4) and (3/4) > - Removed repeated code in (3/4) > - Used 'zynq' and 'zynqmp' instead of 'synps_enh_edac' in function > names > > Changes in v6: > - Splitted the patches according to functionalities > - Addressed code style comments from v5 review > - Moved the Error Injection to CONFIG_EDAC_DEBUG mode > > Changes in v7: > - Included DTS patch (6/7) which was missed in v6 patch set > > Changes in v8: > - patch (1/7) from v7 is split in to 3 different logically different > patches > 1. functional changes like code cleanup > 2. functions renaming > 3. comments cleanup > - Added a separate patch (4) for making always successful functions as > void > - Corrected 'Too many parentheses' review comment in patch (5) > - Corrected comments as per the v7 review feedback > - Made dedicated functions for IRQ setup, IRQ enable and IRQ disable > in patch (8) > - Addressed review comments in patch (10) > > Changes in v9: > - Added check for return value of of_device_get_match_data() function > in (1/6). > - From v8 the first 5 patches are removed in this series as they are > applied on: > > https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/?h=edac-for- > 4.20-synps > - Updated Kconfig to check for ARCH_ZYNQMP instead of ARM64 > > Change in v10: > - Moved the checking for ce_cnt and ue_cnt before the readl() call > - Aligned arguments on the opening brace in setup_irq() > > Manish Narani (6): > edac: synopsys: Add error handling for NULL in probe() > dt: bindings: Document ZynqMP DDRC in Synopsys documentation > edac: synopsys: Add macro defines for ZynqMP DDRC > edac: synopsys: Add EDAC ECC support for ZynqMP DDRC > arm64: zynqmp: Add DDRC node > edac: synopsys: Add Error Injection support for ZynqMP DDRC > > .../bindings/memory-controllers/synopsys.txt | 27 +- > arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 7 + > drivers/edac/Kconfig | 2 +- > drivers/edac/synopsys_edac.c | 911 > - > 4 files changed, 918 insertions(+), 29 deletions(-) > > -- > 2.1.1
RE: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver
Ping! > -Original Message- > From: Manish Narani [mailto:manish.nar...@xilinx.com] > Sent: Thursday, October 25, 2018 11:37 AM > To: robh...@kernel.org; mark.rutl...@arm.com; Michal Simek > ; b...@alien8.de; mche...@kernel.org; Manish Narani > ; amit.kuche...@linaro.org; sudeep.ho...@arm.com; > leoyang...@nxp.com > Cc: devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-e...@vger.kernel.org > Subject: [PATCH v10 0/6] EDAC: Enhancements to Synopsys EDAC driver > > This patch series enhances the current EDAC driver to support different > platforms. This series adds support for ZynqMP DDRC controller in synopsys > EDAC driver. This series also adds Device tree properties and relevant binding > documentation. > > Changes in v2: > - Moved checking of DDR_ECC_INTR_SUPPORT from (1/4) to (3/4) as it > is > a feature of ZynqMP DDRC > - The Binding Documentation in (2/4) is modified as per the review > comments > > Changes in v3: > - The commit message in (2/4) is modified (Synopsys EDAC Driver --> > ZynqMP DDRC) > > Changes in v4: > - Updated the commit message in (1/4) > - Renamed function pointer names removing 'synps_' in (1/4) > - Shortened unnecessary long lines as per the review comment on (1/4) > > Changes in v5: > - Updated the commit message in (2/4) and (4/4). > - Removed the unnecessary check for match data in probe() in (1/4) > - Some Indentation changes for better readability in (1/4) and (3/4) > - Removed repeated code in (3/4) > - Used 'zynq' and 'zynqmp' instead of 'synps_enh_edac' in function > names > > Changes in v6: > - Splitted the patches according to functionalities > - Addressed code style comments from v5 review > - Moved the Error Injection to CONFIG_EDAC_DEBUG mode > > Changes in v7: > - Included DTS patch (6/7) which was missed in v6 patch set > > Changes in v8: > - patch (1/7) from v7 is split in to 3 different logically different > patches > 1. functional changes like code cleanup > 2. functions renaming > 3. comments cleanup > - Added a separate patch (4) for making always successful functions as > void > - Corrected 'Too many parentheses' review comment in patch (5) > - Corrected comments as per the v7 review feedback > - Made dedicated functions for IRQ setup, IRQ enable and IRQ disable > in patch (8) > - Addressed review comments in patch (10) > > Changes in v9: > - Added check for return value of of_device_get_match_data() function > in (1/6). > - From v8 the first 5 patches are removed in this series as they are > applied on: > > https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/?h=edac-for- > 4.20-synps > - Updated Kconfig to check for ARCH_ZYNQMP instead of ARM64 > > Change in v10: > - Moved the checking for ce_cnt and ue_cnt before the readl() call > - Aligned arguments on the opening brace in setup_irq() > > Manish Narani (6): > edac: synopsys: Add error handling for NULL in probe() > dt: bindings: Document ZynqMP DDRC in Synopsys documentation > edac: synopsys: Add macro defines for ZynqMP DDRC > edac: synopsys: Add EDAC ECC support for ZynqMP DDRC > arm64: zynqmp: Add DDRC node > edac: synopsys: Add Error Injection support for ZynqMP DDRC > > .../bindings/memory-controllers/synopsys.txt | 27 +- > arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 7 + > drivers/edac/Kconfig | 2 +- > drivers/edac/synopsys_edac.c | 911 > - > 4 files changed, 918 insertions(+), 29 deletions(-) > > -- > 2.1.1
[PATCH v10 3/6] edac: synopsys: Add macro defines for ZynqMP DDRC
Add macro defines for ZynqMP DDR controller. These macros will be used for ZynqMP ECC operations. Signed-off-by: Manish Narani --- drivers/edac/synopsys_edac.c | 168 +++ 1 file changed, 168 insertions(+) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 0005ef3..d1999e0 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -97,6 +97,174 @@ #define SCRUB_MODE_MASK0x7 #define SCRUB_MODE_SECDED 0x4 +/* DDR ECC Quirks */ +#define DDR_ECC_INTR_SUPPORT BIT(0) +#define DDR_ECC_DATA_POISON_SUPPORTBIT(1) + +/* ZynqMP Enhanced DDR memory controller registers that are relevant to ECC */ +/* ECC Configuration Registers */ +#define ECC_CFG0_OFST 0x70 +#define ECC_CFG1_OFST 0x74 + +/* ECC Status Register */ +#define ECC_STAT_OFST 0x78 + +/* ECC Clear Register */ +#define ECC_CLR_OFST 0x7C + +/* ECC Error count Register */ +#define ECC_ERRCNT_OFST0x80 + +/* ECC Corrected Error Address Register */ +#define ECC_CEADDR0_OFST 0x84 +#define ECC_CEADDR1_OFST 0x88 + +/* ECC Syndrome Registers */ +#define ECC_CSYND0_OFST0x8C +#define ECC_CSYND1_OFST0x90 +#define ECC_CSYND2_OFST0x94 + +/* ECC Bit Mask0 Address Register */ +#define ECC_BITMASK0_OFST 0x98 +#define ECC_BITMASK1_OFST 0x9C +#define ECC_BITMASK2_OFST 0xA0 + +/* ECC UnCorrected Error Address Register */ +#define ECC_UEADDR0_OFST 0xA4 +#define ECC_UEADDR1_OFST 0xA8 + +/* ECC Syndrome Registers */ +#define ECC_UESYND0_OFST 0xAC +#define ECC_UESYND1_OFST 0xB0 +#define ECC_UESYND2_OFST 0xB4 + +/* ECC Poison Address Reg */ +#define ECC_POISON0_OFST 0xB8 +#define ECC_POISON1_OFST 0xBC + +#define ECC_ADDRMAP0_OFFSET0x200 + +/* Control register bitfield definitions */ +#define ECC_CTRL_BUSWIDTH_MASK 0x3000 +#define ECC_CTRL_BUSWIDTH_SHIFT12 +#define ECC_CTRL_CLR_CE_ERRCNT BIT(2) +#define ECC_CTRL_CLR_UE_ERRCNT BIT(3) + +/* DDR Control Register width definitions */ +#define DDRCTL_EWDTH_162 +#define DDRCTL_EWDTH_321 +#define DDRCTL_EWDTH_640 + +/* ECC status register definitions */ +#define ECC_STAT_UECNT_MASK0xF +#define ECC_STAT_UECNT_SHIFT 16 +#define ECC_STAT_CECNT_MASK0xF00 +#define ECC_STAT_CECNT_SHIFT 8 +#define ECC_STAT_BITNUM_MASK 0x7F + +/* DDR QOS Interrupt register definitions */ +#define DDR_QOS_IRQ_STAT_OFST 0x20200 +#define DDR_QOSUE_MASK 0x4 +#defineDDR_QOSCE_MASK 0x2 +#defineECC_CE_UE_INTR_MASK 0x6 +#define DDR_QOS_IRQ_EN_OFST0x20208 +#define DDR_QOS_IRQ_DB_OFST0x2020C + +/* ECC Corrected Error Register Mask and Shifts*/ +#define ECC_CEADDR0_RW_MASK0x3 +#define ECC_CEADDR0_RNK_MASK BIT(24) +#define ECC_CEADDR1_BNKGRP_MASK0x300 +#define ECC_CEADDR1_BNKNR_MASK 0x7 +#define ECC_CEADDR1_BLKNR_MASK 0xFFF +#define ECC_CEADDR1_BNKGRP_SHIFT 24 +#define ECC_CEADDR1_BNKNR_SHIFT16 + +/* ECC Poison register shifts */ +#define ECC_POISON0_RANK_SHIFT 24 +#define ECC_POISON0_RANK_MASK BIT(24) +#define ECC_POISON0_COLUMN_SHIFT 0 +#define ECC_POISON0_COLUMN_MASK0xFFF +#define ECC_POISON1_BG_SHIFT 28 +#define ECC_POISON1_BG_MASK0x3000 +#define ECC_POISON1_BANKNR_SHIFT 24 +#define ECC_POISON1_BANKNR_MASK0x700 +#define ECC_POISON1_ROW_SHIFT 0 +#define ECC_POISON1_ROW_MASK 0x3 + +/* DDR Memory type defines */ +#define MEM_TYPE_DDR3 0x1 +#define MEM_TYPE_LPDDR30x8 +#define MEM_TYPE_DDR2 0x4 +#define MEM_TYPE_DDR4 0x10 +#define MEM_TYPE_LPDDR40x20 + +/* DDRC Software control register */ +#define DDRC_SWCTL 0x320 + +/* DDRC ECC CE & UE poison mask */ +#define ECC_CEPOISON_MASK 0x3 +#define ECC_UEPOISON_MASK 0x1 + +/* DDRC Device config masks */ +#define DDRC_MSTR_CFG_MASK 0xC000 +#define DDRC_MSTR_CFG_SHIFT30 +#define DDRC_MSTR_CFG_X4_MASK 0x0 +#define DDRC_MSTR_CFG_X8_MASK 0x1 +#define DDRC_MSTR_CFG_X16_MASK 0x2 +#define DDRC_MSTR_CFG_X32_MASK 0x3 + +#define DDR_MAX_ROW_SHIFT 18 +#define DDR_MAX_COL_SHIFT 14 +#define DDR_MAX_BANK_SHIFT 3 +#define DDR_MAX_BANKGRP_SHIFT 2 + +#de