2 * arch/arm/plat-orion/addr-map.c
4 * Address map functions for Marvell Orion based SoCs
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.
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/mbus.h>
15 #include <plat/addr-map.h>
17 struct mbus_dram_target_info orion_mbus_dram_info
;
20 * DDR target is the same on all Orion platforms.
25 * Helpers to get DDR bank info
27 #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
28 #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
31 * CPU Address Decode Windows registers
33 #define WIN_CTRL_OFF 0x0000
34 #define WIN_BASE_OFF 0x0004
35 #define WIN_REMAP_LO_OFF 0x0008
36 #define WIN_REMAP_HI_OFF 0x000c
39 * Default implementation
41 static void __init __iomem
*
42 orion_win_cfg_base(const struct orion_addr_map_cfg
*cfg
, int win
)
44 return (void __iomem
*)(cfg
->bridge_virt_base
+ (win
<< 4));
48 * Default implementation
50 static int __init
orion_cpu_win_can_remap(const struct orion_addr_map_cfg
*cfg
,
53 if (win
< cfg
->remappable_wins
)
59 void __init
orion_setup_cpu_win(const struct orion_addr_map_cfg
*cfg
,
60 const int win
, const u32 base
,
61 const u32 size
, const u8 target
,
62 const u8 attr
, const int remap
)
64 void __iomem
*addr
= cfg
->win_cfg_base(cfg
, win
);
65 u32 ctrl
, base_high
, remap_addr
;
67 if (win
>= cfg
->num_wins
) {
68 printk(KERN_ERR
"setup_cpu_win: trying to allocate window "
69 "%d when only %d allowed\n", win
, cfg
->num_wins
);
72 base_high
= base
& 0xffff0000;
73 ctrl
= ((size
- 1) & 0xffff0000) | (attr
<< 8) | (target
<< 4) | 1;
75 writel(base_high
, addr
+ WIN_BASE_OFF
);
76 writel(ctrl
, addr
+ WIN_CTRL_OFF
);
77 if (cfg
->cpu_win_can_remap(cfg
, win
)) {
82 writel(remap_addr
& 0xffff0000, addr
+ WIN_REMAP_LO_OFF
);
83 writel(0, addr
+ WIN_REMAP_HI_OFF
);
88 * Configure a number of windows.
90 static void __init
orion_setup_cpu_wins(const struct orion_addr_map_cfg
* cfg
,
91 const struct orion_addr_map_info
*info
)
93 while (info
->win
!= -1) {
94 orion_setup_cpu_win(cfg
, info
->win
, info
->base
, info
->size
,
95 info
->target
, info
->attr
, info
->remap
);
100 static void __init
orion_disable_wins(const struct orion_addr_map_cfg
* cfg
)
105 for (i
= 0; i
< cfg
->num_wins
; i
++) {
106 addr
= cfg
->win_cfg_base(cfg
, i
);
108 writel(0, addr
+ WIN_BASE_OFF
);
109 writel(0, addr
+ WIN_CTRL_OFF
);
110 if (cfg
->cpu_win_can_remap(cfg
, i
)) {
111 writel(0, addr
+ WIN_REMAP_LO_OFF
);
112 writel(0, addr
+ WIN_REMAP_HI_OFF
);
118 * Disable, clear and configure windows.
120 void __init
orion_config_wins(struct orion_addr_map_cfg
* cfg
,
121 const struct orion_addr_map_info
*info
)
123 if (!cfg
->cpu_win_can_remap
)
124 cfg
->cpu_win_can_remap
= orion_cpu_win_can_remap
;
126 if (!cfg
->win_cfg_base
)
127 cfg
->win_cfg_base
= orion_win_cfg_base
;
129 orion_disable_wins(cfg
);
132 orion_setup_cpu_wins(cfg
, info
);
136 * Setup MBUS dram target info.
138 void __init
orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg
*cfg
,
139 const u32 ddr_window_cpu_base
)
145 orion_mbus_dram_info
.mbus_dram_target_id
= TARGET_DDR
;
147 addr
= (void __iomem
*)ddr_window_cpu_base
;
149 for (i
= 0, cs
= 0; i
< 4; i
++) {
150 u32 base
= readl(addr
+ DDR_BASE_CS_OFF(i
));
151 u32 size
= readl(addr
+ DDR_SIZE_CS_OFF(i
));
154 * Chip select enabled?
157 struct mbus_dram_window
*w
;
159 w
= &orion_mbus_dram_info
.cs
[cs
++];
161 w
->mbus_attr
= 0xf & ~(1 << i
);
162 w
->base
= base
& 0xffff0000;
163 w
->size
= (size
| 0x0000ffff) + 1;
166 orion_mbus_dram_info
.num_cs
= cs
;