brcm63xx: add preliminary support for 3.13
[openwrt/svn-archive/archive.git] / target / linux / brcm63xx / patches-3.13 / 343-MIPS-BCM63XX-add-PCIe-support-for-BCM6318.patch
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 @@ -50,6 +50,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 @@ -317,12 +329,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 @@ -405,7 +422,7 @@ struct clk *clk_get(struct device *dev,
57 if ((BCMCPU_IS_6362() || BCMCPU_IS_6368() || BCMCPU_IS_63268()) &&
58 !strcmp(id, "ipsec"))
59 return &clk_ipsec;
60 - if ((BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_63268()) &&
61 + if ((BCMCPU_IS_6318() || BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_63268()) &&
62 !strcmp(id, "pcie"))
63 return &clk_pcie;
64 return ERR_PTR(-ENOENT);
65 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
66 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
67 @@ -40,6 +40,12 @@
68 #define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \
69 BCM_CB_MEM_SIZE - 1)
70
71 +#define BCM_PCIE_MEM_BASE_PA_6318 0x10200000
72 +#define BCM_PCIE_MEM_SIZE_6318 (1 * 1024 * 1024)
73 +#define BCM_PCIE_MEM_END_PA_6318 (BCM_PCIE_MEM_BASE_PA_6318 + \
74 + BCM_PCIE_MEM_SIZE_6318 - 1)
75 +
76 +
77 #define BCM_PCIE_MEM_BASE_PA_6328 0x10f00000
78 #define BCM_PCIE_MEM_SIZE_6328 (1 * 1024 * 1024)
79 #define BCM_PCIE_MEM_END_PA_6328 (BCM_PCIE_MEM_BASE_PA_6328 + \
80 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
81 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
82 @@ -1662,6 +1662,17 @@
83 * _REG relative to RSET_PCIE
84 *************************************************************************/
85
86 +#define PCIE_SPECIFIC_REG 0x188
87 +#define SPECIFIC_ENDIAN_MODE_BAR1_SHIFT 0
88 +#define SPECIFIC_ENDIAN_MODE_BAR1_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
89 +#define SPECIFIC_ENDIAN_MODE_BAR2_SHIFT 2
90 +#define SPECIFIC_ENDIAN_MODE_BAR2_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
91 +#define SPECIFIC_ENDIAN_MODE_BAR3_SHIFT 4
92 +#define SPECIFIC_ENDIAN_MODE_BAR3_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
93 +#define SPECIFIC_ENDIAN_MODE_WORD_ALIGN 0
94 +#define SPECIFIC_ENDIAN_MODE_HALFWORD_ALIGN 1
95 +#define SPECIFIC_ENDIAN_MODE_BYTE_ALIGN 2
96 +
97 #define PCIE_CONFIG2_REG 0x408
98 #define CONFIG2_BAR1_SIZE_EN 1
99 #define CONFIG2_BAR1_SIZE_MASK 0xf
100 @@ -1707,7 +1718,54 @@
101 #define PCIE_RC_INT_C (1 << 2)
102 #define PCIE_RC_INT_D (1 << 3)
103
104 -#define PCIE_DEVICE_OFFSET 0x8000
105 +#define PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG 0x400c
106 +#define C2P_MEM_WIN_ENDIAN_MODE_MASK 0x3
107 +#define C2P_MEM_WIN_ENDIAN_NO_SWAP 0
108 +#define C2P_MEM_WIN_ENDIAN_HALF_WORD_SWAP 1
109 +#define C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP 2
110 +#define C2P_MEM_WIN_BASE_ADDR_SHIFT 20
111 +#define C2P_MEM_WIN_BASE_ADDR_MASK (0xfff << C2P_MEM_WIN_BASE_ADDR_SHIFT)
112 +
113 +#define PCIE_RC_BAR1_CONFIG_LO_REG 0x402c
114 +#define RC_BAR_CFG_LO_SIZE_256MB 0xd
115 +#define RC_BAR_CFG_LO_MATCH_ADDR_SHIFT 20
116 +#define RC_BAR_CFG_LO_MATCH_ADDR_MASK (0xfff << RC_BAR_CFG_LO_MATCH_ADDR_SHIFT)
117 +
118 +#define PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG 0x4070
119 +#define C2P_BASELIMIT_LIMIT_SHIFT 20
120 +#define C2P_BASELIMIT_LIMIT_MASK (0xfff << C2P_BASELIMIT_LIMIT_SHIFT)
121 +#define C2P_BASELIMIT_BASE_SHIFT 4
122 +#define C2P_BASELIMIT_BASE_MASK (0xfff << C2P_BASELIMIT_BASE_SHIFT)
123 +
124 +#define PCIE_UBUS_BAR1_CFG_REMAP_REG 0x4088
125 +#define BAR1_CFG_REMAP_OFFSET_SHIFT 20
126 +#define BAR1_CFG_REMAP_OFFSET_MASK (0xfff << BAR1_CFG_REMAP_OFFSET_SHIFT)
127 +#define BAR1_CFG_REMAP_ACCESS_EN 1
128 +
129 +#define PCIE_HARD_DEBUG_REG 0x4204
130 +#define HARD_DEBUG_SERDES_IDDQ (1 << 23)
131 +
132 +#define PCIE_CPU_INT1_MASK_CLEAR_REG 0x830c
133 +#define CPU_INT_PCIE_ERR_ATTN_CPU (1 << 0)
134 +#define CPU_INT_PCIE_INTA (1 << 1)
135 +#define CPU_INT_PCIE_INTB (1 << 2)
136 +#define CPU_INT_PCIE_INTC (1 << 3)
137 +#define CPU_INT_PCIE_INTD (1 << 4)
138 +#define CPU_INT_PCIE_INTR (1 << 5)
139 +#define CPU_INT_PCIE_NMI (1 << 6)
140 +#define CPU_INT_PCIE_UBUS (1 << 7)
141 +#define CPU_INT_IPI (1 << 8)
142 +
143 +#define PCIE_EXT_CFG_INDEX_REG 0x8400
144 +#define EXT_CFG_FUNC_NUM_SHIFT 12
145 +#define EXT_CFG_FUNC_NUM_MASK (0x7 << EXT_CFG_FUNC_NUM_SHIFT)
146 +#define EXT_CFG_DEV_NUM_SHIFT 15
147 +#define EXT_CFG_DEV_NUM_MASK (0xf << EXT_CFG_DEV_NUM_SHIFT)
148 +#define EXT_CFG_BUS_NUM_SHIFT 20
149 +#define EXT_CFG_BUS_NUM_MASK (0xff << EXT_CFG_BUS_NUM_SHIFT)
150 +
151 +#define PCIE_DEVICE_OFFSET_6318 0x9000
152 +#define PCIE_DEVICE_OFFSET_6328 0x8000
153
154 /*************************************************************************
155 * _REG relative to RSET_OTP
156 --- a/arch/mips/pci/ops-bcm63xx.c
157 +++ b/arch/mips/pci/ops-bcm63xx.c
158 @@ -489,8 +489,12 @@ static int bcm63xx_pcie_read(struct pci_
159 if (!bcm63xx_pcie_can_access(bus, devfn))
160 return PCIBIOS_DEVICE_NOT_FOUND;
161
162 - if (bus->number == PCIE_BUS_DEVICE)
163 - reg += PCIE_DEVICE_OFFSET;
164 + if (bus->number == PCIE_BUS_DEVICE) {
165 + if (BCMCPU_IS_6318())
166 + reg += PCIE_DEVICE_OFFSET_6318;
167 + else
168 + reg += PCIE_DEVICE_OFFSET_6328;
169 + }
170
171 data = bcm_pcie_readl(reg);
172
173 @@ -509,8 +513,12 @@ static int bcm63xx_pcie_write(struct pci
174 if (!bcm63xx_pcie_can_access(bus, devfn))
175 return PCIBIOS_DEVICE_NOT_FOUND;
176
177 - if (bus->number == PCIE_BUS_DEVICE)
178 - reg += PCIE_DEVICE_OFFSET;
179 + if (bus->number == PCIE_BUS_DEVICE) {
180 + if (BCMCPU_IS_6318())
181 + reg += PCIE_DEVICE_OFFSET_6318;
182 + else
183 + reg += PCIE_DEVICE_OFFSET_6328;
184 + }
185
186
187 data = bcm_pcie_readl(reg);
188 --- a/arch/mips/pci/pci-bcm63xx.c
189 +++ b/arch/mips/pci/pci-bcm63xx.c
190 @@ -118,7 +118,7 @@ static void bcm63xx_int_cfg_writel(u32 v
191
192 void __iomem *pci_iospace_start;
193
194 -static void __init bcm63xx_reset_pcie(void)
195 +static void __init bcm63xx_reset_pcie_gen1(void)
196 {
197 u32 val;
198 u32 reg;
199 @@ -152,20 +152,32 @@ static void __init bcm63xx_reset_pcie(vo
200 mdelay(200);
201 }
202
203 -static struct clk *pcie_clk;
204 -
205 -static int __init bcm63xx_register_pcie(void)
206 +static void __init bcm63xx_reset_pcie_gen2(void)
207 {
208 u32 val;
209
210 - /* enable clock */
211 - pcie_clk = clk_get(NULL, "pcie");
212 - if (IS_ERR_OR_NULL(pcie_clk))
213 - return -ENODEV;
214 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_HARD, 0);
215
216 - clk_prepare_enable(pcie_clk);
217 + /* reset the PCIe core */
218 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1);
219 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1);
220 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_CORE, 1);
221 + mdelay(10);
222 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0);
223 + mdelay(10);
224 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0);
225 + mdelay(10);
226 + val = bcm_pcie_readl(PCIE_HARD_DEBUG_REG);
227 + val &= ~HARD_DEBUG_SERDES_IDDQ;
228 + bcm_pcie_writel(val, PCIE_HARD_DEBUG_REG);
229 + mdelay(10);
230 + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_CORE, 0);
231 + mdelay(200);
232 +}
233
234 - bcm63xx_reset_pcie();
235 +static void __init bcm63xx_init_pcie_gen1(void)
236 +{
237 + u32 val;
238
239 /* configure the PCIe bridge */
240 val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG);
241 @@ -190,6 +202,65 @@ static int __init bcm63xx_register_pcie(
242 val |= OPT2_CFG_TYPE1_BD_SEL;
243 bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG);
244
245 + /* set bar0 to little endian */
246 + val = (bcm_pcie_mem_resource.start >> 20) << BASEMASK_BASE_SHIFT;
247 + val |= (bcm_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT;
248 + val |= BASEMASK_REMAP_EN;
249 + bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG);
250 +
251 + val = (bcm_pcie_mem_resource.start >> 20) << REBASE_ADDR_BASE_SHIFT;
252 + bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG);
253 +}
254 +
255 +static void __init bcm63xx_init_pcie_gen2(void)
256 +{
257 + u32 val;
258 +
259 + bcm_pcie_writel(CPU_INT_PCIE_INTA | CPU_INT_PCIE_INTB |
260 + CPU_INT_PCIE_INTC | CPU_INT_PCIE_INTD,
261 + PCIE_CPU_INT1_MASK_CLEAR_REG);
262 +
263 + val = bcm_pcie_mem_resource.end & C2P_BASELIMIT_LIMIT_MASK;
264 + val |= (bcm_pcie_mem_resource.start >> C2P_BASELIMIT_LIMIT_SHIFT) <<
265 + C2P_BASELIMIT_BASE_SHIFT;
266 +
267 + bcm_pcie_writel(val, PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG);
268 +
269 + /* set bar0 to little endian */
270 + val = bcm_pcie_readl(PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
271 + val |= bcm_pcie_mem_resource.start & C2P_MEM_WIN_BASE_ADDR_MASK;
272 + val |= C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP;
273 + bcm_pcie_writel(val, PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
274 +
275 + bcm_pcie_writel(SPECIFIC_ENDIAN_MODE_BYTE_ALIGN, PCIE_SPECIFIC_REG);
276 + bcm_pcie_writel(RC_BAR_CFG_LO_SIZE_256MB, PCIE_RC_BAR1_CONFIG_LO_REG);
277 + bcm_pcie_writel(BAR1_CFG_REMAP_ACCESS_EN, PCIE_UBUS_BAR1_CFG_REMAP_REG);
278 +
279 + bcm_pcie_writel(PCIE_BUS_DEVICE << EXT_CFG_BUS_NUM_SHIFT,
280 + PCIE_EXT_CFG_INDEX_REG);
281 +}
282 +
283 +static struct clk *pcie_clk;
284 +
285 +static int __init bcm63xx_register_pcie(void)
286 +{
287 + u32 val;
288 +
289 + /* enable clock */
290 + pcie_clk = clk_get(NULL, "pcie");
291 + if (IS_ERR_OR_NULL(pcie_clk))
292 + return -ENODEV;
293 +
294 + clk_prepare_enable(pcie_clk);
295 +
296 + if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_63268()) {
297 + bcm63xx_reset_pcie_gen1();
298 + bcm63xx_init_pcie_gen1();
299 + } else {
300 + bcm63xx_reset_pcie_gen2();
301 + bcm63xx_init_pcie_gen2();
302 + }
303 +
304 /* setup class code as bridge */
305 val = bcm_pcie_readl(PCIE_IDVAL3_REG);
306 val &= ~IDVAL3_CLASS_CODE_MASK;
307 @@ -201,15 +272,6 @@ static int __init bcm63xx_register_pcie(
308 val &= ~CONFIG2_BAR1_SIZE_MASK;
309 bcm_pcie_writel(val, PCIE_CONFIG2_REG);
310
311 - /* set bar0 to little endian */
312 - val = (bcm_pcie_mem_resource.start >> 20) << BASEMASK_BASE_SHIFT;
313 - val |= (bcm_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT;
314 - val |= BASEMASK_REMAP_EN;
315 - bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG);
316 -
317 - val = (bcm_pcie_mem_resource.start >> 20) << REBASE_ADDR_BASE_SHIFT;
318 - bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG);
319 -
320 register_pci_controller(&bcm63xx_pcie_controller);
321
322 return 0;
323 @@ -341,7 +403,10 @@ static int __init bcm63xx_pci_init(void)
324 if (!bcm63xx_pci_enabled)
325 return -ENODEV;
326
327 - if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {
328 + if (BCMCPU_IS_6318()) {
329 + bcm_pcie_mem_resource.start = BCM_PCIE_MEM_BASE_PA_6318;
330 + bcm_pcie_mem_resource.end = BCM_PCIE_MEM_END_PA_6318;
331 + } if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {
332 bcm_pcie_mem_resource.start = BCM_PCIE_MEM_BASE_PA_6328;
333 bcm_pcie_mem_resource.end = BCM_PCIE_MEM_END_PA_6328;
334 } else if (BCMCPU_IS_63268()) {
335 @@ -350,6 +415,7 @@ static int __init bcm63xx_pci_init(void)
336 }
337
338 switch (bcm63xx_get_cpu_id()) {
339 + case BCM6318_CPU_ID:
340 case BCM6328_CPU_ID:
341 case BCM6362_CPU_ID:
342 case BCM63268_CPU_ID: