aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos_drm_fimc.c
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2014-05-19 06:54:06 -0400
committerInki Dae <daeinki@gmail.com>2014-06-01 13:07:11 -0400
commitbe6cdfd17c1baa26bbe0e598cf9016f73ffe4cef (patch)
treec6cfffe7e1026785ebd95290c129083e25479f4f /drivers/gpu/drm/exynos/exynos_drm_fimc.c
parent3164605422d0a8b4b0b130fdf5f18cb3d023b77f (diff)
drm/exynos/fimc: simplify pre-scaler ratio calculation
The patch replaces dedicated function for scaling ratio calculation by fls calls. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fimc.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c56
1 files changed, 13 insertions, 43 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 5060f8a04c61..d40b7fb3349e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -957,43 +957,13 @@ static int fimc_dst_set_transf(struct device *dev,
957 return 0; 957 return 0;
958} 958}
959 959
960static int fimc_get_ratio_shift(u32 src, u32 dst, u32 *ratio, u32 *shift)
961{
962 DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst);
963
964 if (src >= dst * 64) {
965 DRM_ERROR("failed to make ratio and shift.\n");
966 return -EINVAL;
967 } else if (src >= dst * 32) {
968 *ratio = 32;
969 *shift = 5;
970 } else if (src >= dst * 16) {
971 *ratio = 16;
972 *shift = 4;
973 } else if (src >= dst * 8) {
974 *ratio = 8;
975 *shift = 3;
976 } else if (src >= dst * 4) {
977 *ratio = 4;
978 *shift = 2;
979 } else if (src >= dst * 2) {
980 *ratio = 2;
981 *shift = 1;
982 } else {
983 *ratio = 1;
984 *shift = 0;
985 }
986
987 return 0;
988}
989
990static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc, 960static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
991 struct drm_exynos_pos *src, struct drm_exynos_pos *dst) 961 struct drm_exynos_pos *src, struct drm_exynos_pos *dst)
992{ 962{
993 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 963 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
994 u32 cfg, cfg_ext, shfactor; 964 u32 cfg, cfg_ext, shfactor;
995 u32 pre_dst_width, pre_dst_height; 965 u32 pre_dst_width, pre_dst_height;
996 u32 pre_hratio, hfactor, pre_vratio, vfactor; 966 u32 hfactor, vfactor;
997 int ret = 0; 967 int ret = 0;
998 u32 src_w, src_h, dst_w, dst_h; 968 u32 src_w, src_h, dst_w, dst_h;
999 969
@@ -1014,24 +984,24 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
1014 dst_h = dst->h; 984 dst_h = dst->h;
1015 } 985 }
1016 986
1017 ret = fimc_get_ratio_shift(src_w, dst_w, &pre_hratio, &hfactor); 987 /* fimc_ippdrv_check_property assures that dividers are not null */
1018 if (ret) { 988 hfactor = fls(src_w / dst_w / 2);
989 if (hfactor > FIMC_SHFACTOR / 2) {
1019 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n"); 990 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n");
1020 return ret; 991 return -EINVAL;
1021 } 992 }
1022 993
1023 ret = fimc_get_ratio_shift(src_h, dst_h, &pre_vratio, &vfactor); 994 vfactor = fls(src_h / dst_h / 2);
1024 if (ret) { 995 if (vfactor > FIMC_SHFACTOR / 2) {
1025 dev_err(ippdrv->dev, "failed to get ratio vertical.\n"); 996 dev_err(ippdrv->dev, "failed to get ratio vertical.\n");
1026 return ret; 997 return -EINVAL;
1027 } 998 }
1028 999
1029 pre_dst_width = src_w / pre_hratio; 1000 pre_dst_width = src_w >> hfactor;
1030 pre_dst_height = src_h / pre_vratio; 1001 pre_dst_height = src_h >> vfactor;
1031 DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n", 1002 DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n",
1032 pre_dst_width, pre_dst_height); 1003 pre_dst_width, pre_dst_height);
1033 DRM_DEBUG_KMS("pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n", 1004 DRM_DEBUG_KMS("hfactor[%d]vfactor[%d]\n", hfactor, vfactor);
1034 pre_hratio, hfactor, pre_vratio, vfactor);
1035 1005
1036 sc->hratio = (src_w << 14) / (dst_w << hfactor); 1006 sc->hratio = (src_w << 14) / (dst_w << hfactor);
1037 sc->vratio = (src_h << 14) / (dst_h << vfactor); 1007 sc->vratio = (src_h << 14) / (dst_h << vfactor);
@@ -1044,8 +1014,8 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
1044 DRM_DEBUG_KMS("shfactor[%d]\n", shfactor); 1014 DRM_DEBUG_KMS("shfactor[%d]\n", shfactor);
1045 1015
1046 cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) | 1016 cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
1047 EXYNOS_CISCPRERATIO_PREHORRATIO(pre_hratio) | 1017 EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) |
1048 EXYNOS_CISCPRERATIO_PREVERRATIO(pre_vratio)); 1018 EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor));
1049 fimc_write(cfg, EXYNOS_CISCPRERATIO); 1019 fimc_write(cfg, EXYNOS_CISCPRERATIO);
1050 1020
1051 cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) | 1021 cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) |