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