Merge branch 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
This pull request fixes memory leak and some issues related to mixer and gscaler driver issues. * 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos/fimc: fix runtime pm support drm/exynos/mixer: always update INT_EN cache drm/exynos/mixer: correct vsync configuration sequence drm/exynos/mixer: fix interrupt clearing drm/exynos/hdmi: fix edid memory leak drm/exynos: gsc: fix wrong bitwise operation for swap detection
This commit is contained in:
commit
3c6d45b417
@ -1745,7 +1745,6 @@ static int fimc_probe(struct platform_device *pdev)
|
|||||||
spin_lock_init(&ctx->lock);
|
spin_lock_init(&ctx->lock);
|
||||||
platform_set_drvdata(pdev, ctx);
|
platform_set_drvdata(pdev, ctx);
|
||||||
|
|
||||||
pm_runtime_set_active(dev);
|
|
||||||
pm_runtime_enable(dev);
|
pm_runtime_enable(dev);
|
||||||
|
|
||||||
ret = exynos_drm_ippdrv_register(ippdrv);
|
ret = exynos_drm_ippdrv_register(ippdrv);
|
||||||
|
@ -593,8 +593,7 @@ static int gsc_src_set_transf(struct device *dev,
|
|||||||
|
|
||||||
gsc_write(cfg, GSC_IN_CON);
|
gsc_write(cfg, GSC_IN_CON);
|
||||||
|
|
||||||
ctx->rotation = cfg &
|
ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0;
|
||||||
(GSC_IN_ROT_90 | GSC_IN_ROT_270) ? 1 : 0;
|
|
||||||
*swap = ctx->rotation;
|
*swap = ctx->rotation;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -857,8 +856,7 @@ static int gsc_dst_set_transf(struct device *dev,
|
|||||||
|
|
||||||
gsc_write(cfg, GSC_IN_CON);
|
gsc_write(cfg, GSC_IN_CON);
|
||||||
|
|
||||||
ctx->rotation = cfg &
|
ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0;
|
||||||
(GSC_IN_ROT_90 | GSC_IN_ROT_270) ? 1 : 0;
|
|
||||||
*swap = ctx->rotation;
|
*swap = ctx->rotation;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1064,6 +1064,7 @@ static int hdmi_get_modes(struct drm_connector *connector)
|
|||||||
{
|
{
|
||||||
struct hdmi_context *hdata = ctx_from_connector(connector);
|
struct hdmi_context *hdata = ctx_from_connector(connector);
|
||||||
struct edid *edid;
|
struct edid *edid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!hdata->ddc_adpt)
|
if (!hdata->ddc_adpt)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -1079,7 +1080,11 @@ static int hdmi_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_mode_connector_update_edid_property(connector, edid);
|
||||||
|
|
||||||
return drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
|
|
||||||
|
kfree(edid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
|
static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
|
||||||
|
@ -718,6 +718,10 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
|
|||||||
|
|
||||||
/* handling VSYNC */
|
/* handling VSYNC */
|
||||||
if (val & MXR_INT_STATUS_VSYNC) {
|
if (val & MXR_INT_STATUS_VSYNC) {
|
||||||
|
/* vsync interrupt use different bit for read and clear */
|
||||||
|
val |= MXR_INT_CLEAR_VSYNC;
|
||||||
|
val &= ~MXR_INT_STATUS_VSYNC;
|
||||||
|
|
||||||
/* interlace scan need to check shadow register */
|
/* interlace scan need to check shadow register */
|
||||||
if (ctx->interlace) {
|
if (ctx->interlace) {
|
||||||
base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
|
base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
|
||||||
@ -743,11 +747,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
/* clear interrupts */
|
/* clear interrupts */
|
||||||
if (~val & MXR_INT_EN_VSYNC) {
|
|
||||||
/* vsync interrupt use different bit for read and clear */
|
|
||||||
val &= ~MXR_INT_EN_VSYNC;
|
|
||||||
val |= MXR_INT_CLEAR_VSYNC;
|
|
||||||
}
|
|
||||||
mixer_reg_write(res, MXR_INT_STATUS, val);
|
mixer_reg_write(res, MXR_INT_STATUS, val);
|
||||||
|
|
||||||
spin_unlock(&res->reg_slock);
|
spin_unlock(&res->reg_slock);
|
||||||
@ -907,8 +906,8 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* enable vsync interrupt */
|
/* enable vsync interrupt */
|
||||||
mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
|
mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
|
||||||
MXR_INT_EN_VSYNC);
|
mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -918,7 +917,13 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
|
|||||||
struct mixer_context *mixer_ctx = crtc->ctx;
|
struct mixer_context *mixer_ctx = crtc->ctx;
|
||||||
struct mixer_resources *res = &mixer_ctx->mixer_res;
|
struct mixer_resources *res = &mixer_ctx->mixer_res;
|
||||||
|
|
||||||
|
if (!mixer_ctx->powered) {
|
||||||
|
mixer_ctx->int_en &= MXR_INT_EN_VSYNC;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* disable vsync interrupt */
|
/* disable vsync interrupt */
|
||||||
|
mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
|
||||||
mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
|
mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,6 +1052,8 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
|
|||||||
|
|
||||||
mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
|
mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
|
||||||
|
|
||||||
|
if (ctx->int_en & MXR_INT_EN_VSYNC)
|
||||||
|
mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
|
||||||
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
|
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
|
||||||
mixer_win_reset(ctx);
|
mixer_win_reset(ctx);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user