From 7f53fbba3cf8db8f584b26e89802413bc2e8d902 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 30 Jan 2015 20:28:48 +0100 Subject: [PATCH 1/4] drm/rockchip: fix clk enable disable mismatch in vop_crtc_mode_set The function disables the dclk at the beginning, so don't simply return when an error happens, but instead enable the clock again, so that enable and disable calls are balanced. ret_clk is introduced to hold the clk_enable result and not mangle the original error code. Signed-off-by: Heiko Stuebner Reviewed-by: Daniel Kurtz --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index d041921b3bb9b..6115898efe6b1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -893,7 +893,7 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc, u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start; u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start; u16 vact_end = vact_st + vdisplay; - int ret; + int ret, ret_clk; uint32_t val; /* @@ -915,7 +915,8 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc, default: DRM_ERROR("unsupport connector_type[%d]\n", vop->connector_type); - return -EINVAL; + ret = -EINVAL; + goto out; }; VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode); @@ -938,7 +939,7 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc, ret = vop_crtc_mode_set_base(crtc, x, y, fb); if (ret) - return ret; + goto out; /* * reset dclk, take all mode config affect, so the clk would run in @@ -949,13 +950,14 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc, reset_control_deassert(vop->dclk_rst); clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); - ret = clk_enable(vop->dclk); - if (ret < 0) { - dev_err(vop->dev, "failed to enable dclk - %d\n", ret); - return ret; +out: + ret_clk = clk_enable(vop->dclk); + if (ret_clk < 0) { + dev_err(vop->dev, "failed to enable dclk - %d\n", ret_clk); + return ret_clk; } - return 0; + return ret; } static void vop_crtc_commit(struct drm_crtc *crtc) From d3007dabeff493d82416a7ed69e0ff055a579fa1 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Fri, 30 Jan 2015 10:14:17 +0100 Subject: [PATCH 2/4] drm/rockchip: register all connectors after bind Register connectors with userspace after all components are bound. Signed-off-by: Daniel Kurtz Reviewed-by: Dominik Behr drm_connector_get_name -> connector->name This patch is necessary to make X11 see screens it seems. Signed-off-by: Heiko Stuebner --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 21a481b224eba..30da7813d53e0 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -129,6 +129,7 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags) struct rockchip_drm_private *private; struct dma_iommu_mapping *mapping; struct device *dev = drm_dev->dev; + struct drm_connector *connector; int ret; private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL); @@ -171,6 +172,23 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags) if (ret) goto err_detach_device; + /* + * All components are now added, we can publish the connector sysfs + * entries to userspace. This will generate hotplug events and so + * userspace will expect to be able to access DRM at this point. + */ + list_for_each_entry(connector, &drm_dev->mode_config.connector_list, + head) { + ret = drm_connector_register(connector); + if (ret) { + dev_err(drm_dev->dev, + "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n", + connector->base.id, + connector->name, ret); + goto err_unbind; + } + } + /* init kms poll for handling hpd */ drm_kms_helper_poll_init(drm_dev); @@ -200,6 +218,7 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags) drm_vblank_cleanup(drm_dev); err_kms_helper_poll_fini: drm_kms_helper_poll_fini(drm_dev); +err_unbind: component_unbind_all(dev, drm_dev); err_detach_device: arm_iommu_detach_device(dev); From b340b3fb71473291ea924a47e0069828c83da729 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 31 Mar 2015 18:22:50 +0800 Subject: [PATCH 3/4] drm: rockchip: Turn off VT switching on suspend drm/rockchip already has support for disabling all displays on suspend and enabling them on resume. Disable automatic VT switching on suspend by the pm console tracking layer. Tested on veyron, used `echo mem > sys/power/state` => verified no VT switch Reviewed-by: Daniel Kurtz Signed-off-by: Caesar Wang --- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c index d5c1248916b24..5b0dc0f6fd940 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c @@ -119,6 +119,9 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper, DRM_DEBUG_KMS("FB [%dx%d]-%d kvaddr=%p offset=%ld size=%d\n", fb->width, fb->height, fb->depth, rk_obj->kvaddr, offset, size); + + fbi->skip_vt_switch = true; + return 0; err_drm_framebuffer_unref: From 5d82d1a785155fe4ff65628a88b677cfacea863b Mon Sep 17 00:00:00 2001 From: Mark Yao Date: Wed, 1 Apr 2015 13:48:53 +0800 Subject: [PATCH 4/4] drm/rockchip: vop: add vop power domain support Reference the power domain incase vop power down when in use. Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 6115898efe6b1..ccb0ce073ef2a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -421,6 +421,12 @@ static void vop_enable(struct drm_crtc *crtc) if (vop->is_enabled) return; + ret = pm_runtime_get_sync(vop->dev); + if (ret < 0) { + dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); + return; + } + ret = clk_enable(vop->hclk); if (ret < 0) { dev_err(vop->dev, "failed to enable hclk - %d\n", ret); @@ -517,6 +523,7 @@ static void vop_disable(struct drm_crtc *crtc) clk_disable(vop->dclk); clk_disable(vop->aclk); clk_disable(vop->hclk); + pm_runtime_put(vop->dev); } /*