1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) Rockchip Electronics Co., Ltd. 4 * Author: 5 * Mark Yao <mark.yao@rock-chips.com> 6 * Sandy Huang <hjc@rock-chips.com> 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/component.h> 11 #include <linux/mfd/syscon.h> 12 #include <linux/of_graph.h> 13 #include <linux/phy/phy.h> 14 #include <linux/pinctrl/devinfo.h> 15 #include <linux/platform_device.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 #include <linux/reset.h> 19 20 #include <drm/drm_atomic_helper.h> 21 #include <drm/drm_bridge.h> 22 #include <drm/drm_bridge_connector.h> 23 #include <drm/drm_of.h> 24 #include <drm/drm_panel.h> 25 #include <drm/drm_probe_helper.h> 26 #include <drm/drm_simple_kms_helper.h> 27 28 #include "rockchip_drm_drv.h" 29 #include "rockchip_lvds.h" 30 31 #define DISPLAY_OUTPUT_RGB 0 32 #define DISPLAY_OUTPUT_LVDS 1 33 #define DISPLAY_OUTPUT_DUAL_LVDS 2 34 35 struct rockchip_lvds; 36 37 /** 38 * struct rockchip_lvds_soc_data - rockchip lvds Soc private data 39 * @probe: LVDS platform probe function 40 * @helper_funcs: LVDS connector helper functions 41 */ 42 struct rockchip_lvds_soc_data { 43 int (*probe)(struct platform_device *pdev, struct rockchip_lvds *lvds); 44 const struct drm_encoder_helper_funcs *helper_funcs; 45 }; 46 47 struct rockchip_lvds { 48 struct device *dev; 49 void __iomem *regs; 50 struct regmap *grf; 51 struct clk *pclk; 52 struct phy *dphy; 53 const struct rockchip_lvds_soc_data *soc_data; 54 int output; /* rgb lvds or dual lvds output */ 55 int format; /* vesa or jeida format */ 56 struct drm_device *drm_dev; 57 struct drm_panel *panel; 58 struct drm_bridge *bridge; 59 struct drm_connector connector; 60 struct rockchip_encoder encoder; 61 struct dev_pin_info *pins; 62 }; 63 64 static inline struct rockchip_lvds *connector_to_lvds(struct drm_connector *connector) 65 { 66 return container_of(connector, struct rockchip_lvds, connector); 67 } 68 69 static inline struct rockchip_lvds *encoder_to_lvds(struct drm_encoder *encoder) 70 { 71 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); 72 73 return container_of(rkencoder, struct rockchip_lvds, encoder); 74 } 75 76 static inline void rk3288_writel(struct rockchip_lvds *lvds, u32 offset, 77 u32 val) 78 { 79 writel_relaxed(val, lvds->regs + offset); 80 if (lvds->output == DISPLAY_OUTPUT_LVDS) 81 return; 82 writel_relaxed(val, lvds->regs + offset + RK3288_LVDS_CH1_OFFSET); 83 } 84 85 static inline int rockchip_lvds_name_to_format(const char *s) 86 { 87 if (strncmp(s, "jeida-18", 8) == 0) 88 return LVDS_JEIDA_18; 89 else if (strncmp(s, "jeida-24", 8) == 0) 90 return LVDS_JEIDA_24; 91 else if (strncmp(s, "vesa-24", 7) == 0) 92 return LVDS_VESA_24; 93 94 return -EINVAL; 95 } 96 97 static inline int rockchip_lvds_name_to_output(const char *s) 98 { 99 if (strncmp(s, "rgb", 3) == 0) 100 return DISPLAY_OUTPUT_RGB; 101 else if (strncmp(s, "lvds", 4) == 0) 102 return DISPLAY_OUTPUT_LVDS; 103 else if (strncmp(s, "duallvds", 8) == 0) 104 return DISPLAY_OUTPUT_DUAL_LVDS; 105 106 return -EINVAL; 107 } 108 109 static const struct drm_connector_funcs rockchip_lvds_connector_funcs = { 110 .fill_modes = drm_helper_probe_single_connector_modes, 111 .destroy = drm_connector_cleanup, 112 .reset = drm_atomic_helper_connector_reset, 113 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 114 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 115 }; 116 117 static int rockchip_lvds_connector_get_modes(struct drm_connector *connector) 118 { 119 struct rockchip_lvds *lvds = connector_to_lvds(connector); 120 struct drm_panel *panel = lvds->panel; 121 122 return drm_panel_get_modes(panel, connector); 123 } 124 125 static const 126 struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = { 127 .get_modes = rockchip_lvds_connector_get_modes, 128 }; 129 130 static int 131 rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder, 132 struct drm_crtc_state *crtc_state, 133 struct drm_connector_state *conn_state) 134 { 135 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 136 137 s->output_mode = ROCKCHIP_OUT_MODE_P888; 138 s->output_type = DRM_MODE_CONNECTOR_LVDS; 139 140 return 0; 141 } 142 143 static int rk3288_lvds_poweron(struct rockchip_lvds *lvds) 144 { 145 int ret; 146 u32 val; 147 148 ret = clk_enable(lvds->pclk); 149 if (ret < 0) { 150 DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret); 151 return ret; 152 } 153 ret = pm_runtime_resume_and_get(lvds->dev); 154 if (ret < 0) { 155 DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); 156 clk_disable(lvds->pclk); 157 return ret; 158 } 159 val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN | 160 RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN | 161 RK3288_LVDS_CH0_REG0_LANE0_EN; 162 if (lvds->output == DISPLAY_OUTPUT_RGB) { 163 val |= RK3288_LVDS_CH0_REG0_TTL_EN | 164 RK3288_LVDS_CH0_REG0_LANECK_EN; 165 rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val); 166 rk3288_writel(lvds, RK3288_LVDS_CH0_REG2, 167 RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 168 rk3288_writel(lvds, RK3288_LVDS_CH0_REG4, 169 RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE | 170 RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE | 171 RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE | 172 RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE | 173 RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE | 174 RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE); 175 rk3288_writel(lvds, RK3288_LVDS_CH0_REG5, 176 RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA | 177 RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA | 178 RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA | 179 RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA | 180 RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA | 181 RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA); 182 } else { 183 val |= RK3288_LVDS_CH0_REG0_LVDS_EN | 184 RK3288_LVDS_CH0_REG0_LANECK_EN; 185 rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val); 186 rk3288_writel(lvds, RK3288_LVDS_CH0_REG1, 187 RK3288_LVDS_CH0_REG1_LANECK_BIAS | 188 RK3288_LVDS_CH0_REG1_LANE4_BIAS | 189 RK3288_LVDS_CH0_REG1_LANE3_BIAS | 190 RK3288_LVDS_CH0_REG1_LANE2_BIAS | 191 RK3288_LVDS_CH0_REG1_LANE1_BIAS | 192 RK3288_LVDS_CH0_REG1_LANE0_BIAS); 193 rk3288_writel(lvds, RK3288_LVDS_CH0_REG2, 194 RK3288_LVDS_CH0_REG2_RESERVE_ON | 195 RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE | 196 RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE | 197 RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE | 198 RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE | 199 RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE | 200 RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE | 201 RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 202 rk3288_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00); 203 rk3288_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00); 204 } 205 rk3288_writel(lvds, RK3288_LVDS_CH0_REG3, 206 RK3288_LVDS_PLL_FBDIV_REG3(0x46)); 207 rk3288_writel(lvds, RK3288_LVDS_CH0_REGD, 208 RK3288_LVDS_PLL_PREDIV_REGD(0x0a)); 209 rk3288_writel(lvds, RK3288_LVDS_CH0_REG20, 210 RK3288_LVDS_CH0_REG20_LSB); 211 212 rk3288_writel(lvds, RK3288_LVDS_CFG_REGC, 213 RK3288_LVDS_CFG_REGC_PLL_ENABLE); 214 rk3288_writel(lvds, RK3288_LVDS_CFG_REG21, 215 RK3288_LVDS_CFG_REG21_TX_ENABLE); 216 217 return 0; 218 } 219 220 static void rk3288_lvds_poweroff(struct rockchip_lvds *lvds) 221 { 222 int ret; 223 u32 val; 224 225 rk3288_writel(lvds, RK3288_LVDS_CFG_REG21, 226 RK3288_LVDS_CFG_REG21_TX_ENABLE); 227 rk3288_writel(lvds, RK3288_LVDS_CFG_REGC, 228 RK3288_LVDS_CFG_REGC_PLL_ENABLE); 229 val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN; 230 val |= val << 16; 231 ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val); 232 if (ret != 0) 233 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 234 235 pm_runtime_put(lvds->dev); 236 clk_disable(lvds->pclk); 237 } 238 239 static int rk3288_lvds_grf_config(struct drm_encoder *encoder, 240 struct drm_display_mode *mode) 241 { 242 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 243 u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0; 244 u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0; 245 u32 val; 246 int ret; 247 248 /* iomux to LCD data/sync mode */ 249 if (lvds->output == DISPLAY_OUTPUT_RGB) 250 if (lvds->pins && !IS_ERR(lvds->pins->default_state)) 251 pinctrl_select_state(lvds->pins->p, 252 lvds->pins->default_state); 253 val = lvds->format | LVDS_CH0_EN; 254 if (lvds->output == DISPLAY_OUTPUT_RGB) 255 val |= LVDS_TTL_EN | LVDS_CH1_EN; 256 else if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS) 257 val |= LVDS_DUAL | LVDS_CH1_EN; 258 259 if ((mode->htotal - mode->hsync_start) & 0x01) 260 val |= LVDS_START_PHASE_RST_1; 261 262 val |= (pin_dclk << 8) | (pin_hsync << 9); 263 val |= (0xffff << 16); 264 ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val); 265 if (ret) 266 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 267 268 return ret; 269 } 270 271 static int rk3288_lvds_set_vop_source(struct rockchip_lvds *lvds, 272 struct drm_encoder *encoder) 273 { 274 u32 val; 275 int ret; 276 277 ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder); 278 if (ret < 0) 279 return ret; 280 281 val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16; 282 if (ret) 283 val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT; 284 285 ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON6, val); 286 if (ret < 0) 287 return ret; 288 289 return 0; 290 } 291 292 static void rk3288_lvds_encoder_enable(struct drm_encoder *encoder) 293 { 294 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 295 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 296 int ret; 297 298 drm_panel_prepare(lvds->panel); 299 300 ret = rk3288_lvds_poweron(lvds); 301 if (ret < 0) { 302 DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret); 303 drm_panel_unprepare(lvds->panel); 304 return; 305 } 306 307 ret = rk3288_lvds_grf_config(encoder, mode); 308 if (ret) { 309 DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret); 310 drm_panel_unprepare(lvds->panel); 311 return; 312 } 313 314 ret = rk3288_lvds_set_vop_source(lvds, encoder); 315 if (ret) { 316 DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret); 317 drm_panel_unprepare(lvds->panel); 318 return; 319 } 320 321 drm_panel_enable(lvds->panel); 322 } 323 324 static void rk3288_lvds_encoder_disable(struct drm_encoder *encoder) 325 { 326 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 327 328 drm_panel_disable(lvds->panel); 329 rk3288_lvds_poweroff(lvds); 330 drm_panel_unprepare(lvds->panel); 331 } 332 333 static int px30_lvds_poweron(struct rockchip_lvds *lvds) 334 { 335 int ret; 336 337 ret = pm_runtime_resume_and_get(lvds->dev); 338 if (ret < 0) { 339 DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); 340 return ret; 341 } 342 343 /* Enable LVDS mode */ 344 ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 345 PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1), 346 PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1)); 347 if (ret) 348 pm_runtime_put(lvds->dev); 349 350 return ret; 351 } 352 353 static void px30_lvds_poweroff(struct rockchip_lvds *lvds) 354 { 355 regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 356 PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1), 357 PX30_LVDS_MODE_EN(0) | PX30_LVDS_P2S_EN(0)); 358 359 pm_runtime_put(lvds->dev); 360 } 361 362 static int px30_lvds_grf_config(struct drm_encoder *encoder, 363 struct drm_display_mode *mode) 364 { 365 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 366 367 if (lvds->output != DISPLAY_OUTPUT_LVDS) { 368 DRM_DEV_ERROR(lvds->dev, "Unsupported display output %d\n", 369 lvds->output); 370 return -EINVAL; 371 } 372 373 /* Set format */ 374 return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 375 PX30_LVDS_FORMAT(lvds->format), 376 PX30_LVDS_FORMAT(lvds->format)); 377 } 378 379 static int px30_lvds_set_vop_source(struct rockchip_lvds *lvds, 380 struct drm_encoder *encoder) 381 { 382 int vop; 383 384 vop = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder); 385 if (vop < 0) 386 return vop; 387 388 return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 389 PX30_LVDS_VOP_SEL(1), 390 PX30_LVDS_VOP_SEL(vop)); 391 } 392 393 static void px30_lvds_encoder_enable(struct drm_encoder *encoder) 394 { 395 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 396 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 397 int ret; 398 399 drm_panel_prepare(lvds->panel); 400 401 ret = px30_lvds_poweron(lvds); 402 if (ret) { 403 DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret); 404 drm_panel_unprepare(lvds->panel); 405 return; 406 } 407 408 ret = px30_lvds_grf_config(encoder, mode); 409 if (ret) { 410 DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret); 411 drm_panel_unprepare(lvds->panel); 412 return; 413 } 414 415 ret = px30_lvds_set_vop_source(lvds, encoder); 416 if (ret) { 417 DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret); 418 drm_panel_unprepare(lvds->panel); 419 return; 420 } 421 422 drm_panel_enable(lvds->panel); 423 } 424 425 static void px30_lvds_encoder_disable(struct drm_encoder *encoder) 426 { 427 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 428 429 drm_panel_disable(lvds->panel); 430 px30_lvds_poweroff(lvds); 431 drm_panel_unprepare(lvds->panel); 432 } 433 434 static const 435 struct drm_encoder_helper_funcs rk3288_lvds_encoder_helper_funcs = { 436 .enable = rk3288_lvds_encoder_enable, 437 .disable = rk3288_lvds_encoder_disable, 438 .atomic_check = rockchip_lvds_encoder_atomic_check, 439 }; 440 441 static const 442 struct drm_encoder_helper_funcs px30_lvds_encoder_helper_funcs = { 443 .enable = px30_lvds_encoder_enable, 444 .disable = px30_lvds_encoder_disable, 445 .atomic_check = rockchip_lvds_encoder_atomic_check, 446 }; 447 448 static int rk3288_lvds_probe(struct platform_device *pdev, 449 struct rockchip_lvds *lvds) 450 { 451 lvds->regs = devm_platform_ioremap_resource(pdev, 0); 452 if (IS_ERR(lvds->regs)) 453 return PTR_ERR(lvds->regs); 454 455 lvds->pclk = devm_clk_get_prepared(lvds->dev, "pclk_lvds"); 456 if (IS_ERR(lvds->pclk)) 457 return dev_err_probe(lvds->dev, PTR_ERR(lvds->pclk), 458 "could not get or prepare pclk_lvds\n"); 459 460 lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins), 461 GFP_KERNEL); 462 if (!lvds->pins) 463 return -ENOMEM; 464 465 lvds->pins->p = devm_pinctrl_get(lvds->dev); 466 if (IS_ERR(lvds->pins->p)) { 467 dev_warn(lvds->dev, "no pinctrl handle\n"); 468 devm_kfree(lvds->dev, lvds->pins); 469 lvds->pins = NULL; 470 } else { 471 lvds->pins->default_state = 472 pinctrl_lookup_state(lvds->pins->p, "lcdc"); 473 if (IS_ERR(lvds->pins->default_state)) { 474 dev_warn(lvds->dev, "no default pinctrl state\n"); 475 devm_kfree(lvds->dev, lvds->pins); 476 lvds->pins = NULL; 477 } 478 } 479 480 return 0; 481 } 482 483 static int px30_lvds_probe(struct platform_device *pdev, 484 struct rockchip_lvds *lvds) 485 { 486 int ret; 487 488 /* MSB */ 489 ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 490 PX30_LVDS_MSBSEL(1), 491 PX30_LVDS_MSBSEL(1)); 492 if (ret) 493 return ret; 494 495 /* PHY */ 496 lvds->dphy = devm_phy_get(&pdev->dev, "dphy"); 497 if (IS_ERR(lvds->dphy)) 498 return PTR_ERR(lvds->dphy); 499 500 ret = phy_init(lvds->dphy); 501 if (ret) 502 return ret; 503 504 ret = phy_set_mode(lvds->dphy, PHY_MODE_LVDS); 505 if (ret) 506 return ret; 507 508 return phy_power_on(lvds->dphy); 509 } 510 511 static const struct rockchip_lvds_soc_data rk3288_lvds_data = { 512 .probe = rk3288_lvds_probe, 513 .helper_funcs = &rk3288_lvds_encoder_helper_funcs, 514 }; 515 516 static const struct rockchip_lvds_soc_data px30_lvds_data = { 517 .probe = px30_lvds_probe, 518 .helper_funcs = &px30_lvds_encoder_helper_funcs, 519 }; 520 521 static const struct of_device_id rockchip_lvds_dt_ids[] = { 522 { 523 .compatible = "rockchip,rk3288-lvds", 524 .data = &rk3288_lvds_data 525 }, 526 { 527 .compatible = "rockchip,px30-lvds", 528 .data = &px30_lvds_data 529 }, 530 {} 531 }; 532 MODULE_DEVICE_TABLE(of, rockchip_lvds_dt_ids); 533 534 static int rockchip_lvds_bind(struct device *dev, struct device *master, 535 void *data) 536 { 537 struct rockchip_lvds *lvds = dev_get_drvdata(dev); 538 struct drm_device *drm_dev = data; 539 struct drm_encoder *encoder; 540 struct drm_connector *connector; 541 struct device_node *remote = NULL; 542 struct device_node *port, *endpoint; 543 int ret = 0, child_count = 0; 544 const char *name; 545 u32 endpoint_id = 0; 546 547 lvds->drm_dev = drm_dev; 548 port = of_graph_get_port_by_id(dev->of_node, 1); 549 if (!port) 550 return dev_err_probe(dev, -EINVAL, 551 "can't found port point, please init lvds panel port!\n"); 552 553 for_each_child_of_node(port, endpoint) { 554 child_count++; 555 of_property_read_u32(endpoint, "reg", &endpoint_id); 556 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id, 557 &lvds->panel, &lvds->bridge); 558 if (!ret) { 559 of_node_put(endpoint); 560 break; 561 } 562 } 563 if (!child_count) { 564 ret = dev_err_probe(dev, -EINVAL, "lvds port does not have any children\n"); 565 goto err_put_port; 566 } else if (ret) { 567 dev_err_probe(dev, ret, "failed to find panel and bridge node\n"); 568 goto err_put_port; 569 } 570 if (lvds->panel) 571 remote = lvds->panel->dev->of_node; 572 else 573 remote = lvds->bridge->of_node; 574 if (of_property_read_string(dev->of_node, "rockchip,output", &name)) 575 /* default set it as output rgb */ 576 lvds->output = DISPLAY_OUTPUT_RGB; 577 else 578 lvds->output = rockchip_lvds_name_to_output(name); 579 580 if (lvds->output < 0) { 581 ret = dev_err_probe(dev, lvds->output, "invalid output type [%s]\n", name); 582 goto err_put_remote; 583 } 584 585 if (of_property_read_string(remote, "data-mapping", &name)) 586 /* default set it as format vesa 18 */ 587 lvds->format = LVDS_VESA_18; 588 else 589 lvds->format = rockchip_lvds_name_to_format(name); 590 591 if (lvds->format < 0) { 592 ret = dev_err_probe(dev, lvds->format, 593 "invalid data-mapping format [%s]\n", name); 594 goto err_put_remote; 595 } 596 597 encoder = &lvds->encoder.encoder; 598 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, 599 dev->of_node); 600 601 ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_LVDS); 602 if (ret < 0) { 603 drm_err(drm_dev, 604 "failed to initialize encoder: %d\n", ret); 605 goto err_put_remote; 606 } 607 608 drm_encoder_helper_add(encoder, lvds->soc_data->helper_funcs); 609 connector = &lvds->connector; 610 611 if (lvds->panel) { 612 connector->dpms = DRM_MODE_DPMS_OFF; 613 ret = drm_connector_init(drm_dev, connector, 614 &rockchip_lvds_connector_funcs, 615 DRM_MODE_CONNECTOR_LVDS); 616 if (ret < 0) { 617 drm_err(drm_dev, 618 "failed to initialize connector: %d\n", ret); 619 goto err_free_encoder; 620 } 621 622 drm_connector_helper_add(connector, 623 &rockchip_lvds_connector_helper_funcs); 624 } else { 625 ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 626 DRM_BRIDGE_ATTACH_NO_CONNECTOR); 627 if (ret) 628 goto err_free_encoder; 629 630 connector = drm_bridge_connector_init(lvds->drm_dev, encoder); 631 if (IS_ERR(connector)) { 632 drm_err(drm_dev, 633 "failed to initialize bridge connector: %pe\n", 634 connector); 635 ret = PTR_ERR(connector); 636 goto err_free_encoder; 637 } 638 } 639 640 ret = drm_connector_attach_encoder(connector, encoder); 641 if (ret < 0) { 642 drm_err(drm_dev, "failed to attach encoder: %d\n", ret); 643 goto err_free_connector; 644 } 645 646 pm_runtime_enable(dev); 647 of_node_put(remote); 648 of_node_put(port); 649 650 return 0; 651 652 err_free_connector: 653 drm_connector_cleanup(connector); 654 err_free_encoder: 655 drm_encoder_cleanup(encoder); 656 err_put_remote: 657 of_node_put(remote); 658 err_put_port: 659 of_node_put(port); 660 661 return ret; 662 } 663 664 static void rockchip_lvds_unbind(struct device *dev, struct device *master, 665 void *data) 666 { 667 struct rockchip_lvds *lvds = dev_get_drvdata(dev); 668 const struct drm_encoder_helper_funcs *encoder_funcs; 669 670 encoder_funcs = lvds->soc_data->helper_funcs; 671 encoder_funcs->disable(&lvds->encoder.encoder); 672 pm_runtime_disable(dev); 673 drm_connector_cleanup(&lvds->connector); 674 drm_encoder_cleanup(&lvds->encoder.encoder); 675 } 676 677 static const struct component_ops rockchip_lvds_component_ops = { 678 .bind = rockchip_lvds_bind, 679 .unbind = rockchip_lvds_unbind, 680 }; 681 682 static int rockchip_lvds_probe(struct platform_device *pdev) 683 { 684 struct device *dev = &pdev->dev; 685 struct rockchip_lvds *lvds; 686 const struct of_device_id *match; 687 int ret; 688 689 if (!dev->of_node) 690 return -ENODEV; 691 692 lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); 693 if (!lvds) 694 return -ENOMEM; 695 696 lvds->dev = dev; 697 match = of_match_node(rockchip_lvds_dt_ids, dev->of_node); 698 if (!match) 699 return -ENODEV; 700 lvds->soc_data = match->data; 701 702 lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 703 "rockchip,grf"); 704 if (IS_ERR(lvds->grf)) 705 return dev_err_probe(dev, PTR_ERR(lvds->grf), "missing rockchip,grf property\n"); 706 707 ret = lvds->soc_data->probe(pdev, lvds); 708 if (ret) 709 return dev_err_probe(dev, ret, "Platform initialization failed\n"); 710 711 dev_set_drvdata(dev, lvds); 712 713 ret = component_add(&pdev->dev, &rockchip_lvds_component_ops); 714 if (ret < 0) 715 return dev_err_probe(dev, ret, "failed to add component\n"); 716 717 return 0; 718 } 719 720 static void rockchip_lvds_remove(struct platform_device *pdev) 721 { 722 component_del(&pdev->dev, &rockchip_lvds_component_ops); 723 } 724 725 struct platform_driver rockchip_lvds_driver = { 726 .probe = rockchip_lvds_probe, 727 .remove = rockchip_lvds_remove, 728 .driver = { 729 .name = "rockchip-lvds", 730 .of_match_table = rockchip_lvds_dt_ids, 731 }, 732 }; 733