1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
4 * Copyright (c) 2024 Collabora Ltd.
5 *
6 * Author: Algea Cao <algea.cao@rock-chips.com>
7 * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
8 */
9#include <linux/completion.h>
10#include <linux/hdmi.h>
11#include <linux/i2c.h>
12#include <linux/irq.h>
13#include <linux/module.h>
14#include <linux/mutex.h>
15#include <linux/of.h>
16#include <linux/workqueue.h>
17
18#include <drm/bridge/dw_hdmi_qp.h>
19#include <drm/display/drm_hdmi_helper.h>
20#include <drm/display/drm_hdmi_state_helper.h>
21#include <drm/drm_atomic.h>
22#include <drm/drm_atomic_helper.h>
23#include <drm/drm_bridge.h>
24#include <drm/drm_connector.h>
25#include <drm/drm_edid.h>
26#include <drm/drm_modes.h>
27
28#include <sound/hdmi-codec.h>
29
30#include "dw-hdmi-qp.h"
31
32#define DDC_CI_ADDR 0x37
33#define DDC_SEGMENT_ADDR 0x30
34
35#define HDMI14_MAX_TMDSCLK 340000000
36
37#define SCRAMB_POLL_DELAY_MS 3000
38
39/*
40 * Unless otherwise noted, entries in this table are 100% optimization.
41 * Values can be obtained from dw_hdmi_qp_compute_n() but that function is
42 * slow so we pre-compute values we expect to see.
43 *
44 * The values for TMDS 25175, 25200, 27000, 54000, 74250 and 148500 kHz are
45 * the recommended N values specified in the Audio chapter of the HDMI
46 * specification.
47 */
48static const struct dw_hdmi_audio_tmds_n {
49 unsigned long tmds;
50 unsigned int n_32k;
51 unsigned int n_44k1;
52 unsigned int n_48k;
53} common_tmds_n_table[] = {
54 { .tmds = 25175000, .n_32k = 4576, .n_44k1 = 7007, .n_48k = 6864, },
55 { .tmds = 25200000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
56 { .tmds = 27000000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
57 { .tmds = 28320000, .n_32k = 4096, .n_44k1 = 5586, .n_48k = 6144, },
58 { .tmds = 30240000, .n_32k = 4096, .n_44k1 = 5642, .n_48k = 6144, },
59 { .tmds = 31500000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, },
60 { .tmds = 32000000, .n_32k = 4096, .n_44k1 = 5733, .n_48k = 6144, },
61 { .tmds = 33750000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
62 { .tmds = 36000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
63 { .tmds = 40000000, .n_32k = 4096, .n_44k1 = 5733, .n_48k = 6144, },
64 { .tmds = 49500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
65 { .tmds = 50000000, .n_32k = 4096, .n_44k1 = 5292, .n_48k = 6144, },
66 { .tmds = 54000000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
67 { .tmds = 65000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
68 { .tmds = 68250000, .n_32k = 4096, .n_44k1 = 5376, .n_48k = 6144, },
69 { .tmds = 71000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
70 { .tmds = 72000000, .n_32k = 4096, .n_44k1 = 5635, .n_48k = 6144, },
71 { .tmds = 73250000, .n_32k = 11648, .n_44k1 = 14112, .n_48k = 6144, },
72 { .tmds = 74250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
73 { .tmds = 75000000, .n_32k = 4096, .n_44k1 = 5880, .n_48k = 6144, },
74 { .tmds = 78750000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, },
75 { .tmds = 78800000, .n_32k = 4096, .n_44k1 = 5292, .n_48k = 6144, },
76 { .tmds = 79500000, .n_32k = 4096, .n_44k1 = 4704, .n_48k = 6144, },
77 { .tmds = 83500000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
78 { .tmds = 85500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
79 { .tmds = 88750000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, },
80 { .tmds = 97750000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, },
81 { .tmds = 101000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
82 { .tmds = 106500000, .n_32k = 4096, .n_44k1 = 4704, .n_48k = 6144, },
83 { .tmds = 108000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
84 { .tmds = 115500000, .n_32k = 4096, .n_44k1 = 5712, .n_48k = 6144, },
85 { .tmds = 119000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, },
86 { .tmds = 135000000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
87 { .tmds = 146250000, .n_32k = 11648, .n_44k1 = 6272, .n_48k = 6144, },
88 { .tmds = 148500000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
89 { .tmds = 154000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, },
90 { .tmds = 162000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
91
92 /* For 297 MHz+ HDMI spec have some other rule for setting N */
93 { .tmds = 297000000, .n_32k = 3073, .n_44k1 = 4704, .n_48k = 5120, },
94 { .tmds = 594000000, .n_32k = 3073, .n_44k1 = 9408, .n_48k = 10240,},
95
96 /* End of table */
97 { .tmds = 0, .n_32k = 0, .n_44k1 = 0, .n_48k = 0, },
98};
99
100/*
101 * These are the CTS values as recommended in the Audio chapter of the HDMI
102 * specification.
103 */
104static const struct dw_hdmi_audio_tmds_cts {
105 unsigned long tmds;
106 unsigned int cts_32k;
107 unsigned int cts_44k1;
108 unsigned int cts_48k;
109} common_tmds_cts_table[] = {
110 { .tmds = 25175000, .cts_32k = 28125, .cts_44k1 = 31250, .cts_48k = 28125, },
111 { .tmds = 25200000, .cts_32k = 25200, .cts_44k1 = 28000, .cts_48k = 25200, },
112 { .tmds = 27000000, .cts_32k = 27000, .cts_44k1 = 30000, .cts_48k = 27000, },
113 { .tmds = 54000000, .cts_32k = 54000, .cts_44k1 = 60000, .cts_48k = 54000, },
114 { .tmds = 74250000, .cts_32k = 74250, .cts_44k1 = 82500, .cts_48k = 74250, },
115 { .tmds = 148500000, .cts_32k = 148500, .cts_44k1 = 165000, .cts_48k = 148500, },
116
117 /* End of table */
118 { .tmds = 0, .cts_32k = 0, .cts_44k1 = 0, .cts_48k = 0, },
119};
120
121struct dw_hdmi_qp_i2c {
122 struct i2c_adapter adap;
123
124 struct mutex lock; /* used to serialize data transfers */
125 struct completion cmp;
126 u8 stat;
127
128 u8 slave_reg;
129 bool is_regaddr;
130 bool is_segment;
131};
132
133struct dw_hdmi_qp {
134 struct drm_bridge bridge;
135
136 struct device *dev;
137 struct dw_hdmi_qp_i2c *i2c;
138
139 struct {
140 const struct dw_hdmi_qp_phy_ops *ops;
141 void *data;
142 } phy;
143
144 struct regmap *regm;
145
146 unsigned long tmds_char_rate;
147};
148
149static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val,
150 int offset)
151{
152 regmap_write(map: hdmi->regm, reg: offset, val);
153}
154
155static unsigned int dw_hdmi_qp_read(struct dw_hdmi_qp *hdmi, int offset)
156{
157 unsigned int val = 0;
158
159 regmap_read(map: hdmi->regm, reg: offset, val: &val);
160
161 return val;
162}
163
164static void dw_hdmi_qp_mod(struct dw_hdmi_qp *hdmi, unsigned int data,
165 unsigned int mask, unsigned int reg)
166{
167 regmap_update_bits(map: hdmi->regm, reg, mask, val: data);
168}
169
170static struct dw_hdmi_qp *dw_hdmi_qp_from_bridge(struct drm_bridge *bridge)
171{
172 return container_of(bridge, struct dw_hdmi_qp, bridge);
173}
174
175static void dw_hdmi_qp_set_cts_n(struct dw_hdmi_qp *hdmi, unsigned int cts,
176 unsigned int n)
177{
178 /* Set N */
179 dw_hdmi_qp_mod(hdmi, data: n, AUDPKT_ACR_N_VALUE, AUDPKT_ACR_CONTROL0);
180
181 /* Set CTS */
182 if (cts)
183 dw_hdmi_qp_mod(hdmi, AUDPKT_ACR_CTS_OVR_EN, AUDPKT_ACR_CTS_OVR_EN_MSK,
184 AUDPKT_ACR_CONTROL1);
185 else
186 dw_hdmi_qp_mod(hdmi, data: 0, AUDPKT_ACR_CTS_OVR_EN_MSK,
187 AUDPKT_ACR_CONTROL1);
188
189 dw_hdmi_qp_mod(hdmi, AUDPKT_ACR_CTS_OVR_VAL(cts), AUDPKT_ACR_CTS_OVR_VAL_MSK,
190 AUDPKT_ACR_CONTROL1);
191}
192
193static int dw_hdmi_qp_match_tmds_n_table(struct dw_hdmi_qp *hdmi,
194 unsigned long pixel_clk,
195 unsigned long freq)
196{
197 const struct dw_hdmi_audio_tmds_n *tmds_n = NULL;
198 int i;
199
200 for (i = 0; common_tmds_n_table[i].tmds != 0; i++) {
201 if (pixel_clk == common_tmds_n_table[i].tmds) {
202 tmds_n = &common_tmds_n_table[i];
203 break;
204 }
205 }
206
207 if (!tmds_n)
208 return -ENOENT;
209
210 switch (freq) {
211 case 32000:
212 return tmds_n->n_32k;
213 case 44100:
214 case 88200:
215 case 176400:
216 return (freq / 44100) * tmds_n->n_44k1;
217 case 48000:
218 case 96000:
219 case 192000:
220 return (freq / 48000) * tmds_n->n_48k;
221 default:
222 return -ENOENT;
223 }
224}
225
226static u32 dw_hdmi_qp_audio_math_diff(unsigned int freq, unsigned int n,
227 unsigned int pixel_clk)
228{
229 u64 cts = mul_u32_u32(a: pixel_clk, b: n);
230
231 return do_div(cts, 128 * freq);
232}
233
234static unsigned int dw_hdmi_qp_compute_n(struct dw_hdmi_qp *hdmi,
235 unsigned long pixel_clk,
236 unsigned long freq)
237{
238 unsigned int min_n = DIV_ROUND_UP((128 * freq), 1500);
239 unsigned int max_n = (128 * freq) / 300;
240 unsigned int ideal_n = (128 * freq) / 1000;
241 unsigned int best_n_distance = ideal_n;
242 unsigned int best_n = 0;
243 u64 best_diff = U64_MAX;
244 int n;
245
246 /* If the ideal N could satisfy the audio math, then just take it */
247 if (dw_hdmi_qp_audio_math_diff(freq, n: ideal_n, pixel_clk) == 0)
248 return ideal_n;
249
250 for (n = min_n; n <= max_n; n++) {
251 u64 diff = dw_hdmi_qp_audio_math_diff(freq, n, pixel_clk);
252
253 if (diff < best_diff ||
254 (diff == best_diff && abs(n - ideal_n) < best_n_distance)) {
255 best_n = n;
256 best_diff = diff;
257 best_n_distance = abs(best_n - ideal_n);
258 }
259
260 /*
261 * The best N already satisfy the audio math, and also be
262 * the closest value to ideal N, so just cut the loop.
263 */
264 if (best_diff == 0 && (abs(n - ideal_n) > best_n_distance))
265 break;
266 }
267
268 return best_n;
269}
270
271static unsigned int dw_hdmi_qp_find_n(struct dw_hdmi_qp *hdmi, unsigned long pixel_clk,
272 unsigned long sample_rate)
273{
274 int n = dw_hdmi_qp_match_tmds_n_table(hdmi, pixel_clk, freq: sample_rate);
275
276 if (n > 0)
277 return n;
278
279 dev_warn(hdmi->dev, "Rate %lu missing; compute N dynamically\n",
280 pixel_clk);
281
282 return dw_hdmi_qp_compute_n(hdmi, pixel_clk, freq: sample_rate);
283}
284
285static unsigned int dw_hdmi_qp_find_cts(struct dw_hdmi_qp *hdmi, unsigned long pixel_clk,
286 unsigned long sample_rate)
287{
288 const struct dw_hdmi_audio_tmds_cts *tmds_cts = NULL;
289 int i;
290
291 for (i = 0; common_tmds_cts_table[i].tmds != 0; i++) {
292 if (pixel_clk == common_tmds_cts_table[i].tmds) {
293 tmds_cts = &common_tmds_cts_table[i];
294 break;
295 }
296 }
297
298 if (!tmds_cts)
299 return 0;
300
301 switch (sample_rate) {
302 case 32000:
303 return tmds_cts->cts_32k;
304 case 44100:
305 case 88200:
306 case 176400:
307 return tmds_cts->cts_44k1;
308 case 48000:
309 case 96000:
310 case 192000:
311 return tmds_cts->cts_48k;
312 default:
313 return -ENOENT;
314 }
315}
316
317static void dw_hdmi_qp_set_audio_interface(struct dw_hdmi_qp *hdmi,
318 struct hdmi_codec_daifmt *fmt,
319 struct hdmi_codec_params *hparms)
320{
321 u32 conf0 = 0;
322
323 /* Reset the audio data path of the AVP */
324 dw_hdmi_qp_write(hdmi, AVP_DATAPATH_PACKET_AUDIO_SWINIT_P, GLOBAL_SWRESET_REQUEST);
325
326 /* Disable AUDS, ACR, AUDI */
327 dw_hdmi_qp_mod(hdmi, data: 0,
328 PKTSCHED_ACR_TX_EN | PKTSCHED_AUDS_TX_EN | PKTSCHED_AUDI_TX_EN,
329 PKTSCHED_PKT_EN);
330
331 /* Clear the audio FIFO */
332 dw_hdmi_qp_write(hdmi, AUDIO_FIFO_CLR_P, AUDIO_INTERFACE_CONTROL0);
333
334 /* Select I2S interface as the audio source */
335 dw_hdmi_qp_mod(hdmi, AUD_IF_I2S, AUD_IF_SEL_MSK, AUDIO_INTERFACE_CONFIG0);
336
337 /* Enable the active i2s lanes */
338 switch (hparms->channels) {
339 case 7 ... 8:
340 conf0 |= I2S_LINES_EN(3);
341 fallthrough;
342 case 5 ... 6:
343 conf0 |= I2S_LINES_EN(2);
344 fallthrough;
345 case 3 ... 4:
346 conf0 |= I2S_LINES_EN(1);
347 fallthrough;
348 default:
349 conf0 |= I2S_LINES_EN(0);
350 break;
351 }
352
353 dw_hdmi_qp_mod(hdmi, data: conf0, I2S_LINES_EN_MSK, AUDIO_INTERFACE_CONFIG0);
354
355 /*
356 * Enable bpcuv generated internally for L-PCM, or received
357 * from stream for NLPCM/HBR.
358 */
359 switch (fmt->bit_fmt) {
360 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
361 conf0 = (hparms->channels == 8) ? AUD_HBR : AUD_ASP;
362 conf0 |= I2S_BPCUV_RCV_EN;
363 break;
364 default:
365 conf0 = AUD_ASP | I2S_BPCUV_RCV_DIS;
366 break;
367 }
368
369 dw_hdmi_qp_mod(hdmi, data: conf0, I2S_BPCUV_RCV_MSK | AUD_FORMAT_MSK,
370 AUDIO_INTERFACE_CONFIG0);
371
372 /* Enable audio FIFO auto clear when overflow */
373 dw_hdmi_qp_mod(hdmi, AUD_FIFO_INIT_ON_OVF_EN, AUD_FIFO_INIT_ON_OVF_MSK,
374 AUDIO_INTERFACE_CONFIG0);
375}
376
377/*
378 * When transmitting IEC60958 linear PCM audio, these registers allow to
379 * configure the channel status information of all the channel status
380 * bits in the IEC60958 frame. For the moment this configuration is only
381 * used when the I2S audio interface, General Purpose Audio (GPA),
382 * or AHB audio DMA (AHBAUDDMA) interface is active
383 * (for S/PDIF interface this information comes from the stream).
384 */
385static void dw_hdmi_qp_set_channel_status(struct dw_hdmi_qp *hdmi,
386 u8 *channel_status, bool ref2stream)
387{
388 /*
389 * AUDPKT_CHSTATUS_OVR0: { RSV, RSV, CS1, CS0 }
390 * AUDPKT_CHSTATUS_OVR1: { CS6, CS5, CS4, CS3 }
391 *
392 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
393 * CS0: | Mode | d | c | b | a |
394 * CS1: | Category Code |
395 * CS2: | Channel Number | Source Number |
396 * CS3: | Clock Accuracy | Sample Freq |
397 * CS4: | Ori Sample Freq | Word Length |
398 * CS5: | | CGMS-A |
399 * CS6~CS23: Reserved
400 *
401 * a: use of channel status block
402 * b: linear PCM identification: 0 for lpcm, 1 for nlpcm
403 * c: copyright information
404 * d: additional format information
405 */
406
407 if (ref2stream)
408 channel_status[0] |= IEC958_AES0_NONAUDIO;
409
410 if ((dw_hdmi_qp_read(hdmi, AUDIO_INTERFACE_CONFIG0) & GENMASK(25, 24)) == AUD_HBR) {
411 /* fixup cs for HBR */
412 channel_status[3] = (channel_status[3] & 0xf0) | IEC958_AES3_CON_FS_768000;
413 channel_status[4] = (channel_status[4] & 0x0f) | IEC958_AES4_CON_ORIGFS_NOTID;
414 }
415
416 dw_hdmi_qp_write(hdmi, val: channel_status[0] | (channel_status[1] << 8),
417 AUDPKT_CHSTATUS_OVR0);
418
419 regmap_bulk_write(map: hdmi->regm, AUDPKT_CHSTATUS_OVR1, val: &channel_status[3], val_count: 1);
420
421 if (ref2stream)
422 dw_hdmi_qp_mod(hdmi, data: 0,
423 AUDPKT_PBIT_FORCE_EN_MASK | AUDPKT_CHSTATUS_OVR_EN_MASK,
424 AUDPKT_CONTROL0);
425 else
426 dw_hdmi_qp_mod(hdmi, AUDPKT_PBIT_FORCE_EN | AUDPKT_CHSTATUS_OVR_EN,
427 AUDPKT_PBIT_FORCE_EN_MASK | AUDPKT_CHSTATUS_OVR_EN_MASK,
428 AUDPKT_CONTROL0);
429}
430
431static void dw_hdmi_qp_set_sample_rate(struct dw_hdmi_qp *hdmi, unsigned long long tmds_char_rate,
432 unsigned int sample_rate)
433{
434 unsigned int n, cts;
435
436 n = dw_hdmi_qp_find_n(hdmi, pixel_clk: tmds_char_rate, sample_rate);
437 cts = dw_hdmi_qp_find_cts(hdmi, pixel_clk: tmds_char_rate, sample_rate);
438
439 dw_hdmi_qp_set_cts_n(hdmi, cts, n);
440}
441
442static int dw_hdmi_qp_audio_enable(struct drm_connector *connector,
443 struct drm_bridge *bridge)
444{
445 struct dw_hdmi_qp *hdmi = dw_hdmi_qp_from_bridge(bridge);
446
447 if (hdmi->tmds_char_rate)
448 dw_hdmi_qp_mod(hdmi, data: 0, AVP_DATAPATH_PACKET_AUDIO_SWDISABLE, GLOBAL_SWDISABLE);
449
450 return 0;
451}
452
453static int dw_hdmi_qp_audio_prepare(struct drm_connector *connector,
454 struct drm_bridge *bridge,
455 struct hdmi_codec_daifmt *fmt,
456 struct hdmi_codec_params *hparms)
457{
458 struct dw_hdmi_qp *hdmi = dw_hdmi_qp_from_bridge(bridge);
459 bool ref2stream = false;
460
461 if (!hdmi->tmds_char_rate)
462 return -ENODEV;
463
464 if (fmt->bit_clk_provider | fmt->frame_clk_provider) {
465 dev_err(hdmi->dev, "unsupported clock settings\n");
466 return -EINVAL;
467 }
468
469 if (fmt->bit_fmt == SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
470 ref2stream = true;
471
472 dw_hdmi_qp_set_audio_interface(hdmi, fmt, hparms);
473 dw_hdmi_qp_set_sample_rate(hdmi, tmds_char_rate: hdmi->tmds_char_rate, sample_rate: hparms->sample_rate);
474 dw_hdmi_qp_set_channel_status(hdmi, channel_status: hparms->iec.status, ref2stream);
475 drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector, frame: &hparms->cea);
476
477 return 0;
478}
479
480static void dw_hdmi_qp_audio_disable_regs(struct dw_hdmi_qp *hdmi)
481{
482 /*
483 * Keep ACR, AUDI, AUDS packet always on to make SINK device
484 * active for better compatibility and user experience.
485 *
486 * This also fix POP sound on some SINK devices which wakeup
487 * from suspend to active.
488 */
489 dw_hdmi_qp_mod(hdmi, I2S_BPCUV_RCV_DIS, I2S_BPCUV_RCV_MSK,
490 AUDIO_INTERFACE_CONFIG0);
491 dw_hdmi_qp_mod(hdmi, AUDPKT_PBIT_FORCE_EN | AUDPKT_CHSTATUS_OVR_EN,
492 AUDPKT_PBIT_FORCE_EN_MASK | AUDPKT_CHSTATUS_OVR_EN_MASK,
493 AUDPKT_CONTROL0);
494
495 dw_hdmi_qp_mod(hdmi, AVP_DATAPATH_PACKET_AUDIO_SWDISABLE,
496 AVP_DATAPATH_PACKET_AUDIO_SWDISABLE, GLOBAL_SWDISABLE);
497}
498
499static void dw_hdmi_qp_audio_disable(struct drm_connector *connector,
500 struct drm_bridge *bridge)
501{
502 struct dw_hdmi_qp *hdmi = dw_hdmi_qp_from_bridge(bridge);
503
504 drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
505
506 if (hdmi->tmds_char_rate)
507 dw_hdmi_qp_audio_disable_regs(hdmi);
508}
509
510static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
511 unsigned char *buf, unsigned int length)
512{
513 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
514 int stat;
515
516 if (!i2c->is_regaddr) {
517 dev_dbg(hdmi->dev, "set read register address to 0\n");
518 i2c->slave_reg = 0x00;
519 i2c->is_regaddr = true;
520 }
521
522 while (length--) {
523 reinit_completion(x: &i2c->cmp);
524
525 dw_hdmi_qp_mod(hdmi, data: i2c->slave_reg++ << 12, I2CM_ADDR,
526 I2CM_INTERFACE_CONTROL0);
527
528 if (i2c->is_segment)
529 dw_hdmi_qp_mod(hdmi, I2CM_EXT_READ, I2CM_WR_MASK,
530 I2CM_INTERFACE_CONTROL0);
531 else
532 dw_hdmi_qp_mod(hdmi, I2CM_FM_READ, I2CM_WR_MASK,
533 I2CM_INTERFACE_CONTROL0);
534
535 stat = wait_for_completion_timeout(x: &i2c->cmp, HZ / 10);
536 if (!stat) {
537 dev_err(hdmi->dev, "i2c read timed out\n");
538 dw_hdmi_qp_write(hdmi, val: 0x01, I2CM_CONTROL0);
539 return -EAGAIN;
540 }
541
542 /* Check for error condition on the bus */
543 if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
544 dev_err(hdmi->dev, "i2c read error\n");
545 dw_hdmi_qp_write(hdmi, val: 0x01, I2CM_CONTROL0);
546 return -EIO;
547 }
548
549 *buf++ = dw_hdmi_qp_read(hdmi, I2CM_INTERFACE_RDDATA_0_3) & 0xff;
550 dw_hdmi_qp_mod(hdmi, data: 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
551 }
552
553 i2c->is_segment = false;
554
555 return 0;
556}
557
558static int dw_hdmi_qp_i2c_write(struct dw_hdmi_qp *hdmi,
559 unsigned char *buf, unsigned int length)
560{
561 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
562 int stat;
563
564 if (!i2c->is_regaddr) {
565 /* Use the first write byte as register address */
566 i2c->slave_reg = buf[0];
567 length--;
568 buf++;
569 i2c->is_regaddr = true;
570 }
571
572 while (length--) {
573 reinit_completion(x: &i2c->cmp);
574
575 dw_hdmi_qp_write(hdmi, val: *buf++, I2CM_INTERFACE_WRDATA_0_3);
576 dw_hdmi_qp_mod(hdmi, data: i2c->slave_reg++ << 12, I2CM_ADDR,
577 I2CM_INTERFACE_CONTROL0);
578 dw_hdmi_qp_mod(hdmi, I2CM_FM_WRITE, I2CM_WR_MASK,
579 I2CM_INTERFACE_CONTROL0);
580
581 stat = wait_for_completion_timeout(x: &i2c->cmp, HZ / 10);
582 if (!stat) {
583 dev_err(hdmi->dev, "i2c write time out!\n");
584 dw_hdmi_qp_write(hdmi, val: 0x01, I2CM_CONTROL0);
585 return -EAGAIN;
586 }
587
588 /* Check for error condition on the bus */
589 if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
590 dev_err(hdmi->dev, "i2c write nack!\n");
591 dw_hdmi_qp_write(hdmi, val: 0x01, I2CM_CONTROL0);
592 return -EIO;
593 }
594
595 dw_hdmi_qp_mod(hdmi, data: 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
596 }
597
598 return 0;
599}
600
601static int dw_hdmi_qp_i2c_xfer(struct i2c_adapter *adap,
602 struct i2c_msg *msgs, int num)
603{
604 struct dw_hdmi_qp *hdmi = i2c_get_adapdata(adap);
605 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
606 u8 addr = msgs[0].addr;
607 int i, ret = 0;
608
609 if (addr == DDC_CI_ADDR)
610 /*
611 * The internal I2C controller does not support the multi-byte
612 * read and write operations needed for DDC/CI.
613 * FIXME: Blacklist the DDC/CI address until we filter out
614 * unsupported I2C operations.
615 */
616 return -EOPNOTSUPP;
617
618 for (i = 0; i < num; i++) {
619 if (msgs[i].len == 0) {
620 dev_err(hdmi->dev,
621 "unsupported transfer %d/%d, no data\n",
622 i + 1, num);
623 return -EOPNOTSUPP;
624 }
625 }
626
627 guard(mutex)(T: &i2c->lock);
628
629 /* Unmute DONE and ERROR interrupts */
630 dw_hdmi_qp_mod(hdmi, I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
631 I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
632 MAINUNIT_1_INT_MASK_N);
633
634 /* Set slave device address taken from the first I2C message */
635 if (addr == DDC_SEGMENT_ADDR && msgs[0].len == 1)
636 addr = DDC_ADDR;
637
638 dw_hdmi_qp_mod(hdmi, data: addr << 5, I2CM_SLVADDR, I2CM_INTERFACE_CONTROL0);
639
640 /* Set slave device register address on transfer */
641 i2c->is_regaddr = false;
642
643 /* Set segment pointer for I2C extended read mode operation */
644 i2c->is_segment = false;
645
646 for (i = 0; i < num; i++) {
647 if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) {
648 i2c->is_segment = true;
649 dw_hdmi_qp_mod(hdmi, DDC_SEGMENT_ADDR, I2CM_SEG_ADDR,
650 I2CM_INTERFACE_CONTROL1);
651 dw_hdmi_qp_mod(hdmi, data: *msgs[i].buf << 7, I2CM_SEG_PTR,
652 I2CM_INTERFACE_CONTROL1);
653 } else {
654 if (msgs[i].flags & I2C_M_RD)
655 ret = dw_hdmi_qp_i2c_read(hdmi, buf: msgs[i].buf,
656 length: msgs[i].len);
657 else
658 ret = dw_hdmi_qp_i2c_write(hdmi, buf: msgs[i].buf,
659 length: msgs[i].len);
660 }
661 if (ret < 0)
662 break;
663 }
664
665 if (!ret)
666 ret = num;
667
668 /* Mute DONE and ERROR interrupts */
669 dw_hdmi_qp_mod(hdmi, data: 0, I2CM_OP_DONE_MASK_N | I2CM_NACK_RCVD_MASK_N,
670 MAINUNIT_1_INT_MASK_N);
671
672 return ret;
673}
674
675static u32 dw_hdmi_qp_i2c_func(struct i2c_adapter *adapter)
676{
677 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
678}
679
680static const struct i2c_algorithm dw_hdmi_qp_algorithm = {
681 .master_xfer = dw_hdmi_qp_i2c_xfer,
682 .functionality = dw_hdmi_qp_i2c_func,
683};
684
685static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi)
686{
687 struct dw_hdmi_qp_i2c *i2c;
688 struct i2c_adapter *adap;
689 int ret;
690
691 i2c = devm_kzalloc(dev: hdmi->dev, size: sizeof(*i2c), GFP_KERNEL);
692 if (!i2c)
693 return ERR_PTR(error: -ENOMEM);
694
695 mutex_init(&i2c->lock);
696 init_completion(x: &i2c->cmp);
697
698 adap = &i2c->adap;
699 adap->owner = THIS_MODULE;
700 adap->dev.parent = hdmi->dev;
701 adap->algo = &dw_hdmi_qp_algorithm;
702 strscpy(adap->name, "DesignWare HDMI QP", sizeof(adap->name));
703
704 i2c_set_adapdata(adap, data: hdmi);
705
706 ret = devm_i2c_add_adapter(dev: hdmi->dev, adapter: adap);
707 if (ret) {
708 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
709 devm_kfree(dev: hdmi->dev, p: i2c);
710 return ERR_PTR(error: ret);
711 }
712
713 hdmi->i2c = i2c;
714 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
715
716 return adap;
717}
718
719static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi,
720 const u8 *buffer, size_t len)
721{
722 u32 val, i, j;
723
724 if (len != HDMI_INFOFRAME_SIZE(AVI)) {
725 dev_err(hdmi->dev, "failed to configure avi infoframe\n");
726 return -EINVAL;
727 }
728
729 /*
730 * DW HDMI QP IP uses a different byte format from standard AVI info
731 * frames, though generally the bits are in the correct bytes.
732 */
733 val = buffer[1] << 8 | buffer[2] << 16;
734 dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0);
735
736 for (i = 0; i < 4; i++) {
737 for (j = 0; j < 4; j++) {
738 if (i * 4 + j >= 14)
739 break;
740 if (!j)
741 val = buffer[i * 4 + j + 3];
742 val |= buffer[i * 4 + j + 3] << (8 * j);
743 }
744
745 dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4);
746 }
747
748 dw_hdmi_qp_mod(hdmi, data: 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
749
750 dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
751 PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN);
752
753 return 0;
754}
755
756static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi,
757 const u8 *buffer, size_t len)
758{
759 u32 val, i;
760
761 if (len != HDMI_INFOFRAME_SIZE(DRM)) {
762 dev_err(hdmi->dev, "failed to configure drm infoframe\n");
763 return -EINVAL;
764 }
765
766 dw_hdmi_qp_mod(hdmi, data: 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN);
767
768 val = buffer[1] << 8 | buffer[2] << 16;
769 dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0);
770
771 for (i = 0; i <= buffer[2]; i++) {
772 if (i % 4 == 0)
773 val = buffer[3 + i];
774 val |= buffer[3 + i] << ((i % 4) * 8);
775
776 if ((i % 4 == 3) || i == buffer[2])
777 dw_hdmi_qp_write(hdmi, val,
778 PKT_DRMI_CONTENTS1 + ((i / 4) * 4));
779 }
780
781 dw_hdmi_qp_mod(hdmi, data: 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
782 dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN,
783 PKTSCHED_PKT_EN);
784
785 return 0;
786}
787
788/*
789 * Static values documented in the TRM
790 * Different values are only used for debug purposes
791 */
792#define DW_HDMI_QP_AUDIO_INFOFRAME_HB1 0x1
793#define DW_HDMI_QP_AUDIO_INFOFRAME_HB2 0xa
794
795static int dw_hdmi_qp_config_audio_infoframe(struct dw_hdmi_qp *hdmi,
796 const u8 *buffer, size_t len)
797{
798 /*
799 * AUDI_CONTENTS0: { RSV, HB2, HB1, RSV }
800 * AUDI_CONTENTS1: { PB3, PB2, PB1, PB0 }
801 * AUDI_CONTENTS2: { PB7, PB6, PB5, PB4 }
802 *
803 * PB0: CheckSum
804 * PB1: | CT3 | CT2 | CT1 | CT0 | F13 | CC2 | CC1 | CC0 |
805 * PB2: | F27 | F26 | F25 | SF2 | SF1 | SF0 | SS1 | SS0 |
806 * PB3: | F37 | F36 | F35 | F34 | F33 | F32 | F31 | F30 |
807 * PB4: | CA7 | CA6 | CA5 | CA4 | CA3 | CA2 | CA1 | CA0 |
808 * PB5: | DM_INH | LSV3 | LSV2 | LSV1 | LSV0 | F52 | F51 | F50 |
809 * PB6~PB10: Reserved
810 *
811 * AUDI_CONTENTS0 default value defined by HDMI specification,
812 * and shall only be changed for debug purposes.
813 */
814 u32 header_bytes = (DW_HDMI_QP_AUDIO_INFOFRAME_HB1 << 8) |
815 (DW_HDMI_QP_AUDIO_INFOFRAME_HB2 << 16);
816
817 regmap_bulk_write(map: hdmi->regm, PKT_AUDI_CONTENTS0, val: &header_bytes, val_count: 1);
818 regmap_bulk_write(map: hdmi->regm, PKT_AUDI_CONTENTS1, val: &buffer[3], val_count: 1);
819 regmap_bulk_write(map: hdmi->regm, PKT_AUDI_CONTENTS2, val: &buffer[4], val_count: 1);
820
821 /* Enable ACR, AUDI, AMD */
822 dw_hdmi_qp_mod(hdmi,
823 PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN,
824 PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN,
825 PKTSCHED_PKT_EN);
826
827 /* Enable AUDS */
828 dw_hdmi_qp_mod(hdmi, PKTSCHED_AUDS_TX_EN, PKTSCHED_AUDS_TX_EN, PKTSCHED_PKT_EN);
829
830 return 0;
831}
832
833static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
834 struct drm_atomic_state *state)
835{
836 struct dw_hdmi_qp *hdmi = bridge->driver_private;
837 struct drm_connector_state *conn_state;
838 struct drm_connector *connector;
839 unsigned int op_mode;
840
841 connector = drm_atomic_get_new_connector_for_encoder(state, encoder: bridge->encoder);
842 if (WARN_ON(!connector))
843 return;
844
845 conn_state = drm_atomic_get_new_connector_state(state, connector);
846 if (WARN_ON(!conn_state))
847 return;
848
849 if (connector->display_info.is_hdmi) {
850 dev_dbg(hdmi->dev, "%s mode=HDMI rate=%llu\n",
851 __func__, conn_state->hdmi.tmds_char_rate);
852 op_mode = 0;
853 hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
854 } else {
855 dev_dbg(hdmi->dev, "%s mode=DVI\n", __func__);
856 op_mode = OPMODE_DVI;
857 }
858
859 hdmi->phy.ops->init(hdmi, hdmi->phy.data);
860
861 dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0);
862 dw_hdmi_qp_mod(hdmi, data: op_mode, OPMODE_DVI, LINK_CONFIG0);
863
864 drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
865}
866
867static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
868 struct drm_atomic_state *state)
869{
870 struct dw_hdmi_qp *hdmi = bridge->driver_private;
871
872 hdmi->tmds_char_rate = 0;
873
874 hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
875}
876
877static enum drm_connector_status
878dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge)
879{
880 struct dw_hdmi_qp *hdmi = bridge->driver_private;
881
882 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
883}
884
885static const struct drm_edid *
886dw_hdmi_qp_bridge_edid_read(struct drm_bridge *bridge,
887 struct drm_connector *connector)
888{
889 struct dw_hdmi_qp *hdmi = bridge->driver_private;
890 const struct drm_edid *drm_edid;
891
892 drm_edid = drm_edid_read_ddc(connector, adapter: bridge->ddc);
893 if (!drm_edid)
894 dev_dbg(hdmi->dev, "failed to get edid\n");
895
896 return drm_edid;
897}
898
899static enum drm_mode_status
900dw_hdmi_qp_bridge_tmds_char_rate_valid(const struct drm_bridge *bridge,
901 const struct drm_display_mode *mode,
902 unsigned long long rate)
903{
904 struct dw_hdmi_qp *hdmi = bridge->driver_private;
905
906 if (rate > HDMI14_MAX_TMDSCLK) {
907 dev_dbg(hdmi->dev, "Unsupported TMDS char rate: %lld\n", rate);
908 return MODE_CLOCK_HIGH;
909 }
910
911 return MODE_OK;
912}
913
914static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge,
915 enum hdmi_infoframe_type type)
916{
917 struct dw_hdmi_qp *hdmi = bridge->driver_private;
918
919 switch (type) {
920 case HDMI_INFOFRAME_TYPE_AVI:
921 dw_hdmi_qp_mod(hdmi, data: 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
922 PKTSCHED_PKT_EN);
923 break;
924
925 case HDMI_INFOFRAME_TYPE_DRM:
926 dw_hdmi_qp_mod(hdmi, data: 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN);
927 break;
928
929 case HDMI_INFOFRAME_TYPE_AUDIO:
930 dw_hdmi_qp_mod(hdmi, data: 0,
931 PKTSCHED_ACR_TX_EN |
932 PKTSCHED_AUDS_TX_EN |
933 PKTSCHED_AUDI_TX_EN,
934 PKTSCHED_PKT_EN);
935 break;
936 default:
937 dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type);
938 }
939
940 return 0;
941}
942
943static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge,
944 enum hdmi_infoframe_type type,
945 const u8 *buffer, size_t len)
946{
947 struct dw_hdmi_qp *hdmi = bridge->driver_private;
948
949 dw_hdmi_qp_bridge_clear_infoframe(bridge, type);
950
951 switch (type) {
952 case HDMI_INFOFRAME_TYPE_AVI:
953 return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len);
954
955 case HDMI_INFOFRAME_TYPE_DRM:
956 return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len);
957
958 case HDMI_INFOFRAME_TYPE_AUDIO:
959 return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len);
960
961 default:
962 dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type);
963 return 0;
964 }
965}
966
967static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = {
968 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
969 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
970 .atomic_reset = drm_atomic_helper_bridge_reset,
971 .atomic_enable = dw_hdmi_qp_bridge_atomic_enable,
972 .atomic_disable = dw_hdmi_qp_bridge_atomic_disable,
973 .detect = dw_hdmi_qp_bridge_detect,
974 .edid_read = dw_hdmi_qp_bridge_edid_read,
975 .hdmi_tmds_char_rate_valid = dw_hdmi_qp_bridge_tmds_char_rate_valid,
976 .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe,
977 .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe,
978 .hdmi_audio_startup = dw_hdmi_qp_audio_enable,
979 .hdmi_audio_shutdown = dw_hdmi_qp_audio_disable,
980 .hdmi_audio_prepare = dw_hdmi_qp_audio_prepare,
981};
982
983static irqreturn_t dw_hdmi_qp_main_hardirq(int irq, void *dev_id)
984{
985 struct dw_hdmi_qp *hdmi = dev_id;
986 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
987 u32 stat;
988
989 stat = dw_hdmi_qp_read(hdmi, MAINUNIT_1_INT_STATUS);
990
991 i2c->stat = stat & (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ |
992 I2CM_NACK_RCVD_IRQ);
993
994 if (i2c->stat) {
995 dw_hdmi_qp_write(hdmi, val: i2c->stat, MAINUNIT_1_INT_CLEAR);
996 complete(&i2c->cmp);
997 }
998
999 if (stat)
1000 return IRQ_HANDLED;
1001
1002 return IRQ_NONE;
1003}
1004
1005static const struct regmap_config dw_hdmi_qp_regmap_config = {
1006 .reg_bits = 32,
1007 .val_bits = 32,
1008 .reg_stride = 4,
1009 .max_register = EARCRX_1_INT_FORCE,
1010};
1011
1012static void dw_hdmi_qp_init_hw(struct dw_hdmi_qp *hdmi)
1013{
1014 dw_hdmi_qp_write(hdmi, val: 0, MAINUNIT_0_INT_MASK_N);
1015 dw_hdmi_qp_write(hdmi, val: 0, MAINUNIT_1_INT_MASK_N);
1016 dw_hdmi_qp_write(hdmi, val: 428571429, TIMER_BASE_CONFIG0);
1017
1018 /* Software reset */
1019 dw_hdmi_qp_write(hdmi, val: 0x01, I2CM_CONTROL0);
1020
1021 dw_hdmi_qp_write(hdmi, val: 0x085c085c, I2CM_FM_SCL_CONFIG0);
1022
1023 dw_hdmi_qp_mod(hdmi, data: 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0);
1024
1025 /* Clear DONE and ERROR interrupts */
1026 dw_hdmi_qp_write(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR,
1027 MAINUNIT_1_INT_CLEAR);
1028
1029 if (hdmi->phy.ops->setup_hpd)
1030 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
1031}
1032
1033struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
1034 struct drm_encoder *encoder,
1035 const struct dw_hdmi_qp_plat_data *plat_data)
1036{
1037 struct device *dev = &pdev->dev;
1038 struct dw_hdmi_qp *hdmi;
1039 void __iomem *regs;
1040 int ret;
1041
1042 if (!plat_data->phy_ops || !plat_data->phy_ops->init ||
1043 !plat_data->phy_ops->disable || !plat_data->phy_ops->read_hpd) {
1044 dev_err(dev, "Missing platform PHY ops\n");
1045 return ERR_PTR(error: -ENODEV);
1046 }
1047
1048 hdmi = devm_kzalloc(dev, size: sizeof(*hdmi), GFP_KERNEL);
1049 if (!hdmi)
1050 return ERR_PTR(error: -ENOMEM);
1051
1052 hdmi->dev = dev;
1053
1054 regs = devm_platform_ioremap_resource(pdev, index: 0);
1055 if (IS_ERR(ptr: regs))
1056 return ERR_CAST(ptr: regs);
1057
1058 hdmi->regm = devm_regmap_init_mmio(dev, regs, &dw_hdmi_qp_regmap_config);
1059 if (IS_ERR(ptr: hdmi->regm)) {
1060 dev_err(dev, "Failed to configure regmap\n");
1061 return ERR_CAST(ptr: hdmi->regm);
1062 }
1063
1064 hdmi->phy.ops = plat_data->phy_ops;
1065 hdmi->phy.data = plat_data->phy_data;
1066
1067 dw_hdmi_qp_init_hw(hdmi);
1068
1069 ret = devm_request_threaded_irq(dev, irq: plat_data->main_irq,
1070 handler: dw_hdmi_qp_main_hardirq, NULL,
1071 IRQF_SHARED, devname: dev_name(dev), dev_id: hdmi);
1072 if (ret)
1073 return ERR_PTR(error: ret);
1074
1075 hdmi->bridge.driver_private = hdmi;
1076 hdmi->bridge.funcs = &dw_hdmi_qp_bridge_funcs;
1077 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT |
1078 DRM_BRIDGE_OP_EDID |
1079 DRM_BRIDGE_OP_HDMI |
1080 DRM_BRIDGE_OP_HDMI_AUDIO |
1081 DRM_BRIDGE_OP_HPD;
1082 hdmi->bridge.of_node = pdev->dev.of_node;
1083 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
1084 hdmi->bridge.vendor = "Synopsys";
1085 hdmi->bridge.product = "DW HDMI QP TX";
1086
1087 hdmi->bridge.ddc = dw_hdmi_qp_i2c_adapter(hdmi);
1088 if (IS_ERR(ptr: hdmi->bridge.ddc))
1089 return ERR_CAST(ptr: hdmi->bridge.ddc);
1090
1091 hdmi->bridge.hdmi_audio_max_i2s_playback_channels = 8;
1092 hdmi->bridge.hdmi_audio_dev = dev;
1093 hdmi->bridge.hdmi_audio_dai_port = 1;
1094
1095 ret = devm_drm_bridge_add(dev, bridge: &hdmi->bridge);
1096 if (ret)
1097 return ERR_PTR(error: ret);
1098
1099 ret = drm_bridge_attach(encoder, bridge: &hdmi->bridge, NULL,
1100 flags: DRM_BRIDGE_ATTACH_NO_CONNECTOR);
1101 if (ret)
1102 return ERR_PTR(error: ret);
1103
1104 return hdmi;
1105}
1106EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind);
1107
1108void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
1109{
1110 dw_hdmi_qp_init_hw(hdmi);
1111}
1112EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
1113
1114MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>");
1115MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>");
1116MODULE_DESCRIPTION("DW HDMI QP transmitter library");
1117MODULE_LICENSE("GPL");
1118

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of linux/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c