drivers/usb/dwc3/core.c | 24 ++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 8 ++++++++ drivers/usb/dwc3/dwc3-xilinx.c | 18 +++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-)
The GSBUSCFG0 register bits [31:16] are used to configure the cache type
settings of the descriptor and data write/read transfers (Cacheable,
Bufferable/Posted). When CCI is enabled in the design, DWC3 core GSBUSCFG0
cache bits must be updated to support CCI enabled transfers in USB.
To program GSBUSCFG0 cache bits create a software node property
in AMD-xilinx dwc3 glue driver and pass it to dwc3 core. The core
then reads this property value and configures it in dwc3_core_init()
sequence.
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
---
Changes for v3:
In v2 review as suggested by Thinh Nguyen, switch to swnode implementation
for passing GSBUSCFG0 cache bits from AMD-xilinx dwc3 glue driver to
core driver.
Changes for v2:
Make GSBUSCFG0 configuration specific to AMD-xilinx platform.
Taken reference from existing commit ec5eb43813a4 ("usb: dwc3: core:
add support for realtek SoCs custom's global register start address")
v1 link:
https://lore.kernel.org/all/20231013053448.11056-1-piyush.mehta@amd.com
---
drivers/usb/dwc3/core.c | 24 ++++++++++++++++++++++++
drivers/usb/dwc3/core.h | 8 ++++++++
drivers/usb/dwc3/dwc3-xilinx.c | 18 +++++++++++++++++-
3 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 7ee61a89520b..159d21b25629 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_graph.h>
#include <linux/acpi.h>
#include <linux/pinctrl/consumer.h>
@@ -599,6 +600,19 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9);
}
+static void dwc3_config_soc_bus(struct dwc3 *dwc)
+{
+ if (of_dma_is_coherent(dwc->dev->of_node)) {
+ u32 reg;
+
+ reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
+ reg &= ~DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_MASK;
+ reg |= (dwc->acache_data_rd_wr_info <<
+ DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_SHIFT);
+ dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
+ }
+}
+
static int dwc3_core_ulpi_init(struct dwc3 *dwc)
{
int intf;
@@ -1320,6 +1334,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc3_set_incr_burst_type(dwc);
+ dwc3_config_soc_bus(dwc);
+
ret = dwc3_phy_power_on(dwc);
if (ret)
goto err_exit_phy;
@@ -1574,6 +1590,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
u8 tx_max_burst_prd = 0;
u8 tx_fifo_resize_max_num;
const char *usb_psy_name;
+ struct device *tmpdev;
int ret;
/* default to highest possible threshold */
@@ -1716,6 +1733,13 @@ static void dwc3_get_properties(struct dwc3 *dwc)
dwc->dis_split_quirk = device_property_read_bool(dev,
"snps,dis-split-quirk");
+ /* Iterate over all parent nodes for finding swnode properties */
+ for (tmpdev = dwc->dev; tmpdev; tmpdev = tmpdev->parent) {
+ device_property_read_u16(tmpdev,
+ "snps,acache-data-rd-wr-info",
+ &dwc->acache_data_rd_wr_info);
+ }
+
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 3781c736c1a1..57b3cb739353 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -194,6 +194,10 @@
#define DWC3_GSBUSCFG0_INCRBRSTENA (1 << 0) /* undefined length enable */
#define DWC3_GSBUSCFG0_INCRBRST_MASK 0xff
+/* Global SoC Bus Configuration Register: AHB-prot/AXI-cache/OCP-ReqInfo */
+#define DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_MASK GENMASK(31, 16)
+#define DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_SHIFT 16
+
/* Global Debug LSP MUX Select */
#define DWC3_GDBGLSPMUX_ENDBC BIT(15) /* Host only */
#define DWC3_GDBGLSPMUX_HOSTSELECT(n) ((n) & 0x3fff)
@@ -1153,6 +1157,9 @@ struct dwc3_scratchpad_array {
* @num_ep_resized: carries the current number endpoints which have had its tx
* fifo resized.
* @debug_root: root debugfs directory for this device to put its files in.
+ * @acache_data_rd_wr_info: store GSBUSCFG0.DATRDREQINFO, DESRDREQINFO,
+ * DATWRREQINFO, and DESWRREQINFO value passed from
+ * glue driver.
*/
struct dwc3 {
struct work_struct drd_work;
@@ -1380,6 +1387,7 @@ struct dwc3 {
int last_fifo_depth;
int num_ep_resized;
struct dentry *debug_root;
+ u16 acache_data_rd_wr_info;
};
#define INCRX_BURST_MODE 0
diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index 6095f4dee6ce..f3757bfbd650 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -47,6 +47,15 @@ struct dwc3_xlnx {
struct phy *usb3_phy;
};
+static const struct property_entry dwc3_xilinx_properties[] = {
+ PROPERTY_ENTRY_U16("snps,acache-data-rd-wr-info", 0xffff),
+ {},
+};
+
+static const struct software_node dwc3_xilinx_swnode = {
+ .properties = dwc3_xilinx_properties,
+};
+
static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask)
{
u32 reg;
@@ -288,10 +297,14 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
if (ret)
goto err_clk_put;
- ret = of_platform_populate(np, NULL, NULL, dev);
+ ret = device_add_software_node(dev, &dwc3_xilinx_swnode);
if (ret)
goto err_clk_put;
+ ret = of_platform_populate(np, NULL, NULL, dev);
+ if (ret)
+ goto err_remove_swnode;
+
pm_runtime_set_active(dev);
ret = devm_pm_runtime_enable(dev);
if (ret < 0)
@@ -303,6 +316,9 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
err_pm_set_suspended:
pm_runtime_set_suspended(dev);
+err_remove_swnode:
+ device_remove_software_node(dev);
+
err_clk_put:
clk_bulk_disable_unprepare(priv_data->num_clocks, priv_data->clks);
--
2.34.1
On Thu, Jun 06, 2024 at 12:31:19PM +0530, Radhey Shyam Pandey wrote:
> The GSBUSCFG0 register bits [31:16] are used to configure the cache type
> settings of the descriptor and data write/read transfers (Cacheable,
> Bufferable/Posted). When CCI is enabled in the design, DWC3 core GSBUSCFG0
> cache bits must be updated to support CCI enabled transfers in USB.
>
> To program GSBUSCFG0 cache bits create a software node property
> in AMD-xilinx dwc3 glue driver and pass it to dwc3 core. The core
> then reads this property value and configures it in dwc3_core_init()
> sequence.
>
> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
> ---
Radhey:
Do you have plan to continue work on this? We met similar case
with this. If you have not time, I can help core.h and core.c part.
Frank
> Changes for v3:
> In v2 review as suggested by Thinh Nguyen, switch to swnode implementation
> for passing GSBUSCFG0 cache bits from AMD-xilinx dwc3 glue driver to
> core driver.
>
> Changes for v2:
> Make GSBUSCFG0 configuration specific to AMD-xilinx platform.
> Taken reference from existing commit ec5eb43813a4 ("usb: dwc3: core:
> add support for realtek SoCs custom's global register start address")
>
> v1 link:
> https://lore.kernel.org/all/20231013053448.11056-1-piyush.mehta@amd.com
> ---
> drivers/usb/dwc3/core.c | 24 ++++++++++++++++++++++++
> drivers/usb/dwc3/core.h | 8 ++++++++
> drivers/usb/dwc3/dwc3-xilinx.c | 18 +++++++++++++++++-
> 3 files changed, 49 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 7ee61a89520b..159d21b25629 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -23,6 +23,7 @@
> #include <linux/delay.h>
> #include <linux/dma-mapping.h>
> #include <linux/of.h>
> +#include <linux/of_address.h>
> #include <linux/of_graph.h>
> #include <linux/acpi.h>
> #include <linux/pinctrl/consumer.h>
> @@ -599,6 +600,19 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
> parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9);
> }
>
> +static void dwc3_config_soc_bus(struct dwc3 *dwc)
> +{
> + if (of_dma_is_coherent(dwc->dev->of_node)) {
> + u32 reg;
> +
> + reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
> + reg &= ~DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_MASK;
> + reg |= (dwc->acache_data_rd_wr_info <<
> + DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_SHIFT);
> + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
> + }
> +}
> +
> static int dwc3_core_ulpi_init(struct dwc3 *dwc)
> {
> int intf;
> @@ -1320,6 +1334,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
>
> dwc3_set_incr_burst_type(dwc);
>
> + dwc3_config_soc_bus(dwc);
> +
> ret = dwc3_phy_power_on(dwc);
> if (ret)
> goto err_exit_phy;
> @@ -1574,6 +1590,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> u8 tx_max_burst_prd = 0;
> u8 tx_fifo_resize_max_num;
> const char *usb_psy_name;
> + struct device *tmpdev;
> int ret;
>
> /* default to highest possible threshold */
> @@ -1716,6 +1733,13 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> dwc->dis_split_quirk = device_property_read_bool(dev,
> "snps,dis-split-quirk");
>
> + /* Iterate over all parent nodes for finding swnode properties */
> + for (tmpdev = dwc->dev; tmpdev; tmpdev = tmpdev->parent) {
> + device_property_read_u16(tmpdev,
> + "snps,acache-data-rd-wr-info",
> + &dwc->acache_data_rd_wr_info);
> + }
> +
> dwc->lpm_nyet_threshold = lpm_nyet_threshold;
> dwc->tx_de_emphasis = tx_de_emphasis;
>
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 3781c736c1a1..57b3cb739353 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -194,6 +194,10 @@
> #define DWC3_GSBUSCFG0_INCRBRSTENA (1 << 0) /* undefined length enable */
> #define DWC3_GSBUSCFG0_INCRBRST_MASK 0xff
>
> +/* Global SoC Bus Configuration Register: AHB-prot/AXI-cache/OCP-ReqInfo */
> +#define DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_MASK GENMASK(31, 16)
> +#define DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_SHIFT 16
> +
> /* Global Debug LSP MUX Select */
> #define DWC3_GDBGLSPMUX_ENDBC BIT(15) /* Host only */
> #define DWC3_GDBGLSPMUX_HOSTSELECT(n) ((n) & 0x3fff)
> @@ -1153,6 +1157,9 @@ struct dwc3_scratchpad_array {
> * @num_ep_resized: carries the current number endpoints which have had its tx
> * fifo resized.
> * @debug_root: root debugfs directory for this device to put its files in.
> + * @acache_data_rd_wr_info: store GSBUSCFG0.DATRDREQINFO, DESRDREQINFO,
> + * DATWRREQINFO, and DESWRREQINFO value passed from
> + * glue driver.
> */
> struct dwc3 {
> struct work_struct drd_work;
> @@ -1380,6 +1387,7 @@ struct dwc3 {
> int last_fifo_depth;
> int num_ep_resized;
> struct dentry *debug_root;
> + u16 acache_data_rd_wr_info;
> };
>
> #define INCRX_BURST_MODE 0
> diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
> index 6095f4dee6ce..f3757bfbd650 100644
> --- a/drivers/usb/dwc3/dwc3-xilinx.c
> +++ b/drivers/usb/dwc3/dwc3-xilinx.c
> @@ -47,6 +47,15 @@ struct dwc3_xlnx {
> struct phy *usb3_phy;
> };
>
> +static const struct property_entry dwc3_xilinx_properties[] = {
> + PROPERTY_ENTRY_U16("snps,acache-data-rd-wr-info", 0xffff),
> + {},
> +};
> +
> +static const struct software_node dwc3_xilinx_swnode = {
> + .properties = dwc3_xilinx_properties,
> +};
> +
> static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask)
> {
> u32 reg;
> @@ -288,10 +297,14 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
> if (ret)
> goto err_clk_put;
>
> - ret = of_platform_populate(np, NULL, NULL, dev);
> + ret = device_add_software_node(dev, &dwc3_xilinx_swnode);
> if (ret)
> goto err_clk_put;
>
> + ret = of_platform_populate(np, NULL, NULL, dev);
> + if (ret)
> + goto err_remove_swnode;
> +
> pm_runtime_set_active(dev);
> ret = devm_pm_runtime_enable(dev);
> if (ret < 0)
> @@ -303,6 +316,9 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
> err_pm_set_suspended:
> pm_runtime_set_suspended(dev);
>
> +err_remove_swnode:
> + device_remove_software_node(dev);
> +
> err_clk_put:
> clk_bulk_disable_unprepare(priv_data->num_clocks, priv_data->clks);
>
> --
> 2.34.1
>
Hi,
On Thu, Jun 06, 2024, Radhey Shyam Pandey wrote:
> The GSBUSCFG0 register bits [31:16] are used to configure the cache type
> settings of the descriptor and data write/read transfers (Cacheable,
> Bufferable/Posted). When CCI is enabled in the design, DWC3 core GSBUSCFG0
> cache bits must be updated to support CCI enabled transfers in USB.
>
> To program GSBUSCFG0 cache bits create a software node property
> in AMD-xilinx dwc3 glue driver and pass it to dwc3 core. The core
> then reads this property value and configures it in dwc3_core_init()
> sequence.
>
> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
> ---
> Changes for v3:
> In v2 review as suggested by Thinh Nguyen, switch to swnode implementation
> for passing GSBUSCFG0 cache bits from AMD-xilinx dwc3 glue driver to
> core driver.
>
> Changes for v2:
> Make GSBUSCFG0 configuration specific to AMD-xilinx platform.
> Taken reference from existing commit ec5eb43813a4 ("usb: dwc3: core:
> add support for realtek SoCs custom's global register start address")
>
> v1 link:
> https://urldefense.com/v3/__https://lore.kernel.org/all/20231013053448.11056-1-piyush.mehta@amd.com__;!!A4F2R9G_pg!cOoWxmacxPeYVCxDfg3-xlQLhKm8MIEgwWx45cLQjgwRWA4e4QyY_kGVVHo2m_dcRbpBQEFpB9JsYP6nzasK2AIAsyefjQ$
> ---
> drivers/usb/dwc3/core.c | 24 ++++++++++++++++++++++++
> drivers/usb/dwc3/core.h | 8 ++++++++
> drivers/usb/dwc3/dwc3-xilinx.c | 18 +++++++++++++++++-
> 3 files changed, 49 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 7ee61a89520b..159d21b25629 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -23,6 +23,7 @@
> #include <linux/delay.h>
> #include <linux/dma-mapping.h>
> #include <linux/of.h>
> +#include <linux/of_address.h>
> #include <linux/of_graph.h>
> #include <linux/acpi.h>
> #include <linux/pinctrl/consumer.h>
> @@ -599,6 +600,19 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
> parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9);
> }
>
> +static void dwc3_config_soc_bus(struct dwc3 *dwc)
> +{
> + if (of_dma_is_coherent(dwc->dev->of_node)) {
This can be applicable outside of of_node, do we need this if case?
> + u32 reg;
> +
> + reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
> + reg &= ~DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_MASK;
> + reg |= (dwc->acache_data_rd_wr_info <<
What if the user doesn't specify this property? We should not
automatically write 0 by default.
> + DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_SHIFT);
> + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
> + }
> +}
> +
> static int dwc3_core_ulpi_init(struct dwc3 *dwc)
> {
> int intf;
> @@ -1320,6 +1334,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
>
> dwc3_set_incr_burst_type(dwc);
>
> + dwc3_config_soc_bus(dwc);
> +
> ret = dwc3_phy_power_on(dwc);
> if (ret)
> goto err_exit_phy;
> @@ -1574,6 +1590,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> u8 tx_max_burst_prd = 0;
> u8 tx_fifo_resize_max_num;
> const char *usb_psy_name;
> + struct device *tmpdev;
> int ret;
>
> /* default to highest possible threshold */
> @@ -1716,6 +1733,13 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> dwc->dis_split_quirk = device_property_read_bool(dev,
> "snps,dis-split-quirk");
>
> + /* Iterate over all parent nodes for finding swnode properties */
> + for (tmpdev = dwc->dev; tmpdev; tmpdev = tmpdev->parent) {
> + device_property_read_u16(tmpdev,
> + "snps,acache-data-rd-wr-info",
> + &dwc->acache_data_rd_wr_info);
> + }
> +
Please split this to a separate function and name it as
dwc3_get_software_properties(). For now, just the new property you
create is fine. We can introduce new patches to move all the software
defined properties (ie. non ABI/DS) there such as sysdev_is_parent.
> dwc->lpm_nyet_threshold = lpm_nyet_threshold;
> dwc->tx_de_emphasis = tx_de_emphasis;
>
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 3781c736c1a1..57b3cb739353 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -194,6 +194,10 @@
> #define DWC3_GSBUSCFG0_INCRBRSTENA (1 << 0) /* undefined length enable */
> #define DWC3_GSBUSCFG0_INCRBRST_MASK 0xff
>
> +/* Global SoC Bus Configuration Register: AHB-prot/AXI-cache/OCP-ReqInfo */
> +#define DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_MASK GENMASK(31, 16)
Can we rename this to DWC3_GSBUSCFG0_REQINFO_MASK
> +#define DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_SHIFT 16
We don't need a shift value. Either define DWC3_GSBUSCFG0_REQINFO(n) or
use FIELD_PREP and the mask.
> +
> /* Global Debug LSP MUX Select */
> #define DWC3_GDBGLSPMUX_ENDBC BIT(15) /* Host only */
> #define DWC3_GDBGLSPMUX_HOSTSELECT(n) ((n) & 0x3fff)
> @@ -1153,6 +1157,9 @@ struct dwc3_scratchpad_array {
> * @num_ep_resized: carries the current number endpoints which have had its tx
> * fifo resized.
> * @debug_root: root debugfs directory for this device to put its files in.
> + * @acache_data_rd_wr_info: store GSBUSCFG0.DATRDREQINFO, DESRDREQINFO,
> + * DATWRREQINFO, and DESWRREQINFO value passed from
> + * glue driver.
> */
> struct dwc3 {
> struct work_struct drd_work;
> @@ -1380,6 +1387,7 @@ struct dwc3 {
> int last_fifo_depth;
> int num_ep_resized;
> struct dentry *debug_root;
> + u16 acache_data_rd_wr_info;
If we do need to keep this field around, please define the default
for unspecified value. Also rename this to gsbuscfg0_reqinfo.
> };
>
> #define INCRX_BURST_MODE 0
> diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
> index 6095f4dee6ce..f3757bfbd650 100644
> --- a/drivers/usb/dwc3/dwc3-xilinx.c
> +++ b/drivers/usb/dwc3/dwc3-xilinx.c
> @@ -47,6 +47,15 @@ struct dwc3_xlnx {
> struct phy *usb3_phy;
> };
>
> +static const struct property_entry dwc3_xilinx_properties[] = {
> + PROPERTY_ENTRY_U16("snps,acache-data-rd-wr-info", 0xffff),
> + {},
> +};
> +
> +static const struct software_node dwc3_xilinx_swnode = {
> + .properties = dwc3_xilinx_properties,
> +};
> +
> static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask)
> {
> u32 reg;
> @@ -288,10 +297,14 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
> if (ret)
> goto err_clk_put;
>
> - ret = of_platform_populate(np, NULL, NULL, dev);
> + ret = device_add_software_node(dev, &dwc3_xilinx_swnode);
> if (ret)
> goto err_clk_put;
>
> + ret = of_platform_populate(np, NULL, NULL, dev);
> + if (ret)
> + goto err_remove_swnode;
> +
> pm_runtime_set_active(dev);
> ret = devm_pm_runtime_enable(dev);
> if (ret < 0)
> @@ -303,6 +316,9 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
> err_pm_set_suspended:
> pm_runtime_set_suspended(dev);
>
> +err_remove_swnode:
> + device_remove_software_node(dev);
> +
> err_clk_put:
> clk_bulk_disable_unprepare(priv_data->num_clocks, priv_data->clks);
>
> --
> 2.34.1
>
Thanks,
Thinh
On 06/06/2024 09:01, Radhey Shyam Pandey wrote:
> The GSBUSCFG0 register bits [31:16] are used to configure the cache type
> settings of the descriptor and data write/read transfers (Cacheable,
> Bufferable/Posted). When CCI is enabled in the design, DWC3 core GSBUSCFG0
> cache bits must be updated to support CCI enabled transfers in USB.
>
> To program GSBUSCFG0 cache bits create a software node property
> in AMD-xilinx dwc3 glue driver and pass it to dwc3 core. The core
> then reads this property value and configures it in dwc3_core_init()
> sequence.
>
> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
> ---
> Changes for v3:
> In v2 review as suggested by Thinh Nguyen, switch to swnode implementation
> for passing GSBUSCFG0 cache bits from AMD-xilinx dwc3 glue driver to
> core driver.
>
> Changes for v2:
> Make GSBUSCFG0 configuration specific to AMD-xilinx platform.
> Taken reference from existing commit ec5eb43813a4 ("usb: dwc3: core:
> add support for realtek SoCs custom's global register start address")
>
> v1 link:
> https://lore.kernel.org/all/20231013053448.11056-1-piyush.mehta@amd.com
> ---
> drivers/usb/dwc3/core.c | 24 ++++++++++++++++++++++++
> drivers/usb/dwc3/core.h | 8 ++++++++
> drivers/usb/dwc3/dwc3-xilinx.c | 18 +++++++++++++++++-
> 3 files changed, 49 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 7ee61a89520b..159d21b25629 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -23,6 +23,7 @@
> #include <linux/delay.h>
> #include <linux/dma-mapping.h>
> #include <linux/of.h>
> +#include <linux/of_address.h>
> #include <linux/of_graph.h>
> #include <linux/acpi.h>
> #include <linux/pinctrl/consumer.h>
> @@ -599,6 +600,19 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
> parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9);
> }
>
> +static void dwc3_config_soc_bus(struct dwc3 *dwc)
> +{
> + if (of_dma_is_coherent(dwc->dev->of_node)) {
> + u32 reg;
> +
> + reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
> + reg &= ~DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_MASK;
> + reg |= (dwc->acache_data_rd_wr_info <<
> + DWC3_GSBUSCFG0_DAT_DES_RD_WR_REQINFO_SHIFT);
> + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
> + }
> +}
> +
> static int dwc3_core_ulpi_init(struct dwc3 *dwc)
> {
> int intf;
> @@ -1320,6 +1334,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
>
> dwc3_set_incr_burst_type(dwc);
>
> + dwc3_config_soc_bus(dwc);
> +
> ret = dwc3_phy_power_on(dwc);
> if (ret)
> goto err_exit_phy;
> @@ -1574,6 +1590,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> u8 tx_max_burst_prd = 0;
> u8 tx_fifo_resize_max_num;
> const char *usb_psy_name;
> + struct device *tmpdev;
> int ret;
>
> /* default to highest possible threshold */
> @@ -1716,6 +1733,13 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> dwc->dis_split_quirk = device_property_read_bool(dev,
> "snps,dis-split-quirk");
>
> + /* Iterate over all parent nodes for finding swnode properties */
And:
/* non-DT (non-ABI) properties */
so someone will not try to make it ABI post-factum.
Best regards,
Krzysztof
© 2016 - 2026 Red Hat, Inc.