ath79: add support for COMFAST CF-E130N v2
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-4.19 / 950-0502-drm-v3d-Add-support-for-V3D-v4.2.patch
1 From b0e7b8814e74be0559e07f737ef18cc3709d4ac4 Mon Sep 17 00:00:00 2001
2 From: Eric Anholt <eric@anholt.net>
3 Date: Thu, 4 Oct 2018 17:22:43 -0700
4 Subject: [PATCH] drm/v3d: Add support for V3D v4.2.
5
6 No compatible string for it yet, just the version-dependent changes.
7 They've now tied the hub and the core interrupt lines into a single
8 interrupt line coming out of the block. It also turns out I made a
9 mistake in modeling the V3D v3.3 and v4.1 bridge as a part of V3D
10 itself -- the bridge is going away in favor of an external reset
11 controller in a larger HW module.
12
13 v2: Use consistent checks for whether we're on 4.2, and fix a leak in
14 an error path.
15 v3: Use more general means of determining if the current 4.2 changes
16 are in place, as apparently other platforms may switch back (noted
17 by Dave). Update the binding doc.
18
19 Signed-off-by: Eric Anholt <eric@anholt.net>
20 ---
21 .../devicetree/bindings/gpu/brcm,bcm-v3d.txt | 11 ++++--
22 drivers/gpu/drm/v3d/v3d_drv.c | 21 +++++++++---
23 drivers/gpu/drm/v3d/v3d_drv.h | 2 ++
24 drivers/gpu/drm/v3d/v3d_gem.c | 12 ++++++-
25 drivers/gpu/drm/v3d/v3d_irq.c | 34 ++++++++++++++-----
26 5 files changed, 63 insertions(+), 17 deletions(-)
27
28 --- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt
29 +++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt
30 @@ -6,15 +6,20 @@ For V3D 2.x, see brcm,bcm-vc4.txt.
31 Required properties:
32 - compatible: Should be "brcm,7268-v3d" or "brcm,7278-v3d"
33 - reg: Physical base addresses and lengths of the register areas
34 -- reg-names: Names for the register areas. The "hub", "bridge", and "core0"
35 +- reg-names: Names for the register areas. The "hub" and "core0"
36 register areas are always required. The "gca" register area
37 - is required if the GCA cache controller is present.
38 + is required if the GCA cache controller is present. The
39 + "bridge" register area is required if an external reset
40 + controller is not present.
41 - interrupts: The interrupt numbers. The first interrupt is for the hub,
42 - while the following interrupts are for the cores.
43 + while the following interrupts are separate interrupt lines
44 + for the cores (if they don't share the hub's interrupt).
45 See bindings/interrupt-controller/interrupts.txt
46
47 Optional properties:
48 - clocks: The core clock the unit runs on
49 +- resets: The reset line for v3d, if not using a mapping of the bridge
50 + See bindings/reset/reset.txt
51
52 v3d {
53 compatible = "brcm,7268-v3d";
54 --- a/drivers/gpu/drm/v3d/v3d_drv.c
55 +++ b/drivers/gpu/drm/v3d/v3d_drv.c
56 @@ -19,6 +19,7 @@
57 #include <linux/of_platform.h>
58 #include <linux/platform_device.h>
59 #include <linux/pm_runtime.h>
60 +#include <linux/reset.h>
61 #include <drm/drm_fb_cma_helper.h>
62 #include <drm/drm_fb_helper.h>
63
64 @@ -265,10 +266,6 @@ static int v3d_platform_drm_probe(struct
65 v3d->pdev = pdev;
66 drm = &v3d->drm;
67
68 - ret = map_regs(v3d, &v3d->bridge_regs, "bridge");
69 - if (ret)
70 - goto dev_free;
71 -
72 ret = map_regs(v3d, &v3d->hub_regs, "hub");
73 if (ret)
74 goto dev_free;
75 @@ -283,6 +280,22 @@ static int v3d_platform_drm_probe(struct
76 v3d->cores = V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_NCORES);
77 WARN_ON(v3d->cores > 1); /* multicore not yet implemented */
78
79 + v3d->reset = devm_reset_control_get_exclusive(dev, NULL);
80 + if (IS_ERR(v3d->reset)) {
81 + ret = PTR_ERR(v3d->reset);
82 +
83 + if (ret == -EPROBE_DEFER)
84 + goto dev_free;
85 +
86 + v3d->reset = NULL;
87 + ret = map_regs(v3d, &v3d->bridge_regs, "bridge");
88 + if (ret) {
89 + dev_err(dev,
90 + "Failed to get reset control or bridge regs\n");
91 + goto dev_free;
92 + }
93 + }
94 +
95 if (v3d->ver < 41) {
96 ret = map_regs(v3d, &v3d->gca_regs, "gca");
97 if (ret)
98 --- a/drivers/gpu/drm/v3d/v3d_drv.h
99 +++ b/drivers/gpu/drm/v3d/v3d_drv.h
100 @@ -34,6 +34,7 @@ struct v3d_dev {
101 * and revision.
102 */
103 int ver;
104 + bool single_irq_line;
105
106 struct device *dev;
107 struct platform_device *pdev;
108 @@ -42,6 +43,7 @@ struct v3d_dev {
109 void __iomem *bridge_regs;
110 void __iomem *gca_regs;
111 struct clk *clk;
112 + struct reset_control *reset;
113
114 /* Virtual and DMA addresses of the single shared page table. */
115 volatile u32 *pt;
116 --- a/drivers/gpu/drm/v3d/v3d_gem.c
117 +++ b/drivers/gpu/drm/v3d/v3d_gem.c
118 @@ -6,6 +6,7 @@
119 #include <linux/module.h>
120 #include <linux/platform_device.h>
121 #include <linux/pm_runtime.h>
122 +#include <linux/reset.h>
123 #include <linux/device.h>
124 #include <linux/io.h>
125 #include <linux/sched/signal.h>
126 @@ -69,7 +70,7 @@ v3d_idle_gca(struct v3d_dev *v3d)
127 }
128
129 static void
130 -v3d_reset_v3d(struct v3d_dev *v3d)
131 +v3d_reset_by_bridge(struct v3d_dev *v3d)
132 {
133 int version = V3D_BRIDGE_READ(V3D_TOP_GR_BRIDGE_REVISION);
134
135 @@ -89,6 +90,15 @@ v3d_reset_v3d(struct v3d_dev *v3d)
136 V3D_TOP_GR_BRIDGE_SW_INIT_1_V3D_CLK_108_SW_INIT);
137 V3D_BRIDGE_WRITE(V3D_TOP_GR_BRIDGE_SW_INIT_1, 0);
138 }
139 +}
140 +
141 +static void
142 +v3d_reset_v3d(struct v3d_dev *v3d)
143 +{
144 + if (v3d->reset)
145 + reset_control_reset(v3d->reset);
146 + else
147 + v3d_reset_by_bridge(v3d);
148
149 v3d_init_hw_state(v3d);
150 }
151 --- a/drivers/gpu/drm/v3d/v3d_irq.c
152 +++ b/drivers/gpu/drm/v3d/v3d_irq.c
153 @@ -27,6 +27,9 @@
154 V3D_HUB_INT_MMU_CAP | \
155 V3D_HUB_INT_TFUC))
156
157 +static irqreturn_t
158 +v3d_hub_irq(int irq, void *arg);
159 +
160 static void
161 v3d_overflow_mem_work(struct work_struct *work)
162 {
163 @@ -112,6 +115,12 @@ v3d_irq(int irq, void *arg)
164 if (intsts & V3D_INT_GMPV)
165 dev_err(v3d->dev, "GMP violation\n");
166
167 + /* V3D 4.2 wires the hub and core IRQs together, so if we &
168 + * didn't see the common one then check hub for MMU IRQs.
169 + */
170 + if (v3d->single_irq_line && status == IRQ_NONE)
171 + return v3d_hub_irq(irq, arg);
172 +
173 return status;
174 }
175
176 @@ -170,15 +179,22 @@ v3d_irq_init(struct v3d_dev *v3d)
177 V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS);
178 V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);
179
180 - ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0),
181 - v3d_hub_irq, IRQF_SHARED,
182 - "v3d_hub", v3d);
183 - if (ret)
184 - goto fail;
185 -
186 - ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1),
187 - v3d_irq, IRQF_SHARED,
188 - "v3d_core0", v3d);
189 + if (platform_get_irq(v3d->pdev, 1) < 0) {
190 + ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0),
191 + v3d_irq, IRQF_SHARED,
192 + "v3d", v3d);
193 + v3d->single_irq_line = true;
194 + } else {
195 + ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0),
196 + v3d_hub_irq, IRQF_SHARED,
197 + "v3d_hub", v3d);
198 + if (ret)
199 + goto fail;
200 +
201 + ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1),
202 + v3d_irq, IRQF_SHARED,
203 + "v3d_core0", v3d);
204 + }
205 if (ret)
206 goto fail;
207