drm: exynos: hdmi: add support to disable video processor in mixer
authorRahul Sharma <rahul.sharma@samsung.com>
Thu, 4 Oct 2012 15:18:52 +0000 (20:48 +0530)
committerInki Dae <inki.dae@samsung.com>
Fri, 5 Oct 2012 10:15:08 +0000 (19:15 +0900)
This patch adds support for disabling the video processor code based
on the platform type. This is done based on a field in the mixer driver
data which changes with the platform variant.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos_mixer.c

index e312fb1dafdd6aea2aed89191ed1af0cc461fee9..167734529229012eb29d45e14f20670e61121008 100644 (file)
@@ -83,6 +83,7 @@ struct mixer_context {
        int                     pipe;
        bool                    interlace;
        bool                    powered;
+       bool                    vp_enabled;
        u32                     int_en;
 
        struct mutex            mixer_mutex;
@@ -93,6 +94,7 @@ struct mixer_context {
 
 struct mixer_drv_data {
        enum mixer_version_id   version;
+       bool                                    is_vp_enabled;
 };
 
 static const u8 filter_y_horiz_tap8[] = {
@@ -261,7 +263,8 @@ static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
        mixer_reg_writemask(res, MXR_STATUS, enable ?
                        MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
 
-       vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
+       if (ctx->vp_enabled)
+               vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
                        VP_SHADOW_UPDATE_ENABLE : 0);
 }
 
@@ -343,8 +346,11 @@ static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
                mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
                break;
        case 2:
-               vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
-               mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE);
+               if (ctx->vp_enabled) {
+                       vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
+                       mixer_reg_writemask(res, MXR_CFG, val,
+                               MXR_CFG_VP_ENABLE);
+               }
                break;
        }
 }
@@ -602,7 +608,8 @@ static void mixer_win_reset(struct mixer_context *ctx)
         */
        val = MXR_LAYER_CFG_GRP1_VAL(3);
        val |= MXR_LAYER_CFG_GRP0_VAL(2);
-       val |= MXR_LAYER_CFG_VP_VAL(1);
+       if (ctx->vp_enabled)
+               val |= MXR_LAYER_CFG_VP_VAL(1);
        mixer_reg_write(res, MXR_LAYER_CFG, val);
 
        /* setting background color */
@@ -625,14 +632,17 @@ static void mixer_win_reset(struct mixer_context *ctx)
        val = MXR_GRP_CFG_ALPHA_VAL(0);
        mixer_reg_write(res, MXR_VIDEO_CFG, val);
 
-       /* configuration of Video Processor Registers */
-       vp_win_reset(ctx);
-       vp_default_filter(res);
+       if (ctx->vp_enabled) {
+               /* configuration of Video Processor Registers */
+               vp_win_reset(ctx);
+               vp_default_filter(res);
+       }
 
        /* disable all layers */
        mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
        mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
-       mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
+       if (ctx->vp_enabled)
+               mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
 
        mixer_vsync_set_update(ctx, true);
        spin_unlock_irqrestore(&res->reg_slock, flags);
@@ -655,8 +665,10 @@ static void mixer_poweron(struct mixer_context *ctx)
        pm_runtime_get_sync(ctx->dev);
 
        clk_enable(res->mixer);
-       clk_enable(res->vp);
-       clk_enable(res->sclk_mixer);
+       if (ctx->vp_enabled) {
+               clk_enable(res->vp);
+               clk_enable(res->sclk_mixer);
+       }
 
        mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
        mixer_win_reset(ctx);
@@ -676,8 +688,10 @@ static void mixer_poweroff(struct mixer_context *ctx)
        ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
 
        clk_disable(res->mixer);
-       clk_disable(res->vp);
-       clk_disable(res->sclk_mixer);
+       if (ctx->vp_enabled) {
+               clk_disable(res->vp);
+               clk_disable(res->sclk_mixer);
+       }
 
        pm_runtime_put_sync(ctx->dev);
 
@@ -810,7 +824,7 @@ static void mixer_win_commit(void *ctx, int win)
 
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
-       if (win > 1)
+       if (win > 1 && mixer_ctx->vp_enabled)
                vp_video_buffer(mixer_ctx, win);
        else
                mixer_graph_buffer(mixer_ctx, win);
@@ -946,39 +960,20 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
                ret = -ENODEV;
                goto fail;
        }
-       mixer_res->vp = clk_get(dev, "vp");
-       if (IS_ERR_OR_NULL(mixer_res->vp)) {
-               dev_err(dev, "failed to get clock 'vp'\n");
-               ret = -ENODEV;
-               goto fail;
-       }
-       mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
-       if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
-               dev_err(dev, "failed to get clock 'sclk_mixer'\n");
-               ret = -ENODEV;
-               goto fail;
-       }
+
        mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
        if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
                dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
                ret = -ENODEV;
                goto fail;
        }
