1 From 261b3072275937fe64af287c1b61cbb63aca830e Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Wed, 18 Dec 2019 19:15:08 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Implement a register layout
7 The HDMI controllers found in the BCM2711 have most of the registers
8 reorganized in multiple registers areas and at different offsets than
11 The logic however remains pretty much the same, so it doesn't really make
12 sense to create a whole new driver and we should share the code as much as
15 Let's implement some indirection to wrap around a register and depending on
16 the variant will lookup the associated register on that particular variant.
18 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
20 drivers/gpu/drm/vc4/vc4_hdmi.c | 354 ++++++++++++++--------------
21 drivers/gpu/drm/vc4/vc4_hdmi.h | 12 +-
22 drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 250 ++++++++++++++++++++
23 drivers/gpu/drm/vc4/vc4_regs.h | 92 --------
24 4 files changed, 437 insertions(+), 271 deletions(-)
25 create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi_regs.h
27 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
28 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
30 #include "media/cec.h"
33 +#include "vc4_hdmi_regs.h"
36 #define HSM_CLOCK_FREQ 163682864
37 #define CEC_CLOCK_FREQ 40000
38 #define CEC_CLOCK_DIV (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
40 -static const struct debugfs_reg32 hdmi_regs[] = {
41 - VC4_REG32(VC4_HDMI_CORE_REV),
42 - VC4_REG32(VC4_HDMI_SW_RESET_CONTROL),
43 - VC4_REG32(VC4_HDMI_HOTPLUG_INT),
44 - VC4_REG32(VC4_HDMI_HOTPLUG),
45 - VC4_REG32(VC4_HDMI_MAI_CHANNEL_MAP),
46 - VC4_REG32(VC4_HDMI_MAI_CONFIG),
47 - VC4_REG32(VC4_HDMI_MAI_FORMAT),
48 - VC4_REG32(VC4_HDMI_AUDIO_PACKET_CONFIG),
49 - VC4_REG32(VC4_HDMI_RAM_PACKET_CONFIG),
50 - VC4_REG32(VC4_HDMI_HORZA),
51 - VC4_REG32(VC4_HDMI_HORZB),
52 - VC4_REG32(VC4_HDMI_FIFO_CTL),
53 - VC4_REG32(VC4_HDMI_SCHEDULER_CONTROL),
54 - VC4_REG32(VC4_HDMI_VERTA0),
55 - VC4_REG32(VC4_HDMI_VERTA1),
56 - VC4_REG32(VC4_HDMI_VERTB0),
57 - VC4_REG32(VC4_HDMI_VERTB1),
58 - VC4_REG32(VC4_HDMI_TX_PHY_RESET_CTL),
59 - VC4_REG32(VC4_HDMI_TX_PHY_CTL0),
61 - VC4_REG32(VC4_HDMI_CEC_CNTRL_1),
62 - VC4_REG32(VC4_HDMI_CEC_CNTRL_2),
63 - VC4_REG32(VC4_HDMI_CEC_CNTRL_3),
64 - VC4_REG32(VC4_HDMI_CEC_CNTRL_4),
65 - VC4_REG32(VC4_HDMI_CEC_CNTRL_5),
66 - VC4_REG32(VC4_HDMI_CPU_STATUS),
67 - VC4_REG32(VC4_HDMI_CPU_MASK_STATUS),
69 - VC4_REG32(VC4_HDMI_CEC_RX_DATA_1),
70 - VC4_REG32(VC4_HDMI_CEC_RX_DATA_2),
71 - VC4_REG32(VC4_HDMI_CEC_RX_DATA_3),
72 - VC4_REG32(VC4_HDMI_CEC_RX_DATA_4),
73 - VC4_REG32(VC4_HDMI_CEC_TX_DATA_1),
74 - VC4_REG32(VC4_HDMI_CEC_TX_DATA_2),
75 - VC4_REG32(VC4_HDMI_CEC_TX_DATA_3),
76 - VC4_REG32(VC4_HDMI_CEC_TX_DATA_4),
79 -static const struct debugfs_reg32 hd_regs[] = {
80 - VC4_REG32(VC4_HD_M_CTL),
81 - VC4_REG32(VC4_HD_MAI_CTL),
82 - VC4_REG32(VC4_HD_MAI_THR),
83 - VC4_REG32(VC4_HD_MAI_FMT),
84 - VC4_REG32(VC4_HD_MAI_SMP),
85 - VC4_REG32(VC4_HD_VID_CTL),
86 - VC4_REG32(VC4_HD_CSC_CTL),
87 - VC4_REG32(VC4_HD_FRAME_COUNT),
90 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
92 struct drm_info_node *node = (struct drm_info_node *)m->private;
93 @@ -133,7 +84,7 @@ vc4_hdmi_connector_detect(struct drm_con
94 if (drm_probe_ddc(vc4_hdmi->ddc))
95 return connector_status_connected;
97 - if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
98 + if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
99 return connector_status_connected;
100 cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
101 return connector_status_disconnected;
102 @@ -229,10 +180,10 @@ static int vc4_hdmi_stop_packet(struct d
103 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
104 u32 packet_id = type - 0x80;
106 - HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
107 - HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
108 + HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
109 + HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
111 - return wait_for(!(HDMI_READ(VC4_HDMI_RAM_PACKET_STATUS) &
112 + return wait_for(!(HDMI_READ(HDMI_RAM_PACKET_STATUS) &
113 BIT(packet_id)), 100);
116 @@ -241,12 +192,16 @@ static void vc4_hdmi_write_infoframe(str
118 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
119 u32 packet_id = frame->any.type - 0x80;
120 - u32 packet_reg = VC4_HDMI_RAM_PACKET(packet_id);
121 + const struct vc4_hdmi_register *ram_packet_start =
122 + &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
123 + u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id;
124 + void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi,
125 + ram_packet_start->reg);
126 uint8_t buffer[VC4_HDMI_PACKET_STRIDE];
130 - WARN_ONCE(!(HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
131 + WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
132 VC4_HDMI_RAM_PACKET_ENABLE),
133 "Packet RAM has to be on to store the packet.");
135 @@ -261,23 +216,23 @@ static void vc4_hdmi_write_infoframe(str
138 for (i = 0; i < len; i += 7) {
139 - HDMI_WRITE(packet_reg,
140 - buffer[i + 0] << 0 |
141 - buffer[i + 1] << 8 |
142 - buffer[i + 2] << 16);
143 + writel(buffer[i + 0] << 0 |
144 + buffer[i + 1] << 8 |
145 + buffer[i + 2] << 16,
146 + base + packet_reg);
149 - HDMI_WRITE(packet_reg,
150 - buffer[i + 3] << 0 |
151 - buffer[i + 4] << 8 |
152 - buffer[i + 5] << 16 |
153 - buffer[i + 6] << 24);
154 + writel(buffer[i + 3] << 0 |
155 + buffer[i + 4] << 8 |
156 + buffer[i + 5] << 16 |
157 + buffer[i + 6] << 24,
158 + base + packet_reg);
162 - HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
163 - HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
164 - ret = wait_for((HDMI_READ(VC4_HDMI_RAM_PACKET_STATUS) &
165 + HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
166 + HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
167 + ret = wait_for((HDMI_READ(HDMI_RAM_PACKET_STATUS) &
168 BIT(packet_id)), 100);
170 DRM_ERROR("Failed to wait for infoframe to start: %d\n", ret);
171 @@ -358,11 +313,11 @@ static void vc4_hdmi_encoder_disable(str
172 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
175 - HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG, 0);
176 + HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
178 - HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
179 - HD_WRITE(VC4_HD_VID_CTL,
180 - HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
181 + HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
182 + HDMI_WRITE(HDMI_VID_CTL,
183 + HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
185 clk_disable_unprepare(vc4_hdmi->pixel_clock);
187 @@ -417,18 +372,18 @@ static void vc4_hdmi_encoder_enable(stru
191 - HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
192 + HDMI_WRITE(HDMI_SW_RESET_CONTROL,
193 VC4_HDMI_SW_RESET_HDMI |
194 VC4_HDMI_SW_RESET_FORMAT_DETECT);
196 - HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL, 0);
197 + HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
199 /* PHY should be in reset, like
200 * vc4_hdmi_encoder_disable() does.
202 - HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
203 + HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
205 - HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
206 + HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
208 if (debug_dump_regs) {
209 struct drm_printer p = drm_info_printer(&vc4_hdmi->pdev->dev);
210 @@ -438,20 +393,20 @@ static void vc4_hdmi_encoder_enable(stru
211 drm_print_regset32(&p, &vc4_hdmi->hd_regset);
214 - HD_WRITE(VC4_HD_VID_CTL, 0);
215 + HDMI_WRITE(HDMI_VID_CTL, 0);
217 - HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
218 - HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
219 + HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
220 + HDMI_READ(HDMI_SCHEDULER_CONTROL) |
221 VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
222 VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
224 - HDMI_WRITE(VC4_HDMI_HORZA,
225 + HDMI_WRITE(HDMI_HORZA,
226 (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
227 (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
228 VC4_SET_FIELD(mode->hdisplay * pixel_rep,
229 VC4_HDMI_HORZA_HAP));
231 - HDMI_WRITE(VC4_HDMI_HORZB,
232 + HDMI_WRITE(HDMI_HORZB,
233 VC4_SET_FIELD((mode->htotal -
234 mode->hsync_end) * pixel_rep,
235 VC4_HDMI_HORZB_HBP) |
236 @@ -462,13 +417,13 @@ static void vc4_hdmi_encoder_enable(stru
237 mode->hdisplay) * pixel_rep,
238 VC4_HDMI_HORZB_HFP));
240 - HDMI_WRITE(VC4_HDMI_VERTA0, verta);
241 - HDMI_WRITE(VC4_HDMI_VERTA1, verta);
242 + HDMI_WRITE(HDMI_VERTA0, verta);
243 + HDMI_WRITE(HDMI_VERTA1, verta);
245 - HDMI_WRITE(VC4_HDMI_VERTB0, vertb_even);
246 - HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
247 + HDMI_WRITE(HDMI_VERTB0, vertb_even);
248 + HDMI_WRITE(HDMI_VERTB1, vertb);
250 - HD_WRITE(VC4_HD_VID_CTL,
251 + HDMI_WRITE(HDMI_VID_CTL,
252 (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
253 (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
255 @@ -493,21 +448,21 @@ static void vc4_hdmi_encoder_enable(stru
256 csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
257 VC4_HD_CSC_CTL_MODE);
259 - HD_WRITE(VC4_HD_CSC_12_11, (0x000 << 16) | 0x000);
260 - HD_WRITE(VC4_HD_CSC_14_13, (0x100 << 16) | 0x6e0);
261 - HD_WRITE(VC4_HD_CSC_22_21, (0x6e0 << 16) | 0x000);
262 - HD_WRITE(VC4_HD_CSC_24_23, (0x100 << 16) | 0x000);
263 - HD_WRITE(VC4_HD_CSC_32_31, (0x000 << 16) | 0x6e0);
264 - HD_WRITE(VC4_HD_CSC_34_33, (0x100 << 16) | 0x000);
265 + HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
266 + HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
267 + HDMI_WRITE(HDMI_CSC_22_21, (0x6e0 << 16) | 0x000);
268 + HDMI_WRITE(HDMI_CSC_24_23, (0x100 << 16) | 0x000);
269 + HDMI_WRITE(HDMI_CSC_32_31, (0x000 << 16) | 0x6e0);
270 + HDMI_WRITE(HDMI_CSC_34_33, (0x100 << 16) | 0x000);
271 vc4_encoder->limited_rgb_range = true;
273 vc4_encoder->limited_rgb_range = false;
276 /* The RGB order applies even when CSC is disabled. */
277 - HD_WRITE(VC4_HD_CSC_CTL, csc_ctl);
278 + HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
280 - HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
281 + HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
283 if (debug_dump_regs) {
284 struct drm_printer p = drm_info_printer(&vc4_hdmi->pdev->dev);
285 @@ -517,30 +472,30 @@ static void vc4_hdmi_encoder_enable(stru
286 drm_print_regset32(&p, &vc4_hdmi->hd_regset);
289 - HD_WRITE(VC4_HD_VID_CTL,
290 - HD_READ(VC4_HD_VID_CTL) |
291 - VC4_HD_VID_CTL_ENABLE |
292 - VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
293 - VC4_HD_VID_CTL_FRAME_COUNTER_RESET);
294 + HDMI_WRITE(HDMI_VID_CTL,
295 + HDMI_READ(HDMI_VID_CTL) |
296 + VC4_HD_VID_CTL_ENABLE |
297 + VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
298 + VC4_HD_VID_CTL_FRAME_COUNTER_RESET);
300 if (vc4_encoder->hdmi_monitor) {
301 - HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
302 - HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
303 + HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
304 + HDMI_READ(HDMI_SCHEDULER_CONTROL) |
305 VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
307 - ret = wait_for(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
308 + ret = wait_for(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
309 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1000);
310 WARN_ONCE(ret, "Timeout waiting for "
311 "VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
313 - HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
314 - HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
315 + HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
316 + HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
317 ~(VC4_HDMI_RAM_PACKET_ENABLE));
318 - HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
319 - HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
320 + HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
321 + HDMI_READ(HDMI_SCHEDULER_CONTROL) &
322 ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
324 - ret = wait_for(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
325 + ret = wait_for(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
326 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1000);
327 WARN_ONCE(ret, "Timeout waiting for "
328 "!VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
329 @@ -549,31 +504,31 @@ static void vc4_hdmi_encoder_enable(stru
330 if (vc4_encoder->hdmi_monitor) {
333 - WARN_ON(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
334 + WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
335 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
336 - HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
337 - HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
338 + HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
339 + HDMI_READ(HDMI_SCHEDULER_CONTROL) |
340 VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
342 - HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
343 + HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
344 VC4_HDMI_RAM_PACKET_ENABLE);
346 vc4_hdmi_set_infoframes(encoder);
348 - drift = HDMI_READ(VC4_HDMI_FIFO_CTL);
349 + drift = HDMI_READ(HDMI_FIFO_CTL);
350 drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
352 - HDMI_WRITE(VC4_HDMI_FIFO_CTL,
353 + HDMI_WRITE(HDMI_FIFO_CTL,
354 drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
355 - HDMI_WRITE(VC4_HDMI_FIFO_CTL,
356 + HDMI_WRITE(HDMI_FIFO_CTL,
357 drift | VC4_HDMI_FIFO_CTL_RECENTER);
358 usleep_range(1000, 1100);
359 - HDMI_WRITE(VC4_HDMI_FIFO_CTL,
360 + HDMI_WRITE(HDMI_FIFO_CTL,
361 drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
362 - HDMI_WRITE(VC4_HDMI_FIFO_CTL,
363 + HDMI_WRITE(HDMI_FIFO_CTL,
364 drift | VC4_HDMI_FIFO_CTL_RECENTER);
366 - ret = wait_for(HDMI_READ(VC4_HDMI_FIFO_CTL) &
367 + ret = wait_for(HDMI_READ(HDMI_FIFO_CTL) &
368 VC4_HDMI_FIFO_CTL_RECENTER_DONE, 1);
369 WARN_ONCE(ret, "Timeout waiting for "
370 "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
371 @@ -625,7 +580,7 @@ static void vc4_hdmi_audio_set_mai_clock
372 VC4_HD_MAI_SMP_M_SHIFT) + 1,
375 - HD_WRITE(VC4_HD_MAI_SMP,
376 + HDMI_WRITE(HDMI_MAI_SMP,
377 VC4_SET_FIELD(n, VC4_HD_MAI_SMP_N) |
378 VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M));
380 @@ -644,7 +599,7 @@ static void vc4_hdmi_set_n_cts(struct vc
381 do_div(tmp, 128 * samplerate);
384 - HDMI_WRITE(VC4_HDMI_CRP_CFG,
385 + HDMI_WRITE(HDMI_CRP_CFG,
386 VC4_HDMI_CRP_CFG_EXTERNAL_CTS_EN |
387 VC4_SET_FIELD(n, VC4_HDMI_CRP_CFG_N));
389 @@ -653,8 +608,8 @@ static void vc4_hdmi_set_n_cts(struct vc
390 * providing a CTS_1 value. The two CTS values are alternated
391 * between based on the period fields
393 - HDMI_WRITE(VC4_HDMI_CTS_0, cts);
394 - HDMI_WRITE(VC4_HDMI_CTS_1, cts);
395 + HDMI_WRITE(HDMI_CTS_0, cts);
396 + HDMI_WRITE(HDMI_CTS_1, cts);
399 static inline struct vc4_hdmi *dai_to_hdmi(struct snd_soc_dai *dai)
400 @@ -681,7 +636,7 @@ static int vc4_hdmi_audio_startup(struct
401 * If the HDMI encoder hasn't probed, or the encoder is
402 * currently in DVI mode, treat the codec dai as missing.
404 - if (!encoder->crtc || !(HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
405 + if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
406 VC4_HDMI_RAM_PACKET_ENABLE))
409 @@ -707,9 +662,9 @@ static void vc4_hdmi_audio_reset(struct
411 dev_err(dev, "Failed to stop audio infoframe: %d\n", ret);
413 - HD_WRITE(VC4_HD_MAI_CTL, VC4_HD_MAI_CTL_RESET);
414 - HD_WRITE(VC4_HD_MAI_CTL, VC4_HD_MAI_CTL_ERRORF);
415 - HD_WRITE(VC4_HD_MAI_CTL, VC4_HD_MAI_CTL_FLUSH);
416 + HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_RESET);
417 + HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_ERRORF);
418 + HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_FLUSH);
421 static void vc4_hdmi_audio_shutdown(struct snd_pcm_substream *substream,
422 @@ -745,7 +700,7 @@ static int vc4_hdmi_audio_hw_params(stru
423 vc4_hdmi->audio.channels = params_channels(params);
424 vc4_hdmi->audio.samplerate = params_rate(params);
426 - HD_WRITE(VC4_HD_MAI_CTL,
427 + HDMI_WRITE(HDMI_MAI_CTL,
428 VC4_HD_MAI_CTL_RESET |
429 VC4_HD_MAI_CTL_FLUSH |
430 VC4_HD_MAI_CTL_DLATE |
431 @@ -765,22 +720,22 @@ static int vc4_hdmi_audio_hw_params(stru
433 /* Set the MAI threshold. This logic mimics the firmware's. */
434 if (vc4_hdmi->audio.samplerate > 96000) {
435 - HD_WRITE(VC4_HD_MAI_THR,
436 + HDMI_WRITE(HDMI_MAI_THR,
437 VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQHIGH) |
438 VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
439 } else if (vc4_hdmi->audio.samplerate > 48000) {
440 - HD_WRITE(VC4_HD_MAI_THR,
441 + HDMI_WRITE(HDMI_MAI_THR,
442 VC4_SET_FIELD(0x14, VC4_HD_MAI_THR_DREQHIGH) |
443 VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
445 - HD_WRITE(VC4_HD_MAI_THR,
446 + HDMI_WRITE(HDMI_MAI_THR,
447 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
448 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
449 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) |
450 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW));
453 - HDMI_WRITE(VC4_HDMI_MAI_CONFIG,
454 + HDMI_WRITE(HDMI_MAI_CONFIG,
455 VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
456 VC4_SET_FIELD(channel_mask, VC4_HDMI_MAI_CHANNEL_MASK));
458 @@ -790,8 +745,8 @@ static int vc4_hdmi_audio_hw_params(stru
459 channel_map |= i << (3 * i);
462 - HDMI_WRITE(VC4_HDMI_MAI_CHANNEL_MAP, channel_map);
463 - HDMI_WRITE(VC4_HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
464 + HDMI_WRITE(HDMI_MAI_CHANNEL_MAP, channel_map);
465 + HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
466 vc4_hdmi_set_n_cts(vc4_hdmi);
469 @@ -806,21 +761,22 @@ static int vc4_hdmi_audio_trigger(struct
471 case SNDRV_PCM_TRIGGER_START:
472 vc4_hdmi_set_audio_infoframe(encoder);
473 - HDMI_WRITE(VC4_HDMI_TX_PHY_CTL0,
474 - HDMI_READ(VC4_HDMI_TX_PHY_CTL0) &
475 + HDMI_WRITE(HDMI_TX_PHY_CTL_0,
476 + HDMI_READ(HDMI_TX_PHY_CTL_0) &
477 ~VC4_HDMI_TX_PHY_RNG_PWRDN);
478 - HD_WRITE(VC4_HD_MAI_CTL,
480 + HDMI_WRITE(HDMI_MAI_CTL,
481 VC4_SET_FIELD(vc4_hdmi->audio.channels,
482 VC4_HD_MAI_CTL_CHNUM) |
483 VC4_HD_MAI_CTL_ENABLE);
485 case SNDRV_PCM_TRIGGER_STOP:
486 - HD_WRITE(VC4_HD_MAI_CTL,
487 + HDMI_WRITE(HDMI_MAI_CTL,
488 VC4_HD_MAI_CTL_DLATE |
489 VC4_HD_MAI_CTL_ERRORE |
490 VC4_HD_MAI_CTL_ERRORF);
491 - HDMI_WRITE(VC4_HDMI_TX_PHY_CTL0,
492 - HDMI_READ(VC4_HDMI_TX_PHY_CTL0) |
493 + HDMI_WRITE(HDMI_TX_PHY_CTL_0,
494 + HDMI_READ(HDMI_TX_PHY_CTL_0) |
495 VC4_HDMI_TX_PHY_RNG_PWRDN);
498 @@ -954,6 +910,8 @@ static const struct snd_dmaengine_pcm_co
500 static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
502 + const struct vc4_hdmi_register *mai_data =
503 + &vc4_hdmi->variant->registers[HDMI_MAI_DATA];
504 struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
505 struct snd_soc_card *card = &vc4_hdmi->audio.card;
506 struct device *dev = &vc4_hdmi->pdev->dev;
507 @@ -968,6 +926,11 @@ static int vc4_hdmi_audio_init(struct vc
511 + if (mai_data->reg != VC4_HD) {
512 + WARN_ONCE(true, "MAI isn't in the HD block\n");
517 * Get the physical address of VC4_HD_MAI_DATA. We need to retrieve
518 * the bus address specified in the DT, because the physical address
519 @@ -976,7 +939,7 @@ static int vc4_hdmi_audio_init(struct vc
520 * This VC/MMU should probably be exposed to avoid this kind of hacks.
522 addr = of_get_address(dev->of_node, 1, NULL, NULL);
523 - vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + VC4_HD_MAI_DATA;
524 + vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset;
525 vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
526 vc4_hdmi->audio.dma_data.maxburst = 2;
528 @@ -1069,7 +1032,7 @@ static void vc4_cec_read_msg(struct vc4_
529 msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
530 VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
531 for (i = 0; i < msg->len; i += 4) {
532 - u32 val = HDMI_READ(VC4_HDMI_CEC_RX_DATA_1 + i);
533 + u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + i);
535 msg->msg[i] = val & 0xff;
536 msg->msg[i + 1] = (val >> 8) & 0xff;
537 @@ -1081,26 +1044,26 @@ static void vc4_cec_read_msg(struct vc4_
538 static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
540 struct vc4_hdmi *vc4_hdmi = priv;
541 - u32 stat = HDMI_READ(VC4_HDMI_CPU_STATUS);
542 + u32 stat = HDMI_READ(HDMI_CEC_CPU_STATUS);
545 if (!(stat & VC4_HDMI_CPU_CEC))
547 vc4_hdmi->cec_rx_msg.len = 0;
548 - cntrl1 = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
549 - cntrl5 = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
550 + cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1);
551 + cntrl5 = HDMI_READ(HDMI_CEC_CNTRL_5);
552 vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
553 if (vc4_hdmi->cec_irq_was_rx) {
554 vc4_cec_read_msg(vc4_hdmi, cntrl1);
555 cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
556 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
557 + HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
558 cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
560 vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
561 cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
563 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
564 - HDMI_WRITE(VC4_HDMI_CPU_CLEAR, VC4_HDMI_CPU_CEC);
565 + HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
566 + HDMI_WRITE(HDMI_CEC_CPU_CLEAR, VC4_HDMI_CPU_CEC);
568 return IRQ_WAKE_THREAD;
570 @@ -1110,7 +1073,7 @@ static int vc4_hdmi_cec_adap_enable(stru
571 struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
572 /* clock period in microseconds */
573 const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
574 - u32 val = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
575 + u32 val = HDMI_READ(HDMI_CEC_CNTRL_5);
577 val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
578 VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
579 @@ -1119,30 +1082,30 @@ static int vc4_hdmi_cec_adap_enable(stru
580 ((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT);
583 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
584 + HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
585 VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
586 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val);
587 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_2,
588 + HDMI_WRITE(HDMI_CEC_CNTRL_5, val);
589 + HDMI_WRITE(HDMI_CEC_CNTRL_2,
590 ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
591 ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
592 ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
593 ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
594 ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
595 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_3,
596 + HDMI_WRITE(HDMI_CEC_CNTRL_3,
597 ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
598 ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
599 ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
600 ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
601 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_4,
602 + HDMI_WRITE(HDMI_CEC_CNTRL_4,
603 ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
604 ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
605 ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
606 ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
608 - HDMI_WRITE(VC4_HDMI_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
609 + HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
611 - HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
612 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
613 + HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
614 + HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
615 VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
618 @@ -1152,8 +1115,8 @@ static int vc4_hdmi_cec_adap_log_addr(st
620 struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
622 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1,
623 - (HDMI_READ(VC4_HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
624 + HDMI_WRITE(HDMI_CEC_CNTRL_1,
625 + (HDMI_READ(HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
626 (log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT);
629 @@ -1166,20 +1129,20 @@ static int vc4_hdmi_cec_adap_transmit(st
632 for (i = 0; i < msg->len; i += 4)
633 - HDMI_WRITE(VC4_HDMI_CEC_TX_DATA_1 + i,
634 + HDMI_WRITE(HDMI_CEC_TX_DATA_1 + i,
636 (msg->msg[i + 1] << 8) |
637 (msg->msg[i + 2] << 16) |
638 (msg->msg[i + 3] << 24));
640 - val = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
641 + val = HDMI_READ(HDMI_CEC_CNTRL_1);
642 val &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
643 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
644 + HDMI_WRITE(HDMI_CEC_CNTRL_1, val);
645 val &= ~VC4_HDMI_CEC_MESSAGE_LENGTH_MASK;
646 val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT;
647 val |= VC4_HDMI_CEC_START_XMIT_BEGIN;
649 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
650 + HDMI_WRITE(HDMI_CEC_CNTRL_1, val);
654 @@ -1190,26 +1153,63 @@ static const struct cec_adap_ops vc4_hdm
658 +static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi,
659 + struct debugfs_regset32 *regset,
660 + enum vc4_hdmi_regs reg)
662 + const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
663 + struct debugfs_reg32 *regs;
664 + unsigned int count = 0;
667 + regs = kzalloc(variant->num_registers * sizeof(*regs),
672 + for (i = 0; i < variant->num_registers; i++) {
673 + const struct vc4_hdmi_register *field = &variant->registers[i];
675 + if (field->reg != reg)
678 + regs[count].name = field->name;
679 + regs[count].offset = field->offset;
683 + regs = krealloc(regs, count * sizeof(*regs), GFP_KERNEL);
687 + regset->base = __vc4_hdmi_get_field_base(vc4_hdmi, reg);
688 + regset->regs = regs;
689 + regset->nregs = count;
694 static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
696 struct platform_device *pdev = vc4_hdmi->pdev;
697 struct device *dev = &pdev->dev;
700 vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
701 if (IS_ERR(vc4_hdmi->hdmicore_regs))
702 return PTR_ERR(vc4_hdmi->hdmicore_regs);
704 - vc4_hdmi->hdmi_regset.base = vc4_hdmi->hdmicore_regs;
705 - vc4_hdmi->hdmi_regset.regs = hdmi_regs;
706 - vc4_hdmi->hdmi_regset.nregs = ARRAY_SIZE(hdmi_regs);
707 + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD);
711 vc4_hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
712 if (IS_ERR(vc4_hdmi->hd_regs))
713 return PTR_ERR(vc4_hdmi->hd_regs);
715 - vc4_hdmi->hd_regset.base = vc4_hdmi->hd_regs;
716 - vc4_hdmi->hd_regset.regs = hd_regs;
717 - vc4_hdmi->hd_regset.nregs = ARRAY_SIZE(hd_regs);
718 + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI);
722 vc4_hdmi->pixel_clock = devm_clk_get(dev, "pixel");
723 if (IS_ERR(vc4_hdmi->pixel_clock)) {
724 @@ -1302,12 +1302,12 @@ static int vc4_hdmi_bind(struct device *
727 /* HDMI core must be enabled. */
728 - if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
729 - HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
730 + if (!(HDMI_READ(HDMI_M_CTL) & VC4_HD_M_ENABLE)) {
731 + HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_SW_RST);
733 - HD_WRITE(VC4_HD_M_CTL, 0);
734 + HDMI_WRITE(HDMI_M_CTL, 0);
736 - HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
737 + HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_ENABLE);
739 pm_runtime_enable(dev);
741 @@ -1331,8 +1331,8 @@ static int vc4_hdmi_bind(struct device *
742 cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
743 cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
745 - HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
746 - value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
747 + HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
748 + value = HDMI_READ(HDMI_CEC_CNTRL_1);
749 value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
751 * Set the logical address to Unregistered and set the clock
752 @@ -1341,7 +1341,7 @@ static int vc4_hdmi_bind(struct device *
754 value |= VC4_HDMI_CEC_ADDR_MASK |
755 (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
756 - HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, value);
757 + HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
758 ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
760 vc4_cec_irq_handler_thread, 0,
761 @@ -1388,6 +1388,9 @@ static void vc4_hdmi_unbind(struct devic
762 struct snd_soc_card *card = dev_get_drvdata(dev);
763 struct vc4_hdmi *vc4_hdmi = snd_soc_card_get_drvdata(card);
765 + kfree(vc4_hdmi->hdmi_regset.regs);
766 + kfree(vc4_hdmi->hd_regset.regs);
768 cec_unregister_adapter(vc4_hdmi->cec_adap);
769 vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
770 vc4_hdmi_encoder_destroy(&vc4_hdmi->encoder.base.base);
771 @@ -1415,6 +1418,9 @@ static int vc4_hdmi_dev_remove(struct pl
774 static const struct vc4_hdmi_variant bcm2835_variant = {
775 + .registers = vc4_hdmi_fields,
776 + .num_registers = ARRAY_SIZE(vc4_hdmi_fields),
778 .init_resources = vc4_hdmi_init_resources,
781 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
782 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
783 @@ -22,8 +22,15 @@ to_vc4_hdmi_encoder(struct drm_encoder *
787 +struct vc4_hdmi_register;
789 struct vc4_hdmi_variant {
790 + /* List of the registers available on that variant */
791 + const struct vc4_hdmi_register *registers;
793 + /* Number of registers on that variant */
794 + unsigned int num_registers;
796 /* Callback to get the resources (memory region, interrupts,
797 * clocks, etc) for that variant.
799 @@ -85,9 +92,4 @@ encoder_to_vc4_hdmi(struct drm_encoder *
800 return container_of(_encoder, struct vc4_hdmi, encoder);
803 -#define HDMI_READ(offset) readl(vc4_hdmi->hdmicore_regs + offset)
804 -#define HDMI_WRITE(offset, val) writel(val, vc4_hdmi->hdmicore_regs + offset)
805 -#define HD_READ(offset) readl(vc4_hdmi->hd_regs + offset)
806 -#define HD_WRITE(offset, val) writel(val, vc4_hdmi->hd_regs + offset)
808 #endif /* _VC4_HDMI_H_ */
810 +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
812 +#ifndef _VC4_HDMI_REGS_H_
813 +#define _VC4_HDMI_REGS_H_
815 +#include "vc4_hdmi.h"
817 +#define VC4_MASK(high, low) ((u32)GENMASK(high, low))
818 +/* Using the GNU statement expression extension */
819 +#define VC4_SET_FIELD(value, field) \
821 + uint32_t fieldval = (value) << field##_SHIFT; \
822 + WARN_ON((fieldval & ~field##_MASK) != 0); \
823 + fieldval & field##_MASK; \
826 +#define VC4_HDMI_PACKET_STRIDE 0x24
828 +enum vc4_hdmi_regs {
834 +enum vc4_hdmi_field {
835 + HDMI_AUDIO_PACKET_CONFIG,
841 + HDMI_CEC_CPU_CLEAR,
842 + HDMI_CEC_CPU_MASK_CLEAR,
843 + HDMI_CEC_CPU_MASK_SET,
844 + HDMI_CEC_CPU_MASK_STATUS,
845 + HDMI_CEC_CPU_STATUS,
848 + * Transmit data, first byte is low byte of the 32-bit reg.
849 + * MSB of each byte transmitted first.
851 + HDMI_CEC_RX_DATA_1,
852 + HDMI_CEC_RX_DATA_2,
853 + HDMI_CEC_RX_DATA_3,
854 + HDMI_CEC_RX_DATA_4,
855 + HDMI_CEC_TX_DATA_1,
856 + HDMI_CEC_TX_DATA_2,
857 + HDMI_CEC_TX_DATA_3,
858 + HDMI_CEC_TX_DATA_4,
870 + * 20-bit fields containing CTS values to be transmitted if
883 + * 3 bits per field, where each field maps from that
884 + * corresponding MAI bus channel to the given HDMI channel.
886 + HDMI_MAI_CHANNEL_MAP,
891 + * Register for DMAing in audio data to be transported over
892 + * the MAI bus to the Falcon core.
896 + /* Format header to be placed on the MAI data. Unused. */
899 + /* Last received format word on the MAI bus. */
904 + HDMI_RAM_PACKET_CONFIG,
905 + HDMI_RAM_PACKET_START,
906 + HDMI_RAM_PACKET_STATUS,
907 + HDMI_SCHEDULER_CONTROL,
908 + HDMI_SW_RESET_CONTROL,
910 + HDMI_TX_PHY_RESET_CTL,
918 +struct vc4_hdmi_register {
920 + enum vc4_hdmi_regs reg;
921 + unsigned int offset;
924 +#define _VC4_REG(_base, _reg, _offset) \
928 + .offset = _offset, \
931 +#define VC4_HD_REG(reg, offset) _VC4_REG(VC4_HD, reg, offset)
932 +#define VC4_HDMI_REG(reg, offset) _VC4_REG(VC4_HDMI, reg, offset)
934 +static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
935 + VC4_HD_REG(HDMI_M_CTL, 0x000c),
936 + VC4_HD_REG(HDMI_MAI_CTL, 0x0014),
937 + VC4_HD_REG(HDMI_MAI_THR, 0x0018),
938 + VC4_HD_REG(HDMI_MAI_FMT, 0x001c),
939 + VC4_HD_REG(HDMI_MAI_DATA, 0x0020),
940 + VC4_HD_REG(HDMI_MAI_SMP, 0x002c),
941 + VC4_HD_REG(HDMI_VID_CTL, 0x0038),
942 + VC4_HD_REG(HDMI_CSC_CTL, 0x0040),
943 + VC4_HD_REG(HDMI_CSC_12_11, 0x0044),
944 + VC4_HD_REG(HDMI_CSC_14_13, 0x0048),
945 + VC4_HD_REG(HDMI_CSC_22_21, 0x004c),
946 + VC4_HD_REG(HDMI_CSC_24_23, 0x0050),
947 + VC4_HD_REG(HDMI_CSC_32_31, 0x0054),
948 + VC4_HD_REG(HDMI_CSC_34_33, 0x0058),
949 + VC4_HD_REG(HDMI_FRAME_COUNT, 0x0068),
951 + VC4_HDMI_REG(HDMI_CORE_REV, 0x0000),
952 + VC4_HDMI_REG(HDMI_SW_RESET_CONTROL, 0x0004),
953 + VC4_HDMI_REG(HDMI_HOTPLUG_INT, 0x0008),
954 + VC4_HDMI_REG(HDMI_HOTPLUG, 0x000c),
955 + VC4_HDMI_REG(HDMI_FIFO_CTL, 0x005c),
956 + VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x0090),
957 + VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0094),
958 + VC4_HDMI_REG(HDMI_MAI_FORMAT, 0x0098),
959 + VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x009c),
960 + VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x00a0),
961 + VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x00a4),
962 + VC4_HDMI_REG(HDMI_CRP_CFG, 0x00a8),
963 + VC4_HDMI_REG(HDMI_CTS_0, 0x00ac),
964 + VC4_HDMI_REG(HDMI_CTS_1, 0x00b0),
965 + VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x00c0),
966 + VC4_HDMI_REG(HDMI_HORZA, 0x00c4),
967 + VC4_HDMI_REG(HDMI_HORZB, 0x00c8),
968 + VC4_HDMI_REG(HDMI_VERTA0, 0x00cc),
969 + VC4_HDMI_REG(HDMI_VERTB0, 0x00d0),
970 + VC4_HDMI_REG(HDMI_VERTA1, 0x00d4),
971 + VC4_HDMI_REG(HDMI_VERTB1, 0x00d8),
972 + VC4_HDMI_REG(HDMI_CEC_CNTRL_1, 0x00e8),
973 + VC4_HDMI_REG(HDMI_CEC_CNTRL_2, 0x00ec),
974 + VC4_HDMI_REG(HDMI_CEC_CNTRL_3, 0x00f0),
975 + VC4_HDMI_REG(HDMI_CEC_CNTRL_4, 0x00f4),
976 + VC4_HDMI_REG(HDMI_CEC_CNTRL_5, 0x00f8),
977 + VC4_HDMI_REG(HDMI_CEC_TX_DATA_1, 0x00fc),
978 + VC4_HDMI_REG(HDMI_CEC_TX_DATA_2, 0x0100),
979 + VC4_HDMI_REG(HDMI_CEC_TX_DATA_3, 0x0104),
980 + VC4_HDMI_REG(HDMI_CEC_TX_DATA_4, 0x0108),
981 + VC4_HDMI_REG(HDMI_CEC_RX_DATA_1, 0x010c),
982 + VC4_HDMI_REG(HDMI_CEC_RX_DATA_2, 0x0110),
983 + VC4_HDMI_REG(HDMI_CEC_RX_DATA_3, 0x0114),
984 + VC4_HDMI_REG(HDMI_CEC_RX_DATA_4, 0x0118),
985 + VC4_HDMI_REG(HDMI_TX_PHY_RESET_CTL, 0x02c0),
986 + VC4_HDMI_REG(HDMI_TX_PHY_CTL_0, 0x02c4),
987 + VC4_HDMI_REG(HDMI_CEC_CPU_STATUS, 0x0340),
988 + VC4_HDMI_REG(HDMI_CEC_CPU_CLEAR, 0x0348),
989 + VC4_HDMI_REG(HDMI_CEC_CPU_MASK_STATUS, 0x034c),
990 + VC4_HDMI_REG(HDMI_CEC_CPU_MASK_SET, 0x034c),
991 + VC4_HDMI_REG(HDMI_CEC_CPU_MASK_CLEAR, 0x0354),
992 + VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400),
996 +void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
997 + enum vc4_hdmi_regs reg)
1001 + return hdmi->hd_regs;
1004 + return hdmi->hdmicore_regs;
1013 +static inline u32 vc4_hdmi_read(struct vc4_hdmi *hdmi,
1014 + enum vc4_hdmi_regs reg)
1016 + const struct vc4_hdmi_register *field;
1017 + const struct vc4_hdmi_variant *variant = hdmi->variant;
1018 + void __iomem *base;
1020 + if (reg > variant->num_registers) {
1021 + dev_warn(&hdmi->pdev->dev,
1022 + "Invalid register ID %u\n", reg);
1026 + field = &variant->registers[reg];
1027 + base = __vc4_hdmi_get_field_base(hdmi, field->reg);
1029 + dev_warn(&hdmi->pdev->dev,
1030 + "Unknown register ID %u\n", reg);
1034 + return readl(base + field->offset);
1036 +#define HDMI_READ(reg) vc4_hdmi_read(vc4_hdmi, reg)
1038 +static inline void vc4_hdmi_write(struct vc4_hdmi *hdmi,
1039 + enum vc4_hdmi_regs reg,
1042 + const struct vc4_hdmi_register *field;
1043 + const struct vc4_hdmi_variant *variant = hdmi->variant;
1044 + void __iomem *base;
1046 + if (reg > variant->num_registers) {
1047 + dev_warn(&hdmi->pdev->dev,
1048 + "Invalid register ID %u\n", reg);
1052 + field = &variant->registers[reg];
1053 + base = __vc4_hdmi_get_field_base(hdmi, field->reg);
1057 + writel(value, base + field->offset);
1059 +#define HDMI_WRITE(reg, val) vc4_hdmi_write(vc4_hdmi, reg, val)
1061 +#endif /* _VC4_HDMI_REGS_H_ */
1062 --- a/drivers/gpu/drm/vc4/vc4_regs.h
1063 +++ b/drivers/gpu/drm/vc4/vc4_regs.h
1064 @@ -493,32 +493,16 @@
1066 #define SCALER5_DLIST_START 0x00004000
1068 -#define VC4_HDMI_CORE_REV 0x000
1070 -#define VC4_HDMI_SW_RESET_CONTROL 0x004
1071 # define VC4_HDMI_SW_RESET_FORMAT_DETECT BIT(1)
1072 # define VC4_HDMI_SW_RESET_HDMI BIT(0)
1074 -#define VC4_HDMI_HOTPLUG_INT 0x008
1076 -#define VC4_HDMI_HOTPLUG 0x00c
1077 # define VC4_HDMI_HOTPLUG_CONNECTED BIT(0)
1079 -/* 3 bits per field, where each field maps from that corresponding MAI
1080 - * bus channel to the given HDMI channel.
1082 -#define VC4_HDMI_MAI_CHANNEL_MAP 0x090
1084 -#define VC4_HDMI_MAI_CONFIG 0x094
1085 # define VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE BIT(27)
1086 # define VC4_HDMI_MAI_CONFIG_BIT_REVERSE BIT(26)
1087 # define VC4_HDMI_MAI_CHANNEL_MASK_MASK VC4_MASK(15, 0)
1088 # define VC4_HDMI_MAI_CHANNEL_MASK_SHIFT 0
1090 -/* Last received format word on the MAI bus. */
1091 -#define VC4_HDMI_MAI_FORMAT 0x098
1093 -#define VC4_HDMI_AUDIO_PACKET_CONFIG 0x09c
1094 # define VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_SAMPLE_FLAT BIT(29)
1095 # define VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_INACTIVE_CHANNELS BIT(24)
1096 # define VC4_HDMI_AUDIO_PACKET_FORCE_SAMPLE_PRESENT BIT(19)
1097 @@ -532,12 +516,8 @@
1098 # define VC4_HDMI_AUDIO_PACKET_CEA_MASK_MASK VC4_MASK(7, 0)
1099 # define VC4_HDMI_AUDIO_PACKET_CEA_MASK_SHIFT 0
1101 -#define VC4_HDMI_RAM_PACKET_CONFIG 0x0a0
1102 # define VC4_HDMI_RAM_PACKET_ENABLE BIT(16)
1104 -#define VC4_HDMI_RAM_PACKET_STATUS 0x0a4
1106 -#define VC4_HDMI_CRP_CFG 0x0a8
1107 /* When set, the CTS_PERIOD counts based on MAI bus sync pulse instead
1110 @@ -551,23 +531,12 @@
1111 # define VC4_HDMI_CRP_CFG_N_MASK VC4_MASK(19, 0)
1112 # define VC4_HDMI_CRP_CFG_N_SHIFT 0
1114 -/* 20-bit fields containing CTS values to be transmitted if !EXTERNAL_CTS_EN */
1115 -#define VC4_HDMI_CTS_0 0x0ac
1116 -#define VC4_HDMI_CTS_1 0x0b0
1117 -/* 20-bit fields containing number of clocks to send CTS0/1 before
1118 - * switching to the other one.
1120 -#define VC4_HDMI_CTS_PERIOD_0 0x0b4
1121 -#define VC4_HDMI_CTS_PERIOD_1 0x0b8
1123 -#define VC4_HDMI_HORZA 0x0c4
1124 # define VC4_HDMI_HORZA_VPOS BIT(14)
1125 # define VC4_HDMI_HORZA_HPOS BIT(13)
1126 /* Horizontal active pixels (hdisplay). */
1127 # define VC4_HDMI_HORZA_HAP_MASK VC4_MASK(12, 0)
1128 # define VC4_HDMI_HORZA_HAP_SHIFT 0
1130 -#define VC4_HDMI_HORZB 0x0c8
1131 /* Horizontal pack porch (htotal - hsync_end). */
1132 # define VC4_HDMI_HORZB_HBP_MASK VC4_MASK(29, 20)
1133 # define VC4_HDMI_HORZB_HBP_SHIFT 20
1135 # define VC4_HDMI_HORZB_HFP_MASK VC4_MASK(9, 0)
1136 # define VC4_HDMI_HORZB_HFP_SHIFT 0
1138 -#define VC4_HDMI_FIFO_CTL 0x05c
1139 # define VC4_HDMI_FIFO_CTL_RECENTER_DONE BIT(14)
1140 # define VC4_HDMI_FIFO_CTL_USE_EMPTY BIT(13)
1141 # define VC4_HDMI_FIFO_CTL_ON_VB BIT(7)
1142 @@ -591,15 +559,12 @@
1143 # define VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N BIT(0)
1144 # define VC4_HDMI_FIFO_VALID_WRITE_MASK 0xefff
1146 -#define VC4_HDMI_SCHEDULER_CONTROL 0x0c0
1147 # define VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT BIT(15)
1148 # define VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS BIT(5)
1149 # define VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT BIT(3)
1150 # define VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE BIT(1)
1151 # define VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI BIT(0)
1153 -#define VC4_HDMI_VERTA0 0x0cc
1154 -#define VC4_HDMI_VERTA1 0x0d4
1155 /* Vertical sync pulse (vsync_end - vsync_start). */
1156 # define VC4_HDMI_VERTA_VSP_MASK VC4_MASK(24, 20)
1157 # define VC4_HDMI_VERTA_VSP_SHIFT 20
1159 # define VC4_HDMI_VERTA_VAL_MASK VC4_MASK(12, 0)
1160 # define VC4_HDMI_VERTA_VAL_SHIFT 0
1162 -#define VC4_HDMI_VERTB0 0x0d0
1163 -#define VC4_HDMI_VERTB1 0x0d8
1164 /* Vertical sync pulse offset (for interlaced) */
1165 # define VC4_HDMI_VERTB_VSPO_MASK VC4_MASK(21, 9)
1166 # define VC4_HDMI_VERTB_VSPO_SHIFT 9
1168 # define VC4_HDMI_VERTB_VBP_MASK VC4_MASK(8, 0)
1169 # define VC4_HDMI_VERTB_VBP_SHIFT 0
1171 -#define VC4_HDMI_CEC_CNTRL_1 0x0e8
1172 /* Set when the transmission has ended. */
1173 # define VC4_HDMI_CEC_TX_EOM BIT(31)
1174 /* If set, transmission was acked on the 1st or 2nd attempt (only one
1176 /* Set these fields to how many bit clock cycles get to that many
1179 -#define VC4_HDMI_CEC_CNTRL_2 0x0ec
1180 # define VC4_HDMI_CEC_CNT_TO_1500_US_MASK VC4_MASK(30, 24)
1181 # define VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT 24
1182 # define VC4_HDMI_CEC_CNT_TO_1300_US_MASK VC4_MASK(23, 17)
1184 # define VC4_HDMI_CEC_CNT_TO_400_US_MASK VC4_MASK(4, 0)
1185 # define VC4_HDMI_CEC_CNT_TO_400_US_SHIFT 0
1187 -#define VC4_HDMI_CEC_CNTRL_3 0x0f0
1188 # define VC4_HDMI_CEC_CNT_TO_2750_US_MASK VC4_MASK(31, 24)
1189 # define VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT 24
1190 # define VC4_HDMI_CEC_CNT_TO_2400_US_MASK VC4_MASK(23, 16)
1192 # define VC4_HDMI_CEC_CNT_TO_1700_US_MASK VC4_MASK(7, 0)
1193 # define VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT 0
1195 -#define VC4_HDMI_CEC_CNTRL_4 0x0f4
1196 # define VC4_HDMI_CEC_CNT_TO_4300_US_MASK VC4_MASK(31, 24)
1197 # define VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT 24
1198 # define VC4_HDMI_CEC_CNT_TO_3900_US_MASK VC4_MASK(23, 16)
1200 # define VC4_HDMI_CEC_CNT_TO_3500_US_MASK VC4_MASK(7, 0)
1201 # define VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT 0
1203 -#define VC4_HDMI_CEC_CNTRL_5 0x0f8
1204 # define VC4_HDMI_CEC_TX_SW_RESET BIT(27)
1205 # define VC4_HDMI_CEC_RX_SW_RESET BIT(26)
1206 # define VC4_HDMI_CEC_PAD_SW_RESET BIT(25)
1207 @@ -705,39 +663,11 @@
1208 # define VC4_HDMI_CEC_CNT_TO_4500_US_MASK VC4_MASK(7, 0)
1209 # define VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT 0
1211 -/* Transmit data, first byte is low byte of the 32-bit reg. MSB of
1212 - * each byte transmitted first.
1214 -#define VC4_HDMI_CEC_TX_DATA_1 0x0fc
1215 -#define VC4_HDMI_CEC_TX_DATA_2 0x100
1216 -#define VC4_HDMI_CEC_TX_DATA_3 0x104
1217 -#define VC4_HDMI_CEC_TX_DATA_4 0x108
1218 -#define VC4_HDMI_CEC_RX_DATA_1 0x10c
1219 -#define VC4_HDMI_CEC_RX_DATA_2 0x110
1220 -#define VC4_HDMI_CEC_RX_DATA_3 0x114
1221 -#define VC4_HDMI_CEC_RX_DATA_4 0x118
1223 -#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0
1225 -#define VC4_HDMI_TX_PHY_CTL0 0x2c4
1226 # define VC4_HDMI_TX_PHY_RNG_PWRDN BIT(25)
1228 -/* Interrupt status bits */
1229 -#define VC4_HDMI_CPU_STATUS 0x340
1230 -#define VC4_HDMI_CPU_SET 0x344
1231 -#define VC4_HDMI_CPU_CLEAR 0x348
1232 # define VC4_HDMI_CPU_CEC BIT(6)
1233 # define VC4_HDMI_CPU_HOTPLUG BIT(0)
1235 -#define VC4_HDMI_CPU_MASK_STATUS 0x34c
1236 -#define VC4_HDMI_CPU_MASK_SET 0x350
1237 -#define VC4_HDMI_CPU_MASK_CLEAR 0x354
1239 -#define VC4_HDMI_GCP(x) (0x400 + ((x) * 0x4))
1240 -#define VC4_HDMI_RAM_PACKET(x) (0x400 + ((x) * 0x24))
1241 -#define VC4_HDMI_PACKET_STRIDE 0x24
1243 -#define VC4_HD_M_CTL 0x00c
1244 /* Debug: Current receive value on the CEC pad. */
1245 # define VC4_HD_CECRXD BIT(9)
1246 /* Debug: Override CEC output to 0. */
1248 # define VC4_HD_M_SW_RST BIT(2)
1249 # define VC4_HD_M_ENABLE BIT(0)
1251 -#define VC4_HD_MAI_CTL 0x014
1252 /* Set when audio stream is received at a slower rate than the
1253 * sampling period, so MAI fifo goes empty. Write 1 to clear.
1256 /* Single-shot reset bit. Read value is undefined. */
1257 # define VC4_HD_MAI_CTL_RESET BIT(0)
1259 -#define VC4_HD_MAI_THR 0x018
1260 # define VC4_HD_MAI_THR_PANICHIGH_MASK VC4_MASK(29, 24)
1261 # define VC4_HD_MAI_THR_PANICHIGH_SHIFT 24
1262 # define VC4_HD_MAI_THR_PANICLOW_MASK VC4_MASK(21, 16)
1263 @@ -782,31 +710,20 @@
1264 # define VC4_HD_MAI_THR_DREQLOW_MASK VC4_MASK(5, 0)
1265 # define VC4_HD_MAI_THR_DREQLOW_SHIFT 0
1267 -/* Format header to be placed on the MAI data. Unused. */
1268 -#define VC4_HD_MAI_FMT 0x01c
1270 -/* Register for DMAing in audio data to be transported over the MAI
1271 - * bus to the Falcon core.
1273 -#define VC4_HD_MAI_DATA 0x020
1275 /* Divider from HDMI HSM clock to MAI serial clock. Sampling period
1276 * converges to N / (M + 1) cycles.
1278 -#define VC4_HD_MAI_SMP 0x02c
1279 # define VC4_HD_MAI_SMP_N_MASK VC4_MASK(31, 8)
1280 # define VC4_HD_MAI_SMP_N_SHIFT 8
1281 # define VC4_HD_MAI_SMP_M_MASK VC4_MASK(7, 0)
1282 # define VC4_HD_MAI_SMP_M_SHIFT 0
1284 -#define VC4_HD_VID_CTL 0x038
1285 # define VC4_HD_VID_CTL_ENABLE BIT(31)
1286 # define VC4_HD_VID_CTL_UNDERFLOW_ENABLE BIT(30)
1287 # define VC4_HD_VID_CTL_FRAME_COUNTER_RESET BIT(29)
1288 # define VC4_HD_VID_CTL_VSYNC_LOW BIT(28)
1289 # define VC4_HD_VID_CTL_HSYNC_LOW BIT(27)
1291 -#define VC4_HD_CSC_CTL 0x040
1292 # define VC4_HD_CSC_CTL_ORDER_MASK VC4_MASK(7, 5)
1293 # define VC4_HD_CSC_CTL_ORDER_SHIFT 5
1294 # define VC4_HD_CSC_CTL_ORDER_RGB 0
1295 @@ -824,15 +741,6 @@
1296 # define VC4_HD_CSC_CTL_RGB2YCC BIT(1)
1297 # define VC4_HD_CSC_CTL_ENABLE BIT(0)
1299 -#define VC4_HD_CSC_12_11 0x044
1300 -#define VC4_HD_CSC_14_13 0x048
1301 -#define VC4_HD_CSC_22_21 0x04c
1302 -#define VC4_HD_CSC_24_23 0x050
1303 -#define VC4_HD_CSC_32_31 0x054
1304 -#define VC4_HD_CSC_34_33 0x058
1306 -#define VC4_HD_FRAME_COUNT 0x068
1308 /* HVS display list information. */
1309 #define HVS_BOOTLOADER_DLIST_END 32