1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2019 Broadcom.
13 #define DRD2U3H_XHC_REGS_AXIWRA 0xC08
14 #define DRD2U3H_XHC_REGS_AXIRDA 0xC0C
16 #define USBAXI_CACHE 0xF
17 #define USBAXI_PROT 0x8
18 #define USBAXI_SA_MASK 0x1FF
19 #define USBAXI_UA_MASK (0x1FF << 16)
20 #define USBAXI_SA_VAL ((USBAXI_CACHE << 4) | USBAXI_PROT)
21 #define USBAXI_UA_VAL (USBAXI_SA_VAL << 16)
22 #define USBAXI_SA_UA_MASK (USBAXI_UA_MASK | USBAXI_SA_MASK)
23 #define USBAXI_SA_UA_VAL (USBAXI_UA_VAL | USBAXI_SA_VAL)
25 struct brcm_xhci_platdata {
28 void __iomem *hc_base;
31 static int xhci_brcm_probe(struct udevice *dev)
33 struct brcm_xhci_platdata *plat = dev_get_platdata(dev);
34 struct xhci_hcor *hcor;
35 struct xhci_hccr *hcd;
39 dev_err(dev, "Can't get xHCI Plat data\n");
43 hcd = dev_read_addr_ptr(dev);
45 dev_err(dev, "Can't get the xHCI register base address\n");
50 len = HC_LENGTH(xhci_readl(&hcd->cr_capbase));
51 hcor = (struct xhci_hcor *)(plat->hc_base + len);
53 /* Save the default values of AXI read and write attributes */
54 plat->awcache = readl(plat->hc_base + DRD2U3H_XHC_REGS_AXIWRA);
55 plat->arcache = readl(plat->hc_base + DRD2U3H_XHC_REGS_AXIRDA);
57 /* Enable AXI write attributes */
58 clrsetbits_le32(plat->hc_base + DRD2U3H_XHC_REGS_AXIWRA,
59 USBAXI_SA_UA_MASK, USBAXI_SA_UA_VAL);
61 /* Enable AXI read attributes */
62 clrsetbits_le32(plat->hc_base + DRD2U3H_XHC_REGS_AXIRDA,
63 USBAXI_SA_UA_MASK, USBAXI_SA_UA_VAL);
65 ret = xhci_register(dev, hcd, hcor);
67 dev_err(dev, "Failed to register xHCI\n");
72 static int xhci_brcm_deregister(struct udevice *dev)
74 struct brcm_xhci_platdata *plat = dev_get_platdata(dev);
76 /* Restore the default values for AXI read and write attributes */
77 writel(plat->awcache, plat->hc_base + DRD2U3H_XHC_REGS_AXIWRA);
78 writel(plat->arcache, plat->hc_base + DRD2U3H_XHC_REGS_AXIRDA);
80 return xhci_deregister(dev);
83 static const struct udevice_id xhci_brcm_ids[] = {
84 { .compatible = "brcm,generic-xhci" },
88 U_BOOT_DRIVER(usb_xhci) = {
91 .probe = xhci_brcm_probe,
92 .remove = xhci_brcm_deregister,
94 .of_match = xhci_brcm_ids,
95 .platdata_auto_alloc_size = sizeof(struct brcm_xhci_platdata),
96 .priv_auto_alloc_size = sizeof(struct xhci_ctrl),
97 .flags = DM_FLAG_ALLOC_PRIV_DMA,