aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorRahul Sharma <rahul.sharma@samsung.com>2012-10-04 11:18:52 -0400
committerInki Dae <inki.dae@samsung.com>2012-10-05 06:15:08 -0400
commit1b8e5747a9b65928a5a126d128847b29128cae34 (patch)
tree32c6890d2f595cad9008ed780a934f4007a02dfd /drivers/gpu
parent1e12344120df6b1959f47382bac02952bee6226c (diff)
drm: exynos: hdmi: add support to disable video processor in mixer
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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c151
1 files changed, 98 insertions, 53 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index e312fb1dafdd..167734529229 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -83,6 +83,7 @@ struct mixer_context {
83 int pipe; 83 int pipe;
84 bool interlace; 84 bool interlace;
85 bool powered; 85 bool powered;
86 bool vp_enabled;
86 u32 int_en; 87 u32 int_en;
87 88
88 struct mutex mixer_mutex; 89 struct mutex mixer_mutex;
@@ -93,6 +94,7 @@ struct mixer_context {
93 94
94struct mixer_drv_data { 95struct mixer_drv_data {
95 enum mixer_version_id version; 96 enum mixer_version_id version;
97 bool is_vp_enabled;
96}; 98};
97 99
98static const u8 filter_y_horiz_tap8[] = { 100static const u8 filter_y_horiz_tap8[] = {
@@ -261,7 +263,8 @@ static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
261 mixer_reg_writemask(res, MXR_STATUS, enable ? 263 mixer_reg_writemask(res, MXR_STATUS, enable ?
262 MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE); 264 MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
263 265
264 vp_reg_write(res, VP_SHADOW_UPDATE, enable ? 266 if (ctx->vp_enabled)
267 vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
265 VP_SHADOW_UPDATE_ENABLE : 0); 268 VP_SHADOW_UPDATE_ENABLE : 0);
266} 269}
267 270
@@ -343,8 +346,11 @@ static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
343 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); 346 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
344 break; 347 break;
345 case 2: 348 case 2:
346 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); 349 if (ctx->vp_enabled) {
347 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE); 350 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
351 mixer_reg_writemask(res, MXR_CFG, val,
352 MXR_CFG_VP_ENABLE);
353 }
348 break; 354 break;
349 } 355 }
350} 356}
@@ -602,7 +608,8 @@ static void mixer_win_reset(struct mixer_context *ctx)
602 */ 608 */
603 val = MXR_LAYER_CFG_GRP1_VAL(3); 609 val = MXR_LAYER_CFG_GRP1_VAL(3);
604 val |= MXR_LAYER_CFG_GRP0_VAL(2); 610 val |= MXR_LAYER_CFG_GRP0_VAL(2);
605 val |= MXR_LAYER_CFG_VP_VAL(1); 611 if (ctx->vp_enabled)
612 val |= MXR_LAYER_CFG_VP_VAL(1);
606 mixer_reg_write(res, MXR_LAYER_CFG, val); 613 mixer_reg_write(res, MXR_LAYER_CFG, val);
607 614
608 /* setting background color */ 615 /* setting background color */
@@ -625,14 +632,17 @@ static void mixer_win_reset(struct mixer_context *ctx)
625 val = MXR_GRP_CFG_ALPHA_VAL(0); 632 val = MXR_GRP_CFG_ALPHA_VAL(0);
626 mixer_reg_write(res, MXR_VIDEO_CFG, val); 633 mixer_reg_write(res, MXR_VIDEO_CFG, val);
627 634
628 /* configuration of Video Processor Registers */ 635 if (ctx->vp_enabled) {
629 vp_win_reset(ctx); 636 /* configuration of Video Processor Registers */
630 vp_default_filter(res); 637 vp_win_reset(ctx);
638 vp_default_filter(res);
639 }
631 640
632 /* disable all layers */ 641 /* disable all layers */
633 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); 642 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
634 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); 643 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
635 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); 644 if (ctx->vp_enabled)
645 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
636 646
637 mixer_vsync_set_update(ctx, true); 647 mixer_vsync_set_update(ctx, true);
638 spin_unlock_irqrestore(&res->reg_slock, flags); 648 spin_unlock_irqrestore(&res->reg_slock, flags);
@@ -655,8 +665,10 @@ static void mixer_poweron(struct mixer_context *ctx)
655 pm_runtime_get_sync(ctx->dev); 665 pm_runtime_get_sync(ctx->dev);
656 666
657 clk_enable(res->mixer); 667 clk_enable(res->mixer);
658 clk_enable(res->vp); 668 if (ctx->vp_enabled) {
659 clk_enable(res->sclk_mixer); 669 clk_enable(res->vp);
670 clk_enable(res->sclk_mixer);
671 }
660 672
661 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 673 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
662 mixer_win_reset(ctx); 674 mixer_win_reset(ctx);
@@ -676,8 +688,10 @@ static void mixer_poweroff(struct mixer_context *ctx)
676 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 688 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
677 689
678 clk_disable(res->mixer); 690 clk_disable(res->mixer);
679 clk_disable(res->vp); 691 if (ctx->vp_enabled) {
680 clk_disable(res->sclk_mixer); 692 clk_disable(res->vp);
693 clk_disable(res->sclk_mixer);
694 }
681 695
682 pm_runtime_put_sync(ctx->dev); 696 pm_runtime_put_sync(ctx->dev);
683 697
@@ -810,7 +824,7 @@ static void mixer_win_commit(void *ctx, int win)
810 824
811 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); 825 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
812 826
813 if (win > 1) 827 if (win > 1 && mixer_ctx->vp_enabled)
814 vp_video_buffer(mixer_ctx, win); 828 vp_video_buffer(mixer_ctx, win);
815 else 829 else
816 mixer_graph_buffer(mixer_ctx, win); 830 mixer_graph_buffer(mixer_ctx, win);
@@ -946,39 +960,20 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
946 ret = -ENODEV; 960 ret = -ENODEV;
947 goto fail; 961 goto fail;
948 } 962 }
949 mixer_res->vp = clk_get(dev, "vp"); 963
950 if (IS_ERR_OR_NULL(mixer_res->vp)) {
951 dev_err(dev, "failed to get clock 'vp'\n");
952 ret = -ENODEV;
953 goto fail;
954 }
955 mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
956 if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
957 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
958 ret = -ENODEV;
959 goto fail;
960 }
961 mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi"); 964 mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
962 if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) { 965 if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
963 dev_err(dev, "failed to get clock 'sclk_hdmi'\n"); 966 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
964 ret = -ENODEV; 967 ret = -ENODEV;
965 goto fail; 968 goto fail;
966 } 969 }
967 mixer_res->sclk_dac = clk_get(dev, "sclk_dac"); 970 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
968 if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
969 dev_err(dev, "failed to get clock 'sclk_dac'\n");
970 ret = -ENODEV;
971 goto fail;
972 }
973 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
974 if (res == NULL) { 971 if (res == NULL) {
975 dev_err(dev, "get memory resource failed.\n"); 972 dev_err(dev, "get memory resource failed.\n");
976 ret = -ENXIO; 973 ret = -ENXIO;
977 goto fail; 974 goto fail;
978 } 975 }
979 976
980 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
981
982 mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start, 977 mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
983 resource_size(res)); 978 resource_size(res));
984 if (mixer_res->mixer_regs == NULL) { 979 if (mixer_res->mixer_regs == NULL) {
@@ -987,54 +982,92 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
987 goto fail; 982 goto fail;
988 } 983 }
989 984
990 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp"); 985 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
991 if (res == NULL) { 986 if (res == NULL) {
992 dev_err(dev, "get memory resource failed.\n"); 987 dev_err(dev, "get interrupt resource failed.\n");
993 ret = -ENXIO; 988 ret = -ENXIO;
994 goto fail; 989 goto fail;
995 } 990 }
996 991
997 mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start, 992 ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
998 resource_size(res)); 993 0, "drm_mixer", ctx);
999 if (mixer_res->vp_regs == NULL) { 994 if (ret) {
1000 dev_err(dev, "register mapping failed.\n"); 995 dev_err(dev, "request interrupt failed.\n");
1001 ret = -ENXIO;
1002 goto fail; 996 goto fail;
1003 } 997 }
998 mixer_res->irq = res->start;
1004 999
1005 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq"); 1000 return 0;
1001
1002fail:
1003 if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
1004 clk_put(mixer_res->sclk_hdmi);
1005 if (!IS_ERR_OR_NULL(mixer_res->mixer))
1006 clk_put(mixer_res->mixer);
1007 return ret;
1008}
1009
1010static int __devinit vp_resources_init(struct exynos_drm_hdmi_context *ctx,
1011 struct platform_device *pdev)
1012{
1013 struct mixer_context *mixer_ctx = ctx->ctx;
1014 struct device *dev = &pdev->dev;
1015 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1016 struct resource *res;
1017 int ret;
1018
1019 mixer_res->vp = clk_get(dev, "vp");
1020 if (IS_ERR_OR_NULL(mixer_res->vp)) {
1021 dev_err(dev, "failed to get clock 'vp'\n");
1022 ret = -ENODEV;
1023 goto fail;
1024 }
1025 mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
1026 if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
1027 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
1028 ret = -ENODEV;
1029 goto fail;
1030 }
1031 mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
1032 if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
1033 dev_err(dev, "failed to get clock 'sclk_dac'\n");
1034 ret = -ENODEV;
1035 goto fail;
1036 }
1037
1038 if (mixer_res->sclk_hdmi)
1039 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
1040
1041 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1006 if (res == NULL) { 1042 if (res == NULL) {
1007 dev_err(dev, "get interrupt resource failed.\n"); 1043 dev_err(dev, "get memory resource failed.\n");
1008 ret = -ENXIO; 1044 ret = -ENXIO;
1009 goto fail; 1045 goto fail;
1010 } 1046 }
1011 1047
1012 ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler, 1048 mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
1013 0, "drm_mixer", ctx); 1049 resource_size(res));
1014 if (ret) { 1050 if (mixer_res->vp_regs == NULL) {
1015 dev_err(dev, "request interrupt failed.\n"); 1051 dev_err(dev, "register mapping failed.\n");
1052 ret = -ENXIO;
1016 goto fail; 1053 goto fail;
1017 } 1054 }
1018 mixer_res->irq = res->start;
1019 1055
1020 return 0; 1056 return 0;
1021 1057
1022fail: 1058fail:
1023 if (!IS_ERR_OR_NULL(mixer_res->sclk_dac)) 1059 if (!IS_ERR_OR_NULL(mixer_res->sclk_dac))
1024 clk_put(mixer_res->sclk_dac); 1060 clk_put(mixer_res->sclk_dac);
1025 if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
1026 clk_put(mixer_res->sclk_hdmi);
1027 if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer)) 1061 if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer))
1028 clk_put(mixer_res->sclk_mixer); 1062 clk_put(mixer_res->sclk_mixer);
1029 if (!IS_ERR_OR_NULL(mixer_res->vp)) 1063 if (!IS_ERR_OR_NULL(mixer_res->vp))
1030 clk_put(mixer_res->vp); 1064 clk_put(mixer_res->vp);
1031 if (!IS_ERR_OR_NULL(mixer_res->mixer))
1032 clk_put(mixer_res->mixer);
1033 return ret; 1065 return ret;
1034} 1066}
1035 1067
1036static struct mixer_drv_data exynos4_mxr_drv_data = { 1068static struct mixer_drv_data exynos4_mxr_drv_data = {
1037 .version = MXR_VER_0_0_0_16, 1069 .version = MXR_VER_0_0_0_16,
1070 .is_vp_enabled = 1,
1038}; 1071};
1039 1072
1040static struct platform_device_id mixer_driver_types[] = { 1073static struct platform_device_id mixer_driver_types[] = {
@@ -1075,14 +1108,26 @@ static int __devinit mixer_probe(struct platform_device *pdev)
1075 pdev)->driver_data; 1108 pdev)->driver_data;
1076 ctx->dev = &pdev->dev; 1109 ctx->dev = &pdev->dev;
1077 drm_hdmi_ctx->ctx = (void *)ctx; 1110 drm_hdmi_ctx->ctx = (void *)ctx;
1111 ctx->vp_enabled = drv->is_vp_enabled;
1078 ctx->mxr_ver = drv->version; 1112 ctx->mxr_ver = drv->version;
1079 1113
1080 platform_set_drvdata(pdev, drm_hdmi_ctx); 1114 platform_set_drvdata(pdev, drm_hdmi_ctx);
1081 1115
1082 /* acquire resources: regs, irqs, clocks */ 1116 /* acquire resources: regs, irqs, clocks */
1083 ret = mixer_resources_init(drm_hdmi_ctx, pdev); 1117 ret = mixer_resources_init(drm_hdmi_ctx, pdev);
1084 if (ret) 1118 if (ret) {
1119 DRM_ERROR("mixer_resources_init failed\n");
1085 goto fail; 1120 goto fail;
1121 }
1122
1123 if (ctx->vp_enabled) {
1124 /* acquire vp resources: regs, irqs, clocks */
1125 ret = vp_resources_init(drm_hdmi_ctx, pdev);
1126 if (ret) {
1127 DRM_ERROR("vp_resources_init failed\n");
1128 goto fail;
1129 }
1130 }
1086 1131
1087 /* register specific callback point to common hdmi. */ 1132 /* register specific callback point to common hdmi. */
1088 exynos_mixer_ops_register(&mixer_ops); 1133 exynos_mixer_ops_register(&mixer_ops);