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_RGB565_2X8_LE: 199 case MEDIA_BUS_FMT_BGR565_2X8_LE: 200 conn_state->output_mode = ROCKCHIP_OUT_MODE_S565; 201 conn_state->output_if = VOP_OUTPUT_IF_RGB; 202 break; 203 case MEDIA_BUS_FMT_RGB666_3X6: 204 conn_state->output_mode = ROCKCHIP_OUT_MODE_S666; 205 conn_state->output_if = VOP_OUTPUT_IF_RGB; 206 break; 207 case MEDIA_BUS_FMT_RGB888_3X8: 208 case MEDIA_BUS_FMT_BGR888_3X8: 209 conn_state->output_mode = ROCKCHIP_OUT_MODE_S888; 210 conn_state->output_if = VOP_OUTPUT_IF_RGB; 211 break; 212 case MEDIA_BUS_FMT_RGB888_DUMMY_4X8: 213 case MEDIA_BUS_FMT_BGR888_DUMMY_4X8: 214 conn_state->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY; 215 conn_state->output_if = VOP_OUTPUT_IF_RGB; 216 break; 217 case MEDIA_BUS_FMT_YUYV8_2X8: 218 case MEDIA_BUS_FMT_YVYU8_2X8: 219 case MEDIA_BUS_FMT_UYVY8_2X8: 220 case MEDIA_BUS_FMT_VYUY8_2X8: 221 conn_state->output_mode = ROCKCHIP_OUT_MODE_BT656; 222 conn_state->output_if = VOP_OUTPUT_IF_BT656; 223 conn_state->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; 224 conn_state->color_encoding = DRM_COLOR_YCBCR_BT601; 225 break; 226 case MEDIA_BUS_FMT_YUYV8_1X16: 227 case MEDIA_BUS_FMT_YVYU8_1X16: 228 case MEDIA_BUS_FMT_UYVY8_1X16: 229 case MEDIA_BUS_FMT_VYUY8_1X16: 230 conn_state->output_mode = ROCKCHIP_OUT_MODE_BT1120; 231 conn_state->output_if = VOP_OUTPUT_IF_BT1120; 232 conn_state->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; 233 break; 234 case MEDIA_BUS_FMT_RGB888_1X24: 235 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 236 default: 237 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 238 conn_state->output_if = VOP_OUTPUT_IF_RGB; 239 break; 240 } 241 242 return 0; 243 } 244 245 static const struct rockchip_connector_funcs rockchip_rgb_connector_funcs = { 246 .init = rockchip_rgb_connector_init, 247 .prepare = rockchip_rgb_connector_prepare, 248 .unprepare = rockchip_rgb_connector_unprepare, 249 }; 250 251 static int rockchip_mcu_panel_send_cmds(struct display_state *state, 252 struct mcu_cmd_seq *cmds) 253 { 254 int i; 255 256 if (!cmds) 257 return -EINVAL; 258 259 display_send_mcu_cmd(state, MCU_SETBYPASS, 1); 260 for (i = 0; i < cmds->cmd_cnt; i++) { 261 struct mcu_cmd_desc *desc = &cmds->cmds[i]; 262 int value = 0; 263 264 value = desc->payload[0]; 265 display_send_mcu_cmd(state, desc->header.data_type, value); 266 267 if (desc->header.delay) 268 mdelay(desc->header.delay); 269 } 270 display_send_mcu_cmd(state, MCU_SETBYPASS, 0); 271 272 return 0; 273 } 274 275 static void rockchip_mcu_panel_prepare(struct rockchip_panel *panel) 276 { 277 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 278 int ret; 279 280 if (mcu_panel->prepared) 281 return; 282 283 if (dm_gpio_is_valid(&mcu_panel->enable_gpio)) 284 dm_gpio_set_value(&mcu_panel->enable_gpio, 1); 285 286 if (mcu_panel->desc->delay.prepare) 287 mdelay(mcu_panel->desc->delay.prepare); 288 289 if (dm_gpio_is_valid(&mcu_panel->reset_gpio)) 290 dm_gpio_set_value(&mcu_panel->reset_gpio, 1); 291 292 if (mcu_panel->desc->delay.reset) 293 mdelay(mcu_panel->desc->delay.reset); 294 295 if (dm_gpio_is_valid(&mcu_panel->reset_gpio)) 296 dm_gpio_set_value(&mcu_panel->reset_gpio, 0); 297 298 if (mcu_panel->desc->delay.init) 299 mdelay(mcu_panel->desc->delay.init); 300 301 if (mcu_panel->desc->init_seq) { 302 ret = rockchip_mcu_panel_send_cmds(panel->state, mcu_panel->desc->init_seq); 303 if (ret) 304 printf("failed to send mcu panel init cmds: %d\n", ret); 305 } 306 307 mcu_panel->prepared = true; 308 } 309 310 static void rockchip_mcu_panel_unprepare(struct rockchip_panel *panel) 311 { 312 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 313 int ret; 314 315 if (!mcu_panel->prepared) 316 return; 317 318 if (mcu_panel->desc->exit_seq) { 319 ret = rockchip_mcu_panel_send_cmds(panel->state, mcu_panel->desc->exit_seq); 320 if (ret) 321 printf("failed to send mcu panel exit cmds: %d\n", ret); 322 } 323 324 if (dm_gpio_is_valid(&mcu_panel->reset_gpio)) 325 dm_gpio_set_value(&mcu_panel->reset_gpio, 1); 326 327 if (dm_gpio_is_valid(&mcu_panel->enable_gpio)) 328 dm_gpio_set_value(&mcu_panel->enable_gpio, 0); 329 330 if (mcu_panel->desc->delay.unprepare) 331 mdelay(mcu_panel->desc->delay.unprepare); 332 333 mcu_panel->prepared = false; 334 } 335 336 static void rockchip_mcu_panel_enable(struct rockchip_panel *panel) 337 { 338 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 339 340 if (mcu_panel->enabled) 341 return; 342 343 if (mcu_panel->desc->delay.enable) 344 mdelay(mcu_panel->desc->delay.enable); 345 346 if (mcu_panel->backlight) 347 backlight_enable(mcu_panel->backlight); 348 349 mcu_panel->enabled = true; 350 } 351 352 static void rockchip_mcu_panel_disable(struct rockchip_panel *panel) 353 { 354 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel); 355 356 if (!mcu_panel->enabled) 357 return; 358 359 if (mcu_panel->backlight) 360 backlight_disable(mcu_panel->backlight); 361 362 if (mcu_panel->desc->delay.disable) 363 mdelay(mcu_panel->desc->delay.disable); 364 365 mcu_panel->enabled = false; 366 } 367 368 static const struct rockchip_panel_funcs rockchip_mcu_panel_funcs = { 369 .prepare = rockchip_mcu_panel_prepare, 370 .unprepare = rockchip_mcu_panel_unprepare, 371 .enable = rockchip_mcu_panel_enable, 372 .disable = rockchip_mcu_panel_disable, 373 }; 374 375 static int rockchip_mcu_panel_parse_cmds(const u8 *data, int length, 376 struct mcu_cmd_seq *pcmds) 377 { 378 int len; 379 const u8 *buf; 380 const struct mcu_cmd_header *header; 381 int i, cnt = 0; 382 383 /* scan commands */ 384 cnt = 0; 385 buf = data; 386 len = length; 387 while (len > sizeof(*header)) { 388 header = (const struct mcu_cmd_header *)buf; 389 buf += sizeof(*header) + header->payload_length; 390 len -= sizeof(*header) + header->payload_length; 391 cnt++; 392 } 393 394 pcmds->cmds = calloc(cnt, sizeof(struct mcu_cmd_desc)); 395 if (!pcmds->cmds) 396 return -ENOMEM; 397 398 pcmds->cmd_cnt = cnt; 399 400 buf = data; 401 len = length; 402 for (i = 0; i < cnt; i++) { 403 struct mcu_cmd_desc *desc = &pcmds->cmds[i]; 404 405 header = (const struct mcu_cmd_header *)buf; 406 length -= sizeof(*header); 407 buf += sizeof(*header); 408 desc->header.data_type = header->data_type; 409 desc->header.delay = header->delay; 410 desc->header.payload_length = header->payload_length; 411 desc->payload = buf; 412 buf += header->payload_length; 413 length -= header->payload_length; 414 } 415 416 return 0; 417 } 418 419 static int rockchip_mcu_panel_init(struct rockchip_mcu_panel *mcu_panel, ofnode mcu_panel_node) 420 { 421 const void *data; 422 int len; 423 int ret; 424 425 ret = gpio_request_by_name_nodev(mcu_panel_node, "enable-gpios", 0, 426 &mcu_panel->enable_gpio, GPIOD_IS_OUT); 427 if (ret && ret != -ENOENT) { 428 printf("%s: Cannot get mcu panel enable GPIO: %d\n", __func__, ret); 429 return ret; 430 } 431 432 ret = gpio_request_by_name_nodev(mcu_panel_node, "reset-gpios", 0, 433 &mcu_panel->reset_gpio, GPIOD_IS_OUT); 434 if (ret && ret != -ENOENT) { 435 printf("%s: Cannot get mcu panel reset GPIO: %d\n", __func__, ret); 436 return ret; 437 } 438 439 mcu_panel->desc = malloc(sizeof(struct rockchip_mcu_panel_desc)); 440 if (!mcu_panel->desc) 441 return -ENOMEM; 442 443 mcu_panel->desc->power_invert = ofnode_read_bool(mcu_panel_node, "power-invert"); 444 445 mcu_panel->desc->delay.prepare = ofnode_read_u32_default(mcu_panel_node, "prepare-delay-ms", 0); 446 mcu_panel->desc->delay.unprepare = ofnode_read_u32_default(mcu_panel_node, "unprepare-delay-ms", 0); 447 mcu_panel->desc->delay.enable = ofnode_read_u32_default(mcu_panel_node, "enable-delay-ms", 0); 448 mcu_panel->desc->delay.disable = ofnode_read_u32_default(mcu_panel_node, "disable-delay-ms", 0); 449 mcu_panel->desc->delay.init = ofnode_read_u32_default(mcu_panel_node, "init-delay-ms", 0); 450 mcu_panel->desc->delay.reset = ofnode_read_u32_default(mcu_panel_node, "reset-delay-ms", 0); 451 452 mcu_panel->desc->bus_format = ofnode_read_u32_default(mcu_panel_node, "bus-format", 453 MEDIA_BUS_FMT_RBG888_1X24); 454 mcu_panel->desc->bpc = ofnode_read_u32_default(mcu_panel_node, "bpc", 8); 455 456 data = ofnode_get_property(mcu_panel_node, "panel-init-sequence", &len); 457 if (data) { 458 mcu_panel->desc->init_seq = calloc(1, sizeof(*mcu_panel->desc->init_seq)); 459 if (!mcu_panel->desc->init_seq) 460 return -ENOMEM; 461 462 ret = rockchip_mcu_panel_parse_cmds(data, len, mcu_panel->desc->init_seq); 463 if (ret) { 464 printf("failed to parse panel init sequence\n"); 465 goto free_on_cmds; 466 } 467 } 468 469 data = ofnode_get_property(mcu_panel_node, "panel-exit-sequence", &len); 470 if (data) { 471 mcu_panel->desc->exit_seq = calloc(1, sizeof(*mcu_panel->desc->exit_seq)); 472 if (!mcu_panel->desc->exit_seq) { 473 ret = -ENOMEM; 474 goto free_on_cmds; 475 } 476 477 ret = rockchip_mcu_panel_parse_cmds(data, len, mcu_panel->desc->exit_seq); 478 if (ret) { 479 printf("failed to parse panel exit sequence\n"); 480 goto free_cmds; 481 } 482 } 483 484 return 0; 485 486 free_cmds: 487 free(mcu_panel->desc->exit_seq); 488 free_on_cmds: 489 free(mcu_panel->desc->init_seq); 490 return ret; 491 } 492 493 static int rockchip_rgb_probe(struct udevice *dev) 494 { 495 struct rockchip_rgb *rgb = dev_get_priv(dev); 496 ofnode mcu_panel_node; 497 int phandle; 498 int ret; 499 500 rgb->dev = dev; 501 rgb->funcs = (const struct rockchip_rgb_funcs *)dev_get_driver_data(dev); 502 rgb->grf = syscon_get_regmap(dev_get_parent(dev)); 503 rgb->data_sync_bypass = dev_read_bool(dev, "rockchip,data-sync-bypass"); 504 rgb->id = of_alias_get_id(ofnode_to_np(dev->node), "rgb"); 505 if (rgb->id < 0) 506 rgb->id = 0; 507 508 mcu_panel_node = dev_read_subnode(dev, "mcu-panel"); 509 if (ofnode_valid(mcu_panel_node) && ofnode_is_available(mcu_panel_node)) { 510 struct rockchip_mcu_panel *mcu_panel; 511 512 mcu_panel = malloc(sizeof(struct rockchip_mcu_panel)); 513 if (!mcu_panel) { 514 printf("failed to alloc mcu_panel data\n"); 515 return -ENOMEM; 516 } 517 518 ret = rockchip_mcu_panel_init(mcu_panel, mcu_panel_node); 519 if (ret < 0) { 520 printf("failed to init mcu_panel: %d\n", ret); 521 return ret; 522 } 523 524 phandle = ofnode_read_u32_default(mcu_panel_node, "backlight", -1); 525 if (phandle < 0) { 526 printf("failed to find backlight phandle\n"); 527 return -EINVAL; 528 } 529 530 ret = uclass_get_device_by_phandle_id(UCLASS_PANEL_BACKLIGHT, phandle, 531 &mcu_panel->backlight); 532 if (ret && ret != -ENOENT) { 533 printf("%s: failed to get backlight device: %d\n", __func__, ret); 534 return ret; 535 } 536 537 mcu_panel->base.dev = dev; 538 mcu_panel->base.bus_format = mcu_panel->desc->bus_format; 539 mcu_panel->base.bpc = mcu_panel->desc->bpc; 540 mcu_panel->base.funcs = &rockchip_mcu_panel_funcs; 541 mcu_panel->enabled = false; 542 mcu_panel->prepared = false; 543 544 rgb->connector.panel = &mcu_panel->base; 545 } 546 547 rockchip_connector_bind(&rgb->connector, dev, rgb->id, &rockchip_rgb_connector_funcs, 548 NULL, DRM_MODE_CONNECTOR_LVDS); 549 550 return 0; 551 } 552 553 static void rv1106_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 554 { 555 regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER, 556 RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass ? 0x3 : 0x0)); 557 regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS, 558 RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass ? 0x3 : 0x0)); 559 } 560 561 static const struct rockchip_rgb_funcs rv1106_rgb_funcs = { 562 .prepare = rv1106_rgb_prepare, 563 }; 564 565 static void rv1126_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 566 { 567 regmap_write(rgb->grf, RV1126_GRF_IOFUNC_CON3, 568 RV1126_LCDC_IO_BYPASS(rgb->data_sync_bypass)); 569 } 570 571 static const struct rockchip_rgb_funcs rv1126_rgb_funcs = { 572 .prepare = rv1126_rgb_prepare, 573 }; 574 575 static void px30_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 576 { 577 regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, PX30_RGB_VOP_SEL(pipe) | 578 PX30_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass)); 579 } 580 581 static const struct rockchip_rgb_funcs px30_rgb_funcs = { 582 .prepare = px30_rgb_prepare, 583 }; 584 585 static void rk1808_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 586 { 587 regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1, 588 RK1808_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass)); 589 } 590 591 static const struct rockchip_rgb_funcs rk1808_rgb_funcs = { 592 .prepare = rk1808_rgb_prepare, 593 }; 594 595 static void rk3288_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 596 { 597 regmap_write(rgb->grf, RK3288_GRF_SOC_CON6, RK3288_LVDS_LCDC_SEL(pipe)); 598 regmap_write(rgb->grf, RK3288_GRF_SOC_CON7, 599 RK3288_LVDS_PWRDWN(0) | RK3288_LVDS_CON_ENABLE_2(1) | 600 RK3288_LVDS_CON_ENABLE_1(1) | RK3288_LVDS_CON_CLKINV(0) | 601 RK3288_LVDS_CON_TTL_EN(1)); 602 } 603 604 static void rk3288_rgb_unprepare(struct rockchip_rgb *rgb) 605 { 606 regmap_write(rgb->grf, RK3288_GRF_SOC_CON7, 607 RK3288_LVDS_PWRDWN(1) | RK3288_LVDS_CON_ENABLE_2(0) | 608 RK3288_LVDS_CON_ENABLE_1(0) | RK3288_LVDS_CON_TTL_EN(0)); 609 } 610 611 static const struct rockchip_rgb_funcs rk3288_rgb_funcs = { 612 .prepare = rk3288_rgb_prepare, 613 .unprepare = rk3288_rgb_unprepare, 614 }; 615 616 static void rk3368_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 617 { 618 regmap_write(rgb->grf, RK3368_GRF_SOC_CON15, RK3368_FORCE_JETAG(0)); 619 } 620 621 static const struct rockchip_rgb_funcs rk3368_rgb_funcs = { 622 .prepare = rk3368_rgb_prepare, 623 }; 624 625 static void rk3562_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 626 { 627 regmap_write(rgb->grf, RK3562_GRF_IOC_VO_IO_CON, 628 RK3562_RGB_DATA_BYPASS(rgb->data_sync_bypass)); 629 } 630 631 static const struct rockchip_rgb_funcs rk3562_rgb_funcs = { 632 .prepare = rk3562_rgb_prepare, 633 }; 634 635 static void rk3568_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 636 { 637 regmap_write(rgb->grf, RK3568_GRF_VO_CON1, RK3568_RGB_DATA_BYPASS(rgb->data_sync_bypass)); 638 } 639 640 static const struct rockchip_rgb_funcs rk3568_rgb_funcs = { 641 .prepare = rk3568_rgb_prepare, 642 }; 643 644 static void rk3576_rgb_prepare(struct rockchip_rgb *rgb, int pipe) 645 { 646 regmap_write(rgb->grf, RK3576_VCCIO_IOC_MISC_CON8, 647 RK3576_VOP_MCU_SEL(rgb->data_sync_bypass)); 648 } 649 650 static const struct rockchip_rgb_funcs rk3576_rgb_funcs = { 651 .prepare = rk3576_rgb_prepare, 652 }; 653 654 static const struct udevice_id rockchip_rgb_ids[] = { 655 { 656 .compatible = "rockchip,px30-rgb", 657 .data = (ulong)&px30_rgb_funcs, 658 }, 659 { 660 .compatible = "rockchip,rk1808-rgb", 661 .data = (ulong)&rk1808_rgb_funcs, 662 }, 663 { 664 .compatible = "rockchip,rk3066-rgb", 665 }, 666 { 667 .compatible = "rockchip,rk3128-rgb", 668 }, 669 { 670 .compatible = "rockchip,rk3288-rgb", 671 .data = (ulong)&rk3288_rgb_funcs, 672 }, 673 { 674 .compatible = "rockchip,rk3308-rgb", 675 }, 676 { 677 .compatible = "rockchip,rk3368-rgb", 678 .data = (ulong)&rk3368_rgb_funcs, 679 }, 680 { 681 .compatible = "rockchip,rk3562-rgb", 682 .data = (ulong)&rk3562_rgb_funcs, 683 }, 684 { 685 .compatible = "rockchip,rk3568-rgb", 686 .data = (ulong)&rk3568_rgb_funcs, 687 }, 688 { 689 .compatible = "rockchip,rk3576-rgb", 690 .data = (ulong)&rk3576_rgb_funcs, 691 }, 692 { 693 .compatible = "rockchip,rk3588-rgb", 694 }, 695 { 696 .compatible = "rockchip,rv1106-rgb", 697 .data = (ulong)&rv1106_rgb_funcs, 698 }, 699 { 700 .compatible = "rockchip,rv1108-rgb", 701 }, 702 { 703 .compatible = "rockchip,rv1126-rgb", 704 .data = (ulong)&rv1126_rgb_funcs, 705 }, 706 {} 707 }; 708 709 U_BOOT_DRIVER(rockchip_rgb) = { 710 .name = "rockchip_rgb", 711 .id = UCLASS_DISPLAY, 712 .of_match = rockchip_rgb_ids, 713 .probe = rockchip_rgb_probe, 714 .priv_auto_alloc_size = sizeof(struct rockchip_rgb), 715 }; 716