Linux-libre 3.0.19-gnu1
[librecmc/linux-libre.git] / arch / arm / mach-loki / addr-map.c
1 /*
2  * arch/arm/mach-loki/addr-map.c
3  *
4  * Address map functions for Marvell Loki (88RC8480) 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 <mach/hardware.h>
16 #include "common.h"
17
18 /*
19  * Generic Address Decode Windows bit settings
20  */
21 #define TARGET_DDR              0
22 #define TARGET_DEV_BUS          1
23 #define TARGET_PCIE0            3
24 #define TARGET_PCIE1            4
25 #define ATTR_DEV_BOOT           0x0f
26 #define ATTR_DEV_CS2            0x1b
27 #define ATTR_DEV_CS1            0x1d
28 #define ATTR_DEV_CS0            0x1e
29 #define ATTR_PCIE_IO            0x51
30 #define ATTR_PCIE_MEM           0x59
31
32 /*
33  * Helpers to get DDR bank info
34  */
35 #define DDR_SIZE_CS(n)          DDR_REG(0x1500 + ((n) << 3))
36 #define DDR_BASE_CS(n)          DDR_REG(0x1504 + ((n) << 3))
37
38 /*
39  * CPU Address Decode Windows registers
40  */
41 #define BRIDGE_REG(x)           (BRIDGE_VIRT_BASE | (x))
42 #define CPU_WIN_CTRL(n)         BRIDGE_REG(0x000 | ((n) << 4))
43 #define CPU_WIN_BASE(n)         BRIDGE_REG(0x004 | ((n) << 4))
44 #define CPU_WIN_REMAP_LO(n)     BRIDGE_REG(0x008 | ((n) << 4))
45 #define CPU_WIN_REMAP_HI(n)     BRIDGE_REG(0x00c | ((n) << 4))
46
47
48 struct mbus_dram_target_info loki_mbus_dram_info;
49
50 static void __init setup_cpu_win(int win, u32 base, u32 size,
51                                  u8 target, u8 attr, int remap)
52 {
53         u32 ctrl;
54
55         base &= 0xffff0000;
56         ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (1 << 5) | target;
57
58         writel(base, CPU_WIN_BASE(win));
59         writel(ctrl, CPU_WIN_CTRL(win));
60         if (win < 2) {
61                 if (remap < 0)
62                         remap = base;
63
64                 writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
65                 writel(0, CPU_WIN_REMAP_HI(win));
66         }
67 }
68
69 void __init loki_setup_cpu_mbus(void)
70 {
71         int i;
72         int cs;
73
74         /*
75          * First, disable and clear windows.
76          */
77         for (i = 0; i < 8; i++) {
78                 writel(0, CPU_WIN_BASE(i));
79                 writel(0, CPU_WIN_CTRL(i));
80                 if (i < 2) {
81                         writel(0, CPU_WIN_REMAP_LO(i));
82                         writel(0, CPU_WIN_REMAP_HI(i));
83                 }
84         }
85
86         /*
87          * Setup windows for PCIe IO+MEM space.
88          */
89         setup_cpu_win(2, LOKI_PCIE0_MEM_PHYS_BASE, LOKI_PCIE0_MEM_SIZE,
90                       TARGET_PCIE0, ATTR_PCIE_MEM, -1);
91         setup_cpu_win(3, LOKI_PCIE1_MEM_PHYS_BASE, LOKI_PCIE1_MEM_SIZE,
92                       TARGET_PCIE1, ATTR_PCIE_MEM, -1);
93
94         /*
95          * Setup MBUS dram target info.
96          */
97         loki_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
98
99         for (i = 0, cs = 0; i < 4; i++) {
100                 u32 base = readl(DDR_BASE_CS(i));
101                 u32 size = readl(DDR_SIZE_CS(i));
102
103                 /*
104                  * Chip select enabled?
105                  */
106                 if (size & 1) {
107                         struct mbus_dram_window *w;
108
109                         w = &loki_mbus_dram_info.cs[cs++];
110                         w->cs_index = i;
111                         w->mbus_attr = 0xf & ~(1 << i);
112                         w->base = base & 0xffff0000;
113                         w->size = (size | 0x0000ffff) + 1;
114                 }
115         }
116         loki_mbus_dram_info.num_cs = cs;
117 }
118
119 void __init loki_setup_dev_boot_win(u32 base, u32 size)
120 {
121         setup_cpu_win(4, base, size, TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
122 }