]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/exynos/exynos_mixer.c
Merge tag 'fbdev-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
[karo-tx-linux.git] / drivers / gpu / drm / exynos / exynos_mixer.c
index 7529946d0a7427a00548705dc1f2c20c405081e6..e8b4ec84b312cc412351b08ab6e09f0626d5cc05 100644 (file)
@@ -76,7 +76,7 @@ struct mixer_resources {
        struct clk              *vp;
        struct clk              *sclk_mixer;
        struct clk              *sclk_hdmi;
-       struct clk              *sclk_dac;
+       struct clk              *mout_mixer;
 };
 
 enum mixer_version_id {
@@ -93,6 +93,7 @@ struct mixer_context {
        bool                    interlace;
        bool                    powered;
        bool                    vp_enabled;
+       bool                    has_sclk;
        u32                     int_en;
 
        struct mutex            mixer_mutex;
@@ -106,6 +107,7 @@ struct mixer_context {
 struct mixer_drv_data {
        enum mixer_version_id   version;
        bool                                    is_vp_enabled;
+       bool                                    has_sclk;
 };
 
 static const u8 filter_y_horiz_tap8[] = {
@@ -363,6 +365,11 @@ static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
                        vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
                        mixer_reg_writemask(res, MXR_CFG, val,
                                MXR_CFG_VP_ENABLE);
+
+                       /* control blending of graphic layer 0 */
+                       mixer_reg_writemask(res, MXR_GRAPHIC_CFG(0), val,
+                                       MXR_GRP_CFG_BLEND_PRE_MUL |
+                                       MXR_GRP_CFG_PIXEL_BLEND_EN);
                }
                break;
        }
@@ -809,19 +816,23 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
                dev_err(dev, "failed to get clock 'vp'\n");
                return -ENODEV;
        }
-       mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
-       if (IS_ERR(mixer_res->sclk_mixer)) {
-               dev_err(dev, "failed to get clock 'sclk_mixer'\n");
-               return -ENODEV;
-       }
-       mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
-       if (IS_ERR(mixer_res->sclk_dac)) {
-               dev_err(dev, "failed to get clock 'sclk_dac'\n");
-               return -ENODEV;
-       }
 
-       if (mixer_res->sclk_hdmi)
-               clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
+       if (mixer_ctx->has_sclk) {
+               mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
+               if (IS_ERR(mixer_res->sclk_mixer)) {
+                       dev_err(dev, "failed to get clock 'sclk_mixer'\n");
+                       return -ENODEV;
+               }
+               mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
+               if (IS_ERR(mixer_res->mout_mixer)) {
+                       dev_err(dev, "failed to get clock 'mout_mixer'\n");
+                       return -ENODEV;
+               }
+
+               if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
+                       clk_set_parent(mixer_res->mout_mixer,
+                                      mixer_res->sclk_hdmi);
+       }
 
        res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
        if (res == NULL) {
@@ -1082,7 +1093,8 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
        clk_prepare_enable(res->mixer);
        if (ctx->vp_enabled) {
                clk_prepare_enable(res->vp);
-               clk_prepare_enable(res->sclk_mixer);
+               if (ctx->has_sclk)
+                       clk_prepare_enable(res->sclk_mixer);
        }
 
        mutex_lock(&ctx->mixer_mutex);
@@ -1121,7 +1133,8 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
        clk_disable_unprepare(res->mixer);
        if (ctx->vp_enabled) {
                clk_disable_unprepare(res->vp);
-               clk_disable_unprepare(res->sclk_mixer);
+               if (ctx->has_sclk)
+                       clk_disable_unprepare(res->sclk_mixer);
        }
 
        pm_runtime_put_sync(ctx->dev);
@@ -1189,9 +1202,15 @@ static struct mixer_drv_data exynos5250_mxr_drv_data = {
        .is_vp_enabled = 0,
 };
 
+static struct mixer_drv_data exynos4212_mxr_drv_data = {
+       .version = MXR_VER_0_0_0_16,
+       .is_vp_enabled = 1,
+};
+
 static struct mixer_drv_data exynos4210_mxr_drv_data = {
        .version = MXR_VER_0_0_0_16,
        .is_vp_enabled = 1,
+       .has_sclk = 1,
 };
 
 static struct platform_device_id mixer_driver_types[] = {
@@ -1208,6 +1227,12 @@ static struct platform_device_id mixer_driver_types[] = {
 
 static struct of_device_id mixer_match_types[] = {
        {
+               .compatible = "samsung,exynos4210-mixer",
+               .data   = &exynos4210_mxr_drv_data,
+       }, {
+               .compatible = "samsung,exynos4212-mixer",
+               .data   = &exynos4212_mxr_drv_data,
+       }, {
                .compatible = "samsung,exynos5-mixer",
                .data   = &exynos5250_mxr_drv_data,
        }, {
@@ -1220,6 +1245,7 @@ static struct of_device_id mixer_match_types[] = {
                /* end node */
        }
 };
+MODULE_DEVICE_TABLE(of, mixer_match_types);
 
 static int mixer_bind(struct device *dev, struct device *manager, void *data)
 {
@@ -1251,6 +1277,7 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
        ctx->pdev = pdev;
        ctx->dev = dev;
        ctx->vp_enabled = drv->is_vp_enabled;
+       ctx->has_sclk = drv->has_sclk;
        ctx->mxr_ver = drv->version;
        init_waitqueue_head(&ctx->wait_vsync_queue);
        atomic_set(&ctx->wait_vsync_event, 0);