diff options
author | Andrew Lunn <andrew@lunn.ch> | 2011-12-07 15:48:05 -0500 |
---|---|---|
committer | Nicolas Pitre <nico@fluxnic.net> | 2011-12-13 18:46:20 -0500 |
commit | b6d1c33a31deb1784c1d34070db6e84fd6f9d870 (patch) | |
tree | 18739a6c79b10f0fe69c01be5571e7a5af4d0e21 | |
parent | 527ef0550d79e3b3a0ef8f5061072075afef6aaf (diff) |
ARM: Orion: Consolidate the address map setup
Compile tested on Dove, orion5x, mv78xx0. Boot tested on Kirkwood.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Michael Walle <michael@walle.cc>
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
-rw-r--r-- | arch/arm/mach-dove/addr-map.c | 113 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/addr-map.c | 138 | ||||
-rw-r--r-- | arch/arm/mach-mv78xx0/addr-map.c | 102 | ||||
-rw-r--r-- | arch/arm/mach-orion5x/addr-map.c | 146 | ||||
-rw-r--r-- | arch/arm/mach-orion5x/common.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-orion5x/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-orion5x/include/mach/orion5x.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-orion/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/plat-orion/addr-map.c | 166 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/addr-map.h | 52 |
10 files changed, 375 insertions, 355 deletions
diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c index 00be4fc26dd7..1584726088e4 100644 --- a/arch/arm/mach-dove/addr-map.c +++ b/arch/arm/mach-dove/addr-map.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <asm/mach/arch.h> | 15 | #include <asm/mach/arch.h> |
16 | #include <asm/setup.h> | 16 | #include <asm/setup.h> |
17 | #include <plat/addr-map.h> | ||
17 | #include "common.h" | 18 | #include "common.h" |
18 | 19 | ||
19 | /* | 20 | /* |
@@ -34,14 +35,6 @@ | |||
34 | #define ATTR_PCIE_MEM 0xe8 | 35 | #define ATTR_PCIE_MEM 0xe8 |
35 | #define ATTR_SCRATCHPAD 0x0 | 36 | #define ATTR_SCRATCHPAD 0x0 |
36 | 37 | ||
37 | /* | ||
38 | * CPU Address Decode Windows registers | ||
39 | */ | ||
40 | #define WIN_CTRL(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x0) | ||
41 | #define WIN_BASE(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x4) | ||
42 | #define WIN_REMAP_LO(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x8) | ||
43 | #define WIN_REMAP_HI(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0xc) | ||
44 | |||
45 | struct mbus_dram_target_info dove_mbus_dram_info; | 38 | struct mbus_dram_target_info dove_mbus_dram_info; |
46 | 39 | ||
47 | static inline void __iomem *ddr_map_sc(int i) | 40 | static inline void __iomem *ddr_map_sc(int i) |
@@ -49,78 +42,62 @@ static inline void __iomem *ddr_map_sc(int i) | |||
49 | return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4)); | 42 | return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4)); |
50 | } | 43 | } |
51 | 44 | ||
52 | static int cpu_win_can_remap(int win) | 45 | /* |
53 | { | 46 | * Description of the windows needed by the platform code |
54 | if (win < 4) | 47 | */ |
55 | return 1; | 48 | static struct __initdata orion_addr_map_cfg addr_map_cfg = { |
56 | 49 | .num_wins = 8, | |
57 | return 0; | 50 | .remappable_wins = 4, |
58 | } | 51 | .bridge_virt_base = BRIDGE_VIRT_BASE, |
59 | 52 | }; | |
60 | static void __init setup_cpu_win(int win, u32 base, u32 size, | ||
61 | u8 target, u8 attr, int remap) | ||
62 | { | ||
63 | u32 ctrl; | ||
64 | |||
65 | base &= 0xffff0000; | ||
66 | ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; | ||
67 | |||
68 | writel(base, WIN_BASE(win)); | ||
69 | writel(ctrl, WIN_CTRL(win)); | ||
70 | if (cpu_win_can_remap(win)) { | ||
71 | if (remap < 0) | ||
72 | remap = base; | ||
73 | writel(remap & 0xffff0000, WIN_REMAP_LO(win)); | ||
74 | writel(0, WIN_REMAP_HI(win)); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | void __init dove_setup_cpu_mbus(void) | ||
79 | { | ||
80 | int i; | ||
81 | int cs; | ||
82 | 53 | ||
54 | static const struct __initdata orion_addr_map_info addr_map_info[] = { | ||
83 | /* | 55 | /* |
84 | * First, disable and clear windows. | 56 | * Windows for PCIe IO+MEM space. |
85 | */ | 57 | */ |
86 | for (i = 0; i < 8; i++) { | 58 | { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE, |
87 | writel(0, WIN_BASE(i)); | 59 | TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE |
88 | writel(0, WIN_CTRL(i)); | 60 | }, |
89 | if (cpu_win_can_remap(i)) { | 61 | { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE, |
90 | writel(0, WIN_REMAP_LO(i)); | 62 | TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE |
91 | writel(0, WIN_REMAP_HI(i)); | 63 | }, |
92 | } | 64 | { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE, |
93 | } | 65 | TARGET_PCIE0, ATTR_PCIE_MEM, -1 |
94 | 66 | }, | |
67 | { 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE, | ||
68 | TARGET_PCIE1, ATTR_PCIE_MEM, -1 | ||
69 | }, | ||
95 | /* | 70 | /* |
96 | * Setup windows for PCIe IO+MEM space. | 71 | * Window for CESA engine. |
97 | */ | 72 | */ |
98 | setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE, | 73 | { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE, |
99 | TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE); | 74 | TARGET_CESA, ATTR_CESA, -1 |
100 | setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE, | 75 | }, |
101 | TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE); | ||
102 | setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE, | ||
103 | TARGET_PCIE0, ATTR_PCIE_MEM, -1); | ||
104 | setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE, | ||
105 | TARGET_PCIE1, ATTR_PCIE_MEM, -1); | ||
106 | |||
107 | /* | 76 | /* |
108 | * Setup window for CESA engine. | 77 | * Window to the BootROM for Standby and Sleep Resume |
109 | */ | 78 | */ |
110 | setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE, | 79 | { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE, |
111 | TARGET_CESA, ATTR_CESA, -1); | 80 | TARGET_BOOTROM, ATTR_BOOTROM, -1 |
112 | 81 | }, | |
113 | /* | 82 | /* |
114 | * Setup the Window to the BootROM for Standby and Sleep Resume | 83 | * Window to the PMU Scratch Pad space |
115 | */ | 84 | */ |
116 | setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE, | 85 | { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE, |
117 | TARGET_BOOTROM, ATTR_BOOTROM, -1); | 86 | TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1 |
87 | }, | ||
88 | /* End marker */ | ||
89 | { -1, 0, 0, 0, 0, 0 } | ||
90 | }; | ||
91 | |||
92 | void __init dove_setup_cpu_mbus(void) | ||
93 | { | ||
94 | int i; | ||
95 | int cs; | ||
118 | 96 | ||
119 | /* | 97 | /* |
120 | * Setup the Window to the PMU Scratch Pad space | 98 | * Disable, clear and configure windows. |
121 | */ | 99 | */ |
122 | setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE, | 100 | orion_config_wins(&addr_map_cfg, addr_map_info); |
123 | TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1); | ||
124 | 101 | ||
125 | /* | 102 | /* |
126 | * Setup MBUS dram target info. | 103 | * Setup MBUS dram target info. |
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c index 8d03bcef5182..935392f7e13f 100644 --- a/arch/arm/mach-kirkwood/addr-map.c +++ b/arch/arm/mach-kirkwood/addr-map.c | |||
@@ -13,12 +13,12 @@ | |||
13 | #include <linux/mbus.h> | 13 | #include <linux/mbus.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <mach/hardware.h> | 15 | #include <mach/hardware.h> |
16 | #include <plat/addr-map.h> | ||
16 | #include "common.h" | 17 | #include "common.h" |
17 | 18 | ||
18 | /* | 19 | /* |
19 | * Generic Address Decode Windows bit settings | 20 | * Generic Address Decode Windows bit settings |
20 | */ | 21 | */ |
21 | #define TARGET_DDR 0 | ||
22 | #define TARGET_DEV_BUS 1 | 22 | #define TARGET_DEV_BUS 1 |
23 | #define TARGET_SRAM 3 | 23 | #define TARGET_SRAM 3 |
24 | #define TARGET_PCIE 4 | 24 | #define TARGET_PCIE 4 |
@@ -35,119 +35,59 @@ | |||
35 | #define ATTR_PCIE1_MEM 0xd8 | 35 | #define ATTR_PCIE1_MEM 0xd8 |
36 | #define ATTR_SRAM 0x01 | 36 | #define ATTR_SRAM 0x01 |
37 | 37 | ||
38 | /* | 38 | struct mbus_dram_target_info kirkwood_mbus_dram_info; |
39 | * Helpers to get DDR bank info | ||
40 | */ | ||
41 | #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) | ||
42 | #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) | ||
43 | 39 | ||
44 | /* | 40 | /* |
45 | * CPU Address Decode Windows registers | 41 | * Description of the windows needed by the platform code |
46 | */ | 42 | */ |
47 | #define WIN_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) | 43 | static struct __initdata orion_addr_map_cfg addr_map_cfg = { |
48 | #define WIN_CTRL_OFF 0x0000 | 44 | .num_wins = 8, |
49 | #define WIN_BASE_OFF 0x0004 | 45 | .remappable_wins = 4, |
50 | #define WIN_REMAP_LO_OFF 0x0008 | 46 | .bridge_virt_base = BRIDGE_VIRT_BASE, |
51 | #define WIN_REMAP_HI_OFF 0x000c | 47 | }; |
52 | |||
53 | |||
54 | struct mbus_dram_target_info kirkwood_mbus_dram_info; | ||
55 | |||
56 | static int __init cpu_win_can_remap(int win) | ||
57 | { | ||
58 | if (win < 4) | ||
59 | return 1; | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void __init setup_cpu_win(int win, u32 base, u32 size, | ||
65 | u8 target, u8 attr, int remap) | ||
66 | { | ||
67 | void __iomem *addr = (void __iomem *)WIN_OFF(win); | ||
68 | u32 ctrl; | ||
69 | |||
70 | base &= 0xffff0000; | ||
71 | ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; | ||
72 | |||
73 | writel(base, addr + WIN_BASE_OFF); | ||
74 | writel(ctrl, addr + WIN_CTRL_OFF); | ||
75 | if (cpu_win_can_remap(win)) { | ||
76 | if (remap < 0) | ||
77 | remap = base; | ||
78 | |||
79 | writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF); | ||
80 | writel(0, addr + WIN_REMAP_HI_OFF); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | void __init kirkwood_setup_cpu_mbus(void) | ||
85 | { | ||
86 | void __iomem *addr; | ||
87 | int i; | ||
88 | int cs; | ||
89 | 48 | ||
49 | static const struct __initdata orion_addr_map_info addr_map_info[] = { | ||
90 | /* | 50 | /* |
91 | * First, disable and clear windows. | 51 | * Windows for PCIe IO+MEM space. |
92 | */ | 52 | */ |
93 | for (i = 0; i < 8; i++) { | 53 | { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, |
94 | addr = (void __iomem *)WIN_OFF(i); | 54 | TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE |
95 | 55 | }, | |
96 | writel(0, addr + WIN_BASE_OFF); | 56 | { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, |
97 | writel(0, addr + WIN_CTRL_OFF); | 57 | TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE |
98 | if (cpu_win_can_remap(i)) { | 58 | }, |
99 | writel(0, addr + WIN_REMAP_LO_OFF); | 59 | { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE, |
100 | writel(0, addr + WIN_REMAP_HI_OFF); | 60 | TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE |
101 | } | 61 | }, |
102 | } | 62 | { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE, |
103 | 63 | TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE | |
64 | }, | ||
104 | /* | 65 | /* |
105 | * Setup windows for PCIe IO+MEM space. | 66 | * Window for NAND controller. |
106 | */ | 67 | */ |
107 | setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, | 68 | { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, |
108 | TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); | 69 | TARGET_DEV_BUS, ATTR_DEV_NAND, -1 |
109 | setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, | 70 | }, |
110 | TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE); | ||
111 | setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE, | ||
112 | TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE); | ||
113 | setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE, | ||
114 | TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE); | ||
115 | |||
116 | /* | 71 | /* |
117 | * Setup window for NAND controller. | 72 | * Window for SRAM. |
118 | */ | 73 | */ |
119 | setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, | 74 | { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, |
120 | TARGET_DEV_BUS, ATTR_DEV_NAND, -1); | 75 | TARGET_SRAM, ATTR_SRAM, -1 |
76 | }, | ||
77 | /* End marker */ | ||
78 | { -1, 0, 0, 0, 0, 0 } | ||
79 | }; | ||
121 | 80 | ||
81 | void __init kirkwood_setup_cpu_mbus(void) | ||
82 | { | ||
122 | /* | 83 | /* |
123 | * Setup window for SRAM. | 84 | * Disable, clear and configure windows. |
124 | */ | 85 | */ |
125 | setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, | 86 | orion_config_wins(&addr_map_cfg, addr_map_info); |
126 | TARGET_SRAM, ATTR_SRAM, -1); | ||
127 | 87 | ||
128 | /* | 88 | /* |
129 | * Setup MBUS dram target info. | 89 | * Setup MBUS dram target info. |
130 | */ | 90 | */ |
131 | kirkwood_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; | 91 | orion_setup_cpu_mbus_target(&addr_map_cfg, &kirkwood_mbus_dram_info, |
132 | 92 | DDR_WINDOW_CPU_BASE); | |
133 | addr = (void __iomem *)DDR_WINDOW_CPU_BASE; | ||
134 | |||
135 | for (i = 0, cs = 0; i < 4; i++) { | ||
136 | u32 base = readl(addr + DDR_BASE_CS_OFF(i)); | ||
137 | u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); | ||
138 | |||
139 | /* | ||
140 | * Chip select enabled? | ||
141 | */ | ||
142 | if (size & 1) { | ||
143 | struct mbus_dram_window *w; | ||
144 | |||
145 | w = &kirkwood_mbus_dram_info.cs[cs++]; | ||
146 | w->cs_index = i; | ||
147 | w->mbus_attr = 0xf & ~(1 << i); | ||
148 | w->base = base & 0xffff0000; | ||
149 | w->size = (size | 0x0000ffff) + 1; | ||
150 | } | ||
151 | } | ||
152 | kirkwood_mbus_dram_info.num_cs = cs; | ||
153 | } | 93 | } |
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c index 311d5b0e9bc7..6b14555e5766 100644 --- a/arch/arm/mach-mv78xx0/addr-map.c +++ b/arch/arm/mach-mv78xx0/addr-map.c | |||
@@ -12,12 +12,12 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/mbus.h> | 13 | #include <linux/mbus.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <plat/addr-map.h> | ||
15 | #include "common.h" | 16 | #include "common.h" |
16 | 17 | ||
17 | /* | 18 | /* |
18 | * Generic Address Decode Windows bit settings | 19 | * Generic Address Decode Windows bit settings |
19 | */ | 20 | */ |
20 | #define TARGET_DDR 0 | ||
21 | #define TARGET_DEV_BUS 1 | 21 | #define TARGET_DEV_BUS 1 |
22 | #define TARGET_PCIE0 4 | 22 | #define TARGET_PCIE0 4 |
23 | #define TARGET_PCIE1 8 | 23 | #define TARGET_PCIE1 8 |
@@ -32,21 +32,10 @@ | |||
32 | #define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l))) | 32 | #define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l))) |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Helpers to get DDR bank info | ||
36 | */ | ||
37 | #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) | ||
38 | #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) | ||
39 | |||
40 | /* | ||
41 | * CPU Address Decode Windows registers | 35 | * CPU Address Decode Windows registers |
42 | */ | 36 | */ |
43 | #define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) | 37 | #define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) |
44 | #define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) | 38 | #define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) |
45 | #define WIN_CTRL_OFF 0x0000 | ||
46 | #define WIN_BASE_OFF 0x0004 | ||
47 | #define WIN_REMAP_LO_OFF 0x0008 | ||
48 | #define WIN_REMAP_HI_OFF 0x000c | ||
49 | |||
50 | 39 | ||
51 | struct mbus_dram_target_info mv78xx0_mbus_dram_info; | 40 | struct mbus_dram_target_info mv78xx0_mbus_dram_info; |
52 | 41 | ||
@@ -63,94 +52,45 @@ static void __init __iomem *win_cfg_base(int win) | |||
63 | return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win)); | 52 | return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win)); |
64 | } | 53 | } |
65 | 54 | ||
66 | static int __init cpu_win_can_remap(int win) | 55 | /* |
67 | { | 56 | * Description of the windows needed by the platform code |
68 | if (win < 8) | 57 | */ |
69 | return 1; | 58 | static struct __initdata orion_addr_map_cfg addr_map_cfg = { |
70 | 59 | .num_wins = 14, | |
71 | return 0; | 60 | .remappable_wins = 8, |
72 | } | 61 | .win_cfg_base = win_cfg_base, |
73 | 62 | }; | |
74 | static void __init setup_cpu_win(int win, u32 base, u32 size, | ||
75 | u8 target, u8 attr, int remap) | ||
76 | { | ||
77 | void __iomem *addr = win_cfg_base(win); | ||
78 | u32 ctrl; | ||
79 | |||
80 | base &= 0xffff0000; | ||
81 | ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; | ||
82 | |||
83 | writel(base, addr + WIN_BASE_OFF); | ||
84 | writel(ctrl, addr + WIN_CTRL_OFF); | ||
85 | if (cpu_win_can_remap(win)) { | ||
86 | if (remap < 0) | ||
87 | remap = base; | ||
88 | |||
89 | writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF); | ||
90 | writel(0, addr + WIN_REMAP_HI_OFF); | ||
91 | } | ||
92 | } | ||
93 | 63 | ||
94 | void __init mv78xx0_setup_cpu_mbus(void) | 64 | void __init mv78xx0_setup_cpu_mbus(void) |
95 | { | 65 | { |
96 | void __iomem *addr; | ||
97 | int i; | ||
98 | int cs; | ||
99 | |||
100 | /* | 66 | /* |
101 | * First, disable and clear windows. | 67 | * Disable, clear and configure windows. |
102 | */ | 68 | */ |
103 | for (i = 0; i < 14; i++) { | 69 | orion_config_wins(&addr_map_cfg, NULL); |
104 | addr = win_cfg_base(i); | ||
105 | |||
106 | writel(0, addr + WIN_BASE_OFF); | ||
107 | writel(0, addr + WIN_CTRL_OFF); | ||
108 | if (cpu_win_can_remap(i)) { | ||
109 | writel(0, addr + WIN_REMAP_LO_OFF); | ||
110 | writel(0, addr + WIN_REMAP_HI_OFF); | ||
111 | } | ||
112 | } | ||
113 | 70 | ||
114 | /* | 71 | /* |
115 | * Setup MBUS dram target info. | 72 | * Setup MBUS dram target info. |
116 | */ | 73 | */ |
117 | mv78xx0_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; | ||
118 | |||
119 | if (mv78xx0_core_index() == 0) | 74 | if (mv78xx0_core_index() == 0) |
120 | addr = (void __iomem *)DDR_WINDOW_CPU0_BASE; | 75 | orion_setup_cpu_mbus_target(&addr_map_cfg, |
76 | &mv78xx0_mbus_dram_info, | ||
77 | DDR_WINDOW_CPU0_BASE); | ||
121 | else | 78 | else |
122 | addr = (void __iomem *)DDR_WINDOW_CPU1_BASE; | 79 | orion_setup_cpu_mbus_target(&addr_map_cfg, |
123 | 80 | &mv78xx0_mbus_dram_info, | |
124 | for (i = 0, cs = 0; i < 4; i++) { | 81 | DDR_WINDOW_CPU1_BASE); |
125 | u32 base = readl(addr + DDR_BASE_CS_OFF(i)); | ||
126 | u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); | ||
127 | |||
128 | /* | ||
129 | * Chip select enabled? | ||
130 | */ | ||
131 | if (size & 1) { | ||
132 | struct mbus_dram_window *w; | ||
133 | |||
134 | w = &mv78xx0_mbus_dram_info.cs[cs++]; | ||
135 | w->cs_index = i; | ||
136 | w->mbus_attr = 0xf & ~(1 << i); | ||
137 | w->base = base & 0xffff0000; | ||
138 | w->size = (size | 0x0000ffff) + 1; | ||
139 | } | ||
140 | } | ||
141 | mv78xx0_mbus_dram_info.num_cs = cs; | ||
142 | } | 82 | } |
143 | 83 | ||
144 | void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, | 84 | void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, |
145 | int maj, int min) | 85 | int maj, int min) |
146 | { | 86 | { |
147 | setup_cpu_win(window, base, size, TARGET_PCIE(maj), | 87 | orion_setup_cpu_win(&addr_map_cfg, window, base, size, |
148 | ATTR_PCIE_IO(min), -1); | 88 | TARGET_PCIE(maj), ATTR_PCIE_IO(min), -1); |
149 | } | 89 | } |
150 | 90 | ||
151 | void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, | 91 | void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, |
152 | int maj, int min) | 92 | int maj, int min) |
153 | { | 93 | { |
154 | setup_cpu_win(window, base, size, TARGET_PCIE(maj), | 94 | orion_setup_cpu_win(&addr_map_cfg, window, base, size, |
155 | ATTR_PCIE_MEM(min), -1); | 95 | TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1); |
156 | } | 96 | } |
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index 5ceafdccc456..73ceb49de894 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c | |||
@@ -14,8 +14,8 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/mbus.h> | 15 | #include <linux/mbus.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/errno.h> | ||
18 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
18 | #include <plat/addr-map.h> | ||
19 | #include "common.h" | 19 | #include "common.h" |
20 | 20 | ||
21 | /* | 21 | /* |
@@ -41,7 +41,6 @@ | |||
41 | /* | 41 | /* |
42 | * Generic Address Decode Windows bit settings | 42 | * Generic Address Decode Windows bit settings |
43 | */ | 43 | */ |
44 | #define TARGET_DDR 0 | ||
45 | #define TARGET_DEV_BUS 1 | 44 | #define TARGET_DEV_BUS 1 |
46 | #define TARGET_PCI 3 | 45 | #define TARGET_PCI 3 |
47 | #define TARGET_PCIE 4 | 46 | #define TARGET_PCIE 4 |
@@ -57,27 +56,11 @@ | |||
57 | #define ATTR_DEV_BOOT 0xf | 56 | #define ATTR_DEV_BOOT 0xf |
58 | #define ATTR_SRAM 0x0 | 57 | #define ATTR_SRAM 0x0 |
59 | 58 | ||
60 | /* | ||
61 | * Helpers to get DDR bank info | ||
62 | */ | ||
63 | #define ORION5X_DDR_REG(x) (ORION5X_DDR_VIRT_BASE | (x)) | ||
64 | #define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) << 3)) | ||
65 | #define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) << 3)) | ||
66 | |||
67 | /* | ||
68 | * CPU Address Decode Windows registers | ||
69 | */ | ||
70 | #define ORION5X_BRIDGE_REG(x) (ORION5X_BRIDGE_VIRT_BASE | (x)) | ||
71 | #define CPU_WIN_CTRL(n) ORION5X_BRIDGE_REG(0x000 | ((n) << 4)) | ||
72 | #define CPU_WIN_BASE(n) ORION5X_BRIDGE_REG(0x004 | ((n) << 4)) | ||
73 | #define CPU_WIN_REMAP_LO(n) ORION5X_BRIDGE_REG(0x008 | ((n) << 4)) | ||
74 | #define CPU_WIN_REMAP_HI(n) ORION5X_BRIDGE_REG(0x00c | ((n) << 4)) | ||
75 | |||
76 | |||
77 | struct mbus_dram_target_info orion5x_mbus_dram_info; | 59 | struct mbus_dram_target_info orion5x_mbus_dram_info; |
78 | static int __initdata win_alloc_count; | 60 | static int __initdata win_alloc_count; |
79 | 61 | ||
80 | static int __init orion5x_cpu_win_can_remap(int win) | 62 | static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg, |
63 | const int win) | ||
81 | { | 64 | { |
82 | u32 dev, rev; | 65 | u32 dev, rev; |
83 | 66 | ||
@@ -91,116 +74,83 @@ static int __init orion5x_cpu_win_can_remap(int win) | |||
91 | return 0; | 74 | return 0; |
92 | } | 75 | } |
93 | 76 | ||
94 | static int __init setup_cpu_win(int win, u32 base, u32 size, | 77 | /* |
95 | u8 target, u8 attr, int remap) | 78 | * Description of the windows needed by the platform code |
96 | { | 79 | */ |
97 | if (win >= 8) { | 80 | static struct __initdata orion_addr_map_cfg addr_map_cfg = { |
98 | printk(KERN_ERR "setup_cpu_win: trying to allocate " | 81 | .num_wins = 8, |
99 | "window %d\n", win); | 82 | .cpu_win_can_remap = cpu_win_can_remap, |
100 | return -ENOSPC; | 83 | .bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE, |
101 | } | 84 | }; |
102 | |||
103 | writel(base & 0xffff0000, CPU_WIN_BASE(win)); | ||
104 | writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1, | ||
105 | CPU_WIN_CTRL(win)); | ||
106 | |||
107 | if (orion5x_cpu_win_can_remap(win)) { | ||
108 | if (remap < 0) | ||
109 | remap = base; | ||
110 | |||
111 | writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win)); | ||
112 | writel(0, CPU_WIN_REMAP_HI(win)); | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | void __init orion5x_setup_cpu_mbus_bridge(void) | ||
118 | { | ||
119 | int i; | ||
120 | int cs; | ||
121 | 85 | ||
86 | static const struct __initdata orion_addr_map_info addr_map_info[] = { | ||
122 | /* | 87 | /* |
123 | * First, disable and clear windows. | 88 | * Setup windows for PCI+PCIe IO+MEM space. |
124 | */ | 89 | */ |
125 | for (i = 0; i < 8; i++) { | 90 | { 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE, |
126 | writel(0, CPU_WIN_BASE(i)); | 91 | TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE |
127 | writel(0, CPU_WIN_CTRL(i)); | 92 | }, |
128 | if (orion5x_cpu_win_can_remap(i)) { | 93 | { 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE, |
129 | writel(0, CPU_WIN_REMAP_LO(i)); | 94 | TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE |
130 | writel(0, CPU_WIN_REMAP_HI(i)); | 95 | }, |
131 | } | 96 | { 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE, |
132 | } | 97 | TARGET_PCIE, ATTR_PCIE_MEM, -1 |
98 | }, | ||
99 | { 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE, | ||
100 | TARGET_PCI, ATTR_PCI_MEM, -1 | ||
101 | }, | ||
102 | /* End marker */ | ||
103 | { -1, 0, 0, 0, 0, 0 } | ||
104 | }; | ||
133 | 105 | ||
106 | void __init orion5x_setup_cpu_mbus_bridge(void) | ||
107 | { | ||
134 | /* | 108 | /* |
135 | * Setup windows for PCI+PCIe IO+MEM space. | 109 | * Disable, clear and configure windows. |
136 | */ | 110 | */ |
137 | setup_cpu_win(0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE, | 111 | orion_config_wins(&addr_map_cfg, addr_map_info); |
138 | TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE); | ||
139 | setup_cpu_win(1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE, | ||
140 | TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE); | ||
141 | setup_cpu_win(2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE, | ||
142 | TARGET_PCIE, ATTR_PCIE_MEM, -1); | ||
143 | setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE, | ||
144 | TARGET_PCI, ATTR_PCI_MEM, -1); | ||
145 | win_alloc_count = 4; | 112 | win_alloc_count = 4; |
146 | 113 | ||
147 | /* | 114 | /* |
148 | * Setup MBUS dram target info. | 115 | * Setup MBUS dram target info. |
149 | */ | 116 | */ |
150 | orion5x_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; | 117 | orion_setup_cpu_mbus_target(&addr_map_cfg, &orion5x_mbus_dram_info, |
151 | 118 | ORION5X_DDR_WINDOW_CPU_BASE); | |
152 | for (i = 0, cs = 0; i < 4; i++) { | ||
153 | u32 base = readl(DDR_BASE_CS(i)); | ||
154 | u32 size = readl(DDR_SIZE_CS(i)); | ||
155 | |||
156 | /* | ||
157 | * Chip select enabled? | ||
158 | */ | ||
159 | if (size & 1) { | ||
160 | struct mbus_dram_window *w; | ||
161 | |||
162 | w = &orion5x_mbus_dram_info.cs[cs++]; | ||
163 | w->cs_index = i; | ||
164 | w->mbus_attr = 0xf & ~(1 << i); | ||
165 | w->base = base & 0xffff0000; | ||
166 | w->size = (size | 0x0000ffff) + 1; | ||
167 | } | ||
168 | } | ||
169 | orion5x_mbus_dram_info.num_cs = cs; | ||
170 | } | 119 | } |
171 | 120 | ||
172 | void __init orion5x_setup_dev_boot_win(u32 base, u32 size) | 121 | void __init orion5x_setup_dev_boot_win(u32 base, u32 size) |
173 | { | 122 | { |
174 | setup_cpu_win(win_alloc_count++, base, size, | 123 | orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, |
175 | TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); | 124 | TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); |
176 | } | 125 | } |
177 | 126 | ||
178 | void __init orion5x_setup_dev0_win(u32 base, u32 size) | 127 | void __init orion5x_setup_dev0_win(u32 base, u32 size) |
179 | { | 128 | { |
180 | setup_cpu_win(win_alloc_count++, base, size, | 129 | orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, |
181 | TARGET_DEV_BUS, ATTR_DEV_CS0, -1); | 130 | TARGET_DEV_BUS, ATTR_DEV_CS0, -1); |
182 | } | 131 | } |
183 | 132 | ||
184 | void __init orion5x_setup_dev1_win(u32 base, u32 size) | 133 | void __init orion5x_setup_dev1_win(u32 base, u32 size) |
185 | { | 134 | { |
186 | setup_cpu_win(win_alloc_count++, base, size, | 135 | orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, |
187 | TARGET_DEV_BUS, ATTR_DEV_CS1, -1); | 136 | TARGET_DEV_BUS, ATTR_DEV_CS1, -1); |
188 | } | 137 | } |
189 | 138 | ||
190 | void __init orion5x_setup_dev2_win(u32 base, u32 size) | 139 | void __init orion5x_setup_dev2_win(u32 base, u32 size) |
191 | { | 140 | { |
192 | setup_cpu_win(win_alloc_count++, base, size, | 141 | orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, |
193 | TARGET_DEV_BUS, ATTR_DEV_CS2, -1); | 142 | TARGET_DEV_BUS, ATTR_DEV_CS2, -1); |
194 | } | 143 | } |
195 | 144 | ||
196 | void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) | 145 | void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) |
197 | { | 146 | { |
198 | setup_cpu_win(win_alloc_count++, base, size, | 147 | orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, |
199 | TARGET_PCIE, ATTR_PCIE_WA, -1); | 148 | TARGET_PCIE, ATTR_PCIE_WA, -1); |
200 | } | 149 | } |
201 | 150 | ||
202 | int __init orion5x_setup_sram_win(void) | 151 | void __init orion5x_setup_sram_win(void) |
203 | { | 152 | { |
204 | return setup_cpu_win(win_alloc_count++, ORION5X_SRAM_PHYS_BASE, | 153 | orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, |
205 | ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1); | 154 | ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE, |
155 | TARGET_SRAM, ATTR_SRAM, -1); | ||
206 | } | 156 | } |
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 22ace0bf2f92..47ca0ee44a6a 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c | |||
@@ -169,12 +169,7 @@ void __init orion5x_xor_init(void) | |||
169 | ****************************************************************************/ | 169 | ****************************************************************************/ |
170 | static void __init orion5x_crypto_init(void) | 170 | static void __init orion5x_crypto_init(void) |
171 | { | 171 | { |
172 | int ret; | 172 | orion5x_setup_sram_win(); |
173 | |||
174 | ret = orion5x_setup_sram_win(); | ||
175 | if (ret) | ||
176 | return; | ||
177 | |||
178 | orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE, | 173 | orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE, |
179 | SZ_8K, IRQ_ORION5X_CESA); | 174 | SZ_8K, IRQ_ORION5X_CESA); |
180 | } | 175 | } |
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index 909489f4d23e..465e8a458bfb 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h | |||
@@ -27,7 +27,7 @@ void orion5x_setup_dev0_win(u32 base, u32 size); | |||
27 | void orion5x_setup_dev1_win(u32 base, u32 size); | 27 | void orion5x_setup_dev1_win(u32 base, u32 size); |
28 | void orion5x_setup_dev2_win(u32 base, u32 size); | 28 | void orion5x_setup_dev2_win(u32 base, u32 size); |
29 | void orion5x_setup_pcie_wa_win(u32 base, u32 size); | 29 | void orion5x_setup_pcie_wa_win(u32 base, u32 size); |
30 | int orion5x_setup_sram_win(void); | 30 | void orion5x_setup_sram_win(void); |
31 | 31 | ||
32 | void orion5x_ehci0_init(void); | 32 | void orion5x_ehci0_init(void); |
33 | void orion5x_ehci1_init(void); | 33 | void orion5x_ehci1_init(void); |
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h index 0a28bbc76891..2745f5d95b3f 100644 --- a/arch/arm/mach-orion5x/include/mach/orion5x.h +++ b/arch/arm/mach-orion5x/include/mach/orion5x.h | |||
@@ -69,7 +69,7 @@ | |||
69 | ******************************************************************************/ | 69 | ******************************************************************************/ |
70 | 70 | ||
71 | #define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000) | 71 | #define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000) |
72 | 72 | #define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE | 0x1500) | |
73 | #define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000) | 73 | #define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000) |
74 | #define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000) | 74 | #define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000) |
75 | #define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x)) | 75 | #define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x)) |
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile index 95a5fc53b6db..c20ce0f5ce33 100644 --- a/arch/arm/plat-orion/Makefile +++ b/arch/arm/plat-orion/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := irq.o pcie.o time.o common.o mpp.o | 5 | obj-y := irq.o pcie.o time.o common.o mpp.o addr-map.o |
6 | obj-m := | 6 | obj-m := |
7 | obj-n := | 7 | obj-n := |
8 | obj- := | 8 | obj- := |
diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c new file mode 100644 index 000000000000..d3abb34a10aa --- /dev/null +++ b/arch/arm/plat-orion/addr-map.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-orion/addr-map.c | ||
3 | * | ||
4 | * Address map functions for Marvell Orion based SoCs | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/mbus.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <plat/addr-map.h> | ||
16 | |||
17 | /* | ||
18 | * DDR target is the same on all Orion platforms. | ||
19 | */ | ||
20 | #define TARGET_DDR 0 | ||
21 | |||
22 | /* | ||
23 | * Helpers to get DDR bank info | ||
24 | */ | ||
25 | #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) | ||
26 | #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) | ||
27 | |||
28 | /* | ||
29 | * CPU Address Decode Windows registers | ||
30 | */ | ||
31 | #define WIN_CTRL_OFF 0x0000 | ||
32 | #define WIN_BASE_OFF 0x0004 | ||
33 | #define WIN_REMAP_LO_OFF 0x0008 | ||
34 | #define WIN_REMAP_HI_OFF 0x000c | ||
35 | |||
36 | /* | ||
37 | * Default implementation | ||
38 | */ | ||
39 | static void __init __iomem * | ||
40 | orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win) | ||
41 | { | ||
42 | return (void __iomem *)(cfg->bridge_virt_base + (win << 4)); | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * Default implementation | ||
47 | */ | ||
48 | static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg, | ||
49 | const int win) | ||
50 | { | ||
51 | if (win < cfg->remappable_wins) | ||
52 | return 1; | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg, | ||
58 | const int win, const u32 base, | ||
59 | const u32 size, const u8 target, | ||
60 | const u8 attr, const int remap) | ||
61 | { | ||
62 | void __iomem *addr = cfg->win_cfg_base(cfg, win); | ||
63 | u32 ctrl, base_high, remap_addr; | ||
64 | |||
65 | if (win >= cfg->num_wins) { | ||
66 | printk(KERN_ERR "setup_cpu_win: trying to allocate window " | ||
67 | "%d when only %d allowed\n", win, cfg->num_wins); | ||
68 | } | ||
69 | |||
70 | base_high = base & 0xffff0000; | ||
71 | ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; | ||
72 | |||
73 | writel(base_high, addr + WIN_BASE_OFF); | ||
74 | writel(ctrl, addr + WIN_CTRL_OFF); | ||
75 | if (cfg->cpu_win_can_remap(cfg, win)) { | ||
76 | if (remap < 0) | ||
77 | remap_addr = base; | ||
78 | else | ||
79 | remap_addr = remap; | ||
80 | writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF); | ||
81 | writel(0, addr + WIN_REMAP_HI_OFF); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Configure a number of windows. | ||
87 | */ | ||
88 | static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg, | ||
89 | const struct orion_addr_map_info *info) | ||
90 | { | ||
91 | while (info->win != -1) { | ||
92 | orion_setup_cpu_win(cfg, info->win, info->base, info->size, | ||
93 | info->target, info->attr, info->remap); | ||
94 | info++; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg) | ||
99 | { | ||
100 | void __iomem *addr; | ||
101 | int i; | ||
102 | |||
103 | for (i = 0; i < cfg->num_wins; i++) { | ||
104 | addr = cfg->win_cfg_base(cfg, i); | ||
105 | |||
106 | writel(0, addr + WIN_BASE_OFF); | ||
107 | writel(0, addr + WIN_CTRL_OFF); | ||
108 | if (cfg->cpu_win_can_remap(cfg, i)) { | ||
109 | writel(0, addr + WIN_REMAP_LO_OFF); | ||
110 | writel(0, addr + WIN_REMAP_HI_OFF); | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Disable, clear and configure windows. | ||
117 | */ | ||
118 | void __init orion_config_wins(struct orion_addr_map_cfg * cfg, | ||
119 | const struct orion_addr_map_info *info) | ||
120 | { | ||
121 | if (!cfg->cpu_win_can_remap) | ||
122 | cfg->cpu_win_can_remap = orion_cpu_win_can_remap; | ||
123 | |||
124 | if (!cfg->win_cfg_base) | ||
125 | cfg->win_cfg_base = orion_win_cfg_base; | ||
126 | |||
127 | orion_disable_wins(cfg); | ||
128 | |||
129 | if (info) | ||
130 | orion_setup_cpu_wins(cfg, info); | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Setup MBUS dram target info. | ||
135 | */ | ||
136 | void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, | ||
137 | struct mbus_dram_target_info *info, | ||
138 | const u32 ddr_window_cpu_base) | ||
139 | { | ||
140 | void __iomem *addr; | ||
141 | int i; | ||
142 | int cs; | ||
143 | |||
144 | info->mbus_dram_target_id = TARGET_DDR; | ||
145 | |||
146 | addr = (void __iomem *)ddr_window_cpu_base; | ||
147 | |||
148 | for (i = 0, cs = 0; i < 4; i++) { | ||
149 | u32 base = readl(addr + DDR_BASE_CS_OFF(i)); | ||
150 | u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); | ||
151 | |||
152 | /* | ||
153 | * Chip select enabled? | ||
154 | */ | ||
155 | if (size & 1) { | ||
156 | struct mbus_dram_window *w; | ||
157 | |||
158 | w = &info->cs[cs++]; | ||
159 | w->cs_index = i; | ||
160 | w->mbus_attr = 0xf & ~(1 << i); | ||
161 | w->base = base & 0xffff0000; | ||
162 | w->size = (size | 0x0000ffff) + 1; | ||
163 | } | ||
164 | } | ||
165 | info->num_cs = cs; | ||
166 | } | ||
diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h new file mode 100644 index 000000000000..55e40f43f1e6 --- /dev/null +++ b/arch/arm/plat-orion/include/plat/addr-map.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-orion/include/plat/addr-map.h | ||
3 | * | ||
4 | * Marvell Orion SoC address map handling. | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #ifndef __PLAT_ADDR_MAP_H | ||
12 | #define __PLAT_ADDR_MAP_H | ||
13 | |||
14 | struct orion_addr_map_cfg { | ||
15 | const int num_wins; /* Total number of windows */ | ||
16 | const int remappable_wins; | ||
17 | const u32 bridge_virt_base; | ||
18 | |||
19 | /* If NULL, the default cpu_win_can_remap will be used, using | ||
20 | the value in remappable_wins */ | ||
21 | int (*cpu_win_can_remap) (const struct orion_addr_map_cfg *cfg, | ||
22 | const int win); | ||
23 | /* If NULL, the default win_cfg_base will be used, using the | ||
24 | value in bridge_virt_base */ | ||
25 | void __iomem *(*win_cfg_base) (const struct orion_addr_map_cfg *cfg, | ||
26 | const int win); | ||
27 | }; | ||
28 | |||
29 | /* | ||
30 | * Information needed to setup one address mapping. | ||
31 | */ | ||
32 | struct orion_addr_map_info { | ||
33 | const int win; | ||
34 | const u32 base; | ||
35 | const u32 size; | ||
36 | const u8 target; | ||
37 | const u8 attr; | ||
38 | const int remap; | ||
39 | }; | ||
40 | |||
41 | void __init orion_config_wins(struct orion_addr_map_cfg *cfg, | ||
42 | const struct orion_addr_map_info *info); | ||
43 | |||
44 | void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg, | ||
45 | const int win, const u32 base, | ||
46 | const u32 size, const u8 target, | ||
47 | const u8 attr, const int remap); | ||
48 | |||
49 | void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, | ||
50 | struct mbus_dram_target_info *info, | ||
51 | const u32 ddr_window_cpu_base); | ||
52 | #endif | ||