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 249 /* 250 * The hardware IC designed that VOP must output the RGB10 video 251 * format to eDP controller, and if eDP panel only support RGB8, 252 * then eDP controller should cut down the video data, not via VOP 253 * controller, that's why we need to hardcode the VOP output mode 254 * to RGA10 here. 255 */ 256 257 s->output_mode = ROCKCHIP_OUT_MODE_AAAA; 258 s->output_type = DRM_MODE_CONNECTOR_eDP; 259 260 return 0; 261 } 262 263 static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = { 264 .mode_fixup = rockchip_dp_drm_encoder_mode_fixup, 265 .mode_set = rockchip_dp_drm_encoder_mode_set, 266 .enable = rockchip_dp_drm_encoder_enable, 267 .disable = rockchip_dp_drm_encoder_nop, 268 .atomic_check = rockchip_dp_drm_encoder_atomic_check, 269 }; 270 271 static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder) 272 { 273 drm_encoder_cleanup(encoder); 274 } 275 276 static struct drm_encoder_funcs rockchip_dp_encoder_funcs = { 277 .destroy = rockchip_dp_drm_encoder_destroy, 278 }; 279 280 static int rockchip_dp_init(struct rockchip_dp_device *dp) 281 { 282 struct device *dev = dp->dev; 283 struct device_node *np = dev->of_node; 284 int ret; 285 286 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 287 if (IS_ERR(dp->grf)) { 288 dev_err(dev, "failed to get rockchip,grf property\n"); 289 return PTR_ERR(dp->grf); 290 } 291 292 dp->grfclk = devm_clk_get(dev, "grf"); 293 if (PTR_ERR(dp->grfclk) == -ENOENT) { 294 dp->grfclk = NULL; 295 } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) { 296 return -EPROBE_DEFER; 297 } else if (IS_ERR(dp->grfclk)) { 298 dev_err(dev, "failed to get grf clock\n"); 299 return PTR_ERR(dp->grfclk); 300 } 301 302 dp->pclk = devm_clk_get(dev, "pclk"); 303 if (IS_ERR(dp->pclk)) { 304 dev_err(dev, "failed to get pclk property\n"); 305 return PTR_ERR(dp->pclk); 306 } 307 308 dp->rst = devm_reset_control_get(dev, "dp"); 309 if (IS_ERR(dp->rst)) { 310 dev_err(dev, "failed to get dp reset control\n"); 311 return PTR_ERR(dp->rst); 312 } 313 314 ret = clk_prepare_enable(dp->pclk); 315 if (ret < 0) { 316 dev_err(dp->dev, "failed to enable pclk %d\n", ret); 317 return ret; 318 } 319 320 ret = rockchip_dp_pre_init(dp); 321 if (ret < 0) { 322 dev_err(dp->dev, "failed to pre init %d\n", ret); 323 clk_disable_unprepare(dp->pclk); 324 return ret; 325 } 326 327 return 0; 328 } 329 330 static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp) 331 { 332 struct drm_encoder *encoder = &dp->encoder; 333 struct drm_device *drm_dev = dp->drm_dev; 334 struct device *dev = dp->dev; 335 int ret; 336 337 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, 338 dev->of_node); 339 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); 340 341 ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs, 342 DRM_MODE_ENCODER_TMDS, NULL); 343 if (ret) { 344 DRM_ERROR("failed to initialize encoder with drm\n"); 345 return ret; 346 } 347 348 drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs); 349 350 return 0; 351 } 352 353 static int rockchip_dp_bind(struct device *dev, struct device *master, 354 void *data) 355 { 356 struct rockchip_dp_device *dp = dev_get_drvdata(dev); 357 const struct rockchip_dp_chip_data *dp_data; 358 struct drm_device *drm_dev = data; 359 int ret; 360 361 /* 362 * Just like the probe function said, we don't need the 363 * device drvrate anymore, we should leave the charge to 364 * analogix dp driver, set the device drvdata to NULL. 365 */ 366 dev_set_drvdata(dev, NULL); 367 368 dp_data = of_device_get_match_data(dev); 369 if (!dp_data) 370 return -ENODEV; 371 372 ret = rockchip_dp_init(dp); 373 if (ret < 0) 374 return ret; 375 376 dp->data = dp_data; 377 dp->drm_dev = drm_dev; 378 379 ret = rockchip_dp_drm_create_encoder(dp); 380 if (ret) { 381 DRM_ERROR("failed to create drm encoder\n"); 382 return ret; 383 } 384 385 dp->plat_data.encoder = &dp->encoder; 386 387 dp->plat_data.dev_type = dp->data->chip_type; 388 dp->plat_data.power_on = rockchip_dp_poweron; 389 dp->plat_data.power_off = rockchip_dp_powerdown; 390 dp->plat_data.get_modes = rockchip_dp_get_modes; 391 392 spin_lock_init(&dp->psr_lock); 393 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE; 394 INIT_WORK(&dp->psr_work, analogix_dp_psr_work); 395 396 rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set); 397 398 return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); 399 } 400 401 static void rockchip_dp_unbind(struct device *dev, struct device *master, 402 void *data) 403 { 404 struct rockchip_dp_device *dp = dev_get_drvdata(dev); 405 406 rockchip_drm_psr_unregister(&dp->encoder); 407 408 analogix_dp_unbind(dev, master, data); 409 clk_disable_unprepare(dp->pclk); 410 } 411 412 static const struct component_ops rockchip_dp_component_ops = { 413 .bind = rockchip_dp_bind, 414 .unbind = rockchip_dp_unbind, 415 }; 416 417 static int rockchip_dp_probe(struct platform_device *pdev) 418 { 419 struct device *dev = &pdev->dev; 420 struct drm_panel *panel = NULL; 421 struct rockchip_dp_device *dp; 422 int ret; 423 424 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); 425 if (ret) 426 return ret; 427 428 dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); 429 if (!dp) 430 return -ENOMEM; 431 432 dp->dev = dev; 433 434 dp->plat_data.panel = panel; 435 436 /* 437 * We just use the drvdata until driver run into component 438 * add function, and then we would set drvdata to null, so 439 * that analogix dp driver could take charge of the drvdata. 440 */ 441 platform_set_drvdata(pdev, dp); 442 443 return component_add(dev, &rockchip_dp_component_ops); 444 } 445 446 static int rockchip_dp_remove(struct platform_device *pdev) 447 { 448 component_del(&pdev->dev, &rockchip_dp_component_ops); 449 450 return 0; 451 } 452 453 static const struct dev_pm_ops rockchip_dp_pm_ops = { 454 #ifdef CONFIG_PM_SLEEP 455 .suspend = analogix_dp_suspend, 456 .resume_early = analogix_dp_resume, 457 #endif 458 }; 459 460 static const struct rockchip_dp_chip_data rk3399_edp = { 461 .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, 462 .lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL), 463 .lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL), 464 .chip_type = RK3399_EDP, 465 }; 466 467 static const struct rockchip_dp_chip_data rk3288_dp = { 468 .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, 469 .lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL), 470 .lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL), 471 .chip_type = RK3288_DP, 472 }; 473 474 static const struct of_device_id rockchip_dp_dt_ids[] = { 475 {.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp }, 476 {.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp }, 477 {} 478 }; 479 MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids); 480 481 struct platform_driver rockchip_dp_driver = { 482 .probe = rockchip_dp_probe, 483 .remove = rockchip_dp_remove, 484 .driver = { 485 .name = "rockchip-dp", 486 .pm = &rockchip_dp_pm_ops, 487 .of_match_table = of_match_ptr(rockchip_dp_dt_ids), 488 }, 489 }; 490