aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos_mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_mixer.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 7529946d0a74..e8b4ec84b312 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -76,7 +76,7 @@ struct mixer_resources {
76 struct clk *vp; 76 struct clk *vp;
77 struct clk *sclk_mixer; 77 struct clk *sclk_mixer;
78 struct clk *sclk_hdmi; 78 struct clk *sclk_hdmi;
79 struct clk *sclk_dac; 79 struct clk *mout_mixer;
80}; 80};
81 81
82enum mixer_version_id { 82enum mixer_version_id {
@@ -93,6 +93,7 @@ struct mixer_context {
93 bool interlace; 93 bool interlace;
94 bool powered; 94 bool powered;
95 bool vp_enabled; 95 bool vp_enabled;
96 bool has_sclk;
96 u32 int_en; 97 u32 int_en;
97 98
98 struct mutex mixer_mutex; 99 struct mutex mixer_mutex;
@@ -106,6 +107,7 @@ struct mixer_context {
106struct mixer_drv_data { 107struct mixer_drv_data {
107 enum mixer_version_id version; 108 enum mixer_version_id version;
108 bool is_vp_enabled; 109 bool is_vp_enabled;
110 bool has_sclk;
109}; 111};
110 112
111static const u8 filter_y_horiz_tap8[] = { 113static const u8 filter_y_horiz_tap8[] = {
@@ -363,6 +365,11 @@ static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
363 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); 365 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
364 mixer_reg_writemask(res, MXR_CFG, val, 366 mixer_reg_writemask(res, MXR_CFG, val,
365 MXR_CFG_VP_ENABLE); 367 MXR_CFG_VP_ENABLE);
368
369 /* control blending of graphic layer 0 */
370 mixer_reg_writemask(res, MXR_GRAPHIC_CFG(0), val,
371 MXR_GRP_CFG_BLEND_PRE_MUL |
372 MXR_GRP_CFG_PIXEL_BLEND_EN);
366 } 373 }
367 break; 374 break;
368 } 375 }
@@ -809,19 +816,23 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
809 dev_err(dev, "failed to get clock 'vp'\n"); 816 dev_err(dev, "failed to get clock 'vp'\n");
810 return -ENODEV; 817 return -ENODEV;
811 } 818 }
812 mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
813 if (IS_ERR(mixer_res->sclk_mixer)) {
814 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
815 return -ENODEV;
816 }
817 mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
818 if (IS_ERR(mixer_res->sclk_dac)) {
819 dev_err(dev, "failed to get clock 'sclk_dac'\n");
820 return -ENODEV;
821 }
822 819
823 if (mixer_res->sclk_hdmi) 820 if (mixer_ctx->has_sclk) {
824 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi); 821 mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
822 if (IS_ERR(mixer_res->sclk_mixer)) {
823 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
824 return -ENODEV;
825 }
826 mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
827 if (IS_ERR(mixer_res->mout_mixer)) {
828 dev_err(dev, "failed to get clock 'mout_mixer'\n");
829 return -ENODEV;
830 }
831
832 if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
833 clk_set_parent(mixer_res->mout_mixer,
834 mixer_res->sclk_hdmi);
835 }
825 836
826 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1); 837 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
827 if (res == NULL) { 838 if (res == NULL) {
@@ -1082,7 +1093,8 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
1082 clk_prepare_enable(res->mixer); 1093 clk_prepare_enable(res->mixer);
1083 if (ctx->vp_enabled) { 1094 if (ctx->vp_enabled) {
1084 clk_prepare_enable(res->vp); 1095 clk_prepare_enable(res->vp);
1085 clk_prepare_enable(res->sclk_mixer); 1096 if (ctx->has_sclk)
1097 clk_prepare_enable(res->sclk_mixer);
1086 } 1098 }
1087 1099
1088 mutex_lock(&ctx->mixer_mutex); 1100 mutex_lock(&ctx->mixer_mutex);
@@ -1121,7 +1133,8 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
1121 clk_disable_unprepare(res->mixer); 1133 clk_disable_unprepare(res->mixer);
1122 if (ctx->vp_enabled) { 1134 if (ctx->vp_enabled) {
1123 clk_disable_unprepare(res->vp); 1135 clk_disable_unprepare(res->vp);
1124 clk_disable_unprepare(res->sclk_mixer); 1136 if (ctx->has_sclk)
1137 clk_disable_unprepare(res->sclk_mixer);
1125 } 1138 }
1126 1139
1127 pm_runtime_put_sync(ctx->dev); 1140 pm_runtime_put_sync(ctx->dev);
@@ -1189,9 +1202,15 @@ static struct mixer_drv_data exynos5250_mxr_drv_data = {
1189 .is_vp_enabled = 0, 1202 .is_vp_enabled = 0,
1190}; 1203};
1191 1204
1205static struct mixer_drv_data exynos4212_mxr_drv_data = {
1206 .version = MXR_VER_0_0_0_16,
1207 .is_vp_enabled = 1,
1208};
1209
1192static struct mixer_drv_data exynos4210_mxr_drv_data = { 1210static struct mixer_drv_data exynos4210_mxr_drv_data = {
1193 .version = MXR_VER_0_0_0_16, 1211 .version = MXR_VER_0_0_0_16,
1194 .is_vp_enabled = 1, 1212 .is_vp_enabled = 1,
1213 .has_sclk = 1,
1195}; 1214};
1196 1215
1197static struct platform_device_id mixer_driver_types[] = { 1216static struct platform_device_id mixer_driver_types[] = {
@@ -1208,6 +1227,12 @@ static struct platform_device_id mixer_driver_types[] = {
1208 1227
1209static struct of_device_id mixer_match_types[] = { 1228static struct of_device_id mixer_match_types[] = {
1210 { 1229 {
1230 .compatible = "samsung,exynos4210-mixer",
1231 .data = &exynos4210_mxr_drv_data,
1232 }, {
1233 .compatible = "samsung,exynos4212-mixer",
1234 .data = &exynos4212_mxr_drv_data,
1235 }, {
1211 .compatible = "samsung,exynos5-mixer", 1236 .compatible = "samsung,exynos5-mixer",
1212 .data = &exynos5250_mxr_drv_data, 1237 .data = &exynos5250_mxr_drv_data,
1213 }, { 1238 }, {
@@ -1220,6 +1245,7 @@ static struct of_device_id mixer_match_types[] = {
1220 /* end node */ 1245 /* end node */
1221 } 1246 }
1222}; 1247};
1248MODULE_DEVICE_TABLE(of, mixer_match_types);
1223 1249
1224static int mixer_bind(struct device *dev, struct device *manager, void *data) 1250static int mixer_bind(struct device *dev, struct device *manager, void *data)
1225{ 1251{
@@ -1251,6 +1277,7 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
1251 ctx->pdev = pdev; 1277 ctx->pdev = pdev;
1252 ctx->dev = dev; 1278 ctx->dev = dev;
1253 ctx->vp_enabled = drv->is_vp_enabled; 1279 ctx->vp_enabled = drv->is_vp_enabled;
1280 ctx->has_sclk = drv->has_sclk;
1254 ctx->mxr_ver = drv->version; 1281 ctx->mxr_ver = drv->version;
1255 init_waitqueue_head(&ctx->wait_vsync_queue); 1282 init_waitqueue_head(&ctx->wait_vsync_queue);
1256 atomic_set(&ctx->wait_vsync_event, 0); 1283 atomic_set(&ctx->wait_vsync_event, 0);