From 7e1e7063c26dccb6f47a00db72612e9f8c57c016 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 17 Jan 2013 22:29:13 +0000 Subject: mvebu: add preliminary support for PCI express Signed-off-by: Florian Fainelli SVN-Revision: 35211 --- ..._orion_introduce_orion_alloc_free_cpu_win.patch | 96 ++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch (limited to 'target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch') 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 0000000000..91ed678b27 --- /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 +--- + 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 -- cgit v1.2.3