0001
0002
0003
0004
0005
0006
0007 #include <linux/io.h>
0008 #include <linux/mbus.h>
0009 #include <linux/of.h>
0010 #include <linux/platform_device.h>
0011
0012 #include <linux/usb.h>
0013 #include <linux/usb/hcd.h>
0014
0015 #include "xhci-mvebu.h"
0016 #include "xhci.h"
0017
0018 #define USB3_MAX_WINDOWS 4
0019 #define USB3_WIN_CTRL(w) (0x0 + ((w) * 8))
0020 #define USB3_WIN_BASE(w) (0x4 + ((w) * 8))
0021
0022 static void xhci_mvebu_mbus_config(void __iomem *base,
0023 const struct mbus_dram_target_info *dram)
0024 {
0025 int win;
0026
0027
0028 for (win = 0; win < USB3_MAX_WINDOWS; win++) {
0029 writel(0, base + USB3_WIN_CTRL(win));
0030 writel(0, base + USB3_WIN_BASE(win));
0031 }
0032
0033
0034 for (win = 0; win < dram->num_cs; win++) {
0035 const struct mbus_dram_window *cs = dram->cs + win;
0036
0037 writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
0038 (dram->mbus_dram_target_id << 4) | 1,
0039 base + USB3_WIN_CTRL(win));
0040
0041 writel((cs->base & 0xffff0000), base + USB3_WIN_BASE(win));
0042 }
0043 }
0044
0045 int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
0046 {
0047 struct device *dev = hcd->self.controller;
0048 struct platform_device *pdev = to_platform_device(dev);
0049 struct resource *res;
0050 void __iomem *base;
0051 const struct mbus_dram_target_info *dram;
0052
0053 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
0054 if (!res)
0055 return -ENODEV;
0056
0057
0058
0059
0060
0061 base = ioremap(res->start, resource_size(res));
0062 if (!base)
0063 return -ENODEV;
0064
0065 dram = mv_mbus_dram_info();
0066 xhci_mvebu_mbus_config(base, dram);
0067
0068
0069
0070
0071
0072 iounmap(base);
0073
0074 return 0;
0075 }
0076
0077 int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
0078 {
0079 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
0080
0081
0082 xhci->quirks |= XHCI_RESET_ON_RESUME;
0083
0084 return 0;
0085 }