1 /* 2 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm/of_access.h> 9 #include <errno.h> 10 #include <syscon.h> 11 #include <regmap.h> 12 #include <dm/device.h> 13 #include <dm/read.h> 14 #include <dm/pinctrl.h> 15 #include <linux/media-bus-format.h> 16 #include <asm/gpio.h> 17 #include <backlight.h> 18 19 #include "rockchip_display.h" 20 #include "rockchip_crtc.h" 21 #include "rockchip_connector.h" 22 #include "rockchip_phy.h" 23 #include "rockchip_panel.h" 24 25 #define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK(h, l) << 16)) 26 27 #define PX30_GRF_PD_VO_CON1 0x0438 28 #define PX30_RGB_DATA_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3) 29 #define PX30_RGB_VOP_SEL(v) HIWORD_UPDATE(v, 2, 2) 30 31 #define RK1808_GRF_PD_VO_CON1 0x0444 32 #define RK1808_RGB_DATA_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3) 33 34 #define RV1106_VENC_GRF_VOP_IO_WRAPPER 0x1000c 35 #define RV1106_IO_BYPASS_SEL(v) HIWORD_UPDATE(v, 0, 1) 36 #define RV1106_VOGRF_VOP_PIPE_BYPASS 0x60034 37 #define RV1106_VOP_PIPE_BYPASS(v) HIWORD_UPDATE(v, 0, 1) 38 39 #define RV1126_GRF_IOFUNC_CON3 0x1026c 40 #define RV1126_LCDC_IO_BYPASS(v) HIWORD_UPDATE(v, 0, 0) 41 42 #define RK3288_GRF_SOC_CON6 0x025c 43 #define RK3288_LVDS_LCDC_SEL(v) HIWORD_UPDATE(v, 3, 3) 44 #define RK3288_GRF_SOC_CON7 0x0260 45 #define RK3288_LVDS_PWRDWN(v) HIWORD_UPDATE(v, 15, 15) 46 #define RK3288_LVDS_CON_ENABLE_2(v) HIWORD_UPDATE(v, 12, 12) 47 #define RK3288_LVDS_CON_ENABLE_1(v) HIWORD_UPDATE(v, 11, 11) 48 #define RK3288_LVDS_CON_CLKINV(v) HIWORD_UPDATE(v, 8, 8) 49 #define RK3288_LVDS_CON_TTL_EN(v) HIWORD_UPDATE(v, 6, 6) 50 51 #define RK3368_GRF_SOC_CON15 0x043c 52 #define RK3368_FORCE_JETAG(v) HIWORD_UPDATE(v, 13, 13) 53 54 #define RK3562_GRF_IOC_VO_IO_CON 0x10500 55 #define RK3562_RGB_DATA_BYPASS(v) HIWORD_UPDATE(v, 6, 6) 56 57 #define RK3568_GRF_VO_CON1 0X0364 58 #define RK3568_RGB_DATA_BYPASS(v) HIWORD_UPDATE(v, 6, 6) 59 60 #define RK3576_VCCIO_IOC_MISC_CON8 0x6420 61 #define RK3576_VOP_MCU_SEL(v) HIWORD_UPDATE(v, 10, 10) 62 63 struct rockchip_rgb; 64 65 struct rockchip_rgb_funcs { 66 void (*prepare)(struct rockchip_rgb *rgb, int pipe); 67 void (*unprepare)(struct rockchip_rgb *rgb); 68 }; 69 70 struct rockchip_rgb { 71 struct rockchip_connector connector; 72 int id; 73 struct udevice *dev; 74 struct regmap *grf; 75 bool data_sync_bypass; 76 struct rockchip_phy *phy; 77 const struct rockchip_rgb_funcs *funcs; 78 }; 79 80 struct mcu_cmd_header { 81 u8 data_type; 82 u8 delay; 83 u8 payload_length; 84 } __packed; 85 86 struct mcu_cmd_desc { 87 struct mcu_cmd_header header; 88 const u8 *payload; 89 }; 90 91 struct mcu_cmd_seq { 92 struct mcu_cmd_desc *cmds; 93 unsigned int cmd_cnt; 94 }; 95 96 struct rockchip_mcu_panel_desc { 97 struct mcu_cmd_seq *init_seq; 98 struct mcu_cmd_seq *exit_seq; 99 100 struct { 101 unsigned int width; 102 unsigned int height; 103 } size; 104 105 struct { 106 unsigned int prepare; 107 unsigned int enable; 108 unsigned int disable; 109 unsigned int unprepare; 110 unsigned int reset; 111 unsigned int init; 112 } delay; 113 114 unsigned int bpc; 115 u32 bus_format; 116 u32 bus_flags; 117 bool power_invert; 118 }; 119 120 struct rockchip_mcu_panel { 121 struct rockchip_panel base; 122 struct rockchip_mcu_panel_desc *desc; 123 struct udevice *power_supply; 124 struct udevice *backlight; 125 126 struct gpio_desc enable_gpio; 127 struct gpio_desc reset_gpio; 128 129 bool prepared; 130 bool enabled; 131 }; 132 133 static inline struct rockchip_mcu_panel *to_rockchip_mcu_panel(struct rockchip_panel *panel) 134 { 135 return container_of(panel, struct rockchip_mcu_panel, base); 136 } 137 138 static int rockchip_rgb_connector_prepare(struct rockchip_connector *conn, 139 struct display_state *state) 140 { 141 struct rockchip_rgb *rgb = dev_get_priv(conn->dev); 142 struct crtc_state *crtc_state = &state->crtc_state; 143 int pipe = crtc_state->crtc_id; 144 int ret; 145 146 pinctrl_select_state(rgb->dev, "default"); 147 148 if (rgb->funcs && rgb->funcs->prepare) 149 rgb->funcs->prepare(rgb, pipe); 150 151 if (rgb->phy) { 152 ret = rockchip_phy_set_mode(rgb->phy, PHY_MODE_VIDEO_TTL); 153 if (ret) { 154 dev_err(rgb->dev, "failed to set phy mode: %d\n", ret); 155 return ret; 156 } 157 158 rockchip_phy_power_on(rgb->phy); 159 } 160 161 return 0; 162 } 163 164 static void rockchip_rgb_connector_unprepare(struct rockchip_connector *conn, 165 struct display_state *state) 166 { 167 struct rockchip_rgb *rgb = dev_get_priv(conn->dev); 168 169 if (rgb->phy) 170 rockchip_phy_power_off(rgb->phy); 171 172 if (rgb->funcs && rgb->funcs->unprepare) 173 rgb->funcs->unprepare(rgb); 174 175 pinctrl_select_state(rgb->dev, "sleep"); 176 } 177 178 static int rockchip_rgb_connector_init(struct rockchip_connector *conn, struct display_state *state) 179 { 180 struct rockchip_rgb *rgb = dev_get_priv(conn->dev); 181 struct connector_state *conn_state = &state->conn_state; 182 183 rgb->phy = conn->phy; 184 185 conn_state->color_range = DRM_COLOR_YCBCR_FULL_RANGE; 186 conn_state->color_encoding = DRM_COLOR_YCBCR_BT709; 187 conn_state->disp_info = rockchip_get_disp_info(conn_state->type, rgb->id); 188 189 switch (conn_state->bus_format) { 190 case MEDIA_BUS_FMT_RGB666_1X18: 191 conn_state->output_mode = ROCKCHIP_OUT_MODE_P666; 192 conn_state->output_if = VOP_OUTPUT_IF_RGB; 193 break; 194 case MEDIA_BUS_FMT_RGB565_1X16: 195 conn_state->output_mode = ROCKCHIP_OUT_MODE_P565; 196 conn_state->output_if = VOP_OUTPUT_IF_RGB; 197 break; 198 case MEDIA_BUS_FMT_RGB888_3X8: 199 case MEDIA_BUS_FMT_BGR888_3X8: 200 conn_state->output_mode = ROCKCHIP_OUT_MODE_S888; 201 conn_state->output_if = VOP_OUTPUT_IF_RGB; 202 break; 203 case MEDIA_BUS_FMT_RGB888_DUMMY_4X8: 204 case MEDIA_BUS_FMT_BGR888_DUMMY_4X8: 205 conn_state->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY; 206 conn_state->output_if = VOP_OUTPUT_IF_RGB; 207 break; 208 case MEDIA_BUS_FMT_YUYV8_2X8: 209 case MEDIA_BUS_FMT_YVYU8_2X8: 210 case MEDIA_BUS_FMT_UYVY8_2X8: 211 case MEDIA_BUS_FMT_VYUY8_2X8: 212 conn_state->output_mode = ROCKCHIP_OUT_MODE_BT656; 213 conn_state->output_if = VOP_OUTPUT_IF_BT656; 214 conn_state->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; 215 conn_state->color_encoding = DRM_COLOR_YCBCR_BT601; 216 break; 217 case MEDIA_BUS_FMT_YUYV8_1X16: 218 case MEDIA_BUS_FMT_YVYU8_1X16: 219 case MEDIA_BUS_FMT_UYVY8_1X16: 220 case MEDIA_BUS_FMT_VYUY8_1X16: 221 conn_state->output_mode = ROCKCHIP_OUT_MODE_BT1120; 222 conn_state->output_if = VOP_OUTPUT_IF_BT1120; 223 conn_state->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; 224 break; 225 case MEDIA_BUS_FMT_RGB888_1X24: 226 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 227 default: 228 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 229 conn_state->output_if = VOP_OUTPUT_IF_RGB; 230 break; 231 } 232 233 return 0; 234 } 235 236 static const struct rockchip_connector_funcs rockchip_rgb_connector_funcs = { 237 .init = rockchip_rgb_connector_init, 238 .prepare = rockchip_rgb_connector_prepare, 239 .unprepare = rockchip_rgb_connector_unprepare, 240 }; 241 242 static int rockchip_mcu_panel_send_cmds(struct display_state *state, 243 struct mcu_cmd_seq *cmds) 244 { 245 int i; 246 247 if (!cmds) 248 return -EINVAL; 249 250 display_send_mcu_cmd(state, MCU_SETBYPASS, 1); 251 for (i = 0; i < cmds->cmd_cnt; i++) { 252 struct mcu_cmd_desc *desc = &cmds->cmds[i]; 253 int value = 0; 254 255 value = desc->payload[0]; 256 display_send_mcu_cmd(state, desc->header.data_type, value); 257 258 if (desc->header.delay) 259 mdelay(desc->header.delay); 260 } 261 display_send_mcu_cmd(state, MCU_SETBYPASS, 0); 262 263 return 0; 264 } 265 266 static void rockchip_mcu_panel_prepare(struct rockchip_panel *panel) 267 { 268 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 269 int ret; 270 271 if (mcu_panel->prepared) 272 return; 273 274 if (dm_gpio_is_valid(&mcu_panel->enable_gpio)) 275 dm_gpio_set_value(&mcu_panel->enable_gpio, 1); 276 277 if (mcu_panel->desc->delay.prepare) 278 mdelay(mcu_panel->desc->delay.prepare); 279 280 if (dm_gpio_is_valid(&mcu_panel->reset_gpio)) 281 dm_gpio_set_value(&mcu_panel->reset_gpio, 1); 282 283 if (mcu_panel->desc->delay.reset) 284 mdelay(mcu_panel->desc->delay.reset); 285 286 if (dm_gpio_is_valid(&mcu_panel->reset_gpio)) 287 dm_gpio_set_value(&mcu_panel->reset_gpio, 0); 288 289 if (mcu_panel->desc->delay.init) 290 mdelay(mcu_panel->desc->delay.init); 291 292 if (mcu_panel->desc->init_seq) { 293 ret = rockchip_mcu_panel_send_cmds(panel->state, mcu_panel->desc->init_seq); 294 if (ret) 295 printf("failed to send mcu panel init cmds: %d\n", ret); 296 } 297 298 mcu_panel->prepared = true; 299 } 300 301 static void rockchip_mcu_panel_unprepare(struct rockchip_panel *panel) 302 { 303 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 304 int ret; 305 306 if (!mcu_panel->prepared) 307 return; 308 309 if (mcu_panel->desc->exit_seq) { 310 ret = rockchip_mcu_panel_send_cmds(panel->state, mcu_panel->desc->exit_seq); 311 if (ret) 312 printf("failed to send mcu panel exit cmds: %d\n", ret); 313 } 314 315 if (dm_gpio_is_valid(&mcu_panel->reset_gpio)) 316 dm_gpio_set_value(&mcu_panel->reset_gpio, 1); 317 318 if (dm_gpio_is_valid(&mcu_panel->enable_gpio)) 319 dm_gpio_set_value(&mcu_panel->enable_gpio, 0); 320 321 if (mcu_panel->desc->delay.unprepare) 322 mdelay(mcu_panel->desc->delay.unprepare); 323 324 mcu_panel->prepared = false; 325 } 326 327 static void rockchip_mcu_panel_enable(struct rockchip_panel *panel) 328 { 329 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 330 331 if (mcu_panel->enabled) 332 return; 333 334 if (mcu_panel->desc->delay.enable) 335 mdelay(mcu_panel->desc->delay.enable); 336 337 if (mcu_panel->backlight) 338 backlight_enable(mcu_panel->backlight); 339 340 mcu_panel->enabled = true; 341 } 342 343 static void rockchip_mcu_panel_disable(struct rockchip_panel *panel) 344 { 345 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 346 347 if (!mcu_panel->enabled) 348 return; 349 350 if (mcu_panel->backlight) 351 backlight_disable(mcu_panel->backlight); 352 353 if (mcu_panel->desc->delay.disable) 354 mdelay(mcu_panel->desc->delay.disable); 355 356 mcu_panel->enabled = false; 357 } 358 359 static const struct rockchip_panel_funcs rockchip_mcu_panel_funcs = { 360 .prepare = rockchip_mcu_panel_prepare, 361 .unprepare = rockchip_mcu_panel_unprepare, 362 .enable = rockchip_mcu_panel_enable, 363 .disable = rockchip_mcu_panel_disable, 364 }; 365 366 static int rockchip_mcu_panel_parse_cmds(const u8 *data, int length, 367 struct mcu_cmd_seq *pcmds) 368 { 369 int len; 370 const u8 *buf; 371 const struct mcu_cmd_header *header; 372 int i, cnt = 0; 373 374 /* scan commands */ 375 cnt = 0; 376 buf = data; 377 len = length; 378 while (len > sizeof(*header)) { 379 header = (const struct mcu_cmd_header *)buf; 380 buf += sizeof(*header) + header->payload_length; 381 len -= sizeof(*header) + header->payload_length; 382 cnt++; 383 } 384 385 pcmds->cmds = calloc(cnt, sizeof(struct mcu_cmd_desc)); 386 if (!pcmds->cmds) 387 return -ENOMEM; 388 389 pcmds->cmd_cnt = cnt; 390 391 buf = data; 392 len = length; 393 for (i = 0; i < cnt; i++) { 394 struct mcu_cmd_desc *desc = &pcmds->cmds[i]; 395 396 header = (const struct mcu_cmd_header *)buf; 397 length -= sizeof(*header); 398 buf += sizeof(*header); 399 desc->header.data_type = header->data_type; 400 desc->header.delay = header->delay; 401 desc->header.payload_length = header->payload_length; 402 desc->payload = buf; 403 buf += header->payload_length; 404 length -= header->payload_length; 405 } 406 407 return 0; 408 } 409 410 static int rockchip_mcu_panel_init(struct rockchip_mcu_panel *mcu_panel, ofnode mcu_panel_node) 411 { 412 const void *data; 413 int len; 414 int ret; 415 416 ret = gpio_request_by_name_nodev(mcu_panel_node, "enable-gpios", 0, 417 &mcu_panel->enable_gpio, GPIOD_IS_OUT); 418 if (ret && ret != -ENOENT) { 419 printf("%s: Cannot get mcu panel enable GPIO: %d\n", __func__, ret); 420 return ret; 421 } 422 423 ret = gpio_request_by_name_nodev(mcu_panel_node, "reset-gpios", 0, 424 &mcu_panel->reset_gpio, GPIOD_IS_OUT); 425 if (ret && ret != -ENOENT) { 426 printf("%s: Cannot get mcu panel reset GPIO: %d\n", __func__, ret); 427 return ret; 428 } 429 430 mcu_panel->desc = malloc(sizeof(struct rockchip_mcu_panel_desc)); 431 if (!mcu_panel->desc) 432 return -ENOMEM; 433 434 mcu_panel->desc->power_invert = ofnode_read_bool(mcu_panel_node, "power-invert"); 435 436 mcu_panel->desc->delay.prepare = ofnode_read_u32_default(mcu_panel_node, "prepare-delay-ms", 0); 437 mcu_panel->desc->delay.unprepare = ofnode_read_u32_default(mcu_panel_node, "unprepare-delay-ms", 0); 438 mcu_panel->desc->delay.enable = ofnode_read_u32_default(mcu_panel_node, "enable-delay-ms", 0); 439 mcu_panel->desc->delay.disable = ofnode_read_u32_default(mcu_panel_node, "disable-delay-ms", 0); 440 mcu_panel->desc->delay.init = ofnode_read_u32_default(mcu_panel_node, "init-delay-ms", 0); 441 mcu_panel->desc->delay.reset = ofnode_read_u32_default(mcu_panel_node, "reset-delay-ms", 0); 442 443 mcu_panel->desc->bus_format = ofnode_read_u32_default(mcu_panel_node, "bus-format", 444 MEDIA_BUS_FMT_RBG888_1X24); 445 mcu_panel->desc->bpc = ofnode_read_u32_default(mcu_panel_node, "bpc", 8); 446 447 data = ofnode_get_property(mcu_panel_node, "panel-init-sequence", &len); 448 if (data) { 449 mcu_panel->desc->init_seq = calloc(1, sizeof(*mcu_panel->desc->init_seq)); 450 if (!mcu_panel->desc->init_seq) 451 return -ENOMEM; 452 453 ret = rockchip_mcu_panel_parse_cmds(data, len, mcu_panel->desc->init_seq); 454 if (ret) { 455 printf("failed to parse panel init sequence\n"); 456 goto free_on_cmds; 457 } 458 } 459 460 data = ofnode_get_property(mcu_panel_node, "panel-exit-sequence", &len); 461 if (data) { 462 mcu_panel->desc->exit_seq = calloc(1, sizeof(*mcu_panel->desc->exit_seq)); 463 if (!mcu_panel->desc->exit_seq) { 464 ret = -ENOMEM; 465 goto free_on_cmds; 466 } 467 468 ret = rockchip_mcu_panel_parse_cmds(data, len, mcu_panel->desc->exit_seq); 469 if (ret) { 470 printf("failed to parse panel exit sequence\n"); 471 goto free_cmds; 472 } 473 } 474 475 return 0; 476 477 free_cmds: 478 free(mcu_panel->desc->exit_seq); 479 free_on_cmds: 480 free(mcu_panel->desc->init_seq); 481 return ret; 482 } 483 484 static int rockchip_rgb_probe(struct udevice *dev) 485 { 486 struct rockchip_rgb *rgb = dev_get_priv(dev); 487 ofnode mcu_panel_node; 488 int phandle; 489 int ret; 490 491 rgb->dev = dev; 492 rgb->funcs = (const struct rockchip_rgb_funcs *)dev_get_driver_data(dev); 493 rgb->grf = syscon_get_regmap(dev_get_parent(dev)); 494 rgb->data_sync_bypass = dev_read_bool(dev, "rockchip,data-sync-bypass"); 495 rgb->id = of_alias_get_id(ofnode_to_np(dev->node), "rgb"); 496 if (rgb->id < 0) 497 rgb->id = 0; 498 499 mcu_panel_node = dev_read_subnode(dev, "mcu-panel"); 500 if (ofnode_valid(mcu_panel_node) && ofnode_is_available(mcu_panel_node)) { 501 struct rockchip_mcu_panel *mcu_panel; 502 503 mcu_panel = malloc(sizeof(struct rockchip_mcu_panel)); 504 if (!mcu_panel) { 505 printf("failed to alloc mcu_panel data\n"); 506 return -ENOMEM; 507 } 508 509 ret = rockchip_mcu_panel_init(mcu_panel, mcu_panel_node); 510 if (ret < 0) { 511 printf("failed to init mcu_panel: %d\n", ret); 512 return ret; 513 } 514 515 phandle = ofnode_read_u32_default(mcu_panel_node, "backlight", -1); 516 if (phandle < 0) { 517 printf("failed to find backlight phandle\n"); 518 return -EINVAL; 519 } 520 521 ret = uclass_get_device_by_phandle_id(UCLASS_PANEL_BACKLIGHT, phandle, 522 &mcu_panel->backlight); 523 if (ret && ret != -ENOENT) { 524 printf("%s: failed to get backlight device: %d\n", __func__, ret); 525 return ret; 526 } 527 528 mcu_panel->base.dev = dev; 529 mcu_panel->base.bus_format = mcu_panel->desc->bus_format; 530 mcu_panel->base.bpc = mcu_panel->desc->bpc; 531 mcu_panel->base.funcs = &rockchip_mcu_panel_funcs; 532 mcu_panel->enabled = false; 533 mcu_panel->prepared = false; 534 535 rgb->connector.panel = &mcu_panel->base; 536 } 537 538 rockchip_connector_bind(&rgb->connector, dev, rgb->id, &rockchip_rgb_connector_funcs, 539 NULL, DRM_MODE_CONNECTOR_LVDS); 540 541 return 0; 542 } 543 544 static void rv1106_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 545 { 546 regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER, 547 RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass ? 0x3 : 0x0)); 548 regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS, 549 RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass ? 0x3 : 0x0)); 550 } 551 552 static const struct rockchip_rgb_funcs rv1106_rgb_funcs = { 553 .prepare = rv1106_rgb_prepare, 554 }; 555 556 static void rv1126_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 557 { 558 regmap_write(rgb->grf, RV1126_GRF_IOFUNC_CON3, 559 RV1126_LCDC_IO_BYPASS(rgb->data_sync_bypass)); 560 } 561 562 static const struct rockchip_rgb_funcs rv1126_rgb_funcs = { 563 .prepare = rv1126_rgb_prepare, 564 }; 565 566 static void px30_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 567 { 568 regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, PX30_RGB_VOP_SEL(pipe) | 569 PX30_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass)); 570 } 571 572 static const struct rockchip_rgb_funcs px30_rgb_funcs = { 573 .prepare = px30_rgb_prepare, 574 }; 575 576 static void rk1808_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 577 { 578 regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1, 579 RK1808_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass)); 580 } 581 582 static const struct rockchip_rgb_funcs rk1808_rgb_funcs = { 583 .prepare = rk1808_rgb_prepare, 584 }; 585 586 static void rk3288_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 587 { 588 regmap_write(rgb->grf, RK3288_GRF_SOC_CON6, RK3288_LVDS_LCDC_SEL(pipe)); 589 regmap_write(rgb->grf, RK3288_GRF_SOC_CON7, 590 RK3288_LVDS_PWRDWN(0) | RK3288_LVDS_CON_ENABLE_2(1) | 591 RK3288_LVDS_CON_ENABLE_1(1) | RK3288_LVDS_CON_CLKINV(0) | 592 RK3288_LVDS_CON_TTL_EN(1)); 593 } 594 595 static void rk3288_rgb_unprepare(struct rockchip_rgb *rgb) 596 { 597 regmap_write(rgb->grf, RK3288_GRF_SOC_CON7, 598 RK3288_LVDS_PWRDWN(1) | RK3288_LVDS_CON_ENABLE_2(0) | 599 RK3288_LVDS_CON_ENABLE_1(0) | RK3288_LVDS_CON_TTL_EN(0)); 600 } 601 602 static const struct rockchip_rgb_funcs rk3288_rgb_funcs = { 603 .prepare = rk3288_rgb_prepare, 604 .unprepare = rk3288_rgb_unprepare, 605 }; 606 607 static void rk3368_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 608 { 609 regmap_write(rgb->grf, RK3368_GRF_SOC_CON15, RK3368_FORCE_JETAG(0)); 610 } 611 612 static const struct rockchip_rgb_funcs rk3368_rgb_funcs = { 613 .prepare = rk3368_rgb_prepare, 614 }; 615 616 static void rk3562_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 617 { 618 regmap_write(rgb->grf, RK3562_GRF_IOC_VO_IO_CON, 619 RK3562_RGB_DATA_BYPASS(rgb->data_sync_bypass)); 620 } 621 622 static const struct rockchip_rgb_funcs rk3562_rgb_funcs = { 623 .prepare = rk3562_rgb_prepare, 624 }; 625 626 static void rk3568_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 627 { 628 regmap_write(rgb->grf, RK3568_GRF_VO_CON1, RK3568_RGB_DATA_BYPASS(rgb->data_sync_bypass)); 629 } 630 631 static const struct rockchip_rgb_funcs rk3568_rgb_funcs = { 632 .prepare = rk3568_rgb_prepare, 633 }; 634 635 static void rk3576_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 636 { 637 regmap_write(rgb->grf, RK3576_VCCIO_IOC_MISC_CON8, 638 RK3576_VOP_MCU_SEL(rgb->data_sync_bypass)); 639 } 640 641 static const struct rockchip_rgb_funcs rk3576_rgb_funcs = { 642 .prepare = rk3576_rgb_prepare, 643 }; 644 645 static const struct udevice_id rockchip_rgb_ids[] = { 646 { 647 .compatible = "rockchip,px30-rgb", 648 .data = (ulong)&px30_rgb_funcs, 649 }, 650 { 651 .compatible = "rockchip,rk1808-rgb", 652 .data = (ulong)&rk1808_rgb_funcs, 653 }, 654 { 655 .compatible = "rockchip,rk3066-rgb", 656 }, 657 { 658 .compatible = "rockchip,rk3128-rgb", 659 }, 660 { 661 .compatible = "rockchip,rk3288-rgb", 662 .data = (ulong)&rk3288_rgb_funcs, 663 }, 664 { 665 .compatible = "rockchip,rk3308-rgb", 666 }, 667 { 668 .compatible = "rockchip,rk3368-rgb", 669 .data = (ulong)&rk3368_rgb_funcs, 670 }, 671 { 672 .compatible = "rockchip,rk3562-rgb", 673 .data = (ulong)&rk3562_rgb_funcs, 674 }, 675 { 676 .compatible = "rockchip,rk3568-rgb", 677 .data = (ulong)&rk3568_rgb_funcs, 678 }, 679 { 680 .compatible = "rockchip,rk3576-rgb", 681 .data = (ulong)&rk3576_rgb_funcs, 682 }, 683 { 684 .compatible = "rockchip,rk3588-rgb", 685 }, 686 { 687 .compatible = "rockchip,rv1106-rgb", 688 .data = (ulong)&rv1106_rgb_funcs, 689 }, 690 { 691 .compatible = "rockchip,rv1108-rgb", 692 }, 693 { 694 .compatible = "rockchip,rv1126-rgb", 695 .data = (ulong)&rv1126_rgb_funcs, 696 }, 697 {} 698 }; 699 700 U_BOOT_DRIVER(rockchip_rgb) = { 701 .name = "rockchip_rgb", 702 .id = UCLASS_DISPLAY, 703 .of_match = rockchip_rgb_ids, 704 .probe = rockchip_rgb_probe, 705 .priv_auto_alloc_size = sizeof(struct rockchip_rgb), 706 }; 707