root/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rockchip_dp_pre_init
  2. rockchip_dp_poweron_start
  3. rockchip_dp_powerdown
  4. rockchip_dp_get_modes
  5. rockchip_dp_drm_encoder_mode_fixup
  6. rockchip_dp_drm_encoder_mode_set
  7. rockchip_dp_drm_get_new_crtc
  8. rockchip_dp_drm_encoder_enable
  9. rockchip_dp_drm_encoder_disable
  10. rockchip_dp_drm_encoder_atomic_check
  11. rockchip_dp_of_probe
  12. rockchip_dp_drm_create_encoder
  13. rockchip_dp_bind
  14. rockchip_dp_unbind
  15. rockchip_dp_probe
  16. rockchip_dp_remove
  17. rockchip_dp_suspend
  18. rockchip_dp_resume

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

/* [<][>][^][v][top][bottom][index][help] */