OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 11a8ab8dac4ef5d0d70199843043927edce1d4db Mon Sep 17 00:00:00 2001 |
2 | From: Jonas Gorski <jogo@openwrt.org> |
||
3 | Date: Sun, 15 Dec 2013 20:47:34 +0100 |
||
4 | Subject: [PATCH 53/53] MIPS: BCM63XX: add PCIe support for BCM6318 |
||
5 | |||
6 | --- |
||
7 | arch/mips/bcm63xx/clk.c | 25 ++++- |
||
8 | arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h | 6 ++ |
||
9 | arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 60 +++++++++++- |
||
10 | arch/mips/pci/ops-bcm63xx.c | 16 +++- |
||
11 | arch/mips/pci/pci-bcm63xx.c | 106 ++++++++++++++++++---- |
||
12 | 5 files changed, 184 insertions(+), 29 deletions(-) |
||
13 | |||
14 | --- a/arch/mips/bcm63xx/clk.c |
||
15 | +++ b/arch/mips/bcm63xx/clk.c |
||
16 | @@ -51,6 +51,18 @@ static void bcm_hwclock_set(u32 mask, in |
||
17 | bcm_perf_writel(reg, PERF_CKCTL_REG); |
||
18 | } |
||
19 | |||
20 | +static void bcm_ub_hwclock_set(u32 mask, int enable) |
||
21 | +{ |
||
22 | + u32 reg; |
||
23 | + |
||
24 | + reg = bcm_perf_readl(PERF_UB_CKCTL_REG); |
||
25 | + if (enable) |
||
26 | + reg |= mask; |
||
27 | + else |
||
28 | + reg &= ~mask; |
||
29 | + bcm_perf_writel(reg, PERF_UB_CKCTL_REG); |
||
30 | +} |
||
31 | + |
||
32 | /* |
||
33 | * Ethernet MAC "misc" clock: dma clocks and main clock on 6348 |
||
34 | */ |
||
35 | @@ -361,12 +373,17 @@ static struct clk clk_ipsec = { |
||
36 | |||
37 | static void pcie_set(struct clk *clk, int enable) |
||
38 | { |
||
39 | - if (BCMCPU_IS_6328()) |
||
40 | + if (BCMCPU_IS_6318()) { |
||
41 | + bcm_hwclock_set(CKCTL_6318_PCIE_EN, enable); |
||
42 | + bcm_hwclock_set(CKCTL_6318_PCIE25_EN, enable); |
||
43 | + bcm_ub_hwclock_set(UB_CKCTL_6318_PCIE_EN, enable); |
||
44 | + } else if (BCMCPU_IS_6328()) { |
||
45 | bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable); |
||
46 | - else if (BCMCPU_IS_6362()) |
||
47 | + } else if (BCMCPU_IS_6362()) { |
||
48 | bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable); |
||
49 | - else if (BCMCPU_IS_63268()) |
||
50 | + } else if (BCMCPU_IS_63268()) { |
||
51 | bcm_hwclock_set(CKCTL_63268_PCIE_EN, enable); |
||
52 | + } |
||
53 | } |
||
54 | |||
55 | static struct clk clk_pcie = { |
||
56 | --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h |
||
57 | +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h |
||
58 | @@ -40,6 +40,12 @@ |
||
59 | #define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \ |
||
60 | BCM_CB_MEM_SIZE - 1) |
||
61 | |||
62 | +#define BCM_PCIE_MEM_BASE_PA_6318 0x10200000 |
||
63 | +#define BCM_PCIE_MEM_SIZE_6318 (1 * 1024 * 1024) |
||
64 | +#define BCM_PCIE_MEM_END_PA_6318 (BCM_PCIE_MEM_BASE_PA_6318 + \ |
||
65 | + BCM_PCIE_MEM_SIZE_6318 - 1) |
||
66 | + |
||
67 | + |
||
68 | #define BCM_PCIE_MEM_BASE_PA_6328 0x10f00000 |
||
69 | #define BCM_PCIE_MEM_SIZE_6328 (1 * 1024 * 1024) |
||
70 | #define BCM_PCIE_MEM_END_PA_6328 (BCM_PCIE_MEM_BASE_PA_6328 + \ |
||
71 | --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h |
||
72 | +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h |
||
73 | @@ -1529,6 +1529,17 @@ |
||
74 | * _REG relative to RSET_PCIE |
||
75 | *************************************************************************/ |
||
76 | |||
77 | +#define PCIE_SPECIFIC_REG 0x188 |
||
78 | +#define SPECIFIC_ENDIAN_MODE_BAR1_SHIFT 0 |
||
79 | +#define SPECIFIC_ENDIAN_MODE_BAR1_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT) |
||
80 | +#define SPECIFIC_ENDIAN_MODE_BAR2_SHIFT 2 |
||
81 | +#define SPECIFIC_ENDIAN_MODE_BAR2_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT) |
||
82 | +#define SPECIFIC_ENDIAN_MODE_BAR3_SHIFT 4 |
||
83 | +#define SPECIFIC_ENDIAN_MODE_BAR3_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT) |
||
84 | +#define SPECIFIC_ENDIAN_MODE_WORD_ALIGN 0 |
||
85 | +#define SPECIFIC_ENDIAN_MODE_HALFWORD_ALIGN 1 |
||
86 | +#define SPECIFIC_ENDIAN_MODE_BYTE_ALIGN 2 |
||
87 | + |
||
88 | #define PCIE_CONFIG2_REG 0x408 |
||
89 | #define CONFIG2_BAR1_SIZE_EN 1 |
||
90 | #define CONFIG2_BAR1_SIZE_MASK 0xf |
||
91 | @@ -1574,7 +1585,54 @@ |
||
92 | #define PCIE_RC_INT_C (1 << 2) |
||
93 | #define PCIE_RC_INT_D (1 << 3) |
||
94 | |||
95 | -#define PCIE_DEVICE_OFFSET 0x8000 |
||
96 | +#define PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG 0x400c |
||
97 | +#define C2P_MEM_WIN_ENDIAN_MODE_MASK 0x3 |
||
98 | +#define C2P_MEM_WIN_ENDIAN_NO_SWAP 0 |
||
99 | +#define C2P_MEM_WIN_ENDIAN_HALF_WORD_SWAP 1 |
||
100 | +#define C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP 2 |
||
101 | +#define C2P_MEM_WIN_BASE_ADDR_SHIFT 20 |
||
102 | +#define C2P_MEM_WIN_BASE_ADDR_MASK (0xfff << C2P_MEM_WIN_BASE_ADDR_SHIFT) |
||
103 | + |
||
104 | +#define PCIE_RC_BAR1_CONFIG_LO_REG 0x402c |
||
105 | +#define RC_BAR_CFG_LO_SIZE_256MB 0xd |
||
106 | +#define RC_BAR_CFG_LO_MATCH_ADDR_SHIFT 20 |
||
107 | +#define RC_BAR_CFG_LO_MATCH_ADDR_MASK (0xfff << RC_BAR_CFG_LO_MATCH_ADDR_SHIFT) |
||
108 | + |
||
109 | +#define PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG 0x4070 |
||
110 | +#define C2P_BASELIMIT_LIMIT_SHIFT 20 |
||
111 | +#define C2P_BASELIMIT_LIMIT_MASK (0xfff << C2P_BASELIMIT_LIMIT_SHIFT) |
||
112 | +#define C2P_BASELIMIT_BASE_SHIFT 4 |
||
113 | +#define C2P_BASELIMIT_BASE_MASK (0xfff << C2P_BASELIMIT_BASE_SHIFT) |
||
114 | + |
||
115 | +#define PCIE_UBUS_BAR1_CFG_REMAP_REG 0x4088 |
||
116 | +#define BAR1_CFG_REMAP_OFFSET_SHIFT 20 |
||
117 | +#define BAR1_CFG_REMAP_OFFSET_MASK (0xfff << BAR1_CFG_REMAP_OFFSET_SHIFT) |
||
118 | +#define BAR1_CFG_REMAP_ACCESS_EN 1 |
||
119 | + |
||
120 | +#define PCIE_HARD_DEBUG_REG 0x4204 |
||
121 | +#define HARD_DEBUG_SERDES_IDDQ (1 << 23) |
||
122 | + |
||
123 | +#define PCIE_CPU_INT1_MASK_CLEAR_REG 0x830c |
||
124 | +#define CPU_INT_PCIE_ERR_ATTN_CPU (1 << 0) |
||
125 | +#define CPU_INT_PCIE_INTA (1 << 1) |
||
126 | +#define CPU_INT_PCIE_INTB (1 << 2) |
||
127 | +#define CPU_INT_PCIE_INTC (1 << 3) |
||
128 | +#define CPU_INT_PCIE_INTD (1 << 4) |
||
129 | +#define CPU_INT_PCIE_INTR (1 << 5) |
||
130 | +#define CPU_INT_PCIE_NMI (1 << 6) |
||
131 | +#define CPU_INT_PCIE_UBUS (1 << 7) |
||
132 | +#define CPU_INT_IPI (1 << 8) |
||
133 | + |
||
134 | +#define PCIE_EXT_CFG_INDEX_REG 0x8400 |
||
135 | +#define EXT_CFG_FUNC_NUM_SHIFT 12 |
||
136 | +#define EXT_CFG_FUNC_NUM_MASK (0x7 << EXT_CFG_FUNC_NUM_SHIFT) |
||
137 | +#define EXT_CFG_DEV_NUM_SHIFT 15 |
||
138 | +#define EXT_CFG_DEV_NUM_MASK (0xf << EXT_CFG_DEV_NUM_SHIFT) |
||
139 | +#define EXT_CFG_BUS_NUM_SHIFT 20 |
||
140 | +#define EXT_CFG_BUS_NUM_MASK (0xff << EXT_CFG_BUS_NUM_SHIFT) |
||
141 | + |
||
142 | +#define PCIE_DEVICE_OFFSET_6318 0x9000 |
||
143 | +#define PCIE_DEVICE_OFFSET_6328 0x8000 |
||
144 | |||
145 | /************************************************************************* |
||
146 | * _REG relative to RSET_OTP |
||
147 | --- a/arch/mips/pci/ops-bcm63xx.c |
||
148 | +++ b/arch/mips/pci/ops-bcm63xx.c |
||
149 | @@ -488,8 +488,12 @@ static int bcm63xx_pcie_read(struct pci_ |
||
150 | if (!bcm63xx_pcie_can_access(bus, devfn)) |
||
151 | return PCIBIOS_DEVICE_NOT_FOUND; |
||
152 | |||
153 | - if (bus->number == PCIE_BUS_DEVICE) |
||
154 | - reg += PCIE_DEVICE_OFFSET; |
||
155 | + if (bus->number == PCIE_BUS_DEVICE) { |
||
156 | + if (BCMCPU_IS_6318()) |
||
157 | + reg += PCIE_DEVICE_OFFSET_6318; |
||
158 | + else |
||
159 | + reg += PCIE_DEVICE_OFFSET_6328; |
||
160 | + } |
||
161 | |||
162 | data = bcm_pcie_readl(reg); |
||
163 | |||
164 | @@ -508,8 +512,12 @@ static int bcm63xx_pcie_write(struct pci |
||
165 | if (!bcm63xx_pcie_can_access(bus, devfn)) |
||
166 | return PCIBIOS_DEVICE_NOT_FOUND; |
||
167 | |||
168 | - if (bus->number == PCIE_BUS_DEVICE) |
||
169 | - reg += PCIE_DEVICE_OFFSET; |
||
170 | + if (bus->number == PCIE_BUS_DEVICE) { |
||
171 | + if (BCMCPU_IS_6318()) |
||
172 | + reg += PCIE_DEVICE_OFFSET_6318; |
||
173 | + else |
||
174 | + reg += PCIE_DEVICE_OFFSET_6328; |
||
175 | + } |
||
176 | |||
177 | |||
178 | data = bcm_pcie_readl(reg); |
||
179 | --- a/arch/mips/pci/pci-bcm63xx.c |
||
180 | +++ b/arch/mips/pci/pci-bcm63xx.c |
||
181 | @@ -118,7 +118,7 @@ static void bcm63xx_int_cfg_writel(u32 v |
||
182 | |||
183 | void __iomem *pci_iospace_start; |
||
184 | |||
185 | -static void __init bcm63xx_reset_pcie(void) |
||
186 | +static void __init bcm63xx_reset_pcie_gen1(void) |
||
187 | { |
||
188 | u32 val; |
||
189 | u32 reg; |
||
190 | @@ -152,20 +152,32 @@ static void __init bcm63xx_reset_pcie(vo |
||
191 | mdelay(200); |
||
192 | } |
||
193 | |||
194 | -static struct clk *pcie_clk; |
||
195 | - |
||
196 | -static int __init bcm63xx_register_pcie(void) |
||
197 | +static void __init bcm63xx_reset_pcie_gen2(void) |
||
198 | { |
||
199 | u32 val; |
||
200 | |||
201 | - /* enable clock */ |
||
202 | - pcie_clk = clk_get(NULL, "pcie"); |
||
203 | - if (IS_ERR_OR_NULL(pcie_clk)) |
||
204 | - return -ENODEV; |
||
205 | + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_HARD, 0); |
||
206 | |||
207 | - clk_prepare_enable(pcie_clk); |
||
208 | + /* reset the PCIe core */ |
||
209 | + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1); |
||
210 | + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1); |
||
211 | + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_CORE, 1); |
||
212 | + mdelay(10); |
||
213 | + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0); |
||
214 | + mdelay(10); |
||
215 | + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0); |
||
216 | + mdelay(10); |
||
217 | + val = bcm_pcie_readl(PCIE_HARD_DEBUG_REG); |
||
218 | + val &= ~HARD_DEBUG_SERDES_IDDQ; |
||
219 | + bcm_pcie_writel(val, PCIE_HARD_DEBUG_REG); |
||
220 | + mdelay(10); |
||
221 | + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_CORE, 0); |
||
222 | + mdelay(200); |
||
223 | +} |
||
224 | |||
225 | - bcm63xx_reset_pcie(); |
||
226 | +static void __init bcm63xx_init_pcie_gen1(void) |
||
227 | +{ |
||
228 | + u32 val; |
||
229 | |||
230 | /* configure the PCIe bridge */ |
||
231 | val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG); |
||
232 | @@ -190,6 +202,65 @@ static int __init bcm63xx_register_pcie( |
||
233 | val |= OPT2_CFG_TYPE1_BD_SEL; |
||
234 | bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG); |
||
235 | |||
236 | + /* set bar0 to little endian */ |
||
237 | + val = (bcm_pcie_mem_resource.start >> 20) << BASEMASK_BASE_SHIFT; |
||
238 | + val |= (bcm_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT; |
||
239 | + val |= BASEMASK_REMAP_EN; |
||
240 | + bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG); |
||
241 | + |
||
242 | + val = (bcm_pcie_mem_resource.start >> 20) << REBASE_ADDR_BASE_SHIFT; |
||
243 | + bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG); |
||
244 | +} |
||
245 | + |
||
246 | +static void __init bcm63xx_init_pcie_gen2(void) |
||
247 | +{ |
||
248 | + u32 val; |
||
249 | + |
||
250 | + bcm_pcie_writel(CPU_INT_PCIE_INTA | CPU_INT_PCIE_INTB | |
||
251 | + CPU_INT_PCIE_INTC | CPU_INT_PCIE_INTD, |
||
252 | + PCIE_CPU_INT1_MASK_CLEAR_REG); |
||
253 | + |
||
254 | + val = bcm_pcie_mem_resource.end & C2P_BASELIMIT_LIMIT_MASK; |
||
255 | + val |= (bcm_pcie_mem_resource.start >> C2P_BASELIMIT_LIMIT_SHIFT) << |
||
256 | + C2P_BASELIMIT_BASE_SHIFT; |
||
257 | + |
||
258 | + bcm_pcie_writel(val, PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG); |
||
259 | + |
||
260 | + /* set bar0 to little endian */ |
||
261 | + val = bcm_pcie_readl(PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG); |
||
262 | + val |= bcm_pcie_mem_resource.start & C2P_MEM_WIN_BASE_ADDR_MASK; |
||
263 | + val |= C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP; |
||
264 | + bcm_pcie_writel(val, PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG); |
||
265 | + |
||
266 | + bcm_pcie_writel(SPECIFIC_ENDIAN_MODE_BYTE_ALIGN, PCIE_SPECIFIC_REG); |
||
267 | + bcm_pcie_writel(RC_BAR_CFG_LO_SIZE_256MB, PCIE_RC_BAR1_CONFIG_LO_REG); |
||
268 | + bcm_pcie_writel(BAR1_CFG_REMAP_ACCESS_EN, PCIE_UBUS_BAR1_CFG_REMAP_REG); |
||
269 | + |
||
270 | + bcm_pcie_writel(PCIE_BUS_DEVICE << EXT_CFG_BUS_NUM_SHIFT, |
||
271 | + PCIE_EXT_CFG_INDEX_REG); |
||
272 | +} |
||
273 | + |
||
274 | +static struct clk *pcie_clk; |
||
275 | + |
||
276 | +static int __init bcm63xx_register_pcie(void) |
||
277 | +{ |
||
278 | + u32 val; |
||
279 | + |
||
280 | + /* enable clock */ |
||
281 | + pcie_clk = clk_get(NULL, "pcie"); |
||
282 | + if (IS_ERR_OR_NULL(pcie_clk)) |
||
283 | + return -ENODEV; |
||
284 | + |
||
285 | + clk_prepare_enable(pcie_clk); |
||
286 | + |
||
287 | + if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_63268()) { |
||
288 | + bcm63xx_reset_pcie_gen1(); |
||
289 | + bcm63xx_init_pcie_gen1(); |
||
290 | + } else { |
||
291 | + bcm63xx_reset_pcie_gen2(); |
||
292 | + bcm63xx_init_pcie_gen2(); |
||
293 | + } |
||
294 | + |
||
295 | /* setup class code as bridge */ |
||
296 | val = bcm_pcie_readl(PCIE_IDVAL3_REG); |
||
297 | val &= ~IDVAL3_CLASS_CODE_MASK; |
||
298 | @@ -201,15 +272,6 @@ static int __init bcm63xx_register_pcie( |
||
299 | val &= ~CONFIG2_BAR1_SIZE_MASK; |
||
300 | bcm_pcie_writel(val, PCIE_CONFIG2_REG); |
||
301 | |||
302 | - /* set bar0 to little endian */ |
||
303 | - val = (bcm_pcie_mem_resource.start >> 20) << BASEMASK_BASE_SHIFT; |
||
304 | - val |= (bcm_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT; |
||
305 | - val |= BASEMASK_REMAP_EN; |
||
306 | - bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG); |
||
307 | - |
||
308 | - val = (bcm_pcie_mem_resource.start >> 20) << REBASE_ADDR_BASE_SHIFT; |
||
309 | - bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG); |
||
310 | - |
||
311 | register_pci_controller(&bcm63xx_pcie_controller); |
||
312 | |||
313 | return 0; |
||
314 | @@ -341,7 +403,10 @@ static int __init bcm63xx_pci_init(void) |
||
315 | if (!bcm63xx_pci_enabled) |
||
316 | return -ENODEV; |
||
317 | |||
318 | - if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) { |
||
319 | + if (BCMCPU_IS_6318()) { |
||
320 | + bcm_pcie_mem_resource.start = BCM_PCIE_MEM_BASE_PA_6318; |
||
321 | + bcm_pcie_mem_resource.end = BCM_PCIE_MEM_END_PA_6318; |
||
322 | + } if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) { |
||
323 | bcm_pcie_mem_resource.start = BCM_PCIE_MEM_BASE_PA_6328; |
||
324 | bcm_pcie_mem_resource.end = BCM_PCIE_MEM_END_PA_6328; |
||
325 | } else if (BCMCPU_IS_63268()) { |
||
326 | @@ -350,6 +415,7 @@ static int __init bcm63xx_pci_init(void) |
||
327 | } |
||
328 | |||
329 | switch (bcm63xx_get_cpu_id()) { |
||
330 | + case BCM6318_CPU_ID: |
||
331 | case BCM6328_CPU_ID: |
||
332 | case BCM6362_CPU_ID: |
||
333 | case BCM63268_CPU_ID: |