bcm27xx: update 6.1 patches to latest version
[openwrt/staging/svanheule.git] / target / linux / bcm27xx / patches-6.1 / 950-0872-mfd-Add-rp1-driver.patch
1 From 7196a12b94e90225686e6c34cdf65a583214f7a5 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Mon, 10 Oct 2022 14:21:50 +0100
4 Subject: [PATCH] mfd: Add rp1 driver
5
6 RP1 is a multifunction PCIe device that exposes a range of
7 peripherals.
8 Add the parent driver to manage these.
9
10 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
11 ---
12 drivers/mfd/Kconfig | 11 ++
13 drivers/mfd/Makefile | 1 +
14 drivers/mfd/rp1.c | 367 +++++++++++++++++++++++++++++++++++
15 include/linux/rp1_platform.h | 20 ++
16 4 files changed, 399 insertions(+)
17 create mode 100644 drivers/mfd/rp1.c
18 create mode 100644 include/linux/rp1_platform.h
19
20 --- a/drivers/mfd/Kconfig
21 +++ b/drivers/mfd/Kconfig
22 @@ -2252,6 +2252,17 @@ config MFD_INTEL_M10_BMC
23 additional drivers must be enabled in order to use the functionality
24 of the device.
25
26 +config MFD_RP1
27 + tristate "RP1 MFD driver"
28 + depends on PCI
29 + select MFD_CORE
30 + help
31 + Support for the RP1 peripheral chip.
32 +
33 + This driver provides support for the Raspberry Pi RP1 peripheral chip.
34 + It is responsible for enabling the Device Tree node once the PCIe endpoint
35 + has been configured, and handling interrupts.
36 +
37 config MFD_RSMU_I2C
38 tristate "Renesas Synchronization Management Unit with I2C"
39 depends on I2C && OF
40 --- a/drivers/mfd/Makefile
41 +++ b/drivers/mfd/Makefile
42 @@ -273,6 +273,7 @@ obj-$(CONFIG_MFD_RPISENSE_CORE) += rpise
43 obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o
44 obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o
45 obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o
46 +obj-$(CONFIG_MFD_RP1) += rp1.o
47
48 obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o
49 obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o
50 --- /dev/null
51 +++ b/drivers/mfd/rp1.c
52 @@ -0,0 +1,367 @@
53 +// SPDX-License-Identifier: GPL-2.0
54 +/*
55 + * Copyright (c) 2018-22 Raspberry Pi Ltd.
56 + * All rights reserved.
57 + */
58 +
59 +#include <linux/clk.h>
60 +#include <linux/clkdev.h>
61 +#include <linux/clk-provider.h>
62 +#include <linux/completion.h>
63 +#include <linux/etherdevice.h>
64 +#include <linux/err.h>
65 +#include <linux/interrupt.h>
66 +#include <linux/io.h>
67 +#include <linux/irq.h>
68 +#include <linux/irqchip/chained_irq.h>
69 +#include <linux/irqdomain.h>
70 +#include <linux/mfd/core.h>
71 +#include <linux/mmc/host.h>
72 +#include <linux/module.h>
73 +#include <linux/msi.h>
74 +#include <linux/of_platform.h>
75 +#include <linux/pci.h>
76 +#include <linux/platform_device.h>
77 +#include <linux/rp1_platform.h>
78 +#include <linux/reset.h>
79 +#include <linux/slab.h>
80 +
81 +#include <dt-bindings/mfd/rp1.h>
82 +
83 +/* TO DO:
84 + * 1. Occasional shutdown crash - RP1 being closed before its children?
85 + * 2. DT mode interrupt handling.
86 + */
87 +
88 +#define RP1_DRIVER_NAME "rp1"
89 +
90 +#define PCI_VENDOR_ID_RPI 0x1de4
91 +#define PCI_DEVICE_ID_RP1_C0 0x0001
92 +#define PCI_DEVICE_REV_RP1_C0 2
93 +
94 +#define RP1_ACTUAL_IRQS RP1_INT_END
95 +#define RP1_IRQS RP1_ACTUAL_IRQS
96 +
97 +#define RP1_SYSCLK_RATE 200000000
98 +#define RP1_SYSCLK_FPGA_RATE 60000000
99 +
100 +// Don't want to include the whole sysinfo reg header
101 +#define SYSINFO_CHIP_ID_OFFSET 0x00000000
102 +#define SYSINFO_PLATFORM_OFFSET 0x00000004
103 +
104 +#define REG_RW 0x000
105 +#define REG_SET 0x800
106 +#define REG_CLR 0xc00
107 +
108 +// MSIX CFG registers start at 0x8
109 +#define MSIX_CFG(x) (0x8 + (4 * (x)))
110 +
111 +#define MSIX_CFG_IACK_EN BIT(3)
112 +#define MSIX_CFG_IACK BIT(2)
113 +#define MSIX_CFG_TEST BIT(1)
114 +#define MSIX_CFG_ENABLE BIT(0)
115 +
116 +#define INTSTATL 0x108
117 +#define INTSTATH 0x10c
118 +
119 +struct rp1_dev {
120 + struct pci_dev *pdev;
121 + struct device *dev;
122 + resource_size_t bar_start;
123 + resource_size_t bar_end;
124 + struct clk *sys_clk;
125 + struct irq_domain *domain;
126 + struct irq_data *pcie_irqds[64];
127 + void __iomem *msix_cfg_regs;
128 +};
129 +
130 +static bool rp1_level_triggered_irq[RP1_ACTUAL_IRQS] = { 0 };
131 +
132 +static struct rp1_dev *g_rp1;
133 +static u32 g_chip_id, g_platform;
134 +
135 +static void dump_bar(struct pci_dev *pdev, unsigned int bar)
136 +{
137 + dev_info(&pdev->dev,
138 + "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
139 + bar,
140 + pci_resource_len(pdev, bar),
141 + pci_resource_start(pdev, bar),
142 + pci_resource_end(pdev, bar),
143 + pci_resource_flags(pdev, bar));
144 +}
145 +
146 +static void msix_cfg_set(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
147 +{
148 + writel(value, rp1->msix_cfg_regs + REG_SET + MSIX_CFG(hwirq));
149 +}
150 +
151 +static void msix_cfg_clr(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
152 +{
153 + writel(value, rp1->msix_cfg_regs + REG_CLR + MSIX_CFG(hwirq));
154 +}
155 +
156 +static void rp1_mask_irq(struct irq_data *irqd)
157 +{
158 + struct rp1_dev *rp1 = irqd->domain->host_data;
159 + struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
160 +
161 + pci_msi_mask_irq(pcie_irqd);
162 +}
163 +
164 +static void rp1_unmask_irq(struct irq_data *irqd)
165 +{
166 + struct rp1_dev *rp1 = irqd->domain->host_data;
167 + struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
168 +
169 + pci_msi_unmask_irq(pcie_irqd);
170 +}
171 +
172 +static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type)
173 +{
174 + struct rp1_dev *rp1 = irqd->domain->host_data;
175 + unsigned int hwirq = (unsigned int)irqd->hwirq;
176 + int ret = 0;
177 +
178 + switch (type) {
179 + case IRQ_TYPE_LEVEL_HIGH:
180 + dev_dbg(rp1->dev, "MSIX IACK EN for irq %d\n", hwirq);
181 + msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN);
182 + rp1_level_triggered_irq[hwirq] = true;
183 + break;
184 + case IRQ_TYPE_EDGE_RISING:
185 + msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN);
186 + rp1_level_triggered_irq[hwirq] = false;
187 + break;
188 + default:
189 + ret = -EINVAL;
190 + break;
191 + }
192 +
193 + return ret;
194 +}
195 +
196 +static struct irq_chip rp1_irq_chip = {
197 + .name = "rp1_irq_chip",
198 + .irq_mask = rp1_mask_irq,
199 + .irq_unmask = rp1_unmask_irq,
200 + .irq_set_type = rp1_irq_set_type,
201 +};
202 +
203 +static void rp1_chained_handle_irq(struct irq_desc *desc)
204 +{
205 + struct irq_chip *chip = irq_desc_get_chip(desc);
206 + struct rp1_dev *rp1 = desc->irq_data.chip_data;
207 + unsigned int hwirq = desc->irq_data.hwirq & 0x3f;
208 + int new_irq;
209 +
210 + rp1 = g_rp1;
211 +
212 + chained_irq_enter(chip, desc);
213 +
214 + new_irq = irq_linear_revmap(rp1->domain, hwirq);
215 + generic_handle_irq(new_irq);
216 + if (rp1_level_triggered_irq[hwirq])
217 + msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK);
218 +
219 + chained_irq_exit(chip, desc);
220 +}
221 +
222 +static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node,
223 + const u32 *intspec, unsigned int intsize,
224 + unsigned long *out_hwirq, unsigned int *out_type)
225 +{
226 + struct rp1_dev *rp1 = d->host_data;
227 + struct irq_data *pcie_irqd;
228 + unsigned long hwirq;
229 + int pcie_irq;
230 + int ret;
231 +
232 + ret = irq_domain_xlate_twocell(d, node, intspec, intsize,
233 + &hwirq, out_type);
234 + if (!ret) {
235 + pcie_irq = pci_irq_vector(rp1->pdev, hwirq);
236 + pcie_irqd = irq_get_irq_data(pcie_irq);
237 + rp1->pcie_irqds[hwirq] = pcie_irqd;
238 + *out_hwirq = hwirq;
239 + }
240 + return ret;
241 +}
242 +
243 +static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd,
244 + bool reserve)
245 +{
246 + struct rp1_dev *rp1 = d->host_data;
247 + struct irq_data *pcie_irqd;
248 +
249 + pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
250 + msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
251 + return irq_domain_activate_irq(pcie_irqd, reserve);
252 +}
253 +
254 +static void rp1_irq_deactivate(struct irq_domain *d, struct irq_data *irqd)
255 +{
256 + struct rp1_dev *rp1 = d->host_data;
257 + struct irq_data *pcie_irqd;
258 +
259 + pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
260 + msix_cfg_clr(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
261 + return irq_domain_deactivate_irq(pcie_irqd);
262 +}
263 +
264 +static const struct irq_domain_ops rp1_domain_ops = {
265 + .xlate = rp1_irq_xlate,
266 + .activate = rp1_irq_activate,
267 + .deactivate = rp1_irq_deactivate,
268 +};
269 +
270 +static inline dma_addr_t rp1_io_to_phys(struct rp1_dev *rp1, unsigned int offset)
271 +{
272 + return rp1->bar_start + offset;
273 +}
274 +
275 +static u32 rp1_reg_read(struct rp1_dev *rp1, unsigned int base_addr, u32 offset)
276 +{
277 + dma_addr_t phys = rp1_io_to_phys(rp1, base_addr);
278 + void __iomem *regblock = ioremap(phys, 0x1000);
279 + u32 value = readl(regblock + offset);
280 +
281 + iounmap(regblock);
282 + return value;
283 +}
284 +
285 +void rp1_get_platform(u32 *chip_id, u32 *platform)
286 +{
287 + if (chip_id)
288 + *chip_id = g_chip_id;
289 + if (platform)
290 + *platform = g_platform;
291 +}
292 +EXPORT_SYMBOL_GPL(rp1_get_platform);
293 +
294 +static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id)
295 +{
296 + struct reset_control *reset;
297 + struct platform_device *pcie_pdev;
298 + struct device_node *rp1_node;
299 + struct rp1_dev *rp1;
300 + int err = 0;
301 + int i;
302 +
303 + reset = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
304 + if (IS_ERR(reset))
305 + return PTR_ERR(reset);
306 + reset_control_reset(reset);
307 +
308 + dump_bar(pdev, 0);
309 + dump_bar(pdev, 1);
310 +
311 + if (pci_resource_len(pdev, 1) <= 0x10000) {
312 + dev_err(&pdev->dev,
313 + "Not initialised - is the firmware running?\n");
314 + return -EINVAL;
315 + }
316 +
317 + /* enable pci device */
318 + err = pcim_enable_device(pdev);
319 + if (err < 0) {
320 + dev_err(&pdev->dev, "Enabling PCI device has failed: %d",
321 + err);
322 + return err;
323 + }
324 +
325 + pci_set_master(pdev);
326 +
327 + err = pci_alloc_irq_vectors(pdev, RP1_IRQS, RP1_IRQS,
328 + PCI_IRQ_MSIX);
329 + if (err != RP1_IRQS) {
330 + dev_err(&pdev->dev, "pci_alloc_irq_vectors failed - %d\n", err);
331 + return err;
332 + }
333 +
334 + rp1 = devm_kzalloc(&pdev->dev, sizeof(*rp1), GFP_KERNEL);
335 + if (!rp1)
336 + return -ENOMEM;
337 +
338 + rp1->pdev = pdev;
339 + rp1->dev = &pdev->dev;
340 +
341 + pci_set_drvdata(pdev, rp1);
342 +
343 + rp1->bar_start = pci_resource_start(pdev, 1);
344 + rp1->bar_end = pci_resource_end(pdev, 1);
345 +
346 + // Get chip id
347 + g_chip_id = rp1_reg_read(rp1, RP1_SYSINFO_BASE, SYSINFO_CHIP_ID_OFFSET);
348 + g_platform = rp1_reg_read(rp1, RP1_SYSINFO_BASE, SYSINFO_PLATFORM_OFFSET);
349 + dev_info(&pdev->dev, "chip_id 0x%x%s\n", g_chip_id,
350 + (g_platform & RP1_PLATFORM_FPGA) ? " FPGA" : "");
351 + if (g_chip_id != RP1_C0_CHIP_ID) {
352 + dev_err(&pdev->dev, "wrong chip id (%x)\n", g_chip_id);
353 + return -EINVAL;
354 + }
355 +
356 + rp1_node = of_find_node_by_name(NULL, "rp1");
357 + if (!rp1_node) {
358 + dev_err(&pdev->dev, "failed to find RP1 DT node\n");
359 + return -EINVAL;
360 + }
361 +
362 + pcie_pdev = of_find_device_by_node(rp1_node->parent);
363 + rp1->domain = irq_domain_add_linear(rp1_node, RP1_IRQS,
364 + &rp1_domain_ops, rp1);
365 +
366 + g_rp1 = rp1;
367 +
368 + /* TODO can this go in the rp1 device tree entry? */
369 + rp1->msix_cfg_regs = ioremap(rp1_io_to_phys(rp1, RP1_PCIE_APBS_BASE), 0x1000);
370 +
371 + for (i = 0; i < RP1_IRQS; i++) {
372 + int irq = irq_create_mapping(rp1->domain, i);
373 +
374 + if (irq < 0) {
375 + dev_err(&pdev->dev, "failed to create irq mapping\n");
376 + return irq;
377 + }
378 +
379 + irq_set_chip_data(irq, rp1);
380 + irq_set_chip_and_handler(irq, &rp1_irq_chip, handle_level_irq);
381 + irq_set_probe(irq);
382 + irq_set_chained_handler(pci_irq_vector(pdev, i),
383 + rp1_chained_handle_irq);
384 + }
385 +
386 + if (rp1_node)
387 + of_platform_populate(rp1_node, NULL, NULL, &pcie_pdev->dev);
388 +
389 + of_node_put(rp1_node);
390 +
391 + return 0;
392 +}
393 +
394 +static void rp1_remove(struct pci_dev *pdev)
395 +{
396 + struct rp1_dev *rp1 = pci_get_drvdata(pdev);
397 +
398 + mfd_remove_devices(&pdev->dev);
399 +
400 + clk_unregister(rp1->sys_clk);
401 +}
402 +
403 +static const struct pci_device_id dev_id_table[] = {
404 + { PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RP1_C0), },
405 + { 0, }
406 +};
407 +
408 +static struct pci_driver rp1_driver = {
409 + .name = RP1_DRIVER_NAME,
410 + .id_table = dev_id_table,
411 + .probe = rp1_probe,
412 + .remove = rp1_remove,
413 +};
414 +
415 +module_pci_driver(rp1_driver);
416 +
417 +MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
418 +MODULE_DESCRIPTION("RP1 wrapper");
419 +MODULE_LICENSE("GPL");
420 --- /dev/null
421 +++ b/include/linux/rp1_platform.h
422 @@ -0,0 +1,20 @@
423 +/* SPDX-License-Identifier: GPL-2.0 */
424 +/*
425 + * Copyright (c) 2021-2022 Raspberry Pi Ltd.
426 + * All rights reserved.
427 + */
428 +
429 +#ifndef _RP1_PLATFORM_H
430 +#define _RP1_PLATFORM_H
431 +
432 +#include <vdso/bits.h>
433 +
434 +#define RP1_B0_CHIP_ID 0x10001927
435 +#define RP1_C0_CHIP_ID 0x20001927
436 +
437 +#define RP1_PLATFORM_ASIC BIT(1)
438 +#define RP1_PLATFORM_FPGA BIT(0)
439 +
440 +void rp1_get_platform(u32 *chip_id, u32 *platform);
441 +
442 +#endif