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