Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] exynos-gsc: Add support for Exynos5433 specific version

This patch adds support for Exynos5433 specific version of the GScaler
module. The main difference between Exynos 5433 and earlier is addition
of new clocks that have to be controlled.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Tested-by: Javier Martinez Canillas <javier@osg.samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Marek Szyprowski and committed by
Mauro Carvalho Chehab
92955ea0 6f99e1b8

+62 -21
+2 -1
Documentation/devicetree/bindings/media/exynos5-gsc.txt
··· 3 3 G-Scaler is used for scaling and color space conversion on EXYNOS5 SoCs. 4 4 5 5 Required properties: 6 - - compatible: should be "samsung,exynos5-gsc" 6 + - compatible: should be "samsung,exynos5-gsc" (for Exynos 5250, 5420 and 7 + 5422 SoCs) or "samsung,exynos5433-gsc" (Exynos 5433) 7 8 - reg: should contain G-Scaler physical address location and length. 8 9 - interrupts: should contain G-Scaler interrupt number 9 10
+55 -19
drivers/media/platform/exynos-gsc/gsc-core.c
··· 29 29 30 30 #include "gsc-core.h" 31 31 32 - #define GSC_CLOCK_GATE_NAME "gscl" 33 - 34 32 static const struct gsc_fmt gsc_formats[] = { 35 33 { 36 34 .name = "RGB565", ··· 976 978 [3] = &gsc_v_100_variant, 977 979 }, 978 980 .num_entities = 4, 981 + .clk_names = { "gscl" }, 982 + .num_clocks = 1, 983 + }; 984 + 985 + static struct gsc_driverdata gsc_5433_drvdata = { 986 + .variant = { 987 + [0] = &gsc_v_100_variant, 988 + [1] = &gsc_v_100_variant, 989 + [2] = &gsc_v_100_variant, 990 + }, 991 + .num_entities = 3, 992 + .clk_names = { "pclk", "aclk", "aclk_xiu", "aclk_gsclbend" }, 993 + .num_clocks = 4, 979 994 }; 980 995 981 996 static const struct of_device_id exynos_gsc_match[] = { 982 997 { 983 998 .compatible = "samsung,exynos5-gsc", 984 999 .data = &gsc_v_100_drvdata, 1000 + }, 1001 + { 1002 + .compatible = "samsung,exynos5433-gsc", 1003 + .data = &gsc_5433_drvdata, 985 1004 }, 986 1005 {}, 987 1006 }; ··· 1011 996 struct device *dev = &pdev->dev; 1012 997 const struct gsc_driverdata *drv_data = of_device_get_match_data(dev); 1013 998 int ret; 999 + int i; 1014 1000 1015 1001 gsc = devm_kzalloc(dev, sizeof(struct gsc_dev), GFP_KERNEL); 1016 1002 if (!gsc) ··· 1027 1011 return -EINVAL; 1028 1012 } 1029 1013 1014 + gsc->num_clocks = drv_data->num_clocks; 1030 1015 gsc->variant = drv_data->variant[gsc->id]; 1031 1016 gsc->pdev = pdev; 1032 1017 ··· 1046 1029 return -ENXIO; 1047 1030 } 1048 1031 1049 - gsc->clock = devm_clk_get(dev, GSC_CLOCK_GATE_NAME); 1050 - if (IS_ERR(gsc->clock)) { 1051 - dev_err(dev, "failed to get clock~~~: %s\n", 1052 - GSC_CLOCK_GATE_NAME); 1053 - return PTR_ERR(gsc->clock); 1032 + for (i = 0; i < gsc->num_clocks; i++) { 1033 + gsc->clock[i] = devm_clk_get(dev, drv_data->clk_names[i]); 1034 + if (IS_ERR(gsc->clock[i])) { 1035 + dev_err(dev, "failed to get clock: %s\n", 1036 + drv_data->clk_names[i]); 1037 + return PTR_ERR(gsc->clock[i]); 1038 + } 1054 1039 } 1055 1040 1056 - ret = clk_prepare_enable(gsc->clock); 1057 - if (ret) { 1058 - dev_err(&gsc->pdev->dev, "clock prepare failed for clock: %s\n", 1059 - GSC_CLOCK_GATE_NAME); 1060 - return ret; 1041 + for (i = 0; i < gsc->num_clocks; i++) { 1042 + ret = clk_prepare_enable(gsc->clock[i]); 1043 + if (ret) { 1044 + dev_err(dev, "clock prepare failed for clock: %s\n", 1045 + drv_data->clk_names[i]); 1046 + while (--i >= 0) 1047 + clk_disable_unprepare(gsc->clock[i]); 1048 + return ret; 1049 + } 1061 1050 } 1062 1051 1063 1052 ret = devm_request_irq(dev, res->start, gsc_irq_handler, ··· 1098 1075 err_v4l2: 1099 1076 v4l2_device_unregister(&gsc->v4l2_dev); 1100 1077 err_clk: 1101 - clk_disable_unprepare(gsc->clock); 1078 + for (i = gsc->num_clocks - 1; i >= 0; i--) 1079 + clk_disable_unprepare(gsc->clock[i]); 1102 1080 return ret; 1103 1081 } 1104 1082 1105 1083 static int gsc_remove(struct platform_device *pdev) 1106 1084 { 1107 1085 struct gsc_dev *gsc = platform_get_drvdata(pdev); 1086 + int i; 1108 1087 1109 1088 pm_runtime_get_sync(&pdev->dev); 1110 1089 ··· 1114 1089 v4l2_device_unregister(&gsc->v4l2_dev); 1115 1090 1116 1091 vb2_dma_contig_clear_max_seg_size(&pdev->dev); 1117 - clk_disable_unprepare(gsc->clock); 1092 + for (i = 0; i < gsc->num_clocks; i++) 1093 + clk_disable_unprepare(gsc->clock[i]); 1118 1094 1119 1095 pm_runtime_put_noidle(&pdev->dev); 1120 1096 ··· 1165 1139 { 1166 1140 struct gsc_dev *gsc = dev_get_drvdata(dev); 1167 1141 int ret = 0; 1142 + int i; 1168 1143 1169 1144 pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); 1170 1145 1171 - ret = clk_prepare_enable(gsc->clock); 1172 - if (ret) 1173 - return ret; 1146 + for (i = 0; i < gsc->num_clocks; i++) { 1147 + ret = clk_prepare_enable(gsc->clock[i]); 1148 + if (ret) { 1149 + while (--i >= 0) 1150 + clk_disable_unprepare(gsc->clock[i]); 1151 + return ret; 1152 + } 1153 + } 1174 1154 1175 1155 gsc_hw_set_sw_reset(gsc); 1176 1156 gsc_wait_reset(gsc); ··· 1189 1157 { 1190 1158 struct gsc_dev *gsc = dev_get_drvdata(dev); 1191 1159 int ret = 0; 1160 + int i; 1192 1161 1193 1162 ret = gsc_m2m_suspend(gsc); 1194 - if (!ret) 1195 - clk_disable_unprepare(gsc->clock); 1163 + if (ret) 1164 + return ret; 1165 + 1166 + for (i = gsc->num_clocks - 1; i >= 0; i--) 1167 + clk_disable_unprepare(gsc->clock[i]); 1196 1168 1197 1169 pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); 1198 1170 return ret;
+5 -1
drivers/media/platform/exynos-gsc/gsc-core.h
··· 33 33 34 34 #define GSC_SHUTDOWN_TIMEOUT ((100*HZ)/1000) 35 35 #define GSC_MAX_DEVS 4 36 + #define GSC_MAX_CLOCKS 4 36 37 #define GSC_M2M_BUF_NUM 0 37 38 #define GSC_MAX_CTRL_NUM 10 38 39 #define GSC_SC_ALIGN_4 4 ··· 308 307 */ 309 308 struct gsc_driverdata { 310 309 struct gsc_variant *variant[GSC_MAX_DEVS]; 310 + const char *clk_names[GSC_MAX_CLOCKS]; 311 + int num_clocks; 311 312 int num_entities; 312 313 }; 313 314 ··· 333 330 struct platform_device *pdev; 334 331 struct gsc_variant *variant; 335 332 u16 id; 336 - struct clk *clock; 333 + int num_clocks; 334 + struct clk *clock[GSC_MAX_CLOCKS]; 337 335 void __iomem *regs; 338 336 wait_queue_head_t irq_queue; 339 337 struct gsc_m2m_device m2m;