1 /* 2 * Rockchip SoC DP (Display Port) interface driver. 3 * 4 * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd. 5 * Author: Andy Yan <andy.yan@rock-chips.com> 6 * Yakir Yang <ykk@rock-chips.com> 7 * Jeff Chen <jeff.chen@rock-chips.com> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 */ 14 15 #include <linux/component.h> 16 #include <linux/mfd/syscon.h> 17 #include <linux/of_device.h> 18 #include <linux/of_graph.h> 19 #include <linux/regmap.h> 20 #include <linux/reset.h> 21 #include <linux/clk.h> 22 23 #include <drm/drmP.h> 24 #include <drm/drm_crtc_helper.h> 25 #include <drm/drm_dp_helper.h> 26 #include <drm/drm_of.h> 27 #include <drm/drm_panel.h> 28 29 #include <video/of_videomode.h> 30 #include <video/videomode.h> 31 32 #include <drm/bridge/analogix_dp.h> 33 34 #include "rockchip_drm_drv.h" 35 #include "rockchip_drm_psr.h" 36 #include "rockchip_drm_vop.h" 37 38 #define RK3288_GRF_SOC_CON6 0x25c 39 #define RK3288_EDP_LCDC_SEL BIT(5) 40 #define RK3399_GRF_SOC_CON20 0x6250 41 #define RK3399_EDP_LCDC_SEL BIT(5) 42 43 #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) 44 45 #define PSR_WAIT_LINE_FLAG_TIMEOUT_MS 100 46 47 #define to_dp(nm) container_of(nm, struct rockchip_dp_device, nm) 48 49 /** 50 * struct rockchip_dp_chip_data - splite the grf setting of kind of chips 51 * @lcdsel_grf_reg: grf register offset of lcdc select 52 * @lcdsel_big: reg value of selecting vop big for eDP 53 * @lcdsel_lit: reg value of selecting vop little for eDP 54 * @chip_type: specific chip type 55 */ 56 struct rockchip_dp_chip_data { 57 u32 lcdsel_grf_reg; 58 u32 lcdsel_big; 59 u32 lcdsel_lit; 60 u32 chip_type; 61 }; 62 63 struct rockchip_dp_device { 64 struct drm_device *drm_dev; 65 struct device *dev; 66 struct drm_encoder encoder; 67 struct drm_display_mode mode; 68 69 struct clk *pclk; 70 struct clk *grfclk; 71 struct regmap *grf; 72 struct reset_control *rst; 73 74 struct work_struct psr_work; 75 spinlock_t psr_lock; 76 unsigned int psr_state; 77 78 const struct rockchip_dp_chip_data *data; 79 80 struct analogix_dp_plat_data plat_data; 81 }; 82 83 static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled) 84 { 85 struct rockchip_dp_device *dp = to_dp(encoder); 86 unsigned long flags; 87 88 if (!analogix_dp_psr_supported(dp->dev)) 89 return; 90 91 dev_dbg(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); 92 93 spin_lock_irqsave(&dp->psr_lock, flags); 94 if (enabled) 95 dp->psr_state = EDP_VSC_PSR_STATE_ACTIVE; 96 else 97 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE; 98 99 schedule_work(&dp->psr_work); 100 spin_unlock_irqrestore(&dp->psr_lock, flags); 101 } 102 103 static void analogix_dp_psr_work(struct work_struct *work) 104 { 105 struct rockchip_dp_device *dp = 106 container_of(work, typeof(*dp), psr_work); 107 struct drm_crtc *crtc = dp->encoder.crtc; 108 int psr_state = dp->psr_state; 109 int vact_end; 110 int ret; 111 unsigned long flags; 112 113 if (!crtc) 114 return; 115 116 vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + crtc->mode.vdisplay; 117 118 ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end, 119 PSR_WAIT_LINE_FLAG_TIMEOUT_MS); 120 if (ret) { 121 dev_err(dp->dev, "line flag interrupt did not arrive\n"); 122 return; 123 } 124 125 spin_lock_irqsave(&dp->psr_lock, flags); 126 if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) 127 analogix_dp_enable_psr(dp->dev); 128 else 129 analogix_dp_disable_psr(dp->dev); 130 spin_unlock_irqrestore(&dp->psr_lock, flags); 131 } 132 133 static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) 134 { 135 reset_control_assert(dp->rst); 136 usleep_range(10, 20); 137 reset_control_deassert(dp->rst); 138 139 return 0; 140 } 141 142 static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data) 143 { 144 struct rockchip_dp_device *dp = to_dp(plat_data); 145 int ret; 146 147 cancel_work_sync(&dp->psr_work); 148 149 ret = clk_prepare_enable(dp->pclk); 150 if (ret < 0) { 151 dev_err(dp->dev, "failed to enable pclk %d\n", ret); 152 return ret; 153 } 154 155 ret = rockchip_dp_pre_init(dp); 156 if (ret < 0) { 157 dev_err(dp->dev, "failed to dp pre init %d\n", ret); 158 clk_disable_unprepare(dp->pclk); 159 return ret; 160 } 161 162 return 0; 163 } 164 165 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) 166 { 167 struct rockchip_dp_device *dp = to_dp(plat_data); 168 169 clk_disable_unprepare(dp->pclk); 170 171 return 0; 172 } 173 174 static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data, 175 struct drm_connector *connector) 176 { 177 struct drm_display_info *di = &connector->display_info; 178 /* VOP couldn't output YUV video format for eDP rightly */ 179 u32 mask = DRM_COLOR_FORMAT_YCRCB444 | DRM_COLOR_FORMAT_YCRCB422; 180 181 if ((di->color_formats & mask)) { 182 DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n"); 183 di->color_formats &= ~mask; 184 di->color_formats |= DRM_COLOR_FORMAT_RGB444; 185 di->bpc = 8; 186 } 187 188 return 0; 189 } 190 191 static bool 192 rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder, 193 const struct drm_display_mode *mode, 194 struct drm_display_mode *adjusted_mode) 195 { 196 /* do nothing */ 197 return true; 198 } 199 200 static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder, 201 struct drm_display_mode *mode, 202 struct drm_display_mode *adjusted) 203 { 204 /* do nothing */ 205 } 206 207 static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder) 208 { 209 struct rockchip_dp_device *dp = to_dp(encoder); 210 int ret; 211 u32 val; 212 213 ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); 214 if (ret < 0) 215 return; 216 217 if (ret) 218 val = dp->data->lcdsel_lit; 219 else 220 val = dp->data->lcdsel_big; 221 222 dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG"); 223 224 ret = clk_prepare_enable(dp->grfclk); 225 if (ret < 0) { 226 dev_err(dp->dev, "failed to enable grfclk %d\n", ret); 227 return; 228 } 229 230 ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val); 231 if (ret != 0) 232 dev_err(dp->dev, "Could not write to GRF: %d\n", ret); 233 234 clk_disable_unprepare(dp->grfclk); 235 } 236 237 static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder) 238 { 239 /* do nothing */ 240 } 241 242 static int 243 rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, 244 struct drm_crtc_state *crtc_state, 245 struct drm_connector_state *conn_state) 246 { 247 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 248 struct rockchip_dp_device *dp = to_dp(encoder); 249 int ret; 250 251 /* 252 * The hardware IC designed that VOP must output the RGB10 video 253 * format to eDP controller, and if eDP panel only support RGB8, 254 * then eDP controller should cut down the video data, not via VOP 255 * controller, that's why we need to hardcode the VOP output mode 256 * to RGA10 here. 257 */ 258 259 s->output_mode = ROCKCHIP_OUT_MODE_AAAA; 260 s->output_type = DRM_MODE_CONNECTOR_eDP; 261 if (dp->data->chip_type == RK3399_EDP) { 262 /* 263 * For RK3399, VOP Lit must code the out mode to RGB888, 264 * VOP Big must code the out mode to RGB10. 265 */ 266 ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, 267 encoder); 268 if (ret > 0) 269 s->output_mode = ROCKCHIP_OUT_MODE_P888; 270 } 271 272 return 0; 273 } 274 275 static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = { 276 .mode_fixup = rockchip_dp_drm_encoder_mode_fixup, 277 .mode_set = rockchip_dp_drm_encoder_mode_set, 278 .enable = rockchip_dp_drm_encoder_enable, 279 .disable = rockchip_dp_drm_encoder_nop, 280 .atomic_check = rockchip_dp_drm_encoder_atomic_check, 281 }; 282 283 static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder) 284 { 285 drm_encoder_cleanup(encoder); 286 } 287 288 static struct drm_encoder_funcs rockchip_dp_encoder_funcs = { 289 .destroy = rockchip_dp_drm_encoder_destroy, 290 }; 291 292 static int rockchip_dp_init(struct rockchip_dp_device *dp) 293 { 294 struct device *dev = dp->dev; 295 struct device_node *np = dev->of_node; 296 int ret; 297 298 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 299 if (IS_ERR(dp->grf)) { 300 dev_err(dev, "failed to get rockchip,grf property\n"); 301 return PTR_ERR(dp->grf); 302 } 303 304 dp->grfclk = devm_clk_get(dev, "grf"); 305 if (PTR_ERR(dp->grfclk) == -ENOENT) { 306 dp->grfclk = NULL; 307 } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) { 308 return -EPROBE_DEFER; 309 } else if (IS_ERR(dp->grfclk)) { 310 dev_err(dev, "failed to get grf clock\n"); 311 return PTR_ERR(dp->grfclk); 312 } 313 314 dp->pclk = devm_clk_get(dev, "pclk"); 315 if (IS_ERR(dp->pclk)) { 316 dev_err(dev, "failed to get pclk property\n"); 317 return PTR_ERR(dp->pclk); 318 } 319 320 dp->rst = devm_reset_control_get(dev, "dp"); 321 if (IS_ERR(dp->rst)) { 322 dev_err(dev, "failed to get dp reset control\n"); 323 return PTR_ERR(dp->rst); 324 } 325 326 ret = clk_prepare_enable(dp->pclk); 327 if (ret < 0) { 328 dev_err(dp->dev, "failed to enable pclk %d\n", ret); 329 return ret; 330 } 331 332 ret = rockchip_dp_pre_init(dp); 333 if (ret < 0) { 334 dev_err(dp->dev, "failed to pre init %d\n", ret); 335 clk_disable_unprepare(dp->pclk); 336 return ret; 337 } 338 339 return 0; 340 } 341 342 static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp) 343 { 344 struct drm_encoder *encoder = &dp->encoder; 345 struct drm_device *drm_dev = dp->drm_dev; 346 struct device *dev = dp->dev; 347 int ret; 348 349 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, 350 dev->of_node); 351 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); 352 353 ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs, 354 DRM_MODE_ENCODER_TMDS, NULL); 355 if (ret) { 356 DRM_ERROR("failed to initialize encoder with drm\n"); 357 return ret; 358 } 359 360 drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs); 361 362 return 0; 363 } 364 365 static int rockchip_dp_bind(struct device *dev, struct device *master, 366 void *data) 367 { 368 struct rockchip_dp_device *dp = dev_get_drvdata(dev); 369 const struct rockchip_dp_chip_data *dp_data; 370 struct drm_device *drm_dev = data; 371 int ret; 372 373 /* 374 * Just like the probe function said, we don't need the 375 * device drvrate anymore, we should leave the charge to 376 * analogix dp driver, set the device drvdata to NULL. 377 */ 378 dev_set_drvdata(dev, NULL); 379 380 dp_data = of_device_get_match_data(dev); 381 if (!dp_data) 382 return -ENODEV; 383 384 ret = rockchip_dp_init(dp); 385 if (ret < 0) 386 return ret; 387 388 dp->data = dp_data; 389 dp->drm_dev = drm_dev; 390 391 ret = rockchip_dp_drm_create_encoder(dp); 392 if (ret) { 393 DRM_ERROR("failed to create drm encoder\n"); 394 return ret; 395 } 396 397 dp->plat_data.encoder = &dp->encoder; 398 399 dp->plat_data.dev_type = dp->data->chip_type; 400 dp->plat_data.power_on = rockchip_dp_poweron; 401 dp->plat_data.power_off = rockchip_dp_powerdown; 402 dp->plat_data.get_modes = rockchip_dp_get_modes; 403 404 spin_lock_init(&dp->psr_lock); 405 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE; 406 INIT_WORK(&dp->psr_work, analogix_dp_psr_work); 407 408 rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set); 409 410 return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); 411 } 412 413 static void rockchip_dp_unbind(struct device *dev, struct device *master, 414 void *data) 415 { 416 struct rockchip_dp_device *dp = dev_get_drvdata(dev); 417 418 rockchip_drm_psr_unregister(&dp->encoder); 419 420 return analogix_dp_unbind(dev, master, data); 421 } 422 423 static const struct component_ops rockchip_dp_component_ops = { 424 .bind = rockchip_dp_bind, 425 .unbind = rockchip_dp_unbind, 426 }; 427 428 static int rockchip_dp_probe(struct platform_device *pdev) 429 { 430 struct device *dev = &pdev->dev; 431 struct device_node *panel_node, *port, *endpoint; 432 struct drm_panel *panel = NULL; 433 struct rockchip_dp_device *dp; 434 435 port = of_graph_get_port_by_id(dev->of_node, 1); 436 if (port) { 437 endpoint = of_get_child_by_name(port, "endpoint"); 438 of_node_put(port); 439 if (!endpoint) { 440 dev_err(dev, "no output endpoint found\n"); 441 return -EINVAL; 442 } 443 444 panel_node = of_graph_get_remote_port_parent(endpoint); 445 of_node_put(endpoint); 446 if (!panel_node) { 447 dev_err(dev, "no output node found\n"); 448 return -EINVAL; 449 } 450 451 panel = of_drm_find_panel(panel_node); 452 of_node_put(panel_node); 453 if (!panel) 454 return -EPROBE_DEFER; 455 } 456 457 dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); 458 if (!dp) 459 return -ENOMEM; 460 461 dp->dev = dev; 462 463 dp->plat_data.panel = panel; 464 465 /* 466 * We just use the drvdata until driver run into component 467 * add function, and then we would set drvdata to null, so 468 * that analogix dp driver could take charge of the drvdata. 469 */ 470 platform_set_drvdata(pdev, dp); 471 472 return component_add(dev, &rockchip_dp_component_ops); 473 } 474 475 static int rockchip_dp_remove(struct platform_device *pdev) 476 { 477 component_del(&pdev->dev, &rockchip_dp_component_ops); 478 479 return 0; 480 } 481 482 static const struct dev_pm_ops rockchip_dp_pm_ops = { 483 #ifdef CONFIG_PM_SLEEP 484 .suspend = analogix_dp_suspend, 485 .resume_early = analogix_dp_resume, 486 #endif 487 }; 488 489 static const struct rockchip_dp_chip_data rk3399_edp = { 490 .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, 491 .lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL), 492 .lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL), 493 .chip_type = RK3399_EDP, 494 }; 495 496 static const struct rockchip_dp_chip_data rk3288_dp = { 497 .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, 498 .lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL), 499 .lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL), 500 .chip_type = RK3288_DP, 501 }; 502 503 static const struct of_device_id rockchip_dp_dt_ids[] = { 504 {.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp }, 505 {.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp }, 506 {} 507 }; 508 MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids); 509 510 static struct platform_driver rockchip_dp_driver = { 511 .probe = rockchip_dp_probe, 512 .remove = rockchip_dp_remove, 513 .driver = { 514 .name = "rockchip-dp", 515 .pm = &rockchip_dp_pm_ops, 516 .of_match_table = of_match_ptr(rockchip_dp_dt_ids), 517 }, 518 }; 519 520 module_platform_driver(rockchip_dp_driver); 521 522 MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>"); 523 MODULE_AUTHOR("Jeff chen <jeff.chen@rock-chips.com>"); 524 MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension"); 525 MODULE_LICENSE("GPL v2"); 526