1 // SPDX-License-Identifier: GPL-2.0
3 * VPSS SCALER DRM bridge driver
5 * Copyright (C) 2017-2018 Xilinx, Inc.
7 * Author: Venkateshwar rao G <vgannava@xilinx.com>
8 * Rohit Athavale <rathavale@xilinx.com>
13 * This experimentatl driver works as a bridge driver and
14 * reused the code from V4L2.
16 * Need to implement in a modular approach to share driver code between
17 * V4L2 and DRM frameworks.
18 * Should be integrated with plane.
21 #include <linux/device.h>
22 #include <linux/err.h>
23 #include <linux/gpio/consumer.h>
25 #include <linux/module.h>
26 #include <linux/of_device.h>
27 #include <linux/platform_device.h>
28 #include <uapi/linux/media-bus-format.h>
30 #include "xlnx_bridge.h"
32 #define XSCALER_MAX_WIDTH (3840)
33 #define XSCALER_MAX_HEIGHT (2160)
34 #define XSCALER_MAX_PHASES (64)
36 /* Video subsytems block offset */
37 #define S_AXIS_RESET_OFF (0x00010000)
38 #define V_HSCALER_OFF (0x00000000)
39 #define V_VSCALER_OFF (0x00020000)
41 /* HW Reset Network GPIO Channel */
42 #define XGPIO_CH_RESET_SEL (1)
43 #define XGPIO_RESET_MASK_VIDEO_IN BIT(0)
44 #define XGPIO_RESET_MASK_IP_AXIS BIT(1)
45 #define XGPIO_RESET_MASK_ALL_BLOCKS (XGPIO_RESET_MASK_VIDEO_IN | \
46 XGPIO_RESET_MASK_IP_AXIS)
47 #define XGPIO_DATA_OFFSET (0x0)
48 #define XGPIO_DATA2_OFFSET (0x8)
49 #define XGPIO_TRI2_OFFSET (0xc)
51 #define XGPIO_ISR_OFFSET (0x120)
52 #define XGPIO_IER_OFFSET (0x128)
53 #define XGPIO_CHAN_OFFSET (8)
54 #define STEP_PRECISION (65536)
56 /* SCALER POWER MACROS */
57 #define XSCALER_RESET_ASSERT (0x1)
58 #define XSCALER_RESET_DEASSERT (0x0)
61 #define XSCALER_PPC_1 (1)
62 #define XSCALER_PPC_2 (2)
64 #define XV_HSCALER_MAX_H_TAPS (12)
65 #define XV_HSCALER_MAX_H_PHASES (64)
66 #define XV_HSCALER_MAX_LINE_WIDTH (3840)
67 #define XV_VSCALER_MAX_V_TAPS (12)
68 #define XV_VSCALER_MAX_V_PHASES (64)
70 #define XV_HSCALER_TAPS_2 (2)
71 #define XV_HSCALER_TAPS_4 (4)
72 #define XV_HSCALER_TAPS_6 (6)
73 #define XV_HSCALER_TAPS_8 (8)
74 #define XV_HSCALER_TAPS_10 (10)
75 #define XV_HSCALER_TAPS_12 (12)
76 #define XV_VSCALER_TAPS_2 (2)
77 #define XV_VSCALER_TAPS_4 (4)
78 #define XV_VSCALER_TAPS_6 (6)
79 #define XV_VSCALER_TAPS_8 (8)
80 #define XV_VSCALER_TAPS_10 (10)
81 #define XV_VSCALER_TAPS_12 (12)
83 /* Mask definitions for Low and high 16 bits in a 32 bit number */
84 #define XHSC_MASK_LOW_16BITS GENMASK(15, 0)
85 #define XHSC_MASK_HIGH_16BITS GENMASK(31, 16)
86 #define XHSC_MASK_LOW_32BITS GENMASK(31, 0)
87 #define XHSC_STEP_PRECISION_SHIFT (16)
88 #define XHSC_HPHASE_SHIFT_BY_6 (6)
89 #define XHSC_HPHASE_MULTIPLIER (9)
90 #define XSCALER_BITSHIFT_16 (16)
92 /* Mask definitions for Low and high 16 bits in a 32 bit number */
93 #define XVSC_MASK_LOW_16BITS GENMASK(15, 0)
94 #define XVSC_MASK_HIGH_16BITS GENMASK(31, 16)
96 /* Scaler AP Control Registers */
97 #define XSCALER_START BIT(0)
98 #define XSCALER_AUTO_RESTART BIT(7)
99 #define XSCALER_STREAM_ON (XSCALER_START | XSCALER_AUTO_RESTART)
101 /* H-scaler registers */
102 #define XV_HSCALER_CTRL_ADDR_AP_CTRL (0x0000)
103 #define XV_HSCALER_CTRL_ADDR_GIE (0x0004)
104 #define XV_HSCALER_CTRL_ADDR_IER (0x0008)
105 #define XV_HSCALER_CTRL_ADDR_ISR (0x000c)
106 #define XV_HSCALER_CTRL_ADDR_HWREG_HEIGHT_DATA (0x0010)
107 #define XV_HSCALER_CTRL_ADDR_HWREG_WIDTHIN_DATA (0x0018)
108 #define XV_HSCALER_CTRL_ADDR_HWREG_WIDTHOUT_DATA (0x0020)
109 #define XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA (0x0028)
110 #define XV_HSCALER_CTRL_ADDR_HWREG_PIXELRATE_DATA (0x0030)
111 #define XV_HSCALER_CTRL_ADDR_HWREG_COLORMODEOUT_DATA (0X0038)
112 #define XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE (0x0800)
113 #define XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH (0x0bff)
115 #define XV_HSCALER_CTRL_WIDTH_HWREG_HFLTCOEFF (16)
116 #define XV_HSCALER_CTRL_DEPTH_HWREG_HFLTCOEFF (384)
117 #define XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE (0x2000)
118 #define XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH (0x3fff)
119 #define XV_HSCALER_CTRL_WIDTH_HWREG_PHASESH_V (18)
120 #define XV_HSCALER_CTRL_DEPTH_HWREG_PHASESH_V (1920)
123 #define XV_HSCALER_PHASESH_V_OUTPUT_WR_EN BIT(8)
125 /* V-scaler registers */
126 #define XV_VSCALER_CTRL_ADDR_AP_CTRL (0x000)
127 #define XV_VSCALER_CTRL_ADDR_GIE (0x004)
128 #define XV_VSCALER_CTRL_ADDR_IER (0x008)
129 #define XV_VSCALER_CTRL_ADDR_ISR (0x00c)
130 #define XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTIN_DATA (0x010)
131 #define XV_VSCALER_CTRL_ADDR_HWREG_WIDTH_DATA (0x018)
132 #define XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTOUT_DATA (0x020)
133 #define XV_VSCALER_CTRL_ADDR_HWREG_LINERATE_DATA (0x028)
134 #define XV_VSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA (0x030)
135 #define XV_VSCALER_CTRL_ADDR_HWREG_VFLTCOEFF_BASE (0x800)
136 #define XV_VSCALER_CTRL_ADDR_HWREG_VFLTCOEFF_HIGH (0xbff)
138 /* H-scaler coefficients for 6, 8, 10 and 12 tap filters */
140 xhsc_coeff_taps6[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_6] = {
141 { -132, 236, 3824, 236, -132, 64, },
142 { -116, 184, 3816, 292, -144, 64, },
143 { -100, 132, 3812, 348, -160, 64, },
144 { -88, 84, 3808, 404, -176, 64, },
145 { -72, 36, 3796, 464, -192, 64, },
146 { -60, -8, 3780, 524, -208, 68, },
147 { -48, -52, 3768, 588, -228, 68, },
148 { -32, -96, 3748, 652, -244, 68, },
149 { -20, -136, 3724, 716, -260, 72, },
150 { -8, -172, 3696, 784, -276, 72, },
151 { 0, -208, 3676, 848, -292, 72, },
152 { 12, -244, 3640, 920, -308, 76, },
153 { 20, -276, 3612, 988, -324, 76, },
154 { 32, -304, 3568, 1060, -340, 80, },
155 { 40, -332, 3532, 1132, -356, 80, },
156 { 48, -360, 3492, 1204, -372, 84, },
157 { 56, -384, 3448, 1276, -388, 88, },
158 { 64, -408, 3404, 1352, -404, 88, },
159 { 72, -428, 3348, 1428, -416, 92, },
160 { 76, -448, 3308, 1500, -432, 92, },
161 { 84, -464, 3248, 1576, -444, 96, },
162 { 88, -480, 3200, 1652, -460, 96, },
163 { 92, -492, 3140, 1728, -472, 100, },
164 { 96, -504, 3080, 1804, -484, 104, },
165 { 100, -516, 3020, 1880, -492, 104, },
166 { 104, -524, 2956, 1960, -504, 104, },
167 { 104, -532, 2892, 2036, -512, 108, },
168 { 108, -540, 2832, 2108, -520, 108, },
169 { 108, -544, 2764, 2184, -528, 112, },
170 { 112, -544, 2688, 2260, -532, 112, },
171 { 112, -548, 2624, 2336, -540, 112, },
172 { 112, -548, 2556, 2408, -544, 112, },
173 { 112, -544, 2480, 2480, -544, 112, },
174 { 112, -544, 2408, 2556, -548, 112, },
175 { 112, -540, 2336, 2624, -548, 112, },
176 { 112, -532, 2260, 2688, -544, 112, },
177 { 112, -528, 2184, 2764, -544, 108, },
178 { 108, -520, 2108, 2832, -540, 108, },
179 { 108, -512, 2036, 2892, -532, 104, },
180 { 104, -504, 1960, 2956, -524, 104, },
181 { 104, -492, 1880, 3020, -516, 100, },
182 { 104, -484, 1804, 3080, -504, 96, },
183 { 100, -472, 1728, 3140, -492, 92, },
184 { 96, -460, 1652, 3200, -480, 88, },
185 { 96, -444, 1576, 3248, -464, 84, },
186 { 92, -432, 1500, 3308, -448, 76, },
187 { 92, -416, 1428, 3348, -428, 72, },
188 { 88, -404, 1352, 3404, -408, 64, },
189 { 88, -388, 1276, 3448, -384, 56, },
190 { 84, -372, 1204, 3492, -360, 48, },
191 { 80, -356, 1132, 3532, -332, 40, },
192 { 80, -340, 1060, 3568, -304, 32, },
193 { 76, -324, 988, 3612, -276, 20, },
194 { 76, -308, 920, 3640, -244, 12, },
195 { 72, -292, 848, 3676, -208, 0, },
196 { 72, -276, 784, 3696, -172, -8, },
197 { 72, -260, 716, 3724, -136, -20, },
198 { 68, -244, 652, 3748, -96, -32, },
199 { 68, -228, 588, 3768, -52, -48, },
200 { 68, -208, 524, 3780, -8, -60, },
201 { 64, -192, 464, 3796, 36, -72, },
202 { 64, -176, 404, 3808, 84, -88, },
203 { 64, -160, 348, 3812, 132, -100, },
204 { 64, -144, 292, 3816, 184, -116, }
208 xhsc_coeff_taps8[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_8] = {
209 {-5, 309, 1023, 1445, 1034, 317, -3, -24, },
210 {-6, 300, 1011, 1445, 1045, 326, -1, -24, },
211 {-7, 291, 1000, 1444, 1056, 336, 0, -24, },
212 {-9, 282, 988, 1444, 1067, 345, 2, -24, },
213 {-10, 274, 977, 1443, 1078, 354, 4, -24, },
214 {-11, 266, 965, 1441, 1089, 364, 6, -24, },
215 {-12, 258, 953, 1440, 1100, 373, 8, -24, },
216 {-13, 250, 942, 1438, 1110, 383, 10, -24, },
217 {-14, 242, 930, 1437, 1121, 393, 12, -24, },
218 {-15, 234, 918, 1434, 1131, 403, 14, -24, },
219 {-16, 226, 906, 1432, 1142, 413, 17, -24, },
220 {-17, 219, 894, 1430, 1152, 423, 19, -24, },
221 {-17, 211, 882, 1427, 1162, 433, 22, -24, },
222 {-18, 204, 870, 1424, 1172, 443, 24, -24, },
223 {-19, 197, 858, 1420, 1182, 454, 27, -24, },
224 {-19, 190, 846, 1417, 1191, 464, 30, -24, },
225 {-20, 183, 834, 1413, 1201, 475, 33, -24, },
226 {-20, 176, 822, 1409, 1210, 486, 36, -24, },
227 {-21, 170, 810, 1405, 1220, 497, 39, -24, },
228 {-21, 163, 798, 1401, 1229, 507, 42, -24, },
229 {-22, 157, 786, 1396, 1238, 518, 46, -24, },
230 {-22, 151, 774, 1392, 1247, 529, 49, -24, },
231 {-22, 144, 762, 1387, 1255, 540, 53, -24, },
232 {-23, 139, 750, 1382, 1264, 552, 57, -24, },
233 {-23, 133, 738, 1376, 1272, 563, 60, -24, },
234 {-23, 127, 726, 1371, 1280, 574, 64, -24, },
235 {-23, 121, 714, 1365, 1288, 586, 69, -24, },
236 {-23, 116, 703, 1359, 1296, 597, 73, -24, },
237 {-24, 111, 691, 1353, 1304, 609, 77, -24, },
238 {-24, 105, 679, 1346, 1312, 620, 81, -24, },
239 {-24, 100, 667, 1340, 1319, 632, 86, -24, },
240 {-24, 96, 655, 1333, 1326, 644, 91, -24, },
241 {-24, 91, 644, 1326, 1333, 655, 96, -24, },
242 {-24, 86, 632, 1319, 1340, 667, 100, -24, },
243 {-24, 81, 620, 1312, 1346, 679, 105, -24, },
244 {-24, 77, 609, 1304, 1353, 691, 111, -24, },
245 {-24, 73, 597, 1296, 1359, 703, 116, -23, },
246 {-24, 69, 586, 1288, 1365, 714, 121, -23, },
247 {-24, 64, 574, 1280, 1371, 726, 127, -23, },
248 {-24, 60, 563, 1272, 1376, 738, 133, -23, },
249 {-24, 57, 552, 1264, 1382, 750, 139, -23, },
250 {-24, 53, 540, 1255, 1387, 762, 144, -22, },
251 {-24, 49, 529, 1247, 1392, 774, 151, -22, },
252 {-24, 46, 518, 1238, 1396, 786, 157, -22, },
253 {-24, 42, 507, 1229, 1401, 798, 163, -21, },
254 {-24, 39, 497, 1220, 1405, 810, 170, -21, },
255 {-24, 36, 486, 1210, 1409, 822, 176, -20, },
256 {-24, 33, 475, 1201, 1413, 834, 183, -20, },
257 {-24, 30, 464, 1191, 1417, 846, 190, -19, },
258 {-24, 27, 454, 1182, 1420, 858, 197, -19, },
259 {-24, 24, 443, 1172, 1424, 870, 204, -18, },
260 {-24, 22, 433, 1162, 1427, 882, 211, -17, },
261 {-24, 19, 423, 1152, 1430, 894, 219, -17, },
262 {-24, 17, 413, 1142, 1432, 906, 226, -16, },
263 {-24, 14, 403, 1131, 1434, 918, 234, -15, },
264 {-24, 12, 393, 1121, 1437, 930, 242, -14, },
265 {-24, 10, 383, 1110, 1438, 942, 250, -13, },
266 {-24, 8, 373, 1100, 1440, 953, 258, -12, },
267 {-24, 6, 364, 1089, 1441, 965, 266, -11, },
268 {-24, 4, 354, 1078, 1443, 977, 274, -10, },
269 {-24, 2, 345, 1067, 1444, 988, 282, -9, },
270 {-24, 0, 336, 1056, 1444, 1000, 291, -7, },
271 {-24, -1, 326, 1045, 1445, 1011, 300, -6, },
272 {-24, -3, 317, 1034, 1445, 1023, 309, -5, },
276 xhsc_coeff_taps10[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_10] = {
277 {59, 224, 507, 790, 911, 793, 512, 227, 61, 13, },
278 {58, 220, 502, 786, 911, 797, 516, 231, 62, 13, },
279 {56, 216, 497, 783, 911, 800, 521, 235, 64, 13, },
280 {55, 213, 492, 779, 910, 804, 526, 238, 65, 13, },
281 {54, 209, 487, 775, 910, 807, 531, 242, 67, 14, },
282 {52, 206, 482, 772, 910, 810, 536, 246, 69, 14, },
283 {51, 202, 477, 768, 909, 813, 541, 250, 70, 14, },
284 {50, 199, 473, 764, 909, 817, 545, 254, 72, 14, },
285 {48, 195, 468, 760, 908, 820, 550, 258, 74, 15, },
286 {47, 192, 463, 756, 908, 823, 555, 262, 76, 15, },
287 {46, 188, 458, 752, 907, 826, 560, 266, 78, 15, },
288 {45, 185, 453, 748, 906, 829, 565, 270, 79, 16, },
289 {44, 182, 448, 744, 906, 832, 569, 274, 81, 16, },
290 {42, 179, 444, 740, 905, 835, 574, 278, 83, 16, },
291 {41, 175, 439, 736, 904, 837, 579, 282, 85, 17, },
292 {40, 172, 434, 732, 903, 840, 584, 286, 87, 17, },
293 {39, 169, 429, 728, 902, 843, 589, 290, 89, 18, },
294 {38, 166, 425, 724, 901, 846, 593, 294, 91, 18, },
295 {37, 163, 420, 720, 900, 848, 598, 298, 93, 18, },
296 {36, 160, 415, 716, 899, 851, 603, 302, 95, 19, },
297 {35, 157, 410, 711, 897, 854, 608, 307, 98, 19, },
298 {34, 154, 406, 707, 896, 856, 612, 311, 100, 20, },
299 {33, 151, 401, 703, 895, 859, 617, 315, 102, 20, },
300 {33, 148, 396, 698, 893, 861, 622, 320, 104, 21, },
301 {32, 145, 392, 694, 892, 863, 626, 324, 107, 21, },
302 {31, 142, 387, 690, 890, 866, 631, 328, 109, 22, },
303 {30, 140, 382, 685, 889, 868, 636, 333, 111, 23, },
304 {29, 137, 378, 681, 887, 870, 640, 337, 114, 23, },
305 {28, 134, 373, 677, 886, 872, 645, 342, 116, 24, },
306 {28, 131, 369, 672, 884, 874, 649, 346, 119, 24, },
307 {27, 129, 364, 668, 882, 876, 654, 350, 121, 25, },
308 {26, 126, 359, 663, 880, 878, 659, 355, 124, 26, },
309 {26, 124, 355, 659, 878, 880, 663, 359, 126, 26, },
310 {25, 121, 350, 654, 876, 882, 668, 364, 129, 27, },
311 {24, 119, 346, 649, 874, 884, 672, 369, 131, 28, },
312 {24, 116, 342, 645, 872, 886, 677, 373, 134, 28, },
313 {23, 114, 337, 640, 870, 887, 681, 378, 137, 29, },
314 {23, 111, 333, 636, 868, 889, 685, 382, 140, 30, },
315 {22, 109, 328, 631, 866, 890, 690, 387, 142, 31, },
316 {21, 107, 324, 626, 863, 892, 694, 392, 145, 32, },
317 {21, 104, 320, 622, 861, 893, 698, 396, 148, 33, },
318 {20, 102, 315, 617, 859, 895, 703, 401, 151, 33, },
319 {20, 100, 311, 612, 856, 896, 707, 406, 154, 34, },
320 {19, 98, 307, 608, 854, 897, 711, 410, 157, 35, },
321 {19, 95, 302, 603, 851, 899, 716, 415, 160, 36, },
322 {18, 93, 298, 598, 848, 900, 720, 420, 163, 37, },
323 {18, 91, 294, 593, 846, 901, 724, 425, 166, 38, },
324 {18, 89, 290, 589, 843, 902, 728, 429, 169, 39, },
325 {17, 87, 286, 584, 840, 903, 732, 434, 172, 40, },
326 {17, 85, 282, 579, 837, 904, 736, 439, 175, 41, },
327 {16, 83, 278, 574, 835, 905, 740, 444, 179, 42, },
328 {16, 81, 274, 569, 832, 906, 744, 448, 182, 44, },
329 {16, 79, 270, 565, 829, 906, 748, 453, 185, 45, },
330 {15, 78, 266, 560, 826, 907, 752, 458, 188, 46, },
331 {15, 76, 262, 555, 823, 908, 756, 463, 192, 47, },
332 {15, 74, 258, 550, 820, 908, 760, 468, 195, 48, },
333 {14, 72, 254, 545, 817, 909, 764, 473, 199, 50, },
334 {14, 70, 250, 541, 813, 909, 768, 477, 202, 51, },
335 {14, 69, 246, 536, 810, 910, 772, 482, 206, 52, },
336 {14, 67, 242, 531, 807, 910, 775, 487, 209, 54, },
337 {13, 65, 238, 526, 804, 910, 779, 492, 213, 55, },
338 {13, 64, 235, 521, 800, 911, 783, 497, 216, 56, },
339 {13, 62, 231, 516, 797, 911, 786, 502, 220, 58, },
340 {13, 61, 227, 512, 793, 911, 790, 507, 224, 59, },
344 xhsc_coeff_taps12[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_12] = {
345 {48, 143, 307, 504, 667, 730, 669, 507, 310, 145, 49, 18, },
346 {47, 141, 304, 501, 665, 730, 670, 510, 313, 147, 50, 18, },
347 {46, 138, 301, 498, 663, 730, 672, 513, 316, 149, 51, 18, },
348 {45, 136, 298, 495, 661, 730, 674, 516, 319, 151, 52, 18, },
349 {44, 134, 295, 492, 659, 730, 676, 519, 322, 153, 53, 18, },
350 {44, 132, 292, 489, 657, 730, 677, 522, 325, 155, 54, 18, },
351 {43, 130, 289, 486, 655, 729, 679, 525, 328, 157, 55, 19, },
352 {42, 129, 287, 483, 653, 729, 681, 528, 331, 160, 56, 19, },
353 {41, 127, 284, 480, 651, 729, 683, 531, 334, 162, 57, 19, },
354 {40, 125, 281, 477, 648, 729, 684, 534, 337, 164, 58, 19, },
355 {40, 123, 278, 474, 646, 728, 686, 537, 340, 166, 59, 20, },
356 {39, 121, 275, 471, 644, 728, 687, 539, 343, 169, 60, 20, },
357 {38, 119, 272, 468, 642, 727, 689, 542, 346, 171, 61, 20, },
358 {37, 117, 269, 465, 640, 727, 690, 545, 349, 173, 62, 20, },
359 {37, 115, 266, 461, 638, 727, 692, 548, 353, 175, 63, 21, },
360 {36, 114, 264, 458, 635, 726, 693, 551, 356, 178, 65, 21, },
361 {35, 112, 261, 455, 633, 726, 695, 554, 359, 180, 66, 21, },
362 {35, 110, 258, 452, 631, 725, 696, 556, 362, 183, 67, 21, },
363 {34, 108, 255, 449, 628, 724, 698, 559, 365, 185, 68, 22, },
364 {33, 107, 252, 446, 626, 724, 699, 562, 368, 187, 69, 22, },
365 {33, 105, 250, 443, 624, 723, 700, 565, 371, 190, 71, 22, },
366 {32, 103, 247, 440, 621, 723, 702, 567, 374, 192, 72, 23, },
367 {32, 101, 244, 437, 619, 722, 703, 570, 377, 195, 73, 23, },
368 {31, 100, 241, 433, 617, 721, 704, 573, 380, 197, 75, 23, },
369 {31, 98, 239, 430, 614, 720, 705, 576, 383, 200, 76, 24, },
370 {30, 97, 236, 427, 612, 720, 707, 578, 387, 202, 77, 24, },
371 {29, 95, 233, 424, 609, 719, 708, 581, 390, 205, 79, 24, },
372 {29, 93, 231, 421, 607, 718, 709, 584, 393, 207, 80, 25, },
373 {28, 92, 228, 418, 604, 717, 710, 586, 396, 210, 81, 25, },
374 {28, 90, 225, 415, 602, 716, 711, 589, 399, 212, 83, 26, },
375 {27, 89, 223, 412, 599, 715, 712, 591, 402, 215, 84, 26, },
376 {27, 87, 220, 408, 597, 714, 713, 594, 405, 217, 86, 27, },
377 {27, 86, 217, 405, 594, 713, 714, 597, 408, 220, 87, 27, },
378 {26, 84, 215, 402, 591, 712, 715, 599, 412, 223, 89, 27, },
379 {26, 83, 212, 399, 589, 711, 716, 602, 415, 225, 90, 28, },
380 {25, 81, 210, 396, 586, 710, 717, 604, 418, 228, 92, 28, },
381 {25, 80, 207, 393, 584, 709, 718, 607, 421, 231, 93, 29, },
382 {24, 79, 205, 390, 581, 708, 719, 609, 424, 233, 95, 29, },
383 {24, 77, 202, 387, 578, 707, 720, 612, 427, 236, 97, 30, },
384 {24, 76, 200, 383, 576, 705, 720, 614, 430, 239, 98, 31, },
385 {23, 75, 197, 380, 573, 704, 721, 617, 433, 241, 100, 31, },
386 {23, 73, 195, 377, 570, 703, 722, 619, 437, 244, 101, 32, },
387 {23, 72, 192, 374, 567, 702, 723, 621, 440, 247, 103, 32, },
388 {22, 71, 190, 371, 565, 700, 723, 624, 443, 250, 105, 33, },
389 {22, 69, 187, 368, 562, 699, 724, 626, 446, 252, 107, 33, },
390 {22, 68, 185, 365, 559, 698, 724, 628, 449, 255, 108, 34, },
391 {21, 67, 183, 362, 556, 696, 725, 631, 452, 258, 110, 35, },
392 {21, 66, 180, 359, 554, 695, 726, 633, 455, 261, 112, 35, },
393 {21, 65, 178, 356, 551, 693, 726, 635, 458, 264, 114, 36, },
394 {21, 63, 175, 353, 548, 692, 727, 638, 461, 266, 115, 37, },
395 {20, 62, 173, 349, 545, 690, 727, 640, 465, 269, 117, 37, },
396 {20, 61, 171, 346, 542, 689, 727, 642, 468, 272, 119, 38, },
397 {20, 60, 169, 343, 539, 687, 728, 644, 471, 275, 121, 39, },
398 {20, 59, 166, 340, 537, 686, 728, 646, 474, 278, 123, 40, },
399 {19, 58, 164, 337, 534, 684, 729, 648, 477, 281, 125, 40, },
400 {19, 57, 162, 334, 531, 683, 729, 651, 480, 284, 127, 41, },
401 {19, 56, 160, 331, 528, 681, 729, 653, 483, 287, 129, 42, },
402 {19, 55, 157, 328, 525, 679, 729, 655, 486, 289, 130, 43, },
403 {18, 54, 155, 325, 522, 677, 730, 657, 489, 292, 132, 44, },
404 {18, 53, 153, 322, 519, 676, 730, 659, 492, 295, 134, 44, },
405 {18, 52, 151, 319, 516, 674, 730, 661, 495, 298, 136, 45, },
406 {18, 51, 149, 316, 513, 672, 730, 663, 498, 301, 138, 46, },
407 {18, 50, 147, 313, 510, 670, 730, 665, 501, 304, 141, 47, },
408 {18, 49, 145, 310, 507, 669, 730, 667, 504, 307, 143, 48, },
411 /* V-scaler coefficients for 6, 8, 10 and 12 tap filters */
413 xvsc_coeff_taps6[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_6] = {
414 {-132, 236, 3824, 236, -132, 64, },
415 {-116, 184, 3816, 292, -144, 64, },
416 {-100, 132, 3812, 348, -160, 64, },
417 {-88, 84, 3808, 404, -176, 64, },
418 {-72, 36, 3796, 464, -192, 64, },
419 {-60, -8, 3780, 524, -208, 68, },
420 {-48, -52, 3768, 588, -228, 68, },
421 {-32, -96, 3748, 652, -244, 68, },
422 {-20, -136, 3724, 716, -260, 72, },
423 {-8, -172, 3696, 784, -276, 72, },
424 {0, -208, 3676, 848, -292, 72, },
425 {12, -244, 3640, 920, -308, 76, },
426 {20, -276, 3612, 988, -324, 76, },
427 {32, -304, 3568, 1060, -340, 80, },
428 {40, -332, 3532, 1132, -356, 80, },
429 {48, -360, 3492, 1204, -372, 84, },
430 {56, -384, 3448, 1276, -388, 88, },
431 {64, -408, 3404, 1352, -404, 88, },
432 {72, -428, 3348, 1428, -416, 92, },
433 {76, -448, 3308, 1500, -432, 92, },
434 {84, -464, 3248, 1576, -444, 96, },
435 {88, -480, 3200, 1652, -460, 96, },
436 {92, -492, 3140, 1728, -472, 100, },
437 {96, -504, 3080, 1804, -484, 104, },
438 {100, -516, 3020, 1880, -492, 104, },
439 {104, -524, 2956, 1960, -504, 104, },
440 {104, -532, 2892, 2036, -512, 108, },
441 {108, -540, 2832, 2108, -520, 108, },
442 {108, -544, 2764, 2184, -528, 112, },
443 {112, -544, 2688, 2260, -532, 112, },
444 {112, -548, 2624, 2336, -540, 112, },
445 {112, -548, 2556, 2408, -544, 112, },
446 {112, -544, 2480, 2480, -544, 112, },
447 {112, -544, 2408, 2556, -548, 112, },
448 {112, -540, 2336, 2624, -548, 112, },
449 {112, -532, 2260, 2688, -544, 112, },
450 {112, -528, 2184, 2764, -544, 108, },
451 {108, -520, 2108, 2832, -540, 108, },
452 {108, -512, 2036, 2892, -532, 104, },
453 {104, -504, 1960, 2956, -524, 104, },
454 {104, -492, 1880, 3020, -516, 100, },
455 {104, -484, 1804, 3080, -504, 96, },
456 {100, -472, 1728, 3140, -492, 92, },
457 { 96, -460, 1652, 3200, -480, 88, },
458 { 96, -444, 1576, 3248, -464, 84, },
459 { 92, -432, 1500, 3308, -448, 76, },
460 { 92, -416, 1428, 3348, -428, 72, },
461 { 88, -404, 1352, 3404, -408, 64, },
462 { 88, -388, 1276, 3448, -384, 56, },
463 { 84, -372, 1204, 3492, -360, 48, },
464 { 80, -356, 1132, 3532, -332, 40, },
465 { 80, -340, 1060, 3568, -304, 32, },
466 { 76, -324, 988, 3612, -276, 20, },
467 { 76, -308, 920, 3640, -244, 12, },
468 { 72, -292, 848, 3676, -208, 0, },
469 { 72, -276, 784, 3696, -172, -8, },
470 { 72, -260, 716, 3724, -136, -20, },
471 { 68, -244, 652, 3748, -96, -32, },
472 { 68, -228, 588, 3768, -52, -48, },
473 { 68, -208, 524, 3780, -8, -60, },
474 { 64, -192, 464, 3796, 36, -72, },
475 { 64, -176, 404, 3808, 84, -88, },
476 { 64, -160, 348, 3812, 132, -100, },
477 { 64, -144, 292, 3816, 184, -116, }
481 xvsc_coeff_taps8[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_8] = {
482 {-5, 309, 1023, 1445, 1034, 317, -3, -24, },
483 {-6, 300, 1011, 1445, 1045, 326, -1, -24, },
484 {-7, 291, 1000, 1444, 1056, 336, 0, -24, },
485 {-9, 282, 988, 1444, 1067, 345, 2, -24, },
486 {-10, 274, 977, 1443, 1078, 354, 4, -24, },
487 {-11, 266, 965, 1441, 1089, 364, 6, -24, },
488 {-12, 258, 953, 1440, 1100, 373, 8, -24, },
489 {-13, 250, 942, 1438, 1110, 383, 10, -24, },
490 {-14, 242, 930, 1437, 1121, 393, 12, -24, },
491 {-15, 234, 918, 1434, 1131, 403, 14, -24, },
492 {-16, 226, 906, 1432, 1142, 413, 17, -24, },
493 {-17, 219, 894, 1430, 1152, 423, 19, -24, },
494 {-17, 211, 882, 1427, 1162, 433, 22, -24, },
495 {-18, 204, 870, 1424, 1172, 443, 24, -24, },
496 {-19, 197, 858, 1420, 1182, 454, 27, -24, },
497 {-19, 190, 846, 1417, 1191, 464, 30, -24, },
498 {-20, 183, 834, 1413, 1201, 475, 33, -24, },
499 {-20, 176, 822, 1409, 1210, 486, 36, -24, },
500 {-21, 170, 810, 1405, 1220, 497, 39, -24, },
501 {-21, 163, 798, 1401, 1229, 507, 42, -24, },
502 {-22, 157, 786, 1396, 1238, 518, 46, -24, },
503 {-22, 151, 774, 1392, 1247, 529, 49, -24, },
504 {-22, 144, 762, 1387, 1255, 540, 53, -24, },
505 {-23, 139, 750, 1382, 1264, 552, 57, -24, },
506 {-23, 133, 738, 1376, 1272, 563, 60, -24, },
507 {-23, 127, 726, 1371, 1280, 574, 64, -24, },
508 {-23, 121, 714, 1365, 1288, 586, 69, -24, },
509 {-23, 116, 703, 1359, 1296, 597, 73, -24, },
510 {-24, 111, 691, 1353, 1304, 609, 77, -24, },
511 {-24, 105, 679, 1346, 1312, 620, 81, -24, },
512 {-24, 100, 667, 1340, 1319, 632, 86, -24, },
513 {-24, 96, 655, 1333, 1326, 644, 91, -24, },
514 {-24, 91, 644, 1326, 1333, 655, 96, -24, },
515 {-24, 86, 632, 1319, 1340, 667, 100, -24, },
516 {-24, 81, 620, 1312, 1346, 679, 105, -24, },
517 {-24, 77, 609, 1304, 1353, 691, 111, -24, },
518 {-24, 73, 597, 1296, 1359, 703, 116, -23, },
519 {-24, 69, 586, 1288, 1365, 714, 121, -23, },
520 {-24, 64, 574, 1280, 1371, 726, 127, -23, },
521 {-24, 60, 563, 1272, 1376, 738, 133, -23, },
522 {-24, 57, 552, 1264, 1382, 750, 139, -23, },
523 {-24, 53, 540, 1255, 1387, 762, 144, -22, },
524 {-24, 49, 529, 1247, 1392, 774, 151, -22, },
525 {-24, 46, 518, 1238, 1396, 786, 157, -22, },
526 {-24, 42, 507, 1229, 1401, 798, 163, -21, },
527 {-24, 39, 497, 1220, 1405, 810, 170, -21, },
528 {-24, 36, 486, 1210, 1409, 822, 176, -20, },
529 {-24, 33, 475, 1201, 1413, 834, 183, -20, },
530 {-24, 30, 464, 1191, 1417, 846, 190, -19, },
531 {-24, 27, 454, 1182, 1420, 858, 197, -19, },
532 {-24, 24, 443, 1172, 1424, 870, 204, -18, },
533 {-24, 22, 433, 1162, 1427, 882, 211, -17, },
534 {-24, 19, 423, 1152, 1430, 894, 219, -17, },
535 {-24, 17, 413, 1142, 1432, 906, 226, -16, },
536 {-24, 14, 403, 1131, 1434, 918, 234, -15, },
537 {-24, 12, 393, 1121, 1437, 930, 242, -14, },
538 {-24, 10, 383, 1110, 1438, 942, 250, -13, },
539 {-24, 8, 373, 1100, 1440, 953, 258, -12, },
540 {-24, 6, 364, 1089, 1441, 965, 266, -11, },
541 {-24, 4, 354, 1078, 1443, 977, 274, -10, },
542 {-24, 2, 345, 1067, 1444, 988, 282, -9, },
543 {-24, 0, 336, 1056, 1444, 1000, 291, -7, },
544 {-24, -1, 326, 1045, 1445, 1011, 300, -6, },
545 {-24, -3, 317, 1034, 1445, 1023, 309, -5, },
549 xvsc_coeff_taps10[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_10] = {
550 {59, 224, 507, 790, 911, 793, 512, 227, 61, 13, },
551 {58, 220, 502, 786, 911, 797, 516, 231, 62, 13, },
552 {56, 216, 497, 783, 911, 800, 521, 235, 64, 13, },
553 {55, 213, 492, 779, 910, 804, 526, 238, 65, 13, },
554 {54, 209, 487, 775, 910, 807, 531, 242, 67, 14, },
555 {52, 206, 482, 772, 910, 810, 536, 246, 69, 14, },
556 {51, 202, 477, 768, 909, 813, 541, 250, 70, 14, },
557 {50, 199, 473, 764, 909, 817, 545, 254, 72, 14, },
558 {48, 195, 468, 760, 908, 820, 550, 258, 74, 15, },
559 {47, 192, 463, 756, 908, 823, 555, 262, 76, 15, },
560 {46, 188, 458, 752, 907, 826, 560, 266, 78, 15, },
561 {45, 185, 453, 748, 906, 829, 565, 270, 79, 16, },
562 {44, 182, 448, 744, 906, 832, 569, 274, 81, 16, },
563 {42, 179, 444, 740, 905, 835, 574, 278, 83, 16, },
564 {41, 175, 439, 736, 904, 837, 579, 282, 85, 17, },
565 {40, 172, 434, 732, 903, 840, 584, 286, 87, 17, },
566 {39, 169, 429, 728, 902, 843, 589, 290, 89, 18, },
567 {38, 166, 425, 724, 901, 846, 593, 294, 91, 18, },
568 {37, 163, 420, 720, 900, 848, 598, 298, 93, 18, },
569 {36, 160, 415, 716, 899, 851, 603, 302, 95, 19, },
570 {35, 157, 410, 711, 897, 854, 608, 307, 98, 19, },
571 {34, 154, 406, 707, 896, 856, 612, 311, 100, 20, },
572 {33, 151, 401, 703, 895, 859, 617, 315, 102, 20, },
573 {33, 148, 396, 698, 893, 861, 622, 320, 104, 21, },
574 {32, 145, 392, 694, 892, 863, 626, 324, 107, 21, },
575 {31, 142, 387, 690, 890, 866, 631, 328, 109, 22, },
576 {30, 140, 382, 685, 889, 868, 636, 333, 111, 23, },
577 {29, 137, 378, 681, 887, 870, 640, 337, 114, 23, },
578 {28, 134, 373, 677, 886, 872, 645, 342, 116, 24, },
579 {28, 131, 369, 672, 884, 874, 649, 346, 119, 24, },
580 {27, 129, 364, 668, 882, 876, 654, 350, 121, 25, },
581 {26, 126, 359, 663, 880, 878, 659, 355, 124, 26, },
582 {26, 124, 355, 659, 878, 880, 663, 359, 126, 26, },
583 {25, 121, 350, 654, 876, 882, 668, 364, 129, 27, },
584 {24, 119, 346, 649, 874, 884, 672, 369, 131, 28, },
585 {24, 116, 342, 645, 872, 886, 677, 373, 134, 28, },
586 {23, 114, 337, 640, 870, 887, 681, 378, 137, 29, },
587 {23, 111, 333, 636, 868, 889, 685, 382, 140, 30, },
588 {22, 109, 328, 631, 866, 890, 690, 387, 142, 31, },
589 {21, 107, 324, 626, 863, 892, 694, 392, 145, 32, },
590 {21, 104, 320, 622, 861, 893, 698, 396, 148, 33, },
591 {20, 102, 315, 617, 859, 895, 703, 401, 151, 33, },
592 {20, 100, 311, 612, 856, 896, 707, 406, 154, 34, },
593 {19, 98, 307, 608, 854, 897, 711, 410, 157, 35, },
594 {19, 95, 302, 603, 851, 899, 716, 415, 160, 36, },
595 {18, 93, 298, 598, 848, 900, 720, 420, 163, 37, },
596 {18, 91, 294, 593, 846, 901, 724, 425, 166, 38, },
597 {18, 89, 290, 589, 843, 902, 728, 429, 169, 39, },
598 {17, 87, 286, 584, 840, 903, 732, 434, 172, 40, },
599 {17, 85, 282, 579, 837, 904, 736, 439, 175, 41, },
600 {16, 83, 278, 574, 835, 905, 740, 444, 179, 42, },
601 {16, 81, 274, 569, 832, 906, 744, 448, 182, 44, },
602 {16, 79, 270, 565, 829, 906, 748, 453, 185, 45, },
603 {15, 78, 266, 560, 826, 907, 752, 458, 188, 46, },
604 {15, 76, 262, 555, 823, 908, 756, 463, 192, 47, },
605 {15, 74, 258, 550, 820, 908, 760, 468, 195, 48, },
606 {14, 72, 254, 545, 817, 909, 764, 473, 199, 50, },
607 {14, 70, 250, 541, 813, 909, 768, 477, 202, 51, },
608 {14, 69, 246, 536, 810, 910, 772, 482, 206, 52, },
609 {14, 67, 242, 531, 807, 910, 775, 487, 209, 54, },
610 {13, 65, 238, 526, 804, 910, 779, 492, 213, 55, },
611 {13, 64, 235, 521, 800, 911, 783, 497, 216, 56, },
612 {13, 62, 231, 516, 797, 911, 786, 502, 220, 58, },
613 {13, 61, 227, 512, 793, 911, 790, 507, 224, 59, },
617 xvsc_coeff_taps12[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_12] = {
618 {48, 143, 307, 504, 667, 730, 669, 507, 310, 145, 49, 18, },
619 {47, 141, 304, 501, 665, 730, 670, 510, 313, 147, 50, 18, },
620 {46, 138, 301, 498, 663, 730, 672, 513, 316, 149, 51, 18, },
621 {45, 136, 298, 495, 661, 730, 674, 516, 319, 151, 52, 18, },
622 {44, 134, 295, 492, 659, 730, 676, 519, 322, 153, 53, 18, },
623 {44, 132, 292, 489, 657, 730, 677, 522, 325, 155, 54, 18, },
624 {43, 130, 289, 486, 655, 729, 679, 525, 328, 157, 55, 19, },
625 {42, 129, 287, 483, 653, 729, 681, 528, 331, 160, 56, 19, },
626 {41, 127, 284, 480, 651, 729, 683, 531, 334, 162, 57, 19, },
627 {40, 125, 281, 477, 648, 729, 684, 534, 337, 164, 58, 19, },
628 {40, 123, 278, 474, 646, 728, 686, 537, 340, 166, 59, 20, },
629 {39, 121, 275, 471, 644, 728, 687, 539, 343, 169, 60, 20, },
630 {38, 119, 272, 468, 642, 727, 689, 542, 346, 171, 61, 20, },
631 {37, 117, 269, 465, 640, 727, 690, 545, 349, 173, 62, 20, },
632 {37, 115, 266, 461, 638, 727, 692, 548, 353, 175, 63, 21, },
633 {36, 114, 264, 458, 635, 726, 693, 551, 356, 178, 65, 21, },
634 {35, 112, 261, 455, 633, 726, 695, 554, 359, 180, 66, 21, },
635 {35, 110, 258, 452, 631, 725, 696, 556, 362, 183, 67, 21, },
636 {34, 108, 255, 449, 628, 724, 698, 559, 365, 185, 68, 22, },
637 {33, 107, 252, 446, 626, 724, 699, 562, 368, 187, 69, 22, },
638 {33, 105, 250, 443, 624, 723, 700, 565, 371, 190, 71, 22, },
639 {32, 103, 247, 440, 621, 723, 702, 567, 374, 192, 72, 23, },
640 {32, 101, 244, 437, 619, 722, 703, 570, 377, 195, 73, 23, },
641 {31, 100, 241, 433, 617, 721, 704, 573, 380, 197, 75, 23, },
642 {31, 98, 239, 430, 614, 720, 705, 576, 383, 200, 76, 24, },
643 {30, 97, 236, 427, 612, 720, 707, 578, 387, 202, 77, 24, },
644 {29, 95, 233, 424, 609, 719, 708, 581, 390, 205, 79, 24, },
645 {29, 93, 231, 421, 607, 718, 709, 584, 393, 207, 80, 25, },
646 {28, 92, 228, 418, 604, 717, 710, 586, 396, 210, 81, 25, },
647 {28, 90, 225, 415, 602, 716, 711, 589, 399, 212, 83, 26, },
648 {27, 89, 223, 412, 599, 715, 712, 591, 402, 215, 84, 26, },
649 {27, 87, 220, 408, 597, 714, 713, 594, 405, 217, 86, 27, },
650 {27, 86, 217, 405, 594, 713, 714, 597, 408, 220, 87, 27, },
651 {26, 84, 215, 402, 591, 712, 715, 599, 412, 223, 89, 27, },
652 {26, 83, 212, 399, 589, 711, 716, 602, 415, 225, 90, 28, },
653 {25, 81, 210, 396, 586, 710, 717, 604, 418, 228, 92, 28, },
654 {25, 80, 207, 393, 584, 709, 718, 607, 421, 231, 93, 29, },
655 {24, 79, 205, 390, 581, 708, 719, 609, 424, 233, 95, 29, },
656 {24, 77, 202, 387, 578, 707, 720, 612, 427, 236, 97, 30, },
657 {24, 76, 200, 383, 576, 705, 720, 614, 430, 239, 98, 31, },
658 {23, 75, 197, 380, 573, 704, 721, 617, 433, 241, 100, 31, },
659 {23, 73, 195, 377, 570, 703, 722, 619, 437, 244, 101, 32, },
660 {23, 72, 192, 374, 567, 702, 723, 621, 440, 247, 103, 32, },
661 {22, 71, 190, 371, 565, 700, 723, 624, 443, 250, 105, 33, },
662 {22, 69, 187, 368, 562, 699, 724, 626, 446, 252, 107, 33, },
663 {22, 68, 185, 365, 559, 698, 724, 628, 449, 255, 108, 34, },
664 {21, 67, 183, 362, 556, 696, 725, 631, 452, 258, 110, 35, },
665 {21, 66, 180, 359, 554, 695, 726, 633, 455, 261, 112, 35, },
666 {21, 65, 178, 356, 551, 693, 726, 635, 458, 264, 114, 36, },
667 {21, 63, 175, 353, 548, 692, 727, 638, 461, 266, 115, 37, },
668 {20, 62, 173, 349, 545, 690, 727, 640, 465, 269, 117, 37, },
669 {20, 61, 171, 346, 542, 689, 727, 642, 468, 272, 119, 38, },
670 {20, 60, 169, 343, 539, 687, 728, 644, 471, 275, 121, 39, },
671 {20, 59, 166, 340, 537, 686, 728, 646, 474, 278, 123, 40, },
672 {19, 58, 164, 337, 534, 684, 729, 648, 477, 281, 125, 40, },
673 {19, 57, 162, 334, 531, 683, 729, 651, 480, 284, 127, 41, },
674 {19, 56, 160, 331, 528, 681, 729, 653, 483, 287, 129, 42, },
675 {19, 55, 157, 328, 525, 679, 729, 655, 486, 289, 130, 43, },
676 {18, 54, 155, 325, 522, 677, 730, 657, 489, 292, 132, 44, },
677 {18, 53, 153, 322, 519, 676, 730, 659, 492, 295, 134, 44, },
678 {18, 52, 151, 319, 516, 674, 730, 661, 495, 298, 136, 45, },
679 {18, 51, 149, 316, 513, 672, 730, 663, 498, 301, 138, 46, },
680 {18, 50, 147, 313, 510, 670, 730, 665, 501, 304, 141, 47, },
681 {18, 49, 145, 310, 507, 669, 730, 667, 504, 307, 143, 48, },
684 enum xilinx_scaler_vid_reg_fmts {
691 static const u32 xilinx_scaler_video_fmts[] = {
692 MEDIA_BUS_FMT_RGB888_1X24,
693 MEDIA_BUS_FMT_VUY8_1X24,
694 MEDIA_BUS_FMT_UYVY8_1X16,
695 MEDIA_BUS_FMT_VYYUYY8_1X24,
699 * struct xilinx_scaler - Core configuration of scaler device structure
700 * @base: pointer to register base address
701 * @dev: device structure
702 * @bridge: xilinx bridge
703 * @width_in: input width
704 * @height_in: input height
705 * @width_out: output width
706 * @height_out: output height
707 * @fmt_in: input format
708 * @fmt_out: output format
709 * @num_hori_taps: number of horizontal taps
710 * @num_vert_taps: number of vertical taps
711 * @max_num_phases: maximum number of phases
712 * @pix_per_clk: Pixels per Clock cycle the IP operates upon
713 * @max_pixels: The maximum number of pixels that the H-scaler examines
714 * @max_lines: The maximum number of lines that the V-scaler examines
715 * @H_phases: The phases needed to program the H-scaler for different taps
716 * @hscaler_coeff: The complete array of H-scaler coefficients
717 * @vscaler_coeff: The complete array of V-scaler coefficients
718 * @is_polyphase: Track if scaling algorithm is polyphase or not
719 * @rst_gpio: GPIO reset line to bring VPSS Scaler out of reset
721 struct xilinx_scaler {
724 struct xlnx_bridge bridge;
737 u32 H_phases[XV_HSCALER_MAX_LINE_WIDTH];
738 short hscaler_coeff[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS];
739 short vscaler_coeff[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_MAX_V_TAPS];
741 struct gpio_desc *rst_gpio;
744 static inline void xilinx_scaler_write(void __iomem *base, u32 offset, u32 val)
746 writel(val, base + offset);
749 static inline u32 xilinx_scaler_read(void __iomem *base, u32 offset)
751 return readl(base + offset);
754 static inline void xilinx_scaler_clr(void __iomem *base, u32 offset, u32 clr)
756 xilinx_scaler_write(base, offset,
757 xilinx_scaler_read(base, offset) & ~clr);
760 static inline void xilinx_scaler_set(void __iomem *base, u32 offset, u32 set)
762 xilinx_scaler_write(base, offset,
763 xilinx_scaler_read(base, offset) | set);
767 xilinx_scaler_disable_block(struct xilinx_scaler *scaler, u32 channel,
770 xilinx_scaler_clr(scaler->base, ((channel - 1) * XGPIO_CHAN_OFFSET) +
771 XGPIO_DATA_OFFSET + S_AXIS_RESET_OFF, ip_block);
775 xilinx_scaler_enable_block(struct xilinx_scaler *scaler, u32 channel,
778 xilinx_scaler_set(scaler->base, ((channel - 1) * XGPIO_CHAN_OFFSET) +
779 XGPIO_DATA_OFFSET + S_AXIS_RESET_OFF, ip_block);
783 * bridge_to_layer - Gets the parent structure
784 * @bridge: pointer to the member.
786 * Return: parent structure pointer
788 static inline struct xilinx_scaler *bridge_to_layer(struct xlnx_bridge *bridge)
790 return container_of(bridge, struct xilinx_scaler, bridge);
794 * xilinx_scaler_reset - Resets scaler block
795 * @scaler: Pointer to scaler device structure
797 * This function resets scaler block
799 static void xilinx_scaler_reset(struct xilinx_scaler *scaler)
801 xilinx_scaler_disable_block(scaler, XGPIO_CH_RESET_SEL,
802 XGPIO_RESET_MASK_ALL_BLOCKS);
803 xilinx_scaler_enable_block(scaler, XGPIO_CH_RESET_SEL,
804 XGPIO_RESET_MASK_IP_AXIS);
808 * xv_hscaler_calculate_phases - Calculates h-scaler phases
809 * @scaler: Pointer to scaler registers base
810 * @width_in: input width
811 * @width_out: output width
812 * @pixel_rate: pixel rate
815 xv_hscaler_calculate_phases(struct xilinx_scaler *scaler,
816 u32 width_in, u32 width_out, u32 pixel_rate)
818 unsigned int loop_width;
822 bool output_write_en;
828 unsigned int nphases = scaler->max_num_phases;
829 unsigned int nppc = scaler->pix_per_clk;
830 unsigned int shift = XHSC_STEP_PRECISION_SHIFT - ilog2(nphases);
832 loop_width = max_t(u32, width_in, width_out);
833 loop_width = ALIGN(loop_width + nppc - 1, nppc);
835 for (x = 0; x < loop_width; x++) {
837 for (s = 0; s < nppc; s++) {
838 phaseH = (offset >> shift) & (nphases - 1);
840 output_write_en = false;
841 if ((offset >> XHSC_STEP_PRECISION_SHIFT) != 0) {
843 offset -= (1 << XHSC_STEP_PRECISION_SHIFT);
847 if (((offset >> XHSC_STEP_PRECISION_SHIFT) == 0) &&
848 xwrite_pos < width_out) {
849 offset += pixel_rate;
850 output_write_en = true;
854 scaler->H_phases[x] |= (phaseH <<
855 (s * XHSC_HPHASE_MULTIPLIER));
856 scaler->H_phases[x] |= (array_idx <<
857 (XHSC_HPHASE_SHIFT_BY_6 +
858 (s * XHSC_HPHASE_MULTIPLIER)));
859 if (output_write_en) {
860 scaler->H_phases[x] |=
861 (XV_HSCALER_PHASESH_V_OUTPUT_WR_EN <<
862 (s * XHSC_HPHASE_MULTIPLIER));
868 if (array_idx >= nppc)
869 array_idx &= (nppc - 1);
871 nr_rds += nr_rds_clck;
878 * xv_hscaler_load_ext_coeff - Loads external coefficients of h-scaler
879 * @scaler: Pointer to scaler registers base
880 * @coeff: Pointer to coeff array
881 * @ntaps: number of taps
883 * This function loads h-scaler coefficients.
886 xv_hscaler_load_ext_coeff(struct xilinx_scaler *scaler,
887 const short *coeff, u32 ntaps)
889 unsigned int i, j, pad, offset;
890 u32 nphases = scaler->max_num_phases;
892 /* Determine if coefficient needs padding (effective vs. max taps) */
893 pad = XV_HSCALER_MAX_H_TAPS - ntaps;
895 /* Load coefficients into scaler coefficient table */
896 for (i = 0; i < nphases; i++) {
897 for (j = 0; j < ntaps; ++j)
898 scaler->hscaler_coeff[i][j + offset] =
899 coeff[i * ntaps + j];
903 for (i = 0; i < nphases; i++) {
904 for (j = 0; j < offset; j++)
905 scaler->hscaler_coeff[i][j] = 0;
907 for (; j < XV_HSCALER_MAX_H_TAPS; j++)
908 scaler->hscaler_coeff[i][j] = 0;
914 * xv_hscaler_coeff_select - Selection of H-Scaler coefficients of operation
915 * @scaler: Pointer to Scaler device structure
916 * @width_in: Width of input video
917 * @width_out: Width of desired output video
919 * There are instances when a N-tap filter might operate in an M-tap
920 * configuration where N > M.
923 * Depending on the ratio of scaling (while downscaling), a 12-tap
924 * filter may operate with 10 tap coefficients and zero-pads the remaining
927 * While upscaling the driver will program 6-tap filter coefficients
928 * in any N-tap configurations (for N >= 6).
930 * This selection is adopted by the as it gives optimal
931 * video output determined by repeated testing of the IP
933 * Return: Will return 0 if successful. Returns -EINVAL on an unsupported
934 * H-scaler number of taps.
937 xv_hscaler_select_coeff(struct xilinx_scaler *scaler,
938 u32 width_in, u32 width_out)
942 u32 ntaps = scaler->num_hori_taps;
945 * Scale Down Mode will use dynamic filter selection logic
946 * Scale Up Mode (including 1:1) will always use 6 tap filter
948 if (width_out < width_in) {
949 hscale_ratio = ((width_in * 10) / width_out);
951 switch (scaler->num_hori_taps) {
952 case XV_HSCALER_TAPS_6:
953 coeff = &xhsc_coeff_taps6[0][0];
954 ntaps = XV_HSCALER_TAPS_6;
956 case XV_HSCALER_TAPS_8:
957 if (hscale_ratio > 15) {
958 coeff = &xhsc_coeff_taps8[0][0];
959 ntaps = XV_HSCALER_TAPS_8;
961 coeff = &xhsc_coeff_taps6[0][0];
962 ntaps = XV_HSCALER_TAPS_6;
965 case XV_HSCALER_TAPS_10:
966 if (hscale_ratio > 25) {
967 coeff = &xhsc_coeff_taps10[0][0];
968 ntaps = XV_HSCALER_TAPS_10;
969 } else if (hscale_ratio > 15) {
970 coeff = &xhsc_coeff_taps8[0][0];
971 ntaps = XV_HSCALER_TAPS_8;
973 coeff = &xhsc_coeff_taps6[0][0];
974 ntaps = XV_HSCALER_TAPS_6;
977 case XV_HSCALER_TAPS_12:
978 if (hscale_ratio > 35) {
979 coeff = &xhsc_coeff_taps12[0][0];
980 ntaps = XV_HSCALER_TAPS_12;
981 } else if (hscale_ratio > 25) {
982 coeff = &xhsc_coeff_taps10[0][0];
983 ntaps = XV_HSCALER_TAPS_10;
984 } else if (hscale_ratio > 15) {
985 coeff = &xhsc_coeff_taps8[0][0];
986 ntaps = XV_HSCALER_TAPS_8;
988 coeff = &xhsc_coeff_taps6[0][0];
989 ntaps = XV_HSCALER_TAPS_6;
993 dev_info(scaler->dev, "Unsupported H-scaler number of taps\n");
997 coeff = &xhsc_coeff_taps6[0][0];
998 ntaps = XV_HSCALER_TAPS_6;
1000 xv_hscaler_load_ext_coeff(scaler, coeff, ntaps);
1005 * xv_hscaler_set_coeff - Sets h-scaler coefficients
1006 * @scaler: Pointer to scaler device structure
1008 * This function sets coefficients of h-scaler.
1010 static void xv_hscaler_set_coeff(struct xilinx_scaler *scaler)
1012 int val, i, j, offset, rd_indx;
1013 u32 ntaps = scaler->num_hori_taps;
1014 u32 nphases = scaler->max_num_phases;
1017 offset = (XV_HSCALER_MAX_H_TAPS - ntaps) / 2;
1018 base_addr = V_HSCALER_OFF + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE;
1019 for (i = 0; i < nphases; i++) {
1020 for (j = 0; j < ntaps / 2; j++) {
1021 rd_indx = j * 2 + offset;
1022 val = (scaler->hscaler_coeff[i][rd_indx + 1] <<
1023 XSCALER_BITSHIFT_16) |
1024 (scaler->hscaler_coeff[i][rd_indx] &
1025 XHSC_MASK_LOW_16BITS);
1026 xilinx_scaler_write(scaler->base, base_addr +
1027 ((i * ntaps / 2 + j) * 4), val);
1033 * xv_vscaler_load_ext_coeff - Loads external coefficients of v-scaler
1034 * @scaler: Pointer to scaler device structure
1035 * @coeff: Pointer to coeff array
1036 * @ntaps: number of taps
1038 * This function loads v-scaler coefficients.
1041 xv_vscaler_load_ext_coeff(struct xilinx_scaler *scaler,
1042 const short *coeff, u32 ntaps)
1044 int i, j, pad, offset;
1045 u32 nphases = scaler->max_num_phases;
1047 /* Determine if coefficient needs padding (effective vs. max taps) */
1048 pad = XV_VSCALER_MAX_V_TAPS - ntaps;
1049 offset = pad ? (pad >> 1) : 0;
1050 /* Load User defined coefficients into scaler coefficient table */
1051 for (i = 0; i < nphases; i++) {
1052 for (j = 0; j < ntaps; ++j)
1053 scaler->vscaler_coeff[i][j + offset] =
1054 coeff[i * ntaps + j];
1057 /* effective taps < max_taps */
1058 for (i = 0; i < nphases; i++) {
1060 for (j = 0; j < offset; j++)
1061 scaler->vscaler_coeff[i][j] = 0;
1064 for (j = (ntaps + offset); j < XV_VSCALER_MAX_V_TAPS; j++)
1065 scaler->vscaler_coeff[i][j] = 0;
1070 * xv_vscaler_set_coeff - Sets v-scaler coefficients
1071 * @scaler: Pointer to scaler device structure
1073 * This function sets coefficients of v-scaler.
1075 static void xv_vscaler_set_coeff(struct xilinx_scaler *scaler)
1077 u32 nphases = scaler->max_num_phases;
1078 u32 ntaps = scaler->num_vert_taps;
1079 int val, i, j, offset, rd_indx;
1082 offset = (XV_VSCALER_MAX_V_TAPS - ntaps) / 2;
1083 base_addr = V_VSCALER_OFF + XV_VSCALER_CTRL_ADDR_HWREG_VFLTCOEFF_BASE;
1085 for (i = 0; i < nphases; i++) {
1086 for (j = 0; j < ntaps / 2; j++) {
1087 rd_indx = j * 2 + offset;
1088 val = (scaler->vscaler_coeff[i][rd_indx + 1] <<
1089 XSCALER_BITSHIFT_16) |
1090 (scaler->vscaler_coeff[i][rd_indx] &
1091 XVSC_MASK_LOW_16BITS);
1092 xilinx_scaler_write(scaler->base, base_addr +
1093 ((i * ntaps / 2 + j) * 4), val);
1099 * xv_vscaler_coeff_select - Selection of V-Scaler coefficients of operation
1100 * @scaler: Pointer to Scaler device structure
1101 * @height_in: Height of input video
1102 * @height_out: Height of desired output video
1104 * There are instances when a N-tap filter might operate in an M-tap
1105 * configuration where N > M.
1108 * Depending on the ratio of scaling (while downscaling), a 10-tap
1109 * filter may operate with 6 tap coefficients and zero-pads the remaining
1112 * While upscaling the driver will program 6-tap filter coefficients
1113 * in any N-tap configurations (for N >= 6).
1115 * This selection is adopted by the as it gives optimal
1116 * video output determined by repeated testing of the IP
1118 * Return: Will return 0 if successful. Returns -EINVAL on an unsupported
1119 * V-scaler number of taps.
1122 xv_vscaler_select_coeff(struct xilinx_scaler *scaler,
1123 u32 height_in, u32 height_out)
1127 u32 ntaps = scaler->num_vert_taps;
1130 * Scale Down Mode will use dynamic filter selection logic
1131 * Scale Up Mode (including 1:1) will always use 6 tap filter
1134 if (height_out < height_in) {
1135 vscale_ratio = ((height_in * 10) / height_out);
1137 switch (scaler->num_vert_taps) {
1138 case XV_VSCALER_TAPS_6:
1139 coeff = &xvsc_coeff_taps6[0][0];
1140 ntaps = XV_VSCALER_TAPS_6;
1142 case XV_VSCALER_TAPS_8:
1143 if (vscale_ratio > 15) {
1144 coeff = &xvsc_coeff_taps8[0][0];
1145 ntaps = XV_VSCALER_TAPS_8;
1147 coeff = &xvsc_coeff_taps6[0][0];
1148 ntaps = XV_VSCALER_TAPS_6;
1151 case XV_VSCALER_TAPS_10:
1152 if (vscale_ratio > 25) {
1153 coeff = &xvsc_coeff_taps10[0][0];
1154 ntaps = XV_VSCALER_TAPS_10;
1155 } else if (vscale_ratio > 15) {
1156 coeff = &xvsc_coeff_taps8[0][0];
1157 ntaps = XV_VSCALER_TAPS_8;
1159 coeff = &xvsc_coeff_taps6[0][0];
1160 ntaps = XV_VSCALER_TAPS_6;
1163 case XV_VSCALER_TAPS_12:
1164 if (vscale_ratio > 35) {
1165 coeff = &xvsc_coeff_taps12[0][0];
1166 ntaps = XV_VSCALER_TAPS_12;
1167 } else if (vscale_ratio > 25) {
1168 coeff = &xvsc_coeff_taps10[0][0];
1169 ntaps = XV_VSCALER_TAPS_10;
1170 } else if (vscale_ratio > 15) {
1171 coeff = &xvsc_coeff_taps8[0][0];
1172 ntaps = XV_VSCALER_TAPS_8;
1174 coeff = &xvsc_coeff_taps6[0][0];
1175 ntaps = XV_VSCALER_TAPS_6;
1182 coeff = &xvsc_coeff_taps6[0][0];
1183 ntaps = XV_VSCALER_TAPS_6;
1186 xv_vscaler_load_ext_coeff(scaler, coeff, ntaps);
1191 * xv_hscaler_set_phases - Sets phases of h-scaler
1192 * @scaler: Pointer to scaler device structure
1194 * This function sets phases of h-scaler.
1197 xv_hscaler_set_phases(struct xilinx_scaler *scaler)
1201 u32 offset, i, lsb, msb;
1203 loop_width = scaler->max_pixels / scaler->pix_per_clk;
1204 offset = V_HSCALER_OFF + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE;
1206 switch (scaler->pix_per_clk) {
1209 for (i = 0; i < loop_width; i += 2) {
1210 lsb = scaler->H_phases[i] & XHSC_MASK_LOW_16BITS;
1211 msb = scaler->H_phases[i + 1] & XHSC_MASK_LOW_16BITS;
1212 val = (msb << 16 | lsb);
1213 xilinx_scaler_write(scaler->base, offset +
1219 for (i = 0; i < loop_width; i++) {
1220 val = (scaler->H_phases[i] & XHSC_MASK_LOW_32BITS);
1221 xilinx_scaler_write(scaler->base, offset +
1229 * xv_vscaler_setup_video_fmt - Sets video format of v-scaler
1230 * @scaler: Pointer to scaler device structure
1231 * @code_in: format to be set
1233 * This function set the given format of v-scaler
1235 * Return: format value on success. -EINVAL for invalid format.
1239 xv_vscaler_setup_video_fmt(struct xilinx_scaler *scaler, u32 code_in)
1244 case MEDIA_BUS_FMT_UYVY8_1X16:
1245 video_in = XVIDC_CSF_YCRCB_422;
1247 case MEDIA_BUS_FMT_VUY8_1X24:
1248 video_in = XVIDC_CSF_YCRCB_444;
1250 case MEDIA_BUS_FMT_RGB888_1X24:
1251 video_in = XVIDC_CSF_RGB;
1253 case MEDIA_BUS_FMT_VYYUYY8_1X24:
1254 video_in = XVIDC_CSF_YCRCB_420;
1257 dev_info(scaler->dev, "Vscaler Unsupported media fmt\n");
1260 xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1261 XV_VSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA,
1267 * xv_hscaler_setup_video_fmt - Sets video format of h-scaler
1268 * @scaler: Pointer to scaler device structure
1269 * @code_out: bus format to be set
1270 * @vsc_out: return value of vscaler
1272 * This function set the given video format of h-scaler
1274 * Return: format value on success. -EINVAL for invalid format.
1277 static int xv_hscaler_setup_video_fmt(struct xilinx_scaler *scaler,
1278 u32 code_out, u32 vsc_out)
1283 case XVIDC_CSF_YCRCB_422:
1285 case XVIDC_CSF_YCRCB_444:
1289 case XVIDC_CSF_YCRCB_420:
1292 dev_info(scaler->dev, "unsupported format from Vscaler");
1296 xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1297 XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA,
1301 case MEDIA_BUS_FMT_UYVY8_1X16:
1302 video_out = XVIDC_CSF_YCRCB_422;
1304 case MEDIA_BUS_FMT_VUY8_1X24:
1305 video_out = XVIDC_CSF_YCRCB_444;
1307 case MEDIA_BUS_FMT_RGB888_1X24:
1308 video_out = XVIDC_CSF_RGB;
1310 case MEDIA_BUS_FMT_VYYUYY8_1X24:
1311 video_out = XVIDC_CSF_YCRCB_420;
1314 dev_info(scaler->dev, "Hscaler Unsupported Out media fmt\n");
1317 xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1318 XV_HSCALER_CTRL_ADDR_HWREG_COLORMODEOUT_DATA,
1324 * xilinx_scaler_parse_of - Parse device tree information
1325 * @scaler: Pointer to scaler device structure
1327 * This function reads the device tree contents
1329 * Return: 0 on success. -EINVAL for invalid value.
1332 static int xilinx_scaler_parse_of(struct xilinx_scaler *scaler)
1336 struct device_node *node = scaler->dev->of_node;
1338 ret = of_property_read_u32(node, "xlnx,h-scaler-taps",
1339 &scaler->num_hori_taps);
1341 dev_info(scaler->dev, "h-scaler-taps not present in DT\n");
1344 switch (scaler->num_hori_taps) {
1345 case XV_HSCALER_TAPS_2:
1346 case XV_HSCALER_TAPS_4:
1347 scaler->is_polyphase = false;
1349 case XV_HSCALER_TAPS_6:
1350 case XV_HSCALER_TAPS_8:
1351 case XV_HSCALER_TAPS_10:
1352 case XV_HSCALER_TAPS_12:
1353 scaler->is_polyphase = true;
1359 ret = of_property_read_u32(node, "xlnx,v-scaler-taps",
1360 &scaler->num_vert_taps);
1362 dev_info(scaler->dev, "v-scaler-taps not present in DT\n");
1366 switch (scaler->num_vert_taps) {
1367 case XV_HSCALER_TAPS_2:
1368 case XV_VSCALER_TAPS_4:
1369 if (scaler->num_vert_taps != scaler->num_hori_taps)
1372 case XV_VSCALER_TAPS_6:
1373 case XV_VSCALER_TAPS_8:
1374 case XV_VSCALER_TAPS_10:
1375 case XV_VSCALER_TAPS_12:
1376 scaler->is_polyphase = true;
1382 ret = of_property_read_u32(node, "xlnx,samples-per-clk", &dt_ppc);
1384 dev_info(scaler->dev, "PPC is missing in DT\n");
1387 if (dt_ppc != XSCALER_PPC_1 && dt_ppc != XSCALER_PPC_2) {
1388 dev_info(scaler->dev, "Unsupported ppc: %d", dt_ppc);
1391 scaler->pix_per_clk = dt_ppc;
1394 scaler->rst_gpio = devm_gpiod_get(scaler->dev, "reset", GPIOD_OUT_HIGH);
1395 if (IS_ERR(scaler->rst_gpio)) {
1396 if (PTR_ERR(scaler->rst_gpio) != -EPROBE_DEFER)
1397 dev_err(scaler->dev, "Reset GPIO not setup in DT");
1398 return PTR_ERR(scaler->rst_gpio);
1405 * xilinx_scaler_stream - Set up v-scaler and h-scaler for streaming
1406 * @scaler: Pointer to scaler device structure
1408 * This function sets up the required configuration of v-scaler and h-scaler
1410 * Return: 0 on success. Returns -EINVAL on failure conditions.
1412 static int xilinx_scaler_stream(struct xilinx_scaler *scaler)
1414 u32 fmt_in, fmt_out;
1419 fmt_in = scaler->fmt_in;
1420 fmt_out = scaler->fmt_out;
1421 line_rate = (scaler->height_in * STEP_PRECISION) / scaler->height_out;
1423 if (scaler->is_polyphase) {
1424 ret = xv_vscaler_select_coeff(scaler, scaler->height_in,
1425 scaler->height_out);
1427 dev_info(scaler->dev, "Failed: vscaler select coeff\n");
1430 xv_vscaler_set_coeff(scaler);
1432 xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1433 XV_VSCALER_CTRL_ADDR_HWREG_LINERATE_DATA,
1435 ret = xv_vscaler_setup_video_fmt(scaler, scaler->fmt_in);
1437 dev_info(scaler->dev, "Failed: vscaler setup video format\n");
1440 pixel_rate = (scaler->width_in * STEP_PRECISION) / scaler->width_out;
1441 xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1442 XV_HSCALER_CTRL_ADDR_HWREG_PIXELRATE_DATA,
1444 ret = xv_hscaler_setup_video_fmt(scaler, scaler->fmt_out, ret);
1446 dev_info(scaler->dev, "Failed: vscaler setup video format\n");
1449 if (scaler->is_polyphase) {
1450 ret = xv_hscaler_select_coeff(scaler, scaler->width_in,
1453 dev_info(scaler->dev, "Failed: hscaler select coeff\n");
1456 xv_hscaler_set_coeff(scaler);
1458 xv_hscaler_calculate_phases(scaler, scaler->width_in,
1459 scaler->width_out, pixel_rate);
1460 xv_hscaler_set_phases(scaler);
1465 * xilinx_scaler_bridge_enable - enabes scaler sub-cores
1466 * @bridge: bridge instance
1468 * This function enables the scaler sub-cores
1470 * Return: 0 on success. Return -EINVAL on failure conditions.
1473 static int xilinx_scaler_bridge_enable(struct xlnx_bridge *bridge)
1476 struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1478 ret = xilinx_scaler_stream(scaler);
1482 xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1483 XV_HSCALER_CTRL_ADDR_AP_CTRL, XSCALER_STREAM_ON);
1484 xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1485 XV_VSCALER_CTRL_ADDR_AP_CTRL, XSCALER_STREAM_ON);
1486 xilinx_scaler_enable_block(scaler, XGPIO_CH_RESET_SEL,
1487 XGPIO_RESET_MASK_IP_AXIS);
1492 * xilinx_scaler_bridge_disable - disables scaler sub-cores
1493 * @bridge: bridge instance
1495 * This function disables the scaler sub-cores
1497 static void xilinx_scaler_bridge_disable(struct xlnx_bridge *bridge)
1499 struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1501 xilinx_scaler_disable_block(scaler, XGPIO_CH_RESET_SEL,
1502 XGPIO_RESET_MASK_ALL_BLOCKS);
1506 * xilinx_scaler_bridge_set_input - Sets the input parameters of scaler
1507 * @bridge: bridge instance
1508 * @width: width of video
1509 * @height: height of video
1510 * @bus_fmt: video bus format
1512 * This function sets the input parameters of scaler
1513 * Return: 0 on success. -EINVAL for invalid parameters.
1515 static int xilinx_scaler_bridge_set_input(struct xlnx_bridge *bridge,
1516 u32 width, u32 height, u32 bus_fmt)
1518 struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1520 if (width > scaler->max_pixels || height > scaler->max_lines)
1523 scaler->height_in = height;
1524 scaler->width_in = width;
1525 scaler->fmt_in = bus_fmt;
1527 /* IP Reset through GPIO */
1528 gpiod_set_value_cansleep(scaler->rst_gpio, XSCALER_RESET_DEASSERT);
1529 gpiod_set_value_cansleep(scaler->rst_gpio, XSCALER_RESET_ASSERT);
1530 xilinx_scaler_reset(scaler);
1531 memset(scaler->H_phases, 0, sizeof(scaler->H_phases));
1533 xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1534 XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTIN_DATA, height);
1535 xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1536 XV_VSCALER_CTRL_ADDR_HWREG_WIDTH_DATA, width);
1537 xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1538 XV_HSCALER_CTRL_ADDR_HWREG_WIDTHIN_DATA, width);
1544 * xilinx_scaler_bridge_get_input_fmts - input formats supported by scaler
1545 * @bridge: bridge instance
1546 * @fmts: Pointer to be updated with formats information
1547 * @count: count of video bus formats
1549 * This function provides the input video formats information scaler
1550 * Return: 0 on success.
1552 static int xilinx_scaler_bridge_get_input_fmts(struct xlnx_bridge *bridge,
1553 const u32 **fmts, u32 *count)
1555 *fmts = xilinx_scaler_video_fmts;
1556 *count = ARRAY_SIZE(xilinx_scaler_video_fmts);
1561 * xilinx_scaler_bridge_set_output - Sets the output parameters of scaler
1562 * @bridge: bridge instance
1563 * @width: width of video
1564 * @height: height of video
1565 * @bus_fmt: video bus format
1567 * This function sets the output parameters of scaler
1568 * Return: 0 on success. -EINVAL for invalid parameters.
1570 static int xilinx_scaler_bridge_set_output(struct xlnx_bridge *bridge,
1571 u32 width, u32 height, u32 bus_fmt)
1573 struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1575 if (width > scaler->max_pixels || height > scaler->max_lines)
1578 scaler->height_out = height;
1579 scaler->width_out = width;
1580 scaler->fmt_out = bus_fmt;
1582 xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1583 XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTOUT_DATA, height);
1584 xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1585 XV_HSCALER_CTRL_ADDR_HWREG_HEIGHT_DATA, height);
1586 xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1587 XV_HSCALER_CTRL_ADDR_HWREG_WIDTHOUT_DATA, width);
1592 * xilinx_scaler_bridge_get_output_fmts - output formats supported by scaler
1593 * @bridge: bridge instance
1594 * @fmts: Pointer to be updated with formats information
1595 * @count: count of video bus formats
1597 * This function provides the output video formats information scaler
1598 * Return: 0 on success.
1600 static int xilinx_scaler_bridge_get_output_fmts(struct xlnx_bridge *bridge,
1601 const u32 **fmts, u32 *count)
1603 *fmts = xilinx_scaler_video_fmts;
1604 *count = ARRAY_SIZE(xilinx_scaler_video_fmts);
1608 static int xilinx_scaler_probe(struct platform_device *pdev)
1610 struct device *dev = &pdev->dev;
1611 struct resource *res;
1612 struct xilinx_scaler *scaler;
1615 scaler = devm_kzalloc(dev, sizeof(*scaler), GFP_KERNEL);
1619 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1620 scaler->base = devm_ioremap_resource(dev, res);
1621 if (IS_ERR(scaler->base)) {
1622 dev_err(dev, "failed to remap io region\n");
1625 platform_set_drvdata(pdev, scaler);
1627 ret = xilinx_scaler_parse_of(scaler);
1629 dev_info(scaler->dev, "parse_of failed\n");
1632 scaler->max_num_phases = XSCALER_MAX_PHASES;
1633 scaler->max_lines = XSCALER_MAX_HEIGHT;
1634 scaler->max_pixels = XSCALER_MAX_WIDTH;
1636 /* Reset the Global IP Reset through a GPIO */
1637 gpiod_set_value_cansleep(scaler->rst_gpio, XSCALER_RESET_ASSERT);
1638 xilinx_scaler_reset(scaler);
1640 scaler->bridge.enable = &xilinx_scaler_bridge_enable;
1641 scaler->bridge.disable = &xilinx_scaler_bridge_disable;
1642 scaler->bridge.set_input = &xilinx_scaler_bridge_set_input;
1643 scaler->bridge.get_input_fmts = &xilinx_scaler_bridge_get_input_fmts;
1644 scaler->bridge.set_output = &xilinx_scaler_bridge_set_output;
1645 scaler->bridge.get_output_fmts = &xilinx_scaler_bridge_get_output_fmts;
1646 scaler->bridge.of_node = dev->of_node;
1648 ret = xlnx_bridge_register(&scaler->bridge);
1650 dev_info(scaler->dev, "Bridge registration failed\n");
1653 dev_info(scaler->dev, "xlnx drm scaler experimental driver probed\n");
1658 static int xilinx_scaler_remove(struct platform_device *pdev)
1660 struct xilinx_scaler *scaler = platform_get_drvdata(pdev);
1662 xlnx_bridge_unregister(&scaler->bridge);
1666 static const struct of_device_id xilinx_scaler_of_match[] = {
1667 { .compatible = "xlnx,vpss-scaler"},
1670 MODULE_DEVICE_TABLE(of, xilinx_scaler_of_match);
1672 static struct platform_driver scaler_bridge_driver = {
1673 .probe = xilinx_scaler_probe,
1674 .remove = xilinx_scaler_remove,
1676 .name = "xlnx,scaler-bridge",
1677 .of_match_table = xilinx_scaler_of_match,
1681 module_platform_driver(scaler_bridge_driver);
1683 MODULE_AUTHOR("Venkateshwar Rao <vgannava@xilinx.com>");
1684 MODULE_DESCRIPTION("Xilinx FPGA SCALER Bridge Driver");
1685 MODULE_LICENSE("GPL v2");