brcm63xx: add clkdev lookup support
[openwrt/openwrt.git] / target / linux / brcm63xx / patches-4.4 / 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 @@ -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: