1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2024 Rockchip Electronics Co., Ltd
4 */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <i2c.h>
10 #include <video_bridge.h>
11 #include <linux/delay.h>
12 #include <linux/iopoll.h>
13 #include <linux/media-bus-format.h>
14 #include <linux/hdmi.h>
15
16 #include "rockchip_bridge.h"
17 #include "rockchip_display.h"
18 #include "rockchip_panel.h"
19
20 #define SII902X_TPI_VIDEO_DATA 0x0
21
22 #define SII902X_TPI_PIXEL_REPETITION 0x8
23 #define SII902X_TPI_AVI_PIXEL_REP_BUS_24BIT BIT(5)
24 #define SII902X_TPI_AVI_PIXEL_REP_RISING_EDGE BIT(4)
25 #define SII902X_TPI_AVI_PIXEL_REP_4X 3
26 #define SII902X_TPI_AVI_PIXEL_REP_2X 1
27 #define SII902X_TPI_AVI_PIXEL_REP_NONE 0
28 #define SII902X_TPI_CLK_RATIO_MASK GENMASK(7, 6)
29 #define SII902X_TPI_CLK_RATIO_HALF (0 << 6)
30 #define SII902X_TPI_CLK_RATIO_1X (1 << 6)
31 #define SII902X_TPI_CLK_RATIO_2X (2 << 6)
32 #define SII902X_TPI_CLK_RATIO_4X (3 << 6)
33
34 #define SII902X_TPI_AVI_IN_FORMAT 0x9
35 #define SII902X_TPI_AVI_INPUT_BITMODE_12BIT BIT(7)
36 #define SII902X_TPI_AVI_INPUT_DITHER BIT(6)
37 #define SII902X_TPI_AVI_INPUT_RANGE_LIMITED (2 << 2)
38 #define SII902X_TPI_AVI_INPUT_RANGE_FULL (1 << 2)
39 #define SII902X_TPI_AVI_INPUT_RANGE_AUTO (0 << 2)
40 #define SII902X_TPI_AVI_INPUT_COLORSPACE_BLACK (3 << 0)
41 #define SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422 (2 << 0)
42 #define SII902X_TPI_AVI_INPUT_COLORSPACE_YUV444 (1 << 0)
43 #define SII902X_TPI_AVI_INPUT_COLORSPACE_RGB (0 << 0)
44
45 #define SII902X_TPI_AVI_INFOFRAME 0x0c
46
47 #define SII902X_SYS_CTRL_DATA 0x1a
48 #define SII902X_SYS_CTRL_PWR_DWN BIT(4)
49 #define SII902X_SYS_CTRL_AV_MUTE BIT(3)
50 #define SII902X_SYS_CTRL_DDC_BUS_REQ BIT(2)
51 #define SII902X_SYS_CTRL_DDC_BUS_GRTD BIT(1)
52 #define SII902X_SYS_CTRL_OUTPUT_MODE BIT(0)
53 #define SII902X_SYS_CTRL_OUTPUT_HDMI 1
54 #define SII902X_SYS_CTRL_OUTPUT_DVI 0
55
56 #define SII902X_REG_CHIPID(n) (0x1b + (n))
57
58 #define SII902X_PWR_STATE_CTRL 0x1e
59 #define SII902X_AVI_POWER_STATE_MSK GENMASK(1, 0)
60 #define SII902X_AVI_POWER_STATE_D(l) ((l) & SII902X_AVI_POWER_STATE_MSK)
61
62 /* Audio */
63 #define SII902X_TPI_I2S_ENABLE_MAPPING_REG 0x1f
64 #define SII902X_TPI_I2S_CONFIG_FIFO0 (0 << 0)
65 #define SII902X_TPI_I2S_CONFIG_FIFO1 (1 << 0)
66 #define SII902X_TPI_I2S_CONFIG_FIFO2 (2 << 0)
67 #define SII902X_TPI_I2S_CONFIG_FIFO3 (3 << 0)
68 #define SII902X_TPI_I2S_LEFT_RIGHT_SWAP (1 << 2)
69 #define SII902X_TPI_I2S_AUTO_DOWNSAMPLE (1 << 3)
70 #define SII902X_TPI_I2S_SELECT_SD0 (0 << 4)
71 #define SII902X_TPI_I2S_SELECT_SD1 (1 << 4)
72 #define SII902X_TPI_I2S_SELECT_SD2 (2 << 4)
73 #define SII902X_TPI_I2S_SELECT_SD3 (3 << 4)
74 #define SII902X_TPI_I2S_FIFO_ENABLE (1 << 7)
75
76 #define SII902X_TPI_I2S_INPUT_CONFIG_REG 0x20
77 #define SII902X_TPI_I2S_FIRST_BIT_SHIFT_YES (0 << 0)
78 #define SII902X_TPI_I2S_FIRST_BIT_SHIFT_NO (1 << 0)
79 #define SII902X_TPI_I2S_SD_DIRECTION_MSB_FIRST (0 << 1)
80 #define SII902X_TPI_I2S_SD_DIRECTION_LSB_FIRST (1 << 1)
81 #define SII902X_TPI_I2S_SD_JUSTIFY_LEFT (0 << 2)
82 #define SII902X_TPI_I2S_SD_JUSTIFY_RIGHT (1 << 2)
83 #define SII902X_TPI_I2S_WS_POLARITY_LOW (0 << 3)
84 #define SII902X_TPI_I2S_WS_POLARITY_HIGH (1 << 3)
85 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_128 (0 << 4)
86 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_256 (1 << 4)
87 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_384 (2 << 4)
88 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_512 (3 << 4)
89 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_768 (4 << 4)
90 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_1024 (5 << 4)
91 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_1152 (6 << 4)
92 #define SII902X_TPI_I2S_MCLK_MULTIPLIER_192 (7 << 4)
93 #define SII902X_TPI_I2S_SCK_EDGE_FALLING (0 << 7)
94 #define SII902X_TPI_I2S_SCK_EDGE_RISING (1 << 7)
95
96 #define SII902X_TPI_I2S_STRM_HDR_BASE 0x21
97 #define SII902X_TPI_I2S_STRM_HDR_SIZE 5
98
99 #define SII902X_TPI_AUDIO_CONFIG_BYTE2_REG 0x26
100 #define SII902X_TPI_AUDIO_CODING_STREAM_HEADER (0 << 0)
101 #define SII902X_TPI_AUDIO_CODING_PCM (1 << 0)
102 #define SII902X_TPI_AUDIO_CODING_AC3 (2 << 0)
103 #define SII902X_TPI_AUDIO_CODING_MPEG1 (3 << 0)
104 #define SII902X_TPI_AUDIO_CODING_MP3 (4 << 0)
105 #define SII902X_TPI_AUDIO_CODING_MPEG2 (5 << 0)
106 #define SII902X_TPI_AUDIO_CODING_AAC (6 << 0)
107 #define SII902X_TPI_AUDIO_CODING_DTS (7 << 0)
108 #define SII902X_TPI_AUDIO_CODING_ATRAC (8 << 0)
109 #define SII902X_TPI_AUDIO_MUTE_DISABLE (0 << 4)
110 #define SII902X_TPI_AUDIO_MUTE_ENABLE (1 << 4)
111 #define SII902X_TPI_AUDIO_LAYOUT_2_CHANNELS (0 << 5)
112 #define SII902X_TPI_AUDIO_LAYOUT_8_CHANNELS (1 << 5)
113 #define SII902X_TPI_AUDIO_INTERFACE_DISABLE (0 << 6)
114 #define SII902X_TPI_AUDIO_INTERFACE_SPDIF (1 << 6)
115 #define SII902X_TPI_AUDIO_INTERFACE_I2S (2 << 6)
116
117 #define SII902X_TPI_AUDIO_CONFIG_BYTE3_REG 0x27
118 #define SII902X_TPI_AUDIO_FREQ_STREAM (0 << 3)
119 #define SII902X_TPI_AUDIO_FREQ_32KHZ (1 << 3)
120 #define SII902X_TPI_AUDIO_FREQ_44KHZ (2 << 3)
121 #define SII902X_TPI_AUDIO_FREQ_48KHZ (3 << 3)
122 #define SII902X_TPI_AUDIO_FREQ_88KHZ (4 << 3)
123 #define SII902X_TPI_AUDIO_FREQ_96KHZ (5 << 3)
124 #define SII902X_TPI_AUDIO_FREQ_176KHZ (6 << 3)
125 #define SII902X_TPI_AUDIO_FREQ_192KHZ (7 << 3)
126 #define SII902X_TPI_AUDIO_SAMPLE_SIZE_STREAM (0 << 6)
127 #define SII902X_TPI_AUDIO_SAMPLE_SIZE_16 (1 << 6)
128 #define SII902X_TPI_AUDIO_SAMPLE_SIZE_20 (2 << 6)
129 #define SII902X_TPI_AUDIO_SAMPLE_SIZE_24 (3 << 6)
130
131 #define SII902X_TPI_AUDIO_CONFIG_BYTE4_REG 0x28
132
133 #define SII902X_INT_ENABLE 0x3c
134 #define SII902X_INT_STATUS 0x3d
135 #define SII902X_HOTPLUG_EVENT BIT(0)
136 #define SII902X_PLUGGED_STATUS BIT(2)
137
138 #define SII902X_TPI_SYNC_GEN_CTRL 0x60
139 #define SII902X_TPI_SYNC_POLAR_DETECT 0x61
140 #define SII902X_TPI_HBIT_TO_HSYNC 0x62
141 #define SII902X_EMBEDDED_SYNC_EXTRACTION_REG 0x63
142 #define SII902X_EMBEDDED_SYNC_EXTRACTION BIT(6)
143
144 #define SII902X_REG_TPI_RQB 0xc7
145
146 /* Indirect internal register access */
147 #define SII902X_IND_SET_PAGE 0xbc
148 #define SII902X_IND_OFFSET 0xbd
149 #define SII902X_IND_VALUE 0xbe
150
151 #define SII902X_TPI_MISC_INFOFRAME_BASE 0xbf
152 #define SII902X_TPI_MISC_INFOFRAME_END 0xde
153 #define SII902X_TPI_MISC_INFOFRAME_SIZE \
154 (SII902X_TPI_MISC_INFOFRAME_END - SII902X_TPI_MISC_INFOFRAME_BASE)
155
156 #define SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS 500
157
158 #define SII902X_AUDIO_PORT_INDEX 3
159
160 struct sii902x {
161 struct udevice *dev;
162 struct udevice *power_supply;
163 struct gpio_desc enable_gpio;
164 struct gpio_desc reset_gpio;
165 struct rockchip_bridge *bridge;
166 struct drm_display_mode mode;
167 struct ddc_adapter adap;
168 struct hdmi_edid_data edid_data;
169 int bus_format;
170 };
171
172 enum sii902x_bus_format {
173 FORMAT_RGB_INPUT,
174 FORMAT_YCBCR422_INPUT,
175 FORMAT_YCBCR444_INPUT,
176 };
177
bridge_to_sii902x(struct rockchip_bridge * bridge)178 static inline struct sii902x *bridge_to_sii902x(struct rockchip_bridge *bridge)
179 {
180 return container_of(&bridge, struct sii902x, bridge);
181 }
182
sii902x_reg_update_bits(struct sii902x * sii902x,u8 reg,u8 mask,u8 val)183 static int sii902x_reg_update_bits(struct sii902x *sii902x, u8 reg, u8 mask, u8 val)
184 {
185 u8 status;
186
187 status = dm_i2c_reg_read(sii902x->dev, reg);
188 status &= ~mask;
189 status |= val & mask;
190
191 return dm_i2c_reg_write(sii902x->dev, reg, status);
192 }
193
sii902x_bridge_detect(struct rockchip_bridge * bridge)194 static bool sii902x_bridge_detect(struct rockchip_bridge *bridge)
195 {
196 struct udevice *dev = bridge->dev;
197 u8 status;
198
199 status = dm_i2c_reg_read(dev, SII902X_INT_STATUS);
200
201 return (status & SII902X_PLUGGED_STATUS) ? true : false;
202 }
203
sii902x_check_embedded_format(uint32_t bus_format)204 static bool sii902x_check_embedded_format(uint32_t bus_format)
205 {
206 switch (bus_format) {
207 case MEDIA_BUS_FMT_YUYV8_2X8:
208 case MEDIA_BUS_FMT_YVYU8_2X8:
209 case MEDIA_BUS_FMT_UYVY8_2X8:
210 case MEDIA_BUS_FMT_VYUY8_2X8:
211 case MEDIA_BUS_FMT_YUYV8_1X16:
212 case MEDIA_BUS_FMT_YVYU8_1X16:
213 case MEDIA_BUS_FMT_UYVY8_1X16:
214 case MEDIA_BUS_FMT_VYUY8_1X16:
215 return true;
216 default:
217 return false;
218 }
219 }
220
sii902x_set_embedded_sync(struct sii902x * sii902x)221 static void sii902x_set_embedded_sync(struct sii902x *sii902x)
222 {
223 struct udevice *dev = sii902x->dev;
224 unsigned char data[8];
225 struct videomode vm;
226
227 if (!sii902x_check_embedded_format(sii902x->bus_format))
228 return;
229
230 switch (sii902x->bus_format) {
231 case MEDIA_BUS_FMT_YUYV8_2X8:
232 case MEDIA_BUS_FMT_YVYU8_2X8:
233 case MEDIA_BUS_FMT_UYVY8_2X8:
234 case MEDIA_BUS_FMT_VYUY8_2X8:
235 sii902x_reg_update_bits(sii902x, SII902X_TPI_SYNC_GEN_CTRL, 0x20, 0x20);
236 break;
237 default:
238 break;
239 }
240
241 sii902x_reg_update_bits(sii902x, SII902X_TPI_SYNC_GEN_CTRL, 0x80, 0x00);
242 dm_i2c_reg_write(dev, SII902X_EMBEDDED_SYNC_EXTRACTION_REG, 0x00);
243 sii902x_reg_update_bits(sii902x, SII902X_TPI_SYNC_GEN_CTRL, 0x80, 0x80);
244
245 drm_display_mode_to_videomode(&sii902x->mode, &vm);
246 data[0] = vm.hfront_porch & 0xff;
247 data[1] = (vm.hfront_porch >> 8) & 0x03;
248 if (sii902x->mode.flags & DRM_MODE_FLAG_INTERLACE) {
249 data[2] = (sii902x->mode.vtotal >> 1) & 0xff;
250 data[3] = ((sii902x->mode.vtotal >> 1) >> 8) & 0x1f;
251 } else {
252 data[2] = 0;
253 data[3] = 0;
254 }
255 data[4] = vm.hsync_len & 0xff;
256 data[5] = (vm.hsync_len >> 8) & 0x03;
257 data[6] = vm.vfront_porch;
258 data[7] = vm.vsync_len;
259 dm_i2c_write(dev, SII902X_TPI_HBIT_TO_HSYNC, data, 8);
260
261 sii902x_reg_update_bits(sii902x, SII902X_TPI_SYNC_GEN_CTRL, 0x80, 0x80);
262 sii902x_reg_update_bits(sii902x, SII902X_EMBEDDED_SYNC_EXTRACTION_REG, 0x40, 0x40);
263
264 sii902x_reg_update_bits(sii902x, SII902X_EMBEDDED_SYNC_EXTRACTION_REG,
265 SII902X_EMBEDDED_SYNC_EXTRACTION,
266 SII902X_EMBEDDED_SYNC_EXTRACTION);
267 }
268
sii902x_set_format(struct sii902x * sii902x)269 static void sii902x_set_format(struct sii902x *sii902x)
270 {
271 struct udevice *dev = sii902x->dev;
272 u8 val;
273
274 switch (sii902x->bus_format) {
275 case MEDIA_BUS_FMT_YUYV8_1X16:
276 case MEDIA_BUS_FMT_YVYU8_1X16:
277 case MEDIA_BUS_FMT_UYVY8_1X16:
278 case MEDIA_BUS_FMT_VYUY8_1X16:
279 case MEDIA_BUS_FMT_YUYV8_2X8:
280 case MEDIA_BUS_FMT_YVYU8_2X8:
281 case MEDIA_BUS_FMT_UYVY8_2X8:
282 case MEDIA_BUS_FMT_VYUY8_2X8:
283 val = SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422;
284 break;
285 case MEDIA_BUS_FMT_YUV8_1X24:
286 case MEDIA_BUS_FMT_VUY8_1X24:
287 val = SII902X_TPI_AVI_INPUT_COLORSPACE_YUV444;
288 break;
289 case MEDIA_BUS_FMT_RGB888_1X24:
290 default:
291 val = SII902X_TPI_AVI_INPUT_COLORSPACE_RGB;
292 break;
293 }
294
295 val |= SII902X_TPI_AVI_INPUT_RANGE_AUTO;
296 val &= ~(SII902X_TPI_AVI_INPUT_DITHER |
297 SII902X_TPI_AVI_INPUT_BITMODE_12BIT);
298 dm_i2c_reg_write(dev, SII902X_TPI_AVI_IN_FORMAT, val);
299
300 sii902x_set_embedded_sync(sii902x);
301 }
302
sii902x_set_connector_display_info(struct sii902x * sii902x,struct connector_state * conn_state)303 static void sii902x_set_connector_display_info(struct sii902x *sii902x,
304 struct connector_state *conn_state)
305 {
306 conn_state->bus_format = sii902x->bus_format;
307 switch (conn_state->bus_format) {
308 case MEDIA_BUS_FMT_YUYV8_2X8:
309 case MEDIA_BUS_FMT_YVYU8_2X8:
310 case MEDIA_BUS_FMT_UYVY8_2X8:
311 case MEDIA_BUS_FMT_VYUY8_2X8:
312 conn_state->output_mode = ROCKCHIP_OUT_MODE_BT656;
313 conn_state->output_if = VOP_OUTPUT_IF_BT656;
314 conn_state->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
315 conn_state->color_encoding = DRM_COLOR_YCBCR_BT601;
316 break;
317 case MEDIA_BUS_FMT_YUYV8_1X16:
318 case MEDIA_BUS_FMT_YVYU8_1X16:
319 case MEDIA_BUS_FMT_UYVY8_1X16:
320 case MEDIA_BUS_FMT_VYUY8_1X16:
321 conn_state->output_mode = ROCKCHIP_OUT_MODE_BT1120;
322 conn_state->output_if = VOP_OUTPUT_IF_BT1120;
323 conn_state->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
324 conn_state->color_encoding = DRM_COLOR_YCBCR_BT709;
325 break;
326 case MEDIA_BUS_FMT_RGB888_1X24:
327 default:
328 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
329 conn_state->output_if = VOP_OUTPUT_IF_RGB;
330 conn_state->color_range = DRM_COLOR_YCBCR_FULL_RANGE;
331 conn_state->color_encoding = DRM_COLOR_YCBCR_BT709;
332 break;
333 }
334 }
335
sii902x_bridge_mode_set(struct rockchip_bridge * bridge,const struct drm_display_mode * mode)336 static void sii902x_bridge_mode_set(struct rockchip_bridge *bridge,
337 const struct drm_display_mode *mode)
338 {
339 struct sii902x *sii902x = dev_get_priv(bridge->dev);
340 struct connector_state *conn_state = &bridge->state->conn_state;
341 struct edid *edid = (struct edid *)conn_state->edid;
342 struct udevice *dev = sii902x->dev;
343 struct hdmi_avi_infoframe frame;
344 u8 buf[HDMI_INFOFRAME_SIZE(AVI)];
345 u8 output_mode;
346 u16 pixel_clock_10kHz = mode->clock / 10;
347 u8 ratio;
348 int ret, vrefresh;
349
350 if (drm_detect_hdmi_monitor(edid))
351 output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
352 else
353 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
354
355 sii902x_reg_update_bits(sii902x, SII902X_SYS_CTRL_DATA,
356 SII902X_SYS_CTRL_OUTPUT_MODE,
357 output_mode);
358
359 drm_mode_copy(&sii902x->mode, mode);
360 vrefresh = drm_mode_vrefresh(mode) * 100;
361 buf[0] = pixel_clock_10kHz & 0xff;
362 buf[1] = pixel_clock_10kHz >> 8;
363 buf[2] = vrefresh & 0xff;
364 buf[3] = vrefresh >> 8;
365 buf[4] = mode->crtc_htotal;
366 buf[5] = mode->crtc_htotal >> 8;
367 buf[6] = mode->crtc_vtotal;
368 buf[7] = mode->crtc_vtotal >> 8;
369 buf[8] = SII902X_TPI_AVI_PIXEL_REP_NONE | SII902X_TPI_AVI_PIXEL_REP_BUS_24BIT;
370 switch (sii902x->bus_format) {
371 case MEDIA_BUS_FMT_YUYV8_1X16:
372 case MEDIA_BUS_FMT_YVYU8_1X16:
373 case MEDIA_BUS_FMT_UYVY8_1X16:
374 case MEDIA_BUS_FMT_VYUY8_1X16:
375 case MEDIA_BUS_FMT_YUYV8_2X8:
376 case MEDIA_BUS_FMT_YVYU8_2X8:
377 case MEDIA_BUS_FMT_UYVY8_2X8:
378 case MEDIA_BUS_FMT_VYUY8_2X8:
379 buf[8] |= SII902X_TPI_AVI_PIXEL_REP_RISING_EDGE;
380 break;
381 default:
382 break;
383 }
384
385 buf[9] = SII902X_TPI_AVI_INPUT_RANGE_AUTO;
386 switch (sii902x->bus_format) {
387 case MEDIA_BUS_FMT_YUYV8_1X16:
388 case MEDIA_BUS_FMT_YVYU8_1X16:
389 case MEDIA_BUS_FMT_UYVY8_1X16:
390 case MEDIA_BUS_FMT_VYUY8_1X16:
391 case MEDIA_BUS_FMT_YUYV8_2X8:
392 case MEDIA_BUS_FMT_YVYU8_2X8:
393 case MEDIA_BUS_FMT_UYVY8_2X8:
394 case MEDIA_BUS_FMT_VYUY8_2X8:
395 buf[9] |= SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422;
396 break;
397 case MEDIA_BUS_FMT_YUV8_1X24:
398 case MEDIA_BUS_FMT_VUY8_1X24:
399 buf[9] |= SII902X_TPI_AVI_INPUT_COLORSPACE_YUV444;
400 break;
401 case MEDIA_BUS_FMT_RGB888_1X24:
402 default:
403 buf[9] |= SII902X_TPI_AVI_INPUT_COLORSPACE_RGB;
404 break;
405 }
406
407 ret = dm_i2c_write(dev, SII902X_TPI_VIDEO_DATA, buf, 10);
408 if (ret) {
409 dev_err(dev, "failed to set video data\n");
410 return;
411 }
412
413 if (sii902x->mode.flags & DRM_MODE_FLAG_DBLCLK)
414 ratio = SII902X_TPI_CLK_RATIO_2X;
415 else
416 ratio = SII902X_TPI_CLK_RATIO_1X;
417 sii902x_reg_update_bits(sii902x, SII902X_TPI_PIXEL_REPETITION,
418 SII902X_TPI_CLK_RATIO_MASK, ratio);
419
420 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, &sii902x->mode, false);
421 if (ret < 0) {
422 dev_err(dev, "couldn't fill AVI infoframe\n");
423 return;
424 }
425
426 ret = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf));
427 if (ret < 0) {
428 dev_err(dev, "failed to pack AVI infoframe: %d\n", ret);
429 return;
430 }
431
432 /* Do not send the infoframe header, but keep the CRC field. */
433 dm_i2c_write(dev, SII902X_TPI_AVI_INFOFRAME,
434 buf + HDMI_INFOFRAME_HEADER_SIZE - 1,
435 HDMI_AVI_INFOFRAME_SIZE + 1);
436 sii902x_set_format(sii902x);
437 sii902x_set_connector_display_info(sii902x, conn_state);
438 }
439
sii902x_bridge_enable(struct rockchip_bridge * bridge)440 static void sii902x_bridge_enable(struct rockchip_bridge *bridge)
441 {
442 struct sii902x *sii902x = dev_get_priv(bridge->dev);
443
444 sii902x_reg_update_bits(sii902x, SII902X_PWR_STATE_CTRL,
445 SII902X_AVI_POWER_STATE_MSK,
446 SII902X_AVI_POWER_STATE_D(0));
447 sii902x_reg_update_bits(sii902x, SII902X_SYS_CTRL_DATA, SII902X_SYS_CTRL_PWR_DWN, 0);
448 }
449
sii902x_bridge_disable(struct rockchip_bridge * bridge)450 static void sii902x_bridge_disable(struct rockchip_bridge *bridge)
451 {
452 struct sii902x *sii902x = dev_get_priv(bridge->dev);
453
454 sii902x_reg_update_bits(sii902x, SII902X_SYS_CTRL_DATA,
455 SII902X_SYS_CTRL_PWR_DWN,
456 SII902X_SYS_CTRL_PWR_DWN);
457 }
458
459 static const struct rockchip_bridge_funcs sii902x_bridge_funcs = {
460 .detect = sii902x_bridge_detect,
461 .mode_set = sii902x_bridge_mode_set,
462 .enable = sii902x_bridge_enable,
463 .post_disable = sii902x_bridge_disable,
464 };
465
sii902x_reset(struct sii902x * sii902x)466 static void sii902x_reset(struct sii902x *sii902x)
467 {
468 if (!dm_gpio_is_valid(&sii902x->reset_gpio))
469 return;
470
471 dm_gpio_set_value(&sii902x->reset_gpio, 1);
472
473 /* The datasheet says treset-min = 100us. Make it 150us to be sure. */
474 udelay(500);
475
476 dm_gpio_set_value(&sii902x->reset_gpio, 0);
477 }
478
479 #define SII902X_READ_REG(v) dm_i2c_reg_read(sii902x->dev, v)
480
481 /*
482 * The purpose of sii902x_i2c_bypass_select is to enable the pass through
483 * mode of the HDMI transmitter. Do not use regmap from within this function,
484 * only use sii902x_*_unlocked functions to read/modify/write registers.
485 * We are holding the parent adapter lock here, keep this in mind before
486 * adding more i2c transactions.
487 *
488 * Also, since SII902X_SYS_CTRL_DATA is used with regmap_update_bits elsewhere
489 * in this driver, we need to make sure that we only touch 0x1A[2:1] from
490 * within sii902x_i2c_bypass_select and sii902x_i2c_bypass_deselect, and that
491 * we leave the remaining bits as we have found them.
492 */
sii902x_i2c_bypass_select(struct sii902x * sii902x)493 static int sii902x_i2c_bypass_select(struct sii902x *sii902x)
494 {
495 struct udevice *dev = sii902x->dev;
496 u8 status;
497 int ret;
498
499 sii902x_reg_update_bits(sii902x, SII902X_SYS_CTRL_DATA,
500 SII902X_SYS_CTRL_DDC_BUS_REQ,
501 SII902X_SYS_CTRL_DDC_BUS_REQ);
502
503 ret = readx_poll_timeout(SII902X_READ_REG, SII902X_SYS_CTRL_DATA, status,
504 status & SII902X_SYS_CTRL_DDC_BUS_GRTD,
505 SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS * 1000);
506 if (ret) {
507 dev_err(dev, "Failed to acquire the i2c bus\n");
508 return -ETIMEDOUT;
509 }
510
511 dm_i2c_reg_write(dev, SII902X_SYS_CTRL_DATA, status);
512
513 return 0;
514 }
515
516 /*
517 * The purpose of sii902x_i2c_bypass_deselect is to disable the pass through
518 * mode of the HDMI transmitter. Do not use regmap from within this function,
519 * only use sii902x_*_unlocked functions to read/modify/write registers.
520 * We are holding the parent adapter lock here, keep this in mind before
521 * adding more i2c transactions.
522 *
523 * Also, since SII902X_SYS_CTRL_DATA is used with regmap_update_bits elsewhere
524 * in this driver, we need to make sure that we only touch 0x1A[2:1] from
525 * within sii902x_i2c_bypass_select and sii902x_i2c_bypass_deselect, and that
526 * we leave the remaining bits as we have found them.
527 */
sii902x_i2c_bypass_deselect(struct sii902x * sii902x)528 static int sii902x_i2c_bypass_deselect(struct sii902x *sii902x)
529 {
530 struct udevice *dev = sii902x->dev;
531 unsigned int retries;
532 u8 status;
533 int ret;
534
535 /*
536 * When the HDMI transmitter is in pass through mode, we need an
537 * (undocumented) additional delay between STOP and START conditions
538 * to guarantee the bus won't get stuck.
539 */
540 udelay(30);
541
542 /*
543 * Sometimes the I2C bus can stall after failure to use the
544 * EDID channel. Retry a few times to see if things clear
545 * up, else continue anyway.
546 */
547 retries = 5;
548 do {
549 status = dm_i2c_reg_read(dev, SII902X_SYS_CTRL_DATA);
550 retries--;
551 } while (status < 0 && retries);
552 if (status < 0) {
553 dev_err(dev, "failed to read status (%d)\n", status);
554 return status;
555 }
556
557 ret = sii902x_reg_update_bits(sii902x, SII902X_SYS_CTRL_DATA,
558 SII902X_SYS_CTRL_DDC_BUS_REQ |
559 SII902X_SYS_CTRL_DDC_BUS_GRTD, 0);
560 if (ret)
561 return ret;
562
563 ret = readx_poll_timeout(SII902X_READ_REG, SII902X_SYS_CTRL_DATA, status,
564 !(status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
565 SII902X_SYS_CTRL_DDC_BUS_GRTD)),
566 SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS * 1000);
567 if (ret) {
568 dev_err(dev, "failed to release the i2c bus\n");
569 return -ETIMEDOUT;
570 }
571
572 return 0;
573 }
574
sii902x_i2c_xfer(struct ddc_adapter * adap,struct i2c_msg * msgs,int num)575 static int sii902x_i2c_xfer(struct ddc_adapter *adap, struct i2c_msg *msgs, int num)
576 {
577 struct sii902x *sii902x = container_of(adap, struct sii902x, adap);
578 struct udevice *dev = sii902x->dev;
579 u8 addr = msgs[0].addr;
580 int i;
581 int ret;
582
583 ret = sii902x_i2c_bypass_select(sii902x);
584 if (ret)
585 return -EINVAL;
586
587 debug("i2c xfer: num: %d, addr: %#x\n", num, addr);
588
589 for (i = 0; i < num; i++) {
590 debug("xfer: num: %d/%d, len: %d, flags: %#x\n",
591 i + 1, num, msgs[i].len, msgs[i].flags);
592
593 ret = dm_i2c_xfer(dev, msgs, num);
594 if (ret < 0)
595 break;
596 }
597
598 ret = sii902x_i2c_bypass_deselect(sii902x);
599 if (ret)
600 return -EINVAL;
601
602 if (!ret)
603 ret = num;
604
605 return ret;
606 }
607
sii902x_init(struct sii902x * sii902x)608 static int sii902x_init(struct sii902x *sii902x)
609 {
610 struct udevice *dev = sii902x->dev;
611 u8 chipid[4];
612 u8 status;
613 int ret;
614
615 sii902x_reset(sii902x);
616
617 ret = dm_i2c_reg_write(dev, SII902X_REG_TPI_RQB, 0x0);
618 if (ret) {
619 dev_err(dev, "enable TPI mode failed %d\n", ret);
620 return ret;
621 }
622
623 ret = dm_i2c_read(dev, SII902X_REG_CHIPID(0), chipid, 4);
624 if (ret) {
625 dev_err(dev, "regmap_read failed %d\n", ret);
626 return ret;
627 }
628
629 if (chipid[0] != 0xb0) {
630 dev_err(dev, "Invalid chipid: %02x (expecting 0xb0)\n",
631 chipid[0]);
632 return -EINVAL;
633 }
634
635 /* Clear all pending interrupts */
636 status = dm_i2c_reg_read(dev, SII902X_INT_STATUS);
637 dm_i2c_reg_write(dev, SII902X_INT_STATUS, status);
638
639 sii902x->adap.i2c_bus = dev->parent;
640 sii902x->adap.ddc_xfer = sii902x_i2c_xfer;
641
642 sii902x->edid_data.mode_buf = malloc(MODE_LEN * sizeof(struct drm_display_mode));
643 if (!sii902x->edid_data.mode_buf) {
644 dev_err(dev, "failed to malloc mode buffer for edid\n");
645 return -ENOMEM;
646 }
647
648 return 0;
649 }
650
sii902x_probe(struct udevice * dev)651 static int sii902x_probe(struct udevice *dev)
652 {
653 struct sii902x *sii902x = dev_get_priv(dev);
654 struct rockchip_bridge *bridge = (struct rockchip_bridge *)dev_get_driver_data(dev);
655 int val;
656 int ret;
657
658 sii902x->dev = dev;
659 sii902x->bridge = bridge;
660 bridge->dev = dev;
661
662 ret = gpio_request_by_name(dev, "reset-gpio", 0,
663 &sii902x->reset_gpio, GPIOD_IS_OUT);
664 if (ret && ret != -ENOENT) {
665 dev_err(dev, "Cannot get reset GPIO: %d\n", ret);
666 return ret;
667 }
668
669 ret = gpio_request_by_name(dev, "enable-gpio", 0,
670 &sii902x->enable_gpio, GPIOD_IS_OUT);
671 if (ret && ret != -ENOENT) {
672 dev_err(dev, "Cannot get enable GPIO: %d\n", ret);
673 return ret;
674 } else {
675 dm_gpio_set_value(&sii902x->enable_gpio, 1);
676 udelay(2000);
677 }
678
679 val = ofnode_read_u32_default(dev->node, "bus-format", -1);
680 if (val < 0) {
681 sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
682 } else {
683 switch (val) {
684 case FORMAT_RGB_INPUT:
685 sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
686 break;
687 case FORMAT_YCBCR422_INPUT:
688 sii902x->bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
689 break;
690 case FORMAT_YCBCR444_INPUT:
691 sii902x->bus_format = MEDIA_BUS_FMT_YUV8_1X24;
692 break;
693 default:
694 sii902x->bus_format = val;
695 break;
696 }
697 }
698 bridge->bus_format = sii902x->bus_format;
699
700 ret = sii902x_init(sii902x);
701 if (ret < 0) {
702 dev_err(dev, "Failed to init sii902x %d\n", ret);
703 return ret;
704 }
705
706 printf("sii902x init successfully\n");
707
708 return 0;
709 }
710
711 static struct rockchip_bridge sii902x_driver_data = {
712 .funcs = &sii902x_bridge_funcs,
713 };
714
715 static const struct udevice_id sii902x_of_match[] = {
716 {
717 .compatible = "sil,sii9022",
718 .data = (ulong)&sii902x_driver_data,
719 },
720 {}
721 };
722
sii902x_get_timing(struct udevice * dev)723 static int sii902x_get_timing(struct udevice *dev)
724 {
725 struct sii902x *sii902x = dev_get_priv(dev);
726 struct rockchip_bridge *bridge = sii902x->bridge;
727 struct display_state *state = bridge->state;
728 struct connector_state *conn_state = &state->conn_state;
729 struct drm_display_mode *mode = &conn_state->mode;
730 int ret = 0;
731
732 conn_state->edid = drm_do_get_edid(&sii902x->adap);
733 if (conn_state->edid)
734 ret = drm_add_edid_modes(&sii902x->edid_data, conn_state->edid);
735
736 if (ret <= 0) {
737 dev_err(dev, "Failed to get edid %d\n", ret);
738 return ret;
739 }
740
741 drm_mode_max_resolution_filter(&sii902x->edid_data, &state->crtc_state.max_output);
742 if (!drm_mode_prune_invalid(&sii902x->edid_data)) {
743 dev_err(dev, "Failed to find valid display mode\n");
744 return -EINVAL;
745 }
746
747 drm_mode_sort(&sii902x->edid_data);
748 *mode = *sii902x->edid_data.preferred_mode;
749
750 return 0;
751 }
752
753 struct video_bridge_ops sii902x_ops = {
754 .get_timing = sii902x_get_timing,
755 };
756
757 U_BOOT_DRIVER(sii902x) = {
758 .name = "sii902x",
759 .id = UCLASS_VIDEO_BRIDGE,
760 .of_match = sii902x_of_match,
761 .probe = sii902x_probe,
762 .priv_auto_alloc_size = sizeof(struct sii902x),
763 .ops = &sii902x_ops,
764 };
765