summaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch')
-rw-r--r--target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch96
1 files changed, 96 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch b/target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch
new file mode 100644
index 000000000..91ed678b2
--- /dev/null
+++ b/target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch
@@ -0,0 +1,96 @@
+In the address decoding code, we implement two new functions:
+orion_alloc_cpu_win() and orion_free_cpu_win(). The first function
+finds an unused address decoding window, and configures it according
+to the given arguments (in terms of base address, size, target,
+attributes). The second function frees an address decoding window,
+given a physical base address.
+
+Those two new functions will be used by the PCIe code, which needs to
+dynamically register address decoding windows depending on the PCIe
+devices that are detected.
+
+The orion_free_cpu_win() function is only here to handle error cases
+in the PCIe devices initialization, in the normal case, address
+decoding windows are never freed.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+---
+ arch/arm/plat-orion/addr-map.c | 50 +++++++++++++++++++++++++++
+ arch/arm/plat-orion/include/plat/addr-map.h | 7 ++++
+ 2 files changed, 57 insertions(+)
+
+--- a/arch/arm/plat-orion/addr-map.c
++++ b/arch/arm/plat-orion/addr-map.c
+@@ -109,6 +109,56 @@ static void __init orion_disable_cpu_win
+ }
+
+ /*
++ * Find an unused address decoding window, and enable it according to
++ * the arguments passed (base, size, target, attributes, remap).
++ */
++int __init orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg,
++ const u32 base, const u32 size,
++ const u8 target, const u8 attr, const int remap)
++{
++ int win;
++
++ for (win = 0; win < cfg->num_wins; win++) {
++ void __iomem *addr = cfg->win_cfg_base(cfg, win);
++ u32 ctrl = readl(addr + WIN_CTRL_OFF);
++ if (!(ctrl & WIN_CTRL_ENABLE))
++ break;
++ }
++
++ /* No more windows available */
++ if (win == cfg->num_wins)
++ return -ENOMEM;
++
++ orion_setup_cpu_win(cfg, win, base, size, target, attr, remap);
++ return 0;
++}
++
++/*
++ * Free an address decoding window, given its base address.
++ */
++int __init orion_free_cpu_win(const struct orion_addr_map_cfg *cfg,
++ const u32 base)
++{
++ int win;
++
++ for (win = 0; win < cfg->num_wins; win++) {
++ void __iomem *addr = cfg->win_cfg_base(cfg, win);
++ u32 winbase = readl(addr + WIN_BASE_OFF);
++ u32 ctrl = readl(addr + WIN_CTRL_OFF);
++
++ if (!(ctrl & WIN_CTRL_ENABLE))
++ continue;
++
++ if (winbase == (base & 0xffff0000)) {
++ orion_disable_cpu_win(cfg, win);
++ return 0;
++ }
++ }
++
++ return -EINVAL;
++}
++
++/*
+ * Configure a number of windows.
+ */
+ static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg,
+--- a/arch/arm/plat-orion/include/plat/addr-map.h
++++ b/arch/arm/plat-orion/include/plat/addr-map.h
+@@ -49,6 +49,13 @@ void __init orion_setup_cpu_win(const st
+ const u32 size, const u8 target,
+ const u8 attr, const int remap);
+
++int __init orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg,
++ const u32 base, const u32 size,
++ const u8 target, const u8 attr, const int remap);
++
++int __init orion_free_cpu_win(const struct orion_addr_map_cfg *cfg,
++ const u32 base);
++
+ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
+ const void __iomem *ddr_window_cpu_base);
+ #endif