uboot-d1: add bootloader for upcoming d1 target
[openwrt/staging/981213.git] / package / boot / uboot-d1 / patches / 0038-remoteproc-Add-a-driver-for-the-Allwinner-AR100.patch
1 From 7585a12ffec6e42c62222d8ee4085413b3a197f7 Mon Sep 17 00:00:00 2001
2 From: Samuel Holland <samuel@sholland.org>
3 Date: Sat, 9 Oct 2021 14:58:27 -0500
4 Subject: [PATCH 38/90] remoteproc: Add a driver for the Allwinner AR100
5
6 Signed-off-by: Samuel Holland <samuel@sholland.org>
7 ---
8 drivers/remoteproc/Kconfig | 9 ++
9 drivers/remoteproc/Makefile | 1 +
10 drivers/remoteproc/sun6i_ar100_rproc.c | 111 +++++++++++++++++++++++++
11 3 files changed, 121 insertions(+)
12 create mode 100644 drivers/remoteproc/sun6i_ar100_rproc.c
13
14 --- a/drivers/remoteproc/Kconfig
15 +++ b/drivers/remoteproc/Kconfig
16 @@ -41,6 +41,15 @@ config REMOTEPROC_STM32_COPRO
17 Say 'y' here to add support for STM32 Cortex-M4 coprocessors via the
18 remoteproc framework.
19
20 +config REMOTEPROC_SUN6I_AR100
21 + bool "Support for Allwinner AR100 SCP"
22 + select REMOTEPROC
23 + depends on ARCH_SUNXI
24 + help
25 + Say 'y' here to support Allwinner's AR100 System Control Processor
26 + (SCP), found in various sun6i/sun8i/sun50i family SoCs, through the
27 + remoteproc framework.
28 +
29 config REMOTEPROC_TI_K3_ARM64
30 bool "Support for TI's K3 based ARM64 remoteproc driver"
31 select REMOTEPROC
32 --- a/drivers/remoteproc/Makefile
33 +++ b/drivers/remoteproc/Makefile
34 @@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc
35 obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o
36 obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
37 obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o
38 +obj-$(CONFIG_REMOTEPROC_SUN6I_AR100) += sun6i_ar100_rproc.o
39 obj-$(CONFIG_REMOTEPROC_TI_K3_ARM64) += ti_k3_arm64_rproc.o
40 obj-$(CONFIG_REMOTEPROC_TI_K3_DSP) += ti_k3_dsp_rproc.o
41 obj-$(CONFIG_REMOTEPROC_TI_K3_R5F) += ti_k3_r5f_rproc.o
42 --- /dev/null
43 +++ b/drivers/remoteproc/sun6i_ar100_rproc.c
44 @@ -0,0 +1,111 @@
45 +// SPDX-License-Identifier: GPL-2.0
46 +
47 +#include <dm.h>
48 +#include <errno.h>
49 +#include <remoteproc.h>
50 +#include <asm/io.h>
51 +
52 +#define SUNXI_SCP_MAGIC 0xb4400012
53 +
54 +#define OR1K_VEC_FIRST 0x01
55 +#define OR1K_VEC_LAST 0x0e
56 +#define OR1K_VEC_ADDR(n) (0x100 * (n))
57 +
58 +struct sun6i_ar100_rproc_priv {
59 + void *cfg_base;
60 + ulong sram_base;
61 +};
62 +
63 +static int sun6i_ar100_rproc_load(struct udevice *dev, ulong addr, ulong size)
64 +{
65 + struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
66 +
67 + /* Check for a valid SCP firmware. */
68 + if (readl_relaxed(addr) != SUNXI_SCP_MAGIC)
69 + return -ENOENT;
70 +
71 + /* Program exception vectors to the firmware entry point. */
72 + for (u32 i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
73 + ulong vector = priv->sram_base + OR1K_VEC_ADDR(i);
74 + ulong offset = addr - vector;
75 +
76 + writel_relaxed(offset >> 2, vector);
77 + }
78 +
79 + return 0;
80 +}
81 +
82 +static int sun6i_ar100_rproc_start(struct udevice *dev)
83 +{
84 + struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
85 +
86 + setbits_le32(priv->cfg_base, BIT(0));
87 +
88 + return 0;
89 +}
90 +
91 +static int sun6i_ar100_rproc_stop(struct udevice *dev)
92 +{
93 + struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
94 +
95 + clrbits_le32(priv->cfg_base, BIT(0));
96 +
97 + return 0;
98 +}
99 +
100 +static int sun6i_ar100_rproc_reset(struct udevice *dev)
101 +{
102 + int ret;
103 +
104 + ret = sun6i_ar100_rproc_stop(dev);
105 + if (ret)
106 + return ret;
107 +
108 + return sun6i_ar100_rproc_start(dev);
109 +}
110 +
111 +static int sun6i_ar100_rproc_is_running(struct udevice *dev)
112 +{
113 + struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
114 +
115 + return !(readl_relaxed(priv->cfg_base) & BIT(0));
116 +}
117 +
118 +static const struct dm_rproc_ops sun6i_ar100_rproc_ops = {
119 + .load = sun6i_ar100_rproc_load,
120 + .start = sun6i_ar100_rproc_start,
121 + .stop = sun6i_ar100_rproc_stop,
122 + .reset = sun6i_ar100_rproc_reset,
123 + .is_running = sun6i_ar100_rproc_is_running,
124 +};
125 +
126 +static int sun6i_ar100_rproc_probe(struct udevice *dev)
127 +{
128 + struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
129 + struct ofnode_phandle_args sram_handle;
130 + int ret;
131 +
132 + priv->cfg_base = dev_read_addr_ptr(dev);
133 +
134 + ret = dev_read_phandle_with_args(dev, "sram", NULL, 0, 0, &sram_handle);
135 + if (ret)
136 + return ret;
137 +
138 + priv->sram_base = ofnode_get_addr(sram_handle.node);
139 +
140 + return 0;
141 +}
142 +
143 +static const struct udevice_id sun6i_ar100_rproc_ids[] = {
144 + { .compatible = "allwinner,sun6i-a31-ar100" },
145 + { }
146 +};
147 +
148 +U_BOOT_DRIVER(sun6i_ar100_rproc) = {
149 + .name = "sun6i_ar100_rproc",
150 + .id = UCLASS_REMOTEPROC,
151 + .of_match = sun6i_ar100_rproc_ids,
152 + .probe = sun6i_ar100_rproc_probe,
153 + .priv_auto = sizeof(struct sun6i_ar100_rproc_priv),
154 + .ops = &sun6i_ar100_rproc_ops,
155 +};