1 /* 2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 3 * Author: 4 * Mark Yao <mark.yao@rock-chips.com> 5 * Sandy Huang <hjc@rock-chips.com> 6 * 7 * This software is licensed under the terms of the GNU General Public 8 * License version 2, as published by the Free Software Foundation, and 9 * may be copied, distributed, and modified under those terms. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <drm/drmP.h> 18 #include <drm/drm_atomic_helper.h> 19 #include <drm/drm_crtc_helper.h> 20 #include <drm/drm_dp_helper.h> 21 #include <drm/drm_panel.h> 22 #include <drm/drm_of.h> 23 24 #include <linux/component.h> 25 #include <linux/clk.h> 26 #include <linux/mfd/syscon.h> 27 #include <linux/of_graph.h> 28 #include <linux/pm_runtime.h> 29 #include <linux/regmap.h> 30 #include <linux/reset.h> 31 32 #include "rockchip_drm_drv.h" 33 #include "rockchip_drm_vop.h" 34 #include "rockchip_lvds.h" 35 36 #define DISPLAY_OUTPUT_RGB 0 37 #define DISPLAY_OUTPUT_LVDS 1 38 #define DISPLAY_OUTPUT_DUAL_LVDS 2 39 40 #define connector_to_lvds(c) \ 41 container_of(c, struct rockchip_lvds, connector) 42 43 #define encoder_to_lvds(c) \ 44 container_of(c, struct rockchip_lvds, encoder) 45 46 /** 47 * rockchip_lvds_soc_data - rockchip lvds Soc private data 48 * @ch1_offset: lvds channel 1 registe offset 49 * grf_soc_con6: general registe offset for LVDS contrl 50 * grf_soc_con7: general registe offset for LVDS contrl 51 * has_vop_sel: to indicate whether need to choose from different VOP. 52 */ 53 struct rockchip_lvds_soc_data { 54 u32 ch1_offset; 55 int grf_soc_con6; 56 int grf_soc_con7; 57 bool has_vop_sel; 58 }; 59 60 struct rockchip_lvds { 61 struct device *dev; 62 void __iomem *regs; 63 struct regmap *grf; 64 struct clk *pclk; 65 const struct rockchip_lvds_soc_data *soc_data; 66 int output; /* rgb lvds or dual lvds output */ 67 int format; /* vesa or jeida format */ 68 struct drm_device *drm_dev; 69 struct drm_panel *panel; 70 struct drm_bridge *bridge; 71 struct drm_connector connector; 72 struct drm_encoder encoder; 73 struct dev_pin_info *pins; 74 }; 75 76 static inline void lvds_writel(struct rockchip_lvds *lvds, u32 offset, u32 val) 77 { 78 writel_relaxed(val, lvds->regs + offset); 79 if (lvds->output == DISPLAY_OUTPUT_LVDS) 80 return; 81 writel_relaxed(val, lvds->regs + offset + lvds->soc_data->ch1_offset); 82 } 83 84 static inline int lvds_name_to_format(const char *s) 85 { 86 if (strncmp(s, "jeida-18", 8) == 0) 87 return LVDS_JEIDA_18; 88 else if (strncmp(s, "jeida-24", 8) == 0) 89 return LVDS_JEIDA_24; 90 else if (strncmp(s, "vesa-24", 7) == 0) 91 return LVDS_VESA_24; 92 93 return -EINVAL; 94 } 95 96 static inline int lvds_name_to_output(const char *s) 97 { 98 if (strncmp(s, "rgb", 3) == 0) 99 return DISPLAY_OUTPUT_RGB; 100 else if (strncmp(s, "lvds", 4) == 0) 101 return DISPLAY_OUTPUT_LVDS; 102 else if (strncmp(s, "duallvds", 8) == 0) 103 return DISPLAY_OUTPUT_DUAL_LVDS; 104 105 return -EINVAL; 106 } 107 108 static int rockchip_lvds_poweron(struct rockchip_lvds *lvds) 109 { 110 int ret; 111 u32 val; 112 113 ret = clk_enable(lvds->pclk); 114 if (ret < 0) { 115 DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret); 116 return ret; 117 } 118 ret = pm_runtime_get_sync(lvds->dev); 119 if (ret < 0) { 120 DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); 121 clk_disable(lvds->pclk); 122 return ret; 123 } 124 val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN | 125 RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN | 126 RK3288_LVDS_CH0_REG0_LANE0_EN; 127 if (lvds->output == DISPLAY_OUTPUT_RGB) { 128 val |= RK3288_LVDS_CH0_REG0_TTL_EN | 129 RK3288_LVDS_CH0_REG0_LANECK_EN; 130 lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); 131 lvds_writel(lvds, RK3288_LVDS_CH0_REG2, 132 RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 133 lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 134 RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE | 135 RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE | 136 RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE | 137 RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE | 138 RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE | 139 RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE); 140 lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 141 RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA | 142 RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA | 143 RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA | 144 RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA | 145 RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA | 146 RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA); 147 } else { 148 val |= RK3288_LVDS_CH0_REG0_LVDS_EN | 149 RK3288_LVDS_CH0_REG0_LANECK_EN; 150 lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); 151 lvds_writel(lvds, RK3288_LVDS_CH0_REG1, 152 RK3288_LVDS_CH0_REG1_LANECK_BIAS | 153 RK3288_LVDS_CH0_REG1_LANE4_BIAS | 154 RK3288_LVDS_CH0_REG1_LANE3_BIAS | 155 RK3288_LVDS_CH0_REG1_LANE2_BIAS | 156 RK3288_LVDS_CH0_REG1_LANE1_BIAS | 157 RK3288_LVDS_CH0_REG1_LANE0_BIAS); 158 lvds_writel(lvds, RK3288_LVDS_CH0_REG2, 159 RK3288_LVDS_CH0_REG2_RESERVE_ON | 160 RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE | 161 RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE | 162 RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE | 163 RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE | 164 RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE | 165 RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE | 166 RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 167 lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00); 168 lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00); 169 } 170 lvds_writel(lvds, RK3288_LVDS_CH0_REG3, RK3288_LVDS_PLL_FBDIV_REG3(0x46)); 171 lvds_writel(lvds, RK3288_LVDS_CH0_REGD, RK3288_LVDS_PLL_PREDIV_REGD(0x0a)); 172 lvds_writel(lvds, RK3288_LVDS_CH0_REG20, RK3288_LVDS_CH0_REG20_LSB); 173 174 lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); 175 lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); 176 177 return 0; 178 } 179 180 static void rockchip_lvds_poweroff(struct rockchip_lvds *lvds) 181 { 182 int ret; 183 u32 val; 184 185 lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); 186 lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); 187 val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN; 188 val |= val << 16; 189 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); 190 if (ret != 0) 191 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 192 193 pm_runtime_put(lvds->dev); 194 clk_disable(lvds->pclk); 195 } 196 197 static const struct drm_connector_funcs rockchip_lvds_connector_funcs = { 198 .fill_modes = drm_helper_probe_single_connector_modes, 199 .destroy = drm_connector_cleanup, 200 .reset = drm_atomic_helper_connector_reset, 201 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 202 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 203 }; 204 205 static int rockchip_lvds_connector_get_modes(struct drm_connector *connector) 206 { 207 struct rockchip_lvds *lvds = connector_to_lvds(connector); 208 struct drm_panel *panel = lvds->panel; 209 210 return drm_panel_get_modes(panel); 211 } 212 213 static const 214 struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = { 215 .get_modes = rockchip_lvds_connector_get_modes, 216 }; 217 218 static void rockchip_lvds_grf_config(struct drm_encoder *encoder, 219 struct drm_display_mode *mode) 220 { 221 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 222 u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0; 223 u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0; 224 u32 val; 225 int ret; 226 227 /* iomux to LCD data/sync mode */ 228 if (lvds->output == DISPLAY_OUTPUT_RGB) 229 if (lvds->pins && !IS_ERR(lvds->pins->default_state)) 230 pinctrl_select_state(lvds->pins->p, 231 lvds->pins->default_state); 232 val = lvds->format | LVDS_CH0_EN; 233 if (lvds->output == DISPLAY_OUTPUT_RGB) 234 val |= LVDS_TTL_EN | LVDS_CH1_EN; 235 else if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS) 236 val |= LVDS_DUAL | LVDS_CH1_EN; 237 238 if ((mode->htotal - mode->hsync_start) & 0x01) 239 val |= LVDS_START_PHASE_RST_1; 240 241 val |= (pin_dclk << 8) | (pin_hsync << 9); 242 val |= (0xffff << 16); 243 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); 244 if (ret != 0) { 245 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 246 return; 247 } 248 } 249 250 static int rockchip_lvds_set_vop_source(struct rockchip_lvds *lvds, 251 struct drm_encoder *encoder) 252 { 253 u32 val; 254 int ret; 255 256 if (!lvds->soc_data->has_vop_sel) 257 return 0; 258 259 ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder); 260 if (ret < 0) 261 return ret; 262 263 val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16; 264 if (ret) 265 val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT; 266 267 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con6, val); 268 if (ret < 0) 269 return ret; 270 271 return 0; 272 } 273 274 static int 275 rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder, 276 struct drm_crtc_state *crtc_state, 277 struct drm_connector_state *conn_state) 278 { 279 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 280 281 s->output_mode = ROCKCHIP_OUT_MODE_P888; 282 s->output_type = DRM_MODE_CONNECTOR_LVDS; 283 284 return 0; 285 } 286 287 static void rockchip_lvds_encoder_enable(struct drm_encoder *encoder) 288 { 289 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 290 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 291 int ret; 292 293 drm_panel_prepare(lvds->panel); 294 ret = rockchip_lvds_poweron(lvds); 295 if (ret < 0) { 296 DRM_DEV_ERROR(lvds->dev, "failed to power on lvds: %d\n", ret); 297 drm_panel_unprepare(lvds->panel); 298 } 299 rockchip_lvds_grf_config(encoder, mode); 300 rockchip_lvds_set_vop_source(lvds, encoder); 301 drm_panel_enable(lvds->panel); 302 } 303 304 static void rockchip_lvds_encoder_disable(struct drm_encoder *encoder) 305 { 306 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 307 308 drm_panel_disable(lvds->panel); 309 rockchip_lvds_poweroff(lvds); 310 drm_panel_unprepare(lvds->panel); 311 } 312 313 static const 314 struct drm_encoder_helper_funcs rockchip_lvds_encoder_helper_funcs = { 315 .enable = rockchip_lvds_encoder_enable, 316 .disable = rockchip_lvds_encoder_disable, 317 .atomic_check = rockchip_lvds_encoder_atomic_check, 318 }; 319 320 static const struct drm_encoder_funcs rockchip_lvds_encoder_funcs = { 321 .destroy = drm_encoder_cleanup, 322 }; 323 324 static const struct rockchip_lvds_soc_data rk3288_lvds_data = { 325 .ch1_offset = 0x100, 326 .grf_soc_con6 = 0x025c, 327 .grf_soc_con7 = 0x0260, 328 .has_vop_sel = true, 329 }; 330 331 static const struct of_device_id rockchip_lvds_dt_ids[] = { 332 { 333 .compatible = "rockchip,rk3288-lvds", 334 .data = &rk3288_lvds_data 335 }, 336 {} 337 }; 338 MODULE_DEVICE_TABLE(of, rockchip_lvds_dt_ids); 339 340 static int rockchip_lvds_bind(struct device *dev, struct device *master, 341 void *data) 342 { 343 struct rockchip_lvds *lvds = dev_get_drvdata(dev); 344 struct drm_device *drm_dev = data; 345 struct drm_encoder *encoder; 346 struct drm_connector *connector; 347 struct device_node *remote = NULL; 348 struct device_node *port, *endpoint; 349 int ret = 0, child_count = 0; 350 const char *name; 351 u32 endpoint_id; 352 353 lvds->drm_dev = drm_dev; 354 port = of_graph_get_port_by_id(dev->of_node, 1); 355 if (!port) { 356 DRM_DEV_ERROR(dev, 357 "can't found port point, please init lvds panel port!\n"); 358 return -EINVAL; 359 } 360 for_each_child_of_node(port, endpoint) { 361 child_count++; 362 of_property_read_u32(endpoint, "reg", &endpoint_id); 363 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id, 364 &lvds->panel, &lvds->bridge); 365 if (!ret) 366 break; 367 } 368 if (!child_count) { 369 DRM_DEV_ERROR(dev, "lvds port does not have any children\n"); 370 ret = -EINVAL; 371 goto err_put_port; 372 } else if (ret) { 373 DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n"); 374 ret = -EPROBE_DEFER; 375 goto err_put_port; 376 } 377 if (lvds->panel) 378 remote = lvds->panel->dev->of_node; 379 else 380 remote = lvds->bridge->of_node; 381 if (of_property_read_string(dev->of_node, "rockchip,output", &name)) 382 /* default set it as output rgb */ 383 lvds->output = DISPLAY_OUTPUT_RGB; 384 else 385 lvds->output = lvds_name_to_output(name); 386 387 if (lvds->output < 0) { 388 DRM_DEV_ERROR(dev, "invalid output type [%s]\n", name); 389 ret = lvds->output; 390 goto err_put_remote; 391 } 392 393 if (of_property_read_string(remote, "data-mapping", &name)) 394 /* default set it as format vesa 18 */ 395 lvds->format = LVDS_VESA_18; 396 else 397 lvds->format = lvds_name_to_format(name); 398 399 if (lvds->format < 0) { 400 DRM_DEV_ERROR(dev, "invalid data-mapping format [%s]\n", name); 401 ret = lvds->format; 402 goto err_put_remote; 403 } 404 405 encoder = &lvds->encoder; 406 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, 407 dev->of_node); 408 409 ret = drm_encoder_init(drm_dev, encoder, &rockchip_lvds_encoder_funcs, 410 DRM_MODE_ENCODER_LVDS, NULL); 411 if (ret < 0) { 412 DRM_DEV_ERROR(drm_dev->dev, 413 "failed to initialize encoder: %d\n", ret); 414 goto err_put_remote; 415 } 416 417 drm_encoder_helper_add(encoder, &rockchip_lvds_encoder_helper_funcs); 418 419 if (lvds->panel) { 420 connector = &lvds->connector; 421 connector->dpms = DRM_MODE_DPMS_OFF; 422 ret = drm_connector_init(drm_dev, connector, 423 &rockchip_lvds_connector_funcs, 424 DRM_MODE_CONNECTOR_LVDS); 425 if (ret < 0) { 426 DRM_DEV_ERROR(drm_dev->dev, 427 "failed to initialize connector: %d\n", ret); 428 goto err_free_encoder; 429 } 430 431 drm_connector_helper_add(connector, 432 &rockchip_lvds_connector_helper_funcs); 433 434 ret = drm_mode_connector_attach_encoder(connector, encoder); 435 if (ret < 0) { 436 DRM_DEV_ERROR(drm_dev->dev, 437 "failed to attach encoder: %d\n", ret); 438 goto err_free_connector; 439 } 440 441 ret = drm_panel_attach(lvds->panel, connector); 442 if (ret < 0) { 443 DRM_DEV_ERROR(drm_dev->dev, 444 "failed to attach panel: %d\n", ret); 445 goto err_free_connector; 446 } 447 } else { 448 lvds->bridge->encoder = encoder; 449 ret = drm_bridge_attach(encoder, lvds->bridge, NULL); 450 if (ret) { 451 DRM_DEV_ERROR(drm_dev->dev, 452 "failed to attach bridge: %d\n", ret); 453 goto err_free_encoder; 454 } 455 encoder->bridge = lvds->bridge; 456 } 457 458 pm_runtime_enable(dev); 459 of_node_put(remote); 460 of_node_put(port); 461 462 return 0; 463 464 err_free_connector: 465 drm_connector_cleanup(connector); 466 err_free_encoder: 467 drm_encoder_cleanup(encoder); 468 err_put_remote: 469 of_node_put(remote); 470 err_put_port: 471 of_node_put(port); 472 473 return ret; 474 } 475 476 static void rockchip_lvds_unbind(struct device *dev, struct device *master, 477 void *data) 478 { 479 struct rockchip_lvds *lvds = dev_get_drvdata(dev); 480 481 rockchip_lvds_encoder_disable(&lvds->encoder); 482 if (lvds->panel) 483 drm_panel_detach(lvds->panel); 484 pm_runtime_disable(dev); 485 drm_connector_cleanup(&lvds->connector); 486 drm_encoder_cleanup(&lvds->encoder); 487 } 488 489 static const struct component_ops rockchip_lvds_component_ops = { 490 .bind = rockchip_lvds_bind, 491 .unbind = rockchip_lvds_unbind, 492 }; 493 494 static int rockchip_lvds_probe(struct platform_device *pdev) 495 { 496 struct device *dev = &pdev->dev; 497 struct rockchip_lvds *lvds; 498 const struct of_device_id *match; 499 struct resource *res; 500 int ret; 501 502 if (!dev->of_node) 503 return -ENODEV; 504 505 lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); 506 if (!lvds) 507 return -ENOMEM; 508 509 lvds->dev = dev; 510 match = of_match_node(rockchip_lvds_dt_ids, dev->of_node); 511 if (!match) 512 return -ENODEV; 513 lvds->soc_data = match->data; 514 515 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 516 lvds->regs = devm_ioremap_resource(&pdev->dev, res); 517 if (IS_ERR(lvds->regs)) 518 return PTR_ERR(lvds->regs); 519 520 lvds->pclk = devm_clk_get(&pdev->dev, "pclk_lvds"); 521 if (IS_ERR(lvds->pclk)) { 522 DRM_DEV_ERROR(dev, "could not get pclk_lvds\n"); 523 return PTR_ERR(lvds->pclk); 524 } 525 526 lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins), 527 GFP_KERNEL); 528 if (!lvds->pins) 529 return -ENOMEM; 530 531 lvds->pins->p = devm_pinctrl_get(lvds->dev); 532 if (IS_ERR(lvds->pins->p)) { 533 DRM_DEV_ERROR(dev, "no pinctrl handle\n"); 534 devm_kfree(lvds->dev, lvds->pins); 535 lvds->pins = NULL; 536 } else { 537 lvds->pins->default_state = 538 pinctrl_lookup_state(lvds->pins->p, "lcdc"); 539 if (IS_ERR(lvds->pins->default_state)) { 540 DRM_DEV_ERROR(dev, "no default pinctrl state\n"); 541 devm_kfree(lvds->dev, lvds->pins); 542 lvds->pins = NULL; 543 } 544 } 545 546 lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 547 "rockchip,grf"); 548 if (IS_ERR(lvds->grf)) { 549 DRM_DEV_ERROR(dev, "missing rockchip,grf property\n"); 550 return PTR_ERR(lvds->grf); 551 } 552 553 dev_set_drvdata(dev, lvds); 554 555 ret = clk_prepare(lvds->pclk); 556 if (ret < 0) { 557 DRM_DEV_ERROR(dev, "failed to prepare pclk_lvds\n"); 558 return ret; 559 } 560 ret = component_add(&pdev->dev, &rockchip_lvds_component_ops); 561 if (ret < 0) { 562 DRM_DEV_ERROR(dev, "failed to add component\n"); 563 clk_unprepare(lvds->pclk); 564 } 565 566 return ret; 567 } 568 569 static int rockchip_lvds_remove(struct platform_device *pdev) 570 { 571 struct rockchip_lvds *lvds = dev_get_drvdata(&pdev->dev); 572 573 component_del(&pdev->dev, &rockchip_lvds_component_ops); 574 clk_unprepare(lvds->pclk); 575 576 return 0; 577 } 578 579 struct platform_driver rockchip_lvds_driver = { 580 .probe = rockchip_lvds_probe, 581 .remove = rockchip_lvds_remove, 582 .driver = { 583 .name = "rockchip-lvds", 584 .of_match_table = of_match_ptr(rockchip_lvds_dt_ids), 585 }, 586 }; 587