bcm27xx: add kernel 5.10 support
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.10 / 950-0562-drm-vc4-dsi-Introduce-a-variant-structure.patch
1 From 4dd1101f3e16e6202132ae34a8da2a7d78043d56 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Thu, 3 Dec 2020 14:25:39 +0100
4 Subject: [PATCH] drm/vc4: dsi: Introduce a variant structure
5
6 Commit d1d195ce26a14ec0a87816c09ae514e1c40e97f7 upstream.
7
8 Most of the differences between DSI0 and DSI1 are handled through the
9 ID. However, the BCM2711 DSI is going to introduce one more variable to
10 the mix and will break some expectations of the earlier, simpler, test.
11
12 Let's add a variant structure that will address most of the differences
13 between those three controllers.
14
15 Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
16 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
17 Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-5-maxime@cerno.tech
18 ---
19 drivers/gpu/drm/vc4/vc4_dsi.c | 63 ++++++++++++++++++++---------------
20 1 file changed, 37 insertions(+), 26 deletions(-)
21
22 --- a/drivers/gpu/drm/vc4/vc4_dsi.c
23 +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
24 @@ -493,6 +493,18 @@
25 */
26 #define DSI1_ID 0x8c
27
28 +struct vc4_dsi_variant {
29 + /* Whether we're on bcm2835's DSI0 or DSI1. */
30 + unsigned int port;
31 +
32 + bool broken_axi_workaround;
33 +
34 + const char *debugfs_name;
35 + const struct debugfs_reg32 *regs;
36 + size_t nregs;
37 +
38 +};
39 +
40 /* General DSI hardware state. */
41 struct vc4_dsi {
42 struct platform_device *pdev;
43 @@ -509,8 +521,7 @@ struct vc4_dsi {
44 u32 *reg_dma_mem;
45 dma_addr_t reg_paddr;
46
47 - /* Whether we're on bcm2835's DSI0 or DSI1. */
48 - int port;
49 + const struct vc4_dsi_variant *variant;
50
51 /* DSI channel for the panel we're connected to. */
52 u32 channel;
53 @@ -586,10 +597,10 @@ dsi_dma_workaround_write(struct vc4_dsi
54 #define DSI_READ(offset) readl(dsi->regs + (offset))
55 #define DSI_WRITE(offset, val) dsi_dma_workaround_write(dsi, offset, val)
56 #define DSI_PORT_READ(offset) \
57 - DSI_READ(dsi->port ? DSI1_##offset : DSI0_##offset)
58 + DSI_READ(dsi->variant->port ? DSI1_##offset : DSI0_##offset)
59 #define DSI_PORT_WRITE(offset, val) \
60 - DSI_WRITE(dsi->port ? DSI1_##offset : DSI0_##offset, val)
61 -#define DSI_PORT_BIT(bit) (dsi->port ? DSI1_##bit : DSI0_##bit)
62 + DSI_WRITE(dsi->variant->port ? DSI1_##offset : DSI0_##offset, val)
63 +#define DSI_PORT_BIT(bit) (dsi->variant->port ? DSI1_##bit : DSI0_##bit)
64
65 /* VC4 DSI encoder KMS struct */
66 struct vc4_dsi_encoder {
67 @@ -837,7 +848,7 @@ static void vc4_dsi_encoder_enable(struc
68
69 ret = pm_runtime_get_sync(dev);
70 if (ret) {
71 - DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->port);
72 + DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->variant->port);
73 return;
74 }
75
76 @@ -871,7 +882,7 @@ static void vc4_dsi_encoder_enable(struc
77 DSI_PORT_WRITE(STAT, DSI_PORT_READ(STAT));
78
79 /* Set AFE CTR00/CTR1 to release powerdown of analog. */
80 - if (dsi->port == 0) {
81 + if (dsi->variant->port == 0) {
82 u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) |
83 VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ));
84
85 @@ -1017,7 +1028,7 @@ static void vc4_dsi_encoder_enable(struc
86 DSI_PORT_BIT(PHYC_CLANE_ENABLE) |
87 ((dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ?
88 0 : DSI_PORT_BIT(PHYC_HS_CLK_CONTINUOUS)) |
89 - (dsi->port == 0 ?
90 + (dsi->variant->port == 0 ?
91 VC4_SET_FIELD(lpx - 1, DSI0_PHYC_ESC_CLK_LPDT) :
92 VC4_SET_FIELD(lpx - 1, DSI1_PHYC_ESC_CLK_LPDT)));
93
94 @@ -1043,13 +1054,13 @@ static void vc4_dsi_encoder_enable(struc
95 DSI_DISP1_ENABLE);
96
97 /* Ungate the block. */
98 - if (dsi->port == 0)
99 + if (dsi->variant->port == 0)
100 DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI0_CTRL_CTRL0);
101 else
102 DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN);
103
104 /* Bring AFE out of reset. */
105 - if (dsi->port == 0) {
106 + if (dsi->variant->port == 0) {
107 } else {
108 DSI_PORT_WRITE(PHY_AFEC0,
109 DSI_PORT_READ(PHY_AFEC0) &
110 @@ -1305,8 +1316,16 @@ static const struct drm_encoder_helper_f
111 .mode_fixup = vc4_dsi_encoder_mode_fixup,
112 };
113
114 +static const struct vc4_dsi_variant bcm2835_dsi1_variant = {
115 + .port = 1,
116 + .broken_axi_workaround = true,
117 + .debugfs_name = "dsi1_regs",
118 + .regs = dsi1_regs,
119 + .nregs = ARRAY_SIZE(dsi1_regs),
120 +};
121 +
122 static const struct of_device_id vc4_dsi_dt_match[] = {
123 - { .compatible = "brcm,bcm2835-dsi1", (void *)(uintptr_t)1 },
124 + { .compatible = "brcm,bcm2835-dsi1", &bcm2835_dsi1_variant },
125 {}
126 };
127
128 @@ -1317,7 +1336,7 @@ static void dsi_handle_error(struct vc4_
129 if (!(stat & bit))
130 return;
131
132 - DRM_ERROR("DSI%d: %s error\n", dsi->port, type);
133 + DRM_ERROR("DSI%d: %s error\n", dsi->variant->port, type);
134 *ret = IRQ_HANDLED;
135 }
136
137 @@ -1415,7 +1434,7 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *
138 int ret;
139
140 snprintf(clk_name, sizeof(clk_name),
141 - "dsi%u_%s", dsi->port, phy_clocks[i].name);
142 + "dsi%u_%s", dsi->variant->port, phy_clocks[i].name);
143
144 /* We just use core fixed factor clock ops for the PHY
145 * clocks. The clocks are actually gated by the
146 @@ -1463,7 +1482,7 @@ static int vc4_dsi_bind(struct device *d
147 if (!match)
148 return -ENODEV;
149
150 - dsi->port = (uintptr_t)match->data;
151 + dsi->variant = match->data;
152
153 vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder),
154 GFP_KERNEL);
155 @@ -1480,13 +1499,8 @@ static int vc4_dsi_bind(struct device *d
156 return PTR_ERR(dsi->regs);
157
158 dsi->regset.base = dsi->regs;
159 - if (dsi->port == 0) {
160 - dsi->regset.regs = dsi0_regs;
161 - dsi->regset.nregs = ARRAY_SIZE(dsi0_regs);
162 - } else {
163 - dsi->regset.regs = dsi1_regs;
164 - dsi->regset.nregs = ARRAY_SIZE(dsi1_regs);
165 - }
166 + dsi->regset.regs = dsi->variant->regs;
167 + dsi->regset.nregs = dsi->variant->nregs;
168
169 if (DSI_PORT_READ(ID) != DSI_ID_VALUE) {
170 dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n",
171 @@ -1498,7 +1512,7 @@ static int vc4_dsi_bind(struct device *d
172 * from the ARM. It does handle writes from the DMA engine,
173 * so set up a channel for talking to it.
174 */
175 - if (dsi->port == 1) {
176 + if (dsi->variant->broken_axi_workaround) {
177 dsi->reg_dma_mem = dma_alloc_coherent(dev, 4,
178 &dsi->reg_dma_paddr,
179 GFP_KERNEL);
180 @@ -1619,10 +1633,7 @@ static int vc4_dsi_bind(struct device *d
181 */
182 list_splice_init(&dsi->encoder->bridge_chain, &dsi->bridge_chain);
183
184 - if (dsi->port == 0)
185 - vc4_debugfs_add_regset32(drm, "dsi0_regs", &dsi->regset);
186 - else
187 - vc4_debugfs_add_regset32(drm, "dsi1_regs", &dsi->regset);
188 + vc4_debugfs_add_regset32(drm, dsi->variant->debugfs_name, &dsi->regset);
189
190 pm_runtime_enable(dev);
191