Skip to content

Commit d504bfa

Browse files
Radhey Shyam Pandeygregkh
authored andcommitted
usb: dwc3: enable CCI support for AMD-xilinx DWC3 controller
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> Reviewed-by: Frank Li <Frank.Li@nxp.com> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/1720548651-726412-1-git-send-email-radhey.shyam.pandey@amd.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5af4370 commit d504bfa

3 files changed

Lines changed: 74 additions & 0 deletions

File tree

drivers/usb/dwc3/core.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,18 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
604604
parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9);
605605
}
606606

607+
static void dwc3_config_soc_bus(struct dwc3 *dwc)
608+
{
609+
if (dwc->gsbuscfg0_reqinfo != DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED) {
610+
u32 reg;
611+
612+
reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
613+
reg &= ~DWC3_GSBUSCFG0_REQINFO(~0);
614+
reg |= DWC3_GSBUSCFG0_REQINFO(dwc->gsbuscfg0_reqinfo);
615+
dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
616+
}
617+
}
618+
607619
static int dwc3_core_ulpi_init(struct dwc3 *dwc)
608620
{
609621
int intf;
@@ -1343,6 +1355,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
13431355

13441356
dwc3_set_incr_burst_type(dwc);
13451357

1358+
dwc3_config_soc_bus(dwc);
1359+
13461360
ret = dwc3_phy_power_on(dwc);
13471361
if (ret)
13481362
goto err_exit_phy;
@@ -1581,6 +1595,27 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
15811595
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
15821596
}
15831597

1598+
static void dwc3_get_software_properties(struct dwc3 *dwc)
1599+
{
1600+
struct device *tmpdev;
1601+
u16 gsbuscfg0_reqinfo;
1602+
int ret;
1603+
1604+
dwc->gsbuscfg0_reqinfo = DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED;
1605+
1606+
/*
1607+
* Iterate over all parent nodes for finding swnode properties
1608+
* and non-DT (non-ABI) properties.
1609+
*/
1610+
for (tmpdev = dwc->dev; tmpdev; tmpdev = tmpdev->parent) {
1611+
ret = device_property_read_u16(tmpdev,
1612+
"snps,gsbuscfg0-reqinfo",
1613+
&gsbuscfg0_reqinfo);
1614+
if (!ret)
1615+
dwc->gsbuscfg0_reqinfo = gsbuscfg0_reqinfo;
1616+
}
1617+
}
1618+
15841619
static void dwc3_get_properties(struct dwc3 *dwc)
15851620
{
15861621
struct device *dev = dwc->dev;
@@ -2095,6 +2130,8 @@ static int dwc3_probe(struct platform_device *pdev)
20952130

20962131
dwc3_get_properties(dwc);
20972132

2133+
dwc3_get_software_properties(dwc);
2134+
20982135
dwc->reset = devm_reset_control_array_get_optional_shared(dev);
20992136
if (IS_ERR(dwc->reset)) {
21002137
ret = PTR_ERR(dwc->reset);

drivers/usb/dwc3/core.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@
194194
#define DWC3_GSBUSCFG0_INCRBRSTENA (1 << 0) /* undefined length enable */
195195
#define DWC3_GSBUSCFG0_INCRBRST_MASK 0xff
196196

197+
/* Global SoC Bus Configuration Register: AHB-prot/AXI-cache/OCP-ReqInfo */
198+
#define DWC3_GSBUSCFG0_REQINFO(n) (((n) & 0xffff) << 16)
199+
#define DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED 0xffffffff
200+
197201
/* Global Debug LSP MUX Select */
198202
#define DWC3_GDBGLSPMUX_ENDBC BIT(15) /* Host only */
199203
#define DWC3_GDBGLSPMUX_HOSTSELECT(n) ((n) & 0x3fff)
@@ -1153,6 +1157,9 @@ struct dwc3_scratchpad_array {
11531157
* @num_ep_resized: carries the current number endpoints which have had its tx
11541158
* fifo resized.
11551159
* @debug_root: root debugfs directory for this device to put its files in.
1160+
* @gsbuscfg0_reqinfo: store GSBUSCFG0.DATRDREQINFO, DESRDREQINFO,
1161+
* DATWRREQINFO, and DESWRREQINFO value passed from
1162+
* glue driver.
11561163
*/
11571164
struct dwc3 {
11581165
struct work_struct drd_work;
@@ -1380,6 +1387,7 @@ struct dwc3 {
13801387
int last_fifo_depth;
13811388
int num_ep_resized;
13821389
struct dentry *debug_root;
1390+
u32 gsbuscfg0_reqinfo;
13831391
};
13841392

13851393
#define INCRX_BURST_MODE 0

drivers/usb/dwc3/dwc3-xilinx.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,31 @@ static const struct of_device_id dwc3_xlnx_of_match[] = {
246246
};
247247
MODULE_DEVICE_TABLE(of, dwc3_xlnx_of_match);
248248

249+
static int dwc3_set_swnode(struct device *dev)
250+
{
251+
struct device_node *np = dev->of_node, *dwc3_np;
252+
struct property_entry props[2];
253+
int prop_idx = 0, ret = 0;
254+
255+
dwc3_np = of_get_compatible_child(np, "snps,dwc3");
256+
if (!dwc3_np) {
257+
ret = -ENODEV;
258+
dev_err(dev, "failed to find dwc3 core child\n");
259+
return ret;
260+
}
261+
262+
memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
263+
if (of_dma_is_coherent(dwc3_np))
264+
props[prop_idx++] = PROPERTY_ENTRY_U16("snps,gsbuscfg0-reqinfo",
265+
0xffff);
266+
of_node_put(dwc3_np);
267+
268+
if (prop_idx)
269+
ret = device_create_managed_software_node(dev, props, NULL);
270+
271+
return ret;
272+
}
273+
249274
static int dwc3_xlnx_probe(struct platform_device *pdev)
250275
{
251276
struct dwc3_xlnx *priv_data;
@@ -288,6 +313,10 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
288313
if (ret)
289314
goto err_clk_put;
290315

316+
ret = dwc3_set_swnode(dev);
317+
if (ret)
318+
goto err_clk_put;
319+
291320
ret = of_platform_populate(np, NULL, NULL, dev);
292321
if (ret)
293322
goto err_clk_put;

0 commit comments

Comments
 (0)