bmips: add linux v5.15 support
[openwrt/staging/wigyori.git] / target / linux / bmips / files / drivers / pci / controller / pcie-bcm6318.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * BCM6318 PCIe Controller Driver
4 *
5 * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
6 * Copyright (C) 2015 Jonas Gorski <jonas.gorski@gmail.com>
7 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
8 */
9
10 #include <linux/clk.h>
11 #include <linux/init.h>
12 #include <linux/delay.h>
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/of_gpio.h>
16 #include <linux/of_irq.h>
17 #include <linux/of_pci.h>
18 #include <linux/of_platform.h>
19 #include <linux/pci.h>
20 #include <linux/reset.h>
21 #include <linux/types.h>
22 #include <linux/version.h>
23 #include <linux/vmalloc.h>
24
25 #include "../pci.h"
26
27 #define PCIE_BUS_BRIDGE 0
28 #define PCIE_BUS_DEVICE 1
29
30 #define PCIE_SPECIFIC_REG 0x188
31 #define SPECIFIC_ENDIAN_MODE_BAR1_SHIFT 0
32 #define SPECIFIC_ENDIAN_MODE_BAR1_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
33 #define SPECIFIC_ENDIAN_MODE_BAR2_SHIFT 2
34 #define SPECIFIC_ENDIAN_MODE_BAR2_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
35 #define SPECIFIC_ENDIAN_MODE_BAR3_SHIFT 4
36 #define SPECIFIC_ENDIAN_MODE_BAR3_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
37 #define SPECIFIC_ENDIAN_MODE_WORD_ALIGN 0
38 #define SPECIFIC_ENDIAN_MODE_HALFWORD_ALIGN 1
39 #define SPECIFIC_ENDIAN_MODE_BYTE_ALIGN 2
40
41 #define PCIE_CONFIG2_REG 0x408
42 #define CONFIG2_BAR1_SIZE_EN 1
43 #define CONFIG2_BAR1_SIZE_MASK 0xf
44
45 #define PCIE_IDVAL3_REG 0x43c
46 #define IDVAL3_CLASS_CODE_MASK 0xffffff
47 #define IDVAL3_SUBCLASS_SHIFT 8
48 #define IDVAL3_CLASS_SHIFT 16
49
50 #define PCIE_DLSTATUS_REG 0x1048
51 #define DLSTATUS_PHYLINKUP (1 << 13)
52
53 #define PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG 0x400c
54 #define C2P_MEM_WIN_ENDIAN_MODE_MASK 0x3
55 #define C2P_MEM_WIN_ENDIAN_NO_SWAP 0
56 #define C2P_MEM_WIN_ENDIAN_HALF_WORD_SWAP 1
57 #define C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP 2
58 #define C2P_MEM_WIN_BASE_ADDR_SHIFT 20
59 #define C2P_MEM_WIN_BASE_ADDR_MASK (0xfff << C2P_MEM_WIN_BASE_ADDR_SHIFT)
60
61 #define PCIE_RC_BAR1_CONFIG_LO_REG 0x402c
62 #define RC_BAR_CFG_LO_SIZE_256MB 0xd
63 #define RC_BAR_CFG_LO_MATCH_ADDR_SHIFT 20
64 #define RC_BAR_CFG_LO_MATCH_ADDR_MASK (0xfff << RC_BAR_CFG_LO_MATCH_ADDR_SHIFT)
65
66 #define PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG 0x4070
67 #define C2P_BASELIMIT_LIMIT_SHIFT 20
68 #define C2P_BASELIMIT_LIMIT_MASK (0xfff << C2P_BASELIMIT_LIMIT_SHIFT)
69 #define C2P_BASELIMIT_BASE_SHIFT 4
70 #define C2P_BASELIMIT_BASE_MASK (0xfff << C2P_BASELIMIT_BASE_SHIFT)
71
72 #define PCIE_UBUS_BAR1_CFG_REMAP_REG 0x4088
73 #define BAR1_CFG_REMAP_OFFSET_SHIFT 20
74 #define BAR1_CFG_REMAP_OFFSET_MASK (0xfff << BAR1_CFG_REMAP_OFFSET_SHIFT)
75 #define BAR1_CFG_REMAP_ACCESS_EN 1
76
77 #define PCIE_HARD_DEBUG_REG 0x4204
78 #define HARD_DEBUG_SERDES_IDDQ (1 << 23)
79
80 #define PCIE_CPU_INT1_MASK_CLEAR_REG 0x830c
81 #define CPU_INT_PCIE_ERR_ATTN_CPU (1 << 0)
82 #define CPU_INT_PCIE_INTA (1 << 1)
83 #define CPU_INT_PCIE_INTB (1 << 2)
84 #define CPU_INT_PCIE_INTC (1 << 3)
85 #define CPU_INT_PCIE_INTD (1 << 4)
86 #define CPU_INT_PCIE_INTR (1 << 5)
87 #define CPU_INT_PCIE_NMI (1 << 6)
88 #define CPU_INT_PCIE_UBUS (1 << 7)
89 #define CPU_INT_IPI (1 << 8)
90
91 #define PCIE_EXT_CFG_INDEX_REG 0x8400
92 #define EXT_CFG_FUNC_NUM_SHIFT 12
93 #define EXT_CFG_FUNC_NUM_MASK (0x7 << EXT_CFG_FUNC_NUM_SHIFT)
94 #define EXT_CFG_DEV_NUM_SHIFT 15
95 #define EXT_CFG_DEV_NUM_MASK (0xf << EXT_CFG_DEV_NUM_SHIFT)
96 #define EXT_CFG_BUS_NUM_SHIFT 20
97 #define EXT_CFG_BUS_NUM_MASK (0xff << EXT_CFG_BUS_NUM_SHIFT)
98
99 #define PCIE_DEVICE_OFFSET 0x9000
100
101 struct bcm6318_pcie {
102 void __iomem *base;
103 int irq;
104 struct clk *clk;
105 struct clk *clk25;
106 struct clk *clk_ubus;
107 struct reset_control *reset;
108 struct reset_control *reset_ext;
109 struct reset_control *reset_core;
110 struct reset_control *reset_hard;
111 };
112
113 static struct bcm6318_pcie bcm6318_pcie;
114
115 extern int bmips_pci_irq;
116
117 /*
118 * swizzle 32bits data to return only the needed part
119 */
120 static int postprocess_read(u32 data, int where, unsigned int size)
121 {
122 u32 ret = 0;
123
124 switch (size) {
125 case 1:
126 ret = (data >> ((where & 3) << 3)) & 0xff;
127 break;
128 case 2:
129 ret = (data >> ((where & 3) << 3)) & 0xffff;
130 break;
131 case 4:
132 ret = data;
133 break;
134 }
135
136 return ret;
137 }
138
139 static int preprocess_write(u32 orig_data, u32 val, int where,
140 unsigned int size)
141 {
142 u32 ret = 0;
143
144 switch (size) {
145 case 1:
146 ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
147 (val << ((where & 3) << 3));
148 break;
149 case 2:
150 ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
151 (val << ((where & 3) << 3));
152 break;
153 case 4:
154 ret = val;
155 break;
156 }
157
158 return ret;
159 }
160
161 static int bcm6318_pcie_can_access(struct pci_bus *bus, int devfn)
162 {
163 struct bcm6318_pcie *priv = &bcm6318_pcie;
164
165 switch (bus->number) {
166 case PCIE_BUS_BRIDGE:
167 return PCI_SLOT(devfn) == 0;
168 case PCIE_BUS_DEVICE:
169 if (PCI_SLOT(devfn) == 0)
170 return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
171 & DLSTATUS_PHYLINKUP;
172 fallthrough;
173 default:
174 return false;
175 }
176 }
177
178 static int bcm6318_pcie_read(struct pci_bus *bus, unsigned int devfn,
179 int where, int size, u32 *val)
180 {
181 struct bcm6318_pcie *priv = &bcm6318_pcie;
182 u32 data;
183 u32 reg = where & ~3;
184
185 if (!bcm6318_pcie_can_access(bus, devfn))
186 return PCIBIOS_DEVICE_NOT_FOUND;
187
188 if (bus->number == PCIE_BUS_DEVICE)
189 reg += PCIE_DEVICE_OFFSET;
190
191 data = __raw_readl(priv->base + reg);
192 *val = postprocess_read(data, where, size);
193
194 return PCIBIOS_SUCCESSFUL;
195 }
196
197 static int bcm6318_pcie_write(struct pci_bus *bus, unsigned int devfn,
198 int where, int size, u32 val)
199 {
200 struct bcm6318_pcie *priv = &bcm6318_pcie;
201 u32 data;
202 u32 reg = where & ~3;
203
204 if (!bcm6318_pcie_can_access(bus, devfn))
205 return PCIBIOS_DEVICE_NOT_FOUND;
206
207 if (bus->number == PCIE_BUS_DEVICE)
208 reg += PCIE_DEVICE_OFFSET;
209
210 data = __raw_readl(priv->base + reg);
211 data = preprocess_write(data, val, where, size);
212 __raw_writel(data, priv->base + reg);
213
214 return PCIBIOS_SUCCESSFUL;
215 }
216
217 static struct pci_ops bcm6318_pcie_ops = {
218 .read = bcm6318_pcie_read,
219 .write = bcm6318_pcie_write,
220 };
221
222 static struct resource bcm6318_pcie_io_resource;
223 static struct resource bcm6318_pcie_mem_resource;
224 static struct resource bcm6318_pcie_busn_resource;
225
226 static struct pci_controller bcm6318_pcie_controller = {
227 .pci_ops = &bcm6318_pcie_ops,
228 .io_resource = &bcm6318_pcie_io_resource,
229 .mem_resource = &bcm6318_pcie_mem_resource,
230 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0)
231 .busn_resource = &bcm6318_pcie_busn_resource,
232 #endif
233 };
234
235 static void bcm6318_pcie_reset(struct bcm6318_pcie *priv)
236 {
237 u32 val;
238
239 reset_control_deassert(priv->reset_hard);
240
241 reset_control_assert(priv->reset);
242 reset_control_assert(priv->reset_core);
243 reset_control_assert(priv->reset_ext);
244 mdelay(10);
245
246 reset_control_deassert(priv->reset_ext);
247 mdelay(10);
248
249 reset_control_deassert(priv->reset);
250 mdelay(10);
251
252 val = __raw_readl(priv->base + PCIE_HARD_DEBUG_REG);
253 val &= ~HARD_DEBUG_SERDES_IDDQ;
254 __raw_writel(val, priv->base + PCIE_HARD_DEBUG_REG);
255 mdelay(10);
256
257 reset_control_deassert(priv->reset_core);
258 mdelay(200);
259 }
260
261 static void bcm6318_pcie_setup(struct bcm6318_pcie *priv)
262 {
263 u32 val;
264
265 __raw_writel(CPU_INT_PCIE_INTA | CPU_INT_PCIE_INTB |
266 CPU_INT_PCIE_INTC | CPU_INT_PCIE_INTD,
267 priv->base + PCIE_CPU_INT1_MASK_CLEAR_REG);
268
269 val = bcm6318_pcie_mem_resource.end & C2P_BASELIMIT_LIMIT_MASK;
270 val |= (bcm6318_pcie_mem_resource.start >> C2P_BASELIMIT_LIMIT_SHIFT)
271 << C2P_BASELIMIT_BASE_SHIFT;
272 __raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG);
273
274 /* setup class code as bridge */
275 val = __raw_readl(priv->base + PCIE_IDVAL3_REG);
276 val &= ~IDVAL3_CLASS_CODE_MASK;
277 val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT);
278 __raw_writel(val, priv->base + PCIE_IDVAL3_REG);
279
280 /* disable bar1 size */
281 val = __raw_readl(priv->base + PCIE_CONFIG2_REG);
282 val &= ~CONFIG2_BAR1_SIZE_MASK;
283 __raw_writel(val, priv->base + PCIE_CONFIG2_REG);
284
285 /* set bar0 to little endian */
286 val = __raw_readl(priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
287 val |= bcm6318_pcie_mem_resource.start & C2P_MEM_WIN_BASE_ADDR_MASK;
288 val |= C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP;
289 __raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
290
291 __raw_writel(SPECIFIC_ENDIAN_MODE_BYTE_ALIGN,
292 priv->base + PCIE_SPECIFIC_REG);
293
294 __raw_writel(RC_BAR_CFG_LO_SIZE_256MB,
295 priv->base + PCIE_RC_BAR1_CONFIG_LO_REG);
296
297 __raw_writel(BAR1_CFG_REMAP_ACCESS_EN,
298 priv->base + PCIE_UBUS_BAR1_CFG_REMAP_REG);
299
300 __raw_writel(PCIE_BUS_DEVICE << EXT_CFG_BUS_NUM_SHIFT,
301 priv->base + PCIE_EXT_CFG_INDEX_REG);
302 }
303
304 static int bcm6318_pcie_probe(struct platform_device *pdev)
305 {
306 struct device *dev = &pdev->dev;
307 struct device_node *np = dev->of_node;
308 struct bcm6318_pcie *priv = &bcm6318_pcie;
309 struct resource *res;
310 int ret;
311 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
312 LIST_HEAD(resources);
313 #endif
314
315 of_pci_check_probe_only();
316
317 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
318 priv->base = devm_ioremap_resource(dev, res);
319 if (IS_ERR(priv->base))
320 return PTR_ERR(priv->base);
321
322 priv->irq = platform_get_irq(pdev, 0);
323 if (!priv->irq)
324 return -ENODEV;
325
326 bmips_pci_irq = priv->irq;
327
328 priv->reset = devm_reset_control_get(dev, "pcie");
329 if (IS_ERR(priv->reset))
330 return PTR_ERR(priv->reset);
331
332 priv->reset_ext = devm_reset_control_get(dev, "pcie-ext");
333 if (IS_ERR(priv->reset_ext))
334 return PTR_ERR(priv->reset_ext);
335
336 priv->reset_core = devm_reset_control_get(dev, "pcie-core");
337 if (IS_ERR(priv->reset_core))
338 return PTR_ERR(priv->reset_core);
339
340 priv->reset_hard = devm_reset_control_get(dev, "pcie-hard");
341 if (IS_ERR(priv->reset_hard))
342 return PTR_ERR(priv->reset_hard);
343
344 priv->clk = devm_clk_get(dev, "pcie");
345 if (IS_ERR(priv->clk))
346 return PTR_ERR(priv->clk);
347
348 priv->clk25 = devm_clk_get(dev, "pcie25");
349 if (IS_ERR(priv->clk25))
350 return PTR_ERR(priv->clk25);
351
352 priv->clk_ubus = devm_clk_get(dev, "pcie-ubus");
353 if (IS_ERR(priv->clk_ubus))
354 return PTR_ERR(priv->clk_ubus);
355
356 ret = clk_prepare_enable(priv->clk);
357 if (ret) {
358 dev_err(dev, "could not enable clock\n");
359 return ret;
360 }
361
362 ret = clk_prepare_enable(priv->clk25);
363 if (ret) {
364 dev_err(dev, "could not enable clock\n");
365 return ret;
366 }
367
368 ret = clk_prepare_enable(priv->clk_ubus);
369 if (ret) {
370 dev_err(dev, "could not enable clock\n");
371 return ret;
372 }
373
374 pci_load_of_ranges(&bcm6318_pcie_controller, np);
375 if (!bcm6318_pcie_mem_resource.start)
376 return -EINVAL;
377
378 of_pci_parse_bus_range(np, &bcm6318_pcie_busn_resource);
379 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
380 pci_add_resource(&resources, &bcm6318_pcie_busn_resource);
381 #endif
382
383 bcm6318_pcie_reset(priv);
384 bcm6318_pcie_setup(priv);
385
386 register_pci_controller(&bcm6318_pcie_controller);
387
388 return 0;
389 }
390
391 static const struct of_device_id bcm6318_pcie_of_match[] = {
392 { .compatible = "brcm,bcm6318-pcie", },
393 { /* sentinel */ }
394 };
395
396 static struct platform_driver bcm6318_pcie_driver = {
397 .probe = bcm6318_pcie_probe,
398 .driver = {
399 .name = "bcm6318-pcie",
400 .of_match_table = bcm6318_pcie_of_match,
401 },
402 };
403
404 int __init bcm6318_pcie_init(void)
405 {
406 int ret = platform_driver_register(&bcm6318_pcie_driver);
407 if (ret)
408 pr_err("pci-bcm6318: Error registering platform driver!\n");
409 return ret;
410 }
411 late_initcall_sync(bcm6318_pcie_init);