diff options
Diffstat (limited to 'drivers/gpu/drm/rockchip')
-rw-r--r-- | drivers/gpu/drm/rockchip/cdn-dp-reg.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 86 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_fb.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_lvds.c | 6 |
5 files changed, 77 insertions, 107 deletions
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c index eb3042c6d1b2..3105965fc260 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c @@ -792,7 +792,6 @@ err_config_video: int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio) { - u32 val; int ret; ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0); @@ -801,11 +800,7 @@ int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio) return ret; } - val = SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; - val |= SPDIF_FIFO_MID_RANGE(0xe0); - val |= SPDIF_JITTER_THRSH(0xe0); - val |= SPDIF_JITTER_AVG_WIN(7); - writel(val, dp->regs + SPDIF_CTRL_ADDR); + writel(0, dp->regs + SPDIF_CTRL_ADDR); /* clearn the audio config and reset */ writel(0, dp->regs + AUDIO_SRC_CNTL); @@ -929,12 +924,6 @@ static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp) { u32 val; - val = SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; - val |= SPDIF_FIFO_MID_RANGE(0xe0); - val |= SPDIF_JITTER_THRSH(0xe0); - val |= SPDIF_JITTER_AVG_WIN(7); - writel(val, dp->regs + SPDIF_CTRL_ADDR); - writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL); val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); @@ -942,9 +931,6 @@ static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp) writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL); val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; - val |= SPDIF_FIFO_MID_RANGE(0xe0); - val |= SPDIF_JITTER_THRSH(0xe0); - val |= SPDIF_JITTER_AVG_WIN(7); writel(val, dp->regs + SPDIF_CTRL_ADDR); clk_prepare_enable(dp->spdif_clk); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index d4f4118b482d..ea18cb2a76c0 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -18,52 +18,13 @@ #include <drm/drm_atomic.h> #include <drm/drm_fb_helper.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> #include "rockchip_drm_drv.h" #include "rockchip_drm_fb.h" #include "rockchip_drm_gem.h" #include "rockchip_drm_psr.h" -#define to_rockchip_fb(x) container_of(x, struct rockchip_drm_fb, fb) - -struct rockchip_drm_fb { - struct drm_framebuffer fb; - struct drm_gem_object *obj[ROCKCHIP_MAX_FB_BUFFER]; -}; - -struct drm_gem_object *rockchip_fb_get_gem_obj(struct drm_framebuffer *fb, - unsigned int plane) -{ - struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb); - - if (plane >= ROCKCHIP_MAX_FB_BUFFER) - return NULL; - - return rk_fb->obj[plane]; -} - -static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) -{ - struct rockchip_drm_fb *rockchip_fb = to_rockchip_fb(fb); - int i; - - for (i = 0; i < ROCKCHIP_MAX_FB_BUFFER; i++) - drm_gem_object_put_unlocked(rockchip_fb->obj[i]); - - drm_framebuffer_cleanup(fb); - kfree(rockchip_fb); -} - -static int rockchip_drm_fb_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct rockchip_drm_fb *rockchip_fb = to_rockchip_fb(fb); - - return drm_gem_handle_create(file_priv, - rockchip_fb->obj[0], handle); -} - static int rockchip_drm_fb_dirty(struct drm_framebuffer *fb, struct drm_file *file, unsigned int flags, unsigned int color, @@ -75,46 +36,45 @@ static int rockchip_drm_fb_dirty(struct drm_framebuffer *fb, } static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = { - .destroy = rockchip_drm_fb_destroy, - .create_handle = rockchip_drm_fb_create_handle, - .dirty = rockchip_drm_fb_dirty, + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, + .dirty = rockchip_drm_fb_dirty, }; -static struct rockchip_drm_fb * +static struct drm_framebuffer * rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **obj, unsigned int num_planes) { - struct rockchip_drm_fb *rockchip_fb; + struct drm_framebuffer *fb; int ret; int i; - rockchip_fb = kzalloc(sizeof(*rockchip_fb), GFP_KERNEL); - if (!rockchip_fb) + fb = kzalloc(sizeof(*fb), GFP_KERNEL); + if (!fb) return ERR_PTR(-ENOMEM); - drm_helper_mode_fill_fb_struct(dev, &rockchip_fb->fb, mode_cmd); + drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd); for (i = 0; i < num_planes; i++) - rockchip_fb->obj[i] = obj[i]; + fb->obj[i] = obj[i]; - ret = drm_framebuffer_init(dev, &rockchip_fb->fb, - &rockchip_drm_fb_funcs); + ret = drm_framebuffer_init(dev, fb, &rockchip_drm_fb_funcs); if (ret) { DRM_DEV_ERROR(dev->dev, "Failed to initialize framebuffer: %d\n", ret); - kfree(rockchip_fb); + kfree(fb); return ERR_PTR(ret); } - return rockchip_fb; + return fb; } static struct drm_framebuffer * rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) { - struct rockchip_drm_fb *rockchip_fb; + struct drm_framebuffer *fb; struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER]; struct drm_gem_object *obj; unsigned int hsub; @@ -153,13 +113,13 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, objs[i] = obj; } - rockchip_fb = rockchip_fb_alloc(dev, mode_cmd, objs, i); - if (IS_ERR(rockchip_fb)) { - ret = PTR_ERR(rockchip_fb); + fb = rockchip_fb_alloc(dev, mode_cmd, objs, i); + if (IS_ERR(fb)) { + ret = PTR_ERR(fb); goto err_gem_object_unreference; } - return &rockchip_fb->fb; + return fb; err_gem_object_unreference: for (i--; i >= 0; i--) @@ -242,13 +202,13 @@ rockchip_drm_framebuffer_init(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *obj) { - struct rockchip_drm_fb *rockchip_fb; + struct drm_framebuffer *fb; - rockchip_fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1); - if (IS_ERR(rockchip_fb)) - return ERR_CAST(rockchip_fb); + fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1); + if (IS_ERR(fb)) + return ERR_CAST(fb); - return &rockchip_fb->fb; + return fb; } void rockchip_drm_mode_config_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h index 2fe47f1ee98f..f1265cb1aee8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h @@ -22,7 +22,4 @@ rockchip_drm_framebuffer_init(struct drm_device *dev, void rockchip_drm_framebuffer_fini(struct drm_framebuffer *fb); void rockchip_drm_mode_config_init(struct drm_device *dev); - -struct drm_gem_object *rockchip_fb_get_gem_obj(struct drm_framebuffer *fb, - unsigned int plane); #endif /* _ROCKCHIP_DRM_FB_H */ diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 2121345a61af..c9222119767d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -486,6 +486,31 @@ static void vop_line_flag_irq_disable(struct vop *vop) spin_unlock_irqrestore(&vop->irq_lock, flags); } +static int vop_core_clks_enable(struct vop *vop) +{ + int ret; + + ret = clk_enable(vop->hclk); + if (ret < 0) + return ret; + + ret = clk_enable(vop->aclk); + if (ret < 0) + goto err_disable_hclk; + + return 0; + +err_disable_hclk: + clk_disable(vop->hclk); + return ret; +} + +static void vop_core_clks_disable(struct vop *vop) +{ + clk_disable(vop->aclk); + clk_disable(vop->hclk); +} + static int vop_enable(struct drm_crtc *crtc) { struct vop *vop = to_vop(crtc); @@ -497,17 +522,13 @@ static int vop_enable(struct drm_crtc *crtc) return ret; } - ret = clk_enable(vop->hclk); + ret = vop_core_clks_enable(vop); if (WARN_ON(ret < 0)) goto err_put_pm_runtime; ret = clk_enable(vop->dclk); if (WARN_ON(ret < 0)) - goto err_disable_hclk; - - ret = clk_enable(vop->aclk); - if (WARN_ON(ret < 0)) - goto err_disable_dclk; + goto err_disable_core; /* * Slave iommu shares power, irq and clock with vop. It was associated @@ -519,7 +540,7 @@ static int vop_enable(struct drm_crtc *crtc) if (ret) { DRM_DEV_ERROR(vop->dev, "failed to attach dma mapping, %d\n", ret); - goto err_disable_aclk; + goto err_disable_dclk; } spin_lock(&vop->reg_lock); @@ -552,18 +573,14 @@ static int vop_enable(struct drm_crtc *crtc) spin_unlock(&vop->reg_lock); - enable_irq(vop->irq); - drm_crtc_vblank_on(crtc); return 0; -err_disable_aclk: - clk_disable(vop->aclk); err_disable_dclk: clk_disable(vop->dclk); -err_disable_hclk: - clk_disable(vop->hclk); +err_disable_core: + vop_core_clks_disable(vop); err_put_pm_runtime: pm_runtime_put_sync(vop->dev); return ret; @@ -599,8 +616,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc, vop_dsp_hold_valid_irq_disable(vop); - disable_irq(vop->irq); - vop->is_enabled = false; /* @@ -609,8 +624,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc, rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev); clk_disable(vop->dclk); - clk_disable(vop->aclk); - clk_disable(vop->hclk); + vop_core_clks_disable(vop); pm_runtime_put(vop->dev); mutex_unlock(&vop->vop_lock); @@ -728,7 +742,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, return; } - obj = rockchip_fb_get_gem_obj(fb, 0); + obj = fb->obj[0]; rk_obj = to_rockchip_obj(obj); actual_w = drm_rect_width(src) >> 16; @@ -758,7 +772,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, int vsub = drm_format_vert_chroma_subsampling(fb->format->format); int bpp = fb->format->cpp[1]; - uv_obj = rockchip_fb_get_gem_obj(fb, 1); + uv_obj = fb->obj[1]; rk_uv_obj = to_rockchip_obj(uv_obj); offset = (src->x1 >> 16) * bpp / hsub; @@ -1178,6 +1192,18 @@ static irqreturn_t vop_isr(int irq, void *data) int ret = IRQ_NONE; /* + * The irq is shared with the iommu. If the runtime-pm state of the + * vop-device is disabled the irq has to be targeted at the iommu. + */ + if (!pm_runtime_get_if_in_use(vop->dev)) + return IRQ_NONE; + + if (vop_core_clks_enable(vop)) { + DRM_DEV_ERROR_RATELIMITED(vop->dev, "couldn't enable clocks\n"); + goto out; + } + + /* * interrupt register has interrupt status, enable and clear bits, we * must hold irq_lock to avoid a race with enable/disable_vblank(). */ @@ -1192,7 +1218,7 @@ static irqreturn_t vop_isr(int irq, void *data) /* This is expected for vop iommu irqs, since the irq is shared */ if (!active_irqs) - return IRQ_NONE; + goto out_disable; if (active_irqs & DSP_HOLD_VALID_INTR) { complete(&vop->dsp_hold_completion); @@ -1218,6 +1244,10 @@ static irqreturn_t vop_isr(int irq, void *data) DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n", active_irqs); +out_disable: + vop_core_clks_disable(vop); +out: + pm_runtime_put(vop->dev); return ret; } @@ -1596,9 +1626,6 @@ static int vop_bind(struct device *dev, struct device *master, void *data) if (ret) goto err_disable_pm_runtime; - /* IRQ is initially disabled; it gets enabled in power_on */ - disable_irq(vop->irq); - return 0; err_disable_pm_runtime: diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c index e67f4ea28c0e..b3f6f524b402 100644 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -363,8 +363,10 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master, of_property_read_u32(endpoint, "reg", &endpoint_id); ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id, &lvds->panel, &lvds->bridge); - if (!ret) + if (!ret) { + of_node_put(endpoint); break; + } } if (!child_count) { DRM_DEV_ERROR(dev, "lvds port does not have any children\n"); @@ -446,14 +448,12 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master, goto err_free_connector; } } else { - lvds->bridge->encoder = encoder; ret = drm_bridge_attach(encoder, lvds->bridge, NULL); if (ret) { DRM_DEV_ERROR(drm_dev->dev, "failed to attach bridge: %d\n", ret); goto err_free_encoder; } - encoder->bridge = lvds->bridge; } pm_runtime_enable(dev); |