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