-       mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
-       if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
-               dev_err(dev, "failed to get clock 'sclk_dac'\n");
-               ret = -ENODEV;
-               goto fail;
-       }
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res == NULL) {
                dev_err(dev, "get memory resource failed.\n");
                ret = -ENXIO;
                goto fail;
        }
 
-       clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
-
        mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
                                                        resource_size(res));
        if (mixer_res->mixer_regs == NULL) {
@@ -987,54 +982,92 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
                goto fail;
        }
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (res == NULL) {
-               dev_err(dev, "get memory resource failed.\n");
+               dev_err(dev, "get interrupt resource failed.\n");
                ret = -ENXIO;
                goto fail;
        }
 
-       mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
-                                                       resource_size(res));
-       if (mixer_res->vp_regs == NULL) {
-               dev_err(dev, "register mapping failed.\n");
-               ret = -ENXIO;
+       ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
+                                                       0, "drm_mixer", ctx);
+       if (ret) {
+               dev_err(dev, "request interrupt failed.\n");
                goto fail;
        }
+       mixer_res->irq = res->start;
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
+       return 0;
+
+fail:
+       if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
+               clk_put(mixer_res->sclk_hdmi);
+       if (!IS_ERR_OR_NULL(mixer_res->mixer))
+               clk_put(mixer_res->mixer);
+       return ret;
+}
+
+static int __devinit vp_resources_init(struct exynos_drm_hdmi_context *ctx,
+                                struct platform_device *pdev)
+{
+       struct mixer_context *mixer_ctx = ctx->ctx;
+       struct device *dev = &pdev->dev;
+       struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
+       struct resource *res;
+       int ret;
+
+       mixer_res->vp = clk_get(dev, "vp");
+       if (IS_ERR_OR_NULL(mixer_res->vp)) {
+               dev_err(dev, "failed to get clock 'vp'\n");
+               ret = -ENODEV;
+               goto fail;
+       }
+       mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
+       if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
+               dev_err(dev, "failed to get clock 'sclk_mixer'\n");
+               ret = -ENODEV;
+               goto fail;
+       }
+       mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
+       if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
+               dev_err(dev, "failed to get clock 'sclk_dac'\n");
+               ret = -ENODEV;
+               goto fail;
+       }
+
+       if (mixer_res->sclk_hdmi)
+               clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        if (res == NULL) {
-               dev_err(dev, "get interrupt resource failed.\n");
+               dev_err(dev, "get memory resource failed.\n");
                ret = -ENXIO;
                goto fail;
        }
 
-       ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
-                                                       0, "drm_mixer", ctx);
-       if (ret) {
-               dev_err(dev, "request interrupt failed.\n");
+       mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
+                                                       resource_size(res));
+       if (mixer_res->vp_regs == NULL) {
+               dev_err(dev, "register mapping failed.\n");
+               ret = -ENXIO;
                goto fail;
        }
-       mixer_res->irq = res->start;
 
        return 0;
 
 fail:
        if (!IS_ERR_OR_NULL(mixer_res->sclk_dac))
                clk_put(mixer_res->sclk_dac);
-       if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
-               clk_put(mixer_res->sclk_hdmi);
        if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer))
                clk_put(mixer_res->sclk_mixer);
        if (!IS_ERR_OR_NULL(mixer_res->vp))
                clk_put(mixer_res->vp);
-       if (!IS_ERR_OR_NULL(mixer_res->mixer))
-               clk_put(mixer_res->mixer);
        return ret;
 }
 
 static struct mixer_drv_data exynos4_mxr_drv_data = {
        .version = MXR_VER_0_0_0_16,
+       .is_vp_enabled = 1,
 };
 
 static struct platform_device_id mixer_driver_types[] = {
@@ -1075,14 +1108,26 @@ static int __devinit mixer_probe(struct platform_device *pdev)
                        pdev)->driver_data;
        ctx->dev = &pdev->dev;
        drm_hdmi_ctx->ctx = (void *)ctx;
+       ctx->vp_enabled = drv->is_vp_enabled;
        ctx->mxr_ver = drv->version;
 
        platform_set_drvdata(pdev, drm_hdmi_ctx);
 
        /* acquire resources: regs, irqs, clocks */
        ret = mixer_resources_init(drm_hdmi_ctx, pdev);
-       if (ret)
+       if (ret) {
+               DRM_ERROR("mixer_resources_init failed\n");
                goto fail;
+       }
+
+       if (ctx->vp_enabled) {
+               /* acquire vp resources: regs, irqs, clocks */
+               ret = vp_resources_init(drm_hdmi_ctx, pdev);
+               if (ret) {
+                       DRM_ERROR("vp_resources_init failed\n");
+                       goto fail;
+               }
+       }
 
        /* register specific callback point to common hdmi. */
        exynos_mixer_ops_register(&mixer_ops);