91ed678b27f680cb2e345ad3011cbf0caaa35184
[openwrt/staging/mkresin.git] / target / linux / mvebu / patches-3.8 / 032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch
1 In the address decoding code, we implement two new functions:
2 orion_alloc_cpu_win() and orion_free_cpu_win(). The first function
3 finds an unused address decoding window, and configures it according
4 to the given arguments (in terms of base address, size, target,
5 attributes). The second function frees an address decoding window,
6 given a physical base address.
7
8 Those two new functions will be used by the PCIe code, which needs to
9 dynamically register address decoding windows depending on the PCIe
10 devices that are detected.
11
12 The orion_free_cpu_win() function is only here to handle error cases
13 in the PCIe devices initialization, in the normal case, address
14 decoding windows are never freed.
15
16 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
17 ---
18 arch/arm/plat-orion/addr-map.c | 50 +++++++++++++++++++++++++++
19 arch/arm/plat-orion/include/plat/addr-map.h | 7 ++++
20 2 files changed, 57 insertions(+)
21
22 --- a/arch/arm/plat-orion/addr-map.c
23 +++ b/arch/arm/plat-orion/addr-map.c
24 @@ -109,6 +109,56 @@ static void __init orion_disable_cpu_win
25 }
26
27 /*
28 + * Find an unused address decoding window, and enable it according to
29 + * the arguments passed (base, size, target, attributes, remap).
30 + */
31 +int __init orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg,
32 + const u32 base, const u32 size,
33 + const u8 target, const u8 attr, const int remap)
34 +{
35 + int win;
36 +
37 + for (win = 0; win < cfg->num_wins; win++) {
38 + void __iomem *addr = cfg->win_cfg_base(cfg, win);
39 + u32 ctrl = readl(addr + WIN_CTRL_OFF);
40 + if (!(ctrl & WIN_CTRL_ENABLE))
41 + break;
42 + }
43 +
44 + /* No more windows available */
45 + if (win == cfg->num_wins)
46 + return -ENOMEM;
47 +
48 + orion_setup_cpu_win(cfg, win, base, size, target, attr, remap);
49 + return 0;
50 +}
51 +
52 +/*
53 + * Free an address decoding window, given its base address.
54 + */
55 +int __init orion_free_cpu_win(const struct orion_addr_map_cfg *cfg,
56 + const u32 base)
57 +{
58 + int win;
59 +
60 + for (win = 0; win < cfg->num_wins; win++) {
61 + void __iomem *addr = cfg->win_cfg_base(cfg, win);
62 + u32 winbase = readl(addr + WIN_BASE_OFF);
63 + u32 ctrl = readl(addr + WIN_CTRL_OFF);
64 +
65 + if (!(ctrl & WIN_CTRL_ENABLE))
66 + continue;
67 +
68 + if (winbase == (base & 0xffff0000)) {
69 + orion_disable_cpu_win(cfg, win);
70 + return 0;
71 + }
72 + }
73 +
74 + return -EINVAL;
75 +}
76 +
77 +/*
78 * Configure a number of windows.
79 */
80 static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg,
81 --- a/arch/arm/plat-orion/include/plat/addr-map.h
82 +++ b/arch/arm/plat-orion/include/plat/addr-map.h
83 @@ -49,6 +49,13 @@ void __init orion_setup_cpu_win(const st
84 const u32 size, const u8 target,
85 const u8 attr, const int remap);
86
87 +int __init orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg,
88 + const u32 base, const u32 size,
89 + const u8 target, const u8 attr, const int remap);
90 +
91 +int __init orion_free_cpu_win(const struct orion_addr_map_cfg *cfg,
92 + const u32 base);
93 +
94 void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
95 const void __iomem *ddr_window_cpu_base);
96 #endif