aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2011-12-07 15:48:05 -0500
committerNicolas Pitre <nico@fluxnic.net>2011-12-13 18:46:20 -0500
commitb6d1c33a31deb1784c1d34070db6e84fd6f9d870 (patch)
tree18739a6c79b10f0fe69c01be5571e7a5af4d0e21
parent527ef0550d79e3b3a0ef8f5061072075afef6aaf (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.c113
-rw-r--r--arch/arm/mach-kirkwood/addr-map.c138
-rw-r--r--arch/arm/mach-mv78xx0/addr-map.c102
-rw-r--r--arch/arm/mach-orion5x/addr-map.c146
-rw-r--r--arch/arm/mach-orion5x/common.c7
-rw-r--r--arch/arm/mach-orion5x/common.h2
-rw-r--r--arch/arm/mach-orion5x/include/mach/orion5x.h2
-rw-r--r--arch/arm/plat-orion/Makefile2
-rw-r--r--arch/arm/plat-orion/addr-map.c166
-rw-r--r--arch/arm/plat-orion/include/plat/addr-map.h52
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
45struct mbus_dram_target_info dove_mbus_dram_info; 38struct mbus_dram_target_info dove_mbus_dram_info;
46 39
47static inline void __iomem *ddr_map_sc(int i) 40static 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
52static 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; 48static 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};
60static 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
78void __init dove_setup_cpu_mbus(void)
79{
80 int i;
81 int cs;
82 53
54static 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
92void __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/* 38struct 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)) 43static 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
54struct mbus_dram_target_info kirkwood_mbus_dram_info;
55
56static int __init cpu_win_can_remap(int win)
57{
58 if (win < 4)
59 return 1;
60
61 return 0;
62}
63
64static 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
84void __init kirkwood_setup_cpu_mbus(void)
85{
86 void __iomem *addr;
87 int i;
88 int cs;
89 48
49static 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
81void __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
51struct mbus_dram_target_info mv78xx0_mbus_dram_info; 40struct 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
66static 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; 58static 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};
74static 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
94void __init mv78xx0_setup_cpu_mbus(void) 64void __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
144void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, 84void __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
151void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, 91void __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
77struct mbus_dram_target_info orion5x_mbus_dram_info; 59struct mbus_dram_target_info orion5x_mbus_dram_info;
78static int __initdata win_alloc_count; 60static int __initdata win_alloc_count;
79 61
80static int __init orion5x_cpu_win_can_remap(int win) 62static 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
94static 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) { 80static 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
117void __init orion5x_setup_cpu_mbus_bridge(void)
118{
119 int i;
120 int cs;
121 85
86static 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
106void __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
172void __init orion5x_setup_dev_boot_win(u32 base, u32 size) 121void __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
178void __init orion5x_setup_dev0_win(u32 base, u32 size) 127void __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
184void __init orion5x_setup_dev1_win(u32 base, u32 size) 133void __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
190void __init orion5x_setup_dev2_win(u32 base, u32 size) 139void __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
196void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) 145void __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
202int __init orion5x_setup_sram_win(void) 151void __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 ****************************************************************************/
170static void __init orion5x_crypto_init(void) 170static 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);
27void orion5x_setup_dev1_win(u32 base, u32 size); 27void orion5x_setup_dev1_win(u32 base, u32 size);
28void orion5x_setup_dev2_win(u32 base, u32 size); 28void orion5x_setup_dev2_win(u32 base, u32 size);
29void orion5x_setup_pcie_wa_win(u32 base, u32 size); 29void orion5x_setup_pcie_wa_win(u32 base, u32 size);
30int orion5x_setup_sram_win(void); 30void orion5x_setup_sram_win(void);
31 31
32void orion5x_ehci0_init(void); 32void orion5x_ehci0_init(void);
33void orion5x_ehci1_init(void); 33void 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
5obj-y := irq.o pcie.o time.o common.o mpp.o 5obj-y := irq.o pcie.o time.o common.o mpp.o addr-map.o
6obj-m := 6obj-m :=
7obj-n := 7obj-n :=
8obj- := 8obj- :=
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 */
39static void __init __iomem *
40orion_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 */
48static 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
57void __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 */
88static 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
98static 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 */
118void __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 */
136void __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
14struct 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 */
32struct 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
41void __init orion_config_wins(struct orion_addr_map_cfg *cfg,
42 const struct orion_addr_map_info *info);
43
44void __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
49void __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