Commit | Line | Data |
---|---|---|
97374792 GC |
1 | /* |
2 | * Copyright (C) 2014 Marvell | |
3 | * Author: Gregory CLEMENT <gregory.clement@free-electrons.com> | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or | |
6 | * modify it under the terms of the GNU General Public License | |
7 | * version 2 as published by the Free Software Foundation. | |
8 | */ | |
9 | ||
10 | #include <linux/io.h> | |
11 | #include <linux/mbus.h> | |
12 | #include <linux/of.h> | |
13 | #include <linux/platform_device.h> | |
14 | ||
15 | #include "xhci-mvebu.h" | |
16 | ||
17 | #define USB3_MAX_WINDOWS 4 | |
18 | #define USB3_WIN_CTRL(w) (0x0 + ((w) * 8)) | |
19 | #define USB3_WIN_BASE(w) (0x4 + ((w) * 8)) | |
20 | ||
21 | static void xhci_mvebu_mbus_config(void __iomem *base, | |
22 | const struct mbus_dram_target_info *dram) | |
23 | { | |
24 | int win; | |
25 | ||
26 | /* Clear all existing windows */ | |
27 | for (win = 0; win < USB3_MAX_WINDOWS; win++) { | |
28 | writel(0, base + USB3_WIN_CTRL(win)); | |
29 | writel(0, base + USB3_WIN_BASE(win)); | |
30 | } | |
31 | ||
32 | /* Program each DRAM CS in a seperate window */ | |
33 | for (win = 0; win < dram->num_cs; win++) { | |
34 | const struct mbus_dram_window *cs = dram->cs + win; | |
35 | ||
36 | writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | | |
37 | (dram->mbus_dram_target_id << 4) | 1, | |
38 | base + USB3_WIN_CTRL(win)); | |
39 | ||
40 | writel((cs->base & 0xffff0000), base + USB3_WIN_BASE(win)); | |
41 | } | |
42 | } | |
43 | ||
44 | int xhci_mvebu_mbus_init_quirk(struct platform_device *pdev) | |
45 | { | |
46 | struct resource *res; | |
47 | void __iomem *base; | |
48 | const struct mbus_dram_target_info *dram; | |
49 | ||
50 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | |
51 | if (!res) | |
52 | return -ENODEV; | |
53 | ||
54 | /* | |
55 | * We don't use devm_ioremap() because this mapping should | |
56 | * only exists for the duration of this probe function. | |
57 | */ | |
58 | base = ioremap(res->start, resource_size(res)); | |
59 | if (!base) | |
60 | return -ENODEV; | |
61 | ||
62 | dram = mv_mbus_dram_info(); | |
63 | xhci_mvebu_mbus_config(base, dram); | |
64 | ||
65 | /* | |
66 | * This memory area was only needed to configure the MBus | |
67 | * windows, and is therefore no longer useful. | |
68 | */ | |
69 | iounmap(base); | |
70 | ||
71 | return 0; | |
72 | } |