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