mvebu: update to 3.8-rc4
[openwrt.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