1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/gpio/consumer.h>
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/platform_device.h>
22
23#include <media/v4l2-async.h>
24#include <media/v4l2-subdev.h>
25#include "xilinx-vip.h"
26
27#define XSCALER_MIN_WIDTH (32)
28#define XSCALER_MAX_WIDTH (3840)
29#define XSCALER_MIN_HEIGHT (32)
30#define XSCALER_MAX_HEIGHT (2160)
31#define XSCALER_MAX_PHASES (64)
32
33
34#define XSCALER_DEF_IN_HEIGHT (720)
35#define XSCALER_DEF_IN_WIDTH (1280)
36#define XSCALER_DEF_OUT_HEIGHT (1080)
37#define XSCALER_DEF_OUT_WIDTH (1920)
38
39#define XSCALER_HSF (0x0100)
40#define XSCALER_VSF (0x0104)
41#define XSCALER_SF_SHIFT (20)
42#define XSCALER_SF_MASK (0xffffff)
43#define XSCALER_SOURCE_SIZE (0x0108)
44#define XSCALER_SIZE_HORZ_SHIFT (0)
45#define XSCALER_SIZE_VERT_SHIFT (16)
46#define XSCALER_SIZE_MASK (0xfff)
47#define XSCALER_HAPERTURE (0x010c)
48#define XSCALER_VAPERTURE (0x0110)
49#define XSCALER_APERTURE_START_SHIFT (0)
50#define XSCALER_APERTURE_END_SHIFT (16)
51#define XSCALER_OUTPUT_SIZE (0x0114)
52#define XSCALER_COEF_DATA_IN (0x0134)
53#define XSCALER_BITSHIFT_16 (16)
54
55
56#define S_AXIS_RESET_OFF (0x00010000)
57#define V_HSCALER_OFF (0x00000000)
58#define V_VSCALER_OFF (0x00020000)
59
60
61#define XGPIO_CH_RESET_SEL (1)
62#define XGPIO_RESET_MASK_VIDEO_IN BIT(0)
63#define XGPIO_RESET_MASK_IP_AXIS BIT(1)
64#define XGPIO_RESET_MASK_IP_AXIMM BIT(0)
65#define XGPIO_RESET_MASK_ALL_BLOCKS (XGPIO_RESET_MASK_VIDEO_IN | \
66 XGPIO_RESET_MASK_IP_AXIS)
67#define XGPIO_DATA_OFFSET (0x0)
68#define XGPIO_TRI_OFFSET (0x4)
69#define XGPIO_DATA2_OFFSET (0x8)
70#define XGPIO_TRI2_OFFSET (0xc)
71
72#define XGPIO_GIE_OFFSET (0x11c)
73#define XGPIO_ISR_OFFSET (0x120)
74#define XGPIO_IER_OFFSET (0x128)
75#define XGPIO_CHAN_OFFSET (8)
76#define STEP_PRECISION (65536)
77
78
79enum xscaler_vid_reg_fmts {
80 XVIDC_CSF_RGB = 0,
81 XVIDC_CSF_YCRCB_444,
82 XVIDC_CSF_YCRCB_422,
83 XVIDC_CSF_YCRCB_420,
84};
85
86
87#define XSCALER_PPC_1 (1)
88#define XSCALER_PPC_2 (2)
89
90#define XV_HSCALER_MAX_H_TAPS (12)
91#define XV_HSCALER_MAX_H_PHASES (64)
92#define XV_HSCALER_MAX_LINE_WIDTH (3840)
93#define XV_VSCALER_MAX_V_TAPS (12)
94#define XV_VSCALER_MAX_V_PHASES (64)
95
96#define XV_HSCALER_TAPS_2 (2)
97#define XV_HSCALER_TAPS_4 (4)
98#define XV_HSCALER_TAPS_6 (6)
99#define XV_HSCALER_TAPS_8 (8)
100#define XV_HSCALER_TAPS_10 (10)
101#define XV_HSCALER_TAPS_12 (12)
102#define XV_VSCALER_TAPS_2 (2)
103#define XV_VSCALER_TAPS_4 (4)
104#define XV_VSCALER_TAPS_6 (6)
105#define XV_VSCALER_TAPS_8 (8)
106#define XV_VSCALER_TAPS_10 (10)
107#define XV_VSCALER_TAPS_12 (12)
108
109
110#define XHSC_MASK_LOW_16BITS GENMASK(15, 0)
111#define XHSC_MASK_HIGH_16BITS GENMASK(31, 16)
112#define XHSC_MASK_LOW_32BITS GENMASK(31, 0)
113#define XHSC_STEP_PRECISION_SHIFT (16)
114#define XHSC_HPHASE_SHIFT_BY_6 (6)
115#define XHSC_HPHASE_MULTIPLIER (9)
116
117
118#define XVSC_MASK_LOW_16BITS GENMASK(15, 0)
119#define XVSC_MASK_HIGH_16BITS GENMASK(31, 16)
120
121
122#define XSCALER_RESET_ASSERT (0x1)
123#define XSCALER_RESET_DEASSERT (0x0)
124
125
126#define XSCALER_START BIT(0)
127#define XSCALER_AUTO_RESTART BIT(7)
128#define XSCALER_STREAM_ON (XSCALER_START | XSCALER_AUTO_RESTART)
129
130
131#define XV_HSCALER_CTRL_ADDR_AP_CTRL (0x0000)
132#define XV_HSCALER_CTRL_ADDR_GIE (0x0004)
133#define XV_HSCALER_CTRL_ADDR_IER (0x0008)
134#define XV_HSCALER_CTRL_ADDR_ISR (0x000c)
135#define XV_HSCALER_CTRL_ADDR_HWREG_HEIGHT_DATA (0x0010)
136#define XV_HSCALER_CTRL_ADDR_HWREG_WIDTHIN_DATA (0x0018)
137#define XV_HSCALER_CTRL_ADDR_HWREG_WIDTHOUT_DATA (0x0020)
138#define XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA (0x0028)
139#define XV_HSCALER_CTRL_ADDR_HWREG_PIXELRATE_DATA (0x0030)
140#define XV_HSCALER_CTRL_ADDR_HWREG_COLORMODEOUT_DATA (0X0038)
141#define XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE (0x0800)
142#define XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH (0x0bff)
143
144
145static const u16
146xhsc_coeff_taps6[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_6] = {
147 { -132, 236, 3824, 236, -132, 64, },
148 { -116, 184, 3816, 292, -144, 64, },
149 { -100, 132, 3812, 348, -160, 64, },
150 { -88, 84, 3808, 404, -176, 64, },
151 { -72, 36, 3796, 464, -192, 64, },
152 { -60, -8, 3780, 524, -208, 68, },
153 { -48, -52, 3768, 588, -228, 68, },
154 { -32, -96, 3748, 652, -244, 68, },
155 { -20, -136, 3724, 716, -260, 72, },
156 { -8, -172, 3696, 784, -276, 72, },
157 { 0, -208, 3676, 848, -292, 72, },
158 { 12, -244, 3640, 920, -308, 76, },
159 { 20, -276, 3612, 988, -324, 76, },
160 { 32, -304, 3568, 1060, -340, 80, },
161 { 40, -332, 3532, 1132, -356, 80, },
162 { 48, -360, 3492, 1204, -372, 84, },
163 { 56, -384, 3448, 1276, -388, 88, },
164 { 64, -408, 3404, 1352, -404, 88, },
165 { 72, -428, 3348, 1428, -416, 92, },
166 { 76, -448, 3308, 1500, -432, 92, },
167 { 84, -464, 3248, 1576, -444, 96, },
168 { 88, -480, 3200, 1652, -460, 96, },
169 { 92, -492, 3140, 1728, -472, 100, },
170 { 96, -504, 3080, 1804, -484, 104, },
171 { 100, -516, 3020, 1880, -492, 104, },
172 { 104, -524, 2956, 1960, -504, 104, },
173 { 104, -532, 2892, 2036, -512, 108, },
174 { 108, -540, 2832, 2108, -520, 108, },
175 { 108, -544, 2764, 2184, -528, 112, },
176 { 112, -544, 2688, 2260, -532, 112, },
177 { 112, -548, 2624, 2336, -540, 112, },
178 { 112, -548, 2556, 2408, -544, 112, },
179 { 112, -544, 2480, 2480, -544, 112, },
180 { 112, -544, 2408, 2556, -548, 112, },
181 { 112, -540, 2336, 2624, -548, 112, },
182 { 112, -532, 2260, 2688, -544, 112, },
183 { 112, -528, 2184, 2764, -544, 108, },
184 { 108, -520, 2108, 2832, -540, 108, },
185 { 108, -512, 2036, 2892, -532, 104, },
186 { 104, -504, 1960, 2956, -524, 104, },
187 { 104, -492, 1880, 3020, -516, 100, },
188 { 104, -484, 1804, 3080, -504, 96, },
189 { 100, -472, 1728, 3140, -492, 92, },
190 { 96, -460, 1652, 3200, -480, 88, },
191 { 96, -444, 1576, 3248, -464, 84, },
192 { 92, -432, 1500, 3308, -448, 76, },
193 { 92, -416, 1428, 3348, -428, 72, },
194 { 88, -404, 1352, 3404, -408, 64, },
195 { 88, -388, 1276, 3448, -384, 56, },
196 { 84, -372, 1204, 3492, -360, 48, },
197 { 80, -356, 1132, 3532, -332, 40, },
198 { 80, -340, 1060, 3568, -304, 32, },
199 { 76, -324, 988, 3612, -276, 20, },
200 { 76, -308, 920, 3640, -244, 12, },
201 { 72, -292, 848, 3676, -208, 0, },
202 { 72, -276, 784, 3696, -172, -8, },
203 { 72, -260, 716, 3724, -136, -20, },
204 { 68, -244, 652, 3748, -96, -32, },
205 { 68, -228, 588, 3768, -52, -48, },
206 { 68, -208, 524, 3780, -8, -60, },
207 { 64, -192, 464, 3796, 36, -72, },
208 { 64, -176, 404, 3808, 84, -88, },
209 { 64, -160, 348, 3812, 132, -100, },
210 { 64, -144, 292, 3816, 184, -116, }
211};
212
213static const u16
214xhsc_coeff_taps8[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_8] = {
215 {-5, 309, 1023, 1445, 1034, 317, -3, -24, },
216 {-6, 300, 1011, 1445, 1045, 326, -1, -24, },
217 {-7, 291, 1000, 1444, 1056, 336, 0, -24, },
218 {-9, 282, 988, 1444, 1067, 345, 2, -24, },
219 {-10, 274, 977, 1443, 1078, 354, 4, -24, },
220 {-11, 266, 965, 1441, 1089, 364, 6, -24, },
221 {-12, 258, 953, 1440, 1100, 373, 8, -24, },
222 {-13, 250, 942, 1438, 1110, 383, 10, -24, },
223 {-14, 242, 930, 1437, 1121, 393, 12, -24, },
224 {-15, 234, 918, 1434, 1131, 403, 14, -24, },
225 {-16, 226, 906, 1432, 1142, 413, 17, -24, },
226 {-17, 219, 894, 1430, 1152, 423, 19, -24, },
227 {-17, 211, 882, 1427, 1162, 433, 22, -24, },
228 {-18, 204, 870, 1424, 1172, 443, 24, -24, },
229 {-19, 197, 858, 1420, 1182, 454, 27, -24, },
230 {-19, 190, 846, 1417, 1191, 464, 30, -24, },
231 {-20, 183, 834, 1413, 1201, 475, 33, -24, },
232 {-20, 176, 822, 1409, 1210, 486, 36, -24, },
233 {-21, 170, 810, 1405, 1220, 497, 39, -24, },
234 {-21, 163, 798, 1401, 1229, 507, 42, -24, },
235 {-22, 157, 786, 1396, 1238, 518, 46, -24, },
236 {-22, 151, 774, 1392, 1247, 529, 49, -24, },
237 {-22, 144, 762, 1387, 1255, 540, 53, -24, },
238 {-23, 139, 750, 1382, 1264, 552, 57, -24, },
239 {-23, 133, 738, 1376, 1272, 563, 60, -24, },
240 {-23, 127, 726, 1371, 1280, 574, 64, -24, },
241 {-23, 121, 714, 1365, 1288, 586, 69, -24, },
242 {-23, 116, 703, 1359, 1296, 597, 73, -24, },
243 {-24, 111, 691, 1353, 1304, 609, 77, -24, },
244 {-24, 105, 679, 1346, 1312, 620, 81, -24, },
245 {-24, 100, 667, 1340, 1319, 632, 86, -24, },
246 {-24, 96, 655, 1333, 1326, 644, 91, -24, },
247 {-24, 91, 644, 1326, 1333, 655, 96, -24, },
248 {-24, 86, 632, 1319, 1340, 667, 100, -24, },
249 {-24, 81, 620, 1312, 1346, 679, 105, -24, },
250 {-24, 77, 609, 1304, 1353, 691, 111, -24, },
251 {-24, 73, 597, 1296, 1359, 703, 116, -23, },
252 {-24, 69, 586, 1288, 1365, 714, 121, -23, },
253 {-24, 64, 574, 1280, 1371, 726, 127, -23, },
254 {-24, 60, 563, 1272, 1376, 738, 133, -23, },
255 {-24, 57, 552, 1264, 1382, 750, 139, -23, },
256 {-24, 53, 540, 1255, 1387, 762, 144, -22, },
257 {-24, 49, 529, 1247, 1392, 774, 151, -22, },
258 {-24, 46, 518, 1238, 1396, 786, 157, -22, },
259 {-24, 42, 507, 1229, 1401, 798, 163, -21, },
260 {-24, 39, 497, 1220, 1405, 810, 170, -21, },
261 {-24, 36, 486, 1210, 1409, 822, 176, -20, },
262 {-24, 33, 475, 1201, 1413, 834, 183, -20, },
263 {-24, 30, 464, 1191, 1417, 846, 190, -19, },
264 {-24, 27, 454, 1182, 1420, 858, 197, -19, },
265 {-24, 24, 443, 1172, 1424, 870, 204, -18, },
266 {-24, 22, 433, 1162, 1427, 882, 211, -17, },
267 {-24, 19, 423, 1152, 1430, 894, 219, -17, },
268 {-24, 17, 413, 1142, 1432, 906, 226, -16, },
269 {-24, 14, 403, 1131, 1434, 918, 234, -15, },
270 {-24, 12, 393, 1121, 1437, 930, 242, -14, },
271 {-24, 10, 383, 1110, 1438, 942, 250, -13, },
272 {-24, 8, 373, 1100, 1440, 953, 258, -12, },
273 {-24, 6, 364, 1089, 1441, 965, 266, -11, },
274 {-24, 4, 354, 1078, 1443, 977, 274, -10, },
275 {-24, 2, 345, 1067, 1444, 988, 282, -9, },
276 {-24, 0, 336, 1056, 1444, 1000, 291, -7, },
277 {-24, -1, 326, 1045, 1445, 1011, 300, -6, },
278 {-24, -3, 317, 1034, 1445, 1023, 309, -5, },
279};
280
281static const u16
282xhsc_coeff_taps10[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_10] = {
283 {59, 224, 507, 790, 911, 793, 512, 227, 61, 13, },
284 {58, 220, 502, 786, 911, 797, 516, 231, 62, 13, },
285 {56, 216, 497, 783, 911, 800, 521, 235, 64, 13, },
286 {55, 213, 492, 779, 910, 804, 526, 238, 65, 13, },
287 {54, 209, 487, 775, 910, 807, 531, 242, 67, 14, },
288 {52, 206, 482, 772, 910, 810, 536, 246, 69, 14, },
289 {51, 202, 477, 768, 909, 813, 541, 250, 70, 14, },
290 {50, 199, 473, 764, 909, 817, 545, 254, 72, 14, },
291 {48, 195, 468, 760, 908, 820, 550, 258, 74, 15, },
292 {47, 192, 463, 756, 908, 823, 555, 262, 76, 15, },
293 {46, 188, 458, 752, 907, 826, 560, 266, 78, 15, },
294 {45, 185, 453, 748, 906, 829, 565, 270, 79, 16, },
295 {44, 182, 448, 744, 906, 832, 569, 274, 81, 16, },
296 {42, 179, 444, 740, 905, 835, 574, 278, 83, 16, },
297 {41, 175, 439, 736, 904, 837, 579, 282, 85, 17, },
298 {40, 172, 434, 732, 903, 840, 584, 286, 87, 17, },
299 {39, 169, 429, 728, 902, 843, 589, 290, 89, 18, },
300 {38, 166, 425, 724, 901, 846, 593, 294, 91, 18, },
301 {37, 163, 420, 720, 900, 848, 598, 298, 93, 18, },
302 {36, 160, 415, 716, 899, 851, 603, 302, 95, 19, },
303 {35, 157, 410, 711, 897, 854, 608, 307, 98, 19, },
304 {34, 154, 406, 707, 896, 856, 612, 311, 100, 20, },
305 {33, 151, 401, 703, 895, 859, 617, 315, 102, 20, },
306 {33, 148, 396, 698, 893, 861, 622, 320, 104, 21, },
307 {32, 145, 392, 694, 892, 863, 626, 324, 107, 21, },
308 {31, 142, 387, 690, 890, 866, 631, 328, 109, 22, },
309 {30, 140, 382, 685, 889, 868, 636, 333, 111, 23, },
310 {29, 137, 378, 681, 887, 870, 640, 337, 114, 23, },
311 {28, 134, 373, 677, 886, 872, 645, 342, 116, 24, },
312 {28, 131, 369, 672, 884, 874, 649, 346, 119, 24, },
313 {27, 129, 364, 668, 882, 876, 654, 350, 121, 25, },
314 {26, 126, 359, 663, 880, 878, 659, 355, 124, 26, },
315 {26, 124, 355, 659, 878, 880, 663, 359, 126, 26, },
316 {25, 121, 350, 654, 876, 882, 668, 364, 129, 27, },
317 {24, 119, 346, 649, 874, 884, 672, 369, 131, 28, },
318 {24, 116, 342, 645, 872, 886, 677, 373, 134, 28, },
319 {23, 114, 337, 640, 870, 887, 681, 378, 137, 29, },
320 {23, 111, 333, 636, 868, 889, 685, 382, 140, 30, },
321 {22, 109, 328, 631, 866, 890, 690, 387, 142, 31, },
322 {21, 107, 324, 626, 863, 892, 694, 392, 145, 32, },
323 {21, 104, 320, 622, 861, 893, 698, 396, 148, 33, },
324 {20, 102, 315, 617, 859, 895, 703, 401, 151, 33, },
325 {20, 100, 311, 612, 856, 896, 707, 406, 154, 34, },
326 {19, 98, 307, 608, 854, 897, 711, 410, 157, 35, },
327 {19, 95, 302, 603, 851, 899, 716, 415, 160, 36, },
328 {18, 93, 298, 598, 848, 900, 720, 420, 163, 37, },
329 {18, 91, 294, 593, 846, 901, 724, 425, 166, 38, },
330 {18, 89, 290, 589, 843, 902, 728, 429, 169, 39, },
331 {17, 87, 286, 584, 840, 903, 732, 434, 172, 40, },
332 {17, 85, 282, 579, 837, 904, 736, 439, 175, 41, },
333 {16, 83, 278, 574, 835, 905, 740, 444, 179, 42, },
334 {16, 81, 274, 569, 832, 906, 744, 448, 182, 44, },
335 {16, 79, 270, 565, 829, 906, 748, 453, 185, 45, },
336 {15, 78, 266, 560, 826, 907, 752, 458, 188, 46, },
337 {15, 76, 262, 555, 823, 908, 756, 463, 192, 47, },
338 {15, 74, 258, 550, 820, 908, 760, 468, 195, 48, },
339 {14, 72, 254, 545, 817, 909, 764, 473, 199, 50, },
340 {14, 70, 250, 541, 813, 909, 768, 477, 202, 51, },
341 {14, 69, 246, 536, 810, 910, 772, 482, 206, 52, },
342 {14, 67, 242, 531, 807, 910, 775, 487, 209, 54, },
343 {13, 65, 238, 526, 804, 910, 779, 492, 213, 55, },
344 {13, 64, 235, 521, 800, 911, 783, 497, 216, 56, },
345 {13, 62, 231, 516, 797, 911, 786, 502, 220, 58, },
346 {13, 61, 227, 512, 793, 911, 790, 507, 224, 59, },
347};
348
349static const u16
350xhsc_coeff_taps12[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_TAPS_12] = {
351 {48, 143, 307, 504, 667, 730, 669, 507, 310, 145, 49, 18, },
352 {47, 141, 304, 501, 665, 730, 670, 510, 313, 147, 50, 18, },
353 {46, 138, 301, 498, 663, 730, 672, 513, 316, 149, 51, 18, },
354 {45, 136, 298, 495, 661, 730, 674, 516, 319, 151, 52, 18, },
355 {44, 134, 295, 492, 659, 730, 676, 519, 322, 153, 53, 18, },
356 {44, 132, 292, 489, 657, 730, 677, 522, 325, 155, 54, 18, },
357 {43, 130, 289, 486, 655, 729, 679, 525, 328, 157, 55, 19, },
358 {42, 129, 287, 483, 653, 729, 681, 528, 331, 160, 56, 19, },
359 {41, 127, 284, 480, 651, 729, 683, 531, 334, 162, 57, 19, },
360 {40, 125, 281, 477, 648, 729, 684, 534, 337, 164, 58, 19, },
361 {40, 123, 278, 474, 646, 728, 686, 537, 340, 166, 59, 20, },
362 {39, 121, 275, 471, 644, 728, 687, 539, 343, 169, 60, 20, },
363 {38, 119, 272, 468, 642, 727, 689, 542, 346, 171, 61, 20, },
364 {37, 117, 269, 465, 640, 727, 690, 545, 349, 173, 62, 20, },
365 {37, 115, 266, 461, 638, 727, 692, 548, 353, 175, 63, 21, },
366 {36, 114, 264, 458, 635, 726, 693, 551, 356, 178, 65, 21, },
367 {35, 112, 261, 455, 633, 726, 695, 554, 359, 180, 66, 21, },
368 {35, 110, 258, 452, 631, 725, 696, 556, 362, 183, 67, 21, },
369 {34, 108, 255, 449, 628, 724, 698, 559, 365, 185, 68, 22, },
370 {33, 107, 252, 446, 626, 724, 699, 562, 368, 187, 69, 22, },
371 {33, 105, 250, 443, 624, 723, 700, 565, 371, 190, 71, 22, },
372 {32, 103, 247, 440, 621, 723, 702, 567, 374, 192, 72, 23, },
373 {32, 101, 244, 437, 619, 722, 703, 570, 377, 195, 73, 23, },
374 {31, 100, 241, 433, 617, 721, 704, 573, 380, 197, 75, 23, },
375 {31, 98, 239, 430, 614, 720, 705, 576, 383, 200, 76, 24, },
376 {30, 97, 236, 427, 612, 720, 707, 578, 387, 202, 77, 24, },
377 {29, 95, 233, 424, 609, 719, 708, 581, 390, 205, 79, 24, },
378 {29, 93, 231, 421, 607, 718, 709, 584, 393, 207, 80, 25, },
379 {28, 92, 228, 418, 604, 717, 710, 586, 396, 210, 81, 25, },
380 {28, 90, 225, 415, 602, 716, 711, 589, 399, 212, 83, 26, },
381 {27, 89, 223, 412, 599, 715, 712, 591, 402, 215, 84, 26, },
382 {27, 87, 220, 408, 597, 714, 713, 594, 405, 217, 86, 27, },
383 {27, 86, 217, 405, 594, 713, 714, 597, 408, 220, 87, 27, },
384 {26, 84, 215, 402, 591, 712, 715, 599, 412, 223, 89, 27, },
385 {26, 83, 212, 399, 589, 711, 716, 602, 415, 225, 90, 28, },
386 {25, 81, 210, 396, 586, 710, 717, 604, 418, 228, 92, 28, },
387 {25, 80, 207, 393, 584, 709, 718, 607, 421, 231, 93, 29, },
388 {24, 79, 205, 390, 581, 708, 719, 609, 424, 233, 95, 29, },
389 {24, 77, 202, 387, 578, 707, 720, 612, 427, 236, 97, 30, },
390 {24, 76, 200, 383, 576, 705, 720, 614, 430, 239, 98, 31, },
391 {23, 75, 197, 380, 573, 704, 721, 617, 433, 241, 100, 31, },
392 {23, 73, 195, 377, 570, 703, 722, 619, 437, 244, 101, 32, },
393 {23, 72, 192, 374, 567, 702, 723, 621, 440, 247, 103, 32, },
394 {22, 71, 190, 371, 565, 700, 723, 624, 443, 250, 105, 33, },
395 {22, 69, 187, 368, 562, 699, 724, 626, 446, 252, 107, 33, },
396 {22, 68, 185, 365, 559, 698, 724, 628, 449, 255, 108, 34, },
397 {21, 67, 183, 362, 556, 696, 725, 631, 452, 258, 110, 35, },
398 {21, 66, 180, 359, 554, 695, 726, 633, 455, 261, 112, 35, },
399 {21, 65, 178, 356, 551, 693, 726, 635, 458, 264, 114, 36, },
400 {21, 63, 175, 353, 548, 692, 727, 638, 461, 266, 115, 37, },
401 {20, 62, 173, 349, 545, 690, 727, 640, 465, 269, 117, 37, },
402 {20, 61, 171, 346, 542, 689, 727, 642, 468, 272, 119, 38, },
403 {20, 60, 169, 343, 539, 687, 728, 644, 471, 275, 121, 39, },
404 {20, 59, 166, 340, 537, 686, 728, 646, 474, 278, 123, 40, },
405 {19, 58, 164, 337, 534, 684, 729, 648, 477, 281, 125, 40, },
406 {19, 57, 162, 334, 531, 683, 729, 651, 480, 284, 127, 41, },
407 {19, 56, 160, 331, 528, 681, 729, 653, 483, 287, 129, 42, },
408 {19, 55, 157, 328, 525, 679, 729, 655, 486, 289, 130, 43, },
409 {18, 54, 155, 325, 522, 677, 730, 657, 489, 292, 132, 44, },
410 {18, 53, 153, 322, 519, 676, 730, 659, 492, 295, 134, 44, },
411 {18, 52, 151, 319, 516, 674, 730, 661, 495, 298, 136, 45, },
412 {18, 51, 149, 316, 513, 672, 730, 663, 498, 301, 138, 46, },
413 {18, 50, 147, 313, 510, 670, 730, 665, 501, 304, 141, 47, },
414 {18, 49, 145, 310, 507, 669, 730, 667, 504, 307, 143, 48, },
415};
416
417#define XV_HSCALER_CTRL_WIDTH_HWREG_HFLTCOEFF (16)
418#define XV_HSCALER_CTRL_DEPTH_HWREG_HFLTCOEFF (384)
419#define XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE (0x2000)
420#define XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH (0x3fff)
421#define XV_HSCALER_CTRL_WIDTH_HWREG_PHASESH_V (18)
422#define XV_HSCALER_CTRL_DEPTH_HWREG_PHASESH_V (1920)
423
424
425#define XV_HSCALER_PHASESH_V_OUTPUT_WR_EN BIT(8)
426
427
428#define XV_VSCALER_CTRL_ADDR_AP_CTRL (0x000)
429#define XV_VSCALER_CTRL_ADDR_GIE (0x004)
430#define XV_VSCALER_CTRL_ADDR_IER (0x008)
431#define XV_VSCALER_CTRL_ADDR_ISR (0x00c)
432#define XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTIN_DATA (0x010)
433#define XV_VSCALER_CTRL_ADDR_HWREG_WIDTH_DATA (0x018)
434#define XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTOUT_DATA (0x020)
435#define XV_VSCALER_CTRL_ADDR_HWREG_LINERATE_DATA (0x028)
436#define XV_VSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA (0x030)
437#define XV_VSCALER_CTRL_ADDR_HWREG_VFLTCOEFF_BASE (0x800)
438#define XV_VSCALER_CTRL_ADDR_HWREG_VFLTCOEFF_HIGH (0xbff)
439
440
441static const u16
442xvsc_coeff_taps6[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_6] = {
443 {-132, 236, 3824, 236, -132, 64, },
444 {-116, 184, 3816, 292, -144, 64, },
445 {-100, 132, 3812, 348, -160, 64, },
446 {-88, 84, 3808, 404, -176, 64, },
447 {-72, 36, 3796, 464, -192, 64, },
448 {-60, -8, 3780, 524, -208, 68, },
449 {-48, -52, 3768, 588, -228, 68, },
450 {-32, -96, 3748, 652, -244, 68, },
451 {-20, -136, 3724, 716, -260, 72, },
452 {-8, -172, 3696, 784, -276, 72, },
453 {0, -208, 3676, 848, -292, 72, },
454 {12, -244, 3640, 920, -308, 76, },
455 {20, -276, 3612, 988, -324, 76, },
456 {32, -304, 3568, 1060, -340, 80, },
457 {40, -332, 3532, 1132, -356, 80, },
458 {48, -360, 3492, 1204, -372, 84, },
459 {56, -384, 3448, 1276, -388, 88, },
460 {64, -408, 3404, 1352, -404, 88, },
461 {72, -428, 3348, 1428, -416, 92, },
462 {76, -448, 3308, 1500, -432, 92, },
463 {84, -464, 3248, 1576, -444, 96, },
464 {88, -480, 3200, 1652, -460, 96, },
465 {92, -492, 3140, 1728, -472, 100, },
466 {96, -504, 3080, 1804, -484, 104, },
467 {100, -516, 3020, 1880, -492, 104, },
468 {104, -524, 2956, 1960, -504, 104, },
469 {104, -532, 2892, 2036, -512, 108, },
470 {108, -540, 2832, 2108, -520, 108, },
471 {108, -544, 2764, 2184, -528, 112, },
472 {112, -544, 2688, 2260, -532, 112, },
473 {112, -548, 2624, 2336, -540, 112, },
474 {112, -548, 2556, 2408, -544, 112, },
475 {112, -544, 2480, 2480, -544, 112, },
476 {112, -544, 2408, 2556, -548, 112, },
477 {112, -540, 2336, 2624, -548, 112, },
478 {112, -532, 2260, 2688, -544, 112, },
479 {112, -528, 2184, 2764, -544, 108, },
480 {108, -520, 2108, 2832, -540, 108, },
481 {108, -512, 2036, 2892, -532, 104, },
482 {104, -504, 1960, 2956, -524, 104, },
483 {104, -492, 1880, 3020, -516, 100, },
484 {104, -484, 1804, 3080, -504, 96, },
485 {100, -472, 1728, 3140, -492, 92, },
486 { 96, -460, 1652, 3200, -480, 88, },
487 { 96, -444, 1576, 3248, -464, 84, },
488 { 92, -432, 1500, 3308, -448, 76, },
489 { 92, -416, 1428, 3348, -428, 72, },
490 { 88, -404, 1352, 3404, -408, 64, },
491 { 88, -388, 1276, 3448, -384, 56, },
492 { 84, -372, 1204, 3492, -360, 48, },
493 { 80, -356, 1132, 3532, -332, 40, },
494 { 80, -340, 1060, 3568, -304, 32, },
495 { 76, -324, 988, 3612, -276, 20, },
496 { 76, -308, 920, 3640, -244, 12, },
497 { 72, -292, 848, 3676, -208, 0, },
498 { 72, -276, 784, 3696, -172, -8, },
499 { 72, -260, 716, 3724, -136, -20, },
500 { 68, -244, 652, 3748, -96, -32, },
501 { 68, -228, 588, 3768, -52, -48, },
502 { 68, -208, 524, 3780, -8, -60, },
503 { 64, -192, 464, 3796, 36, -72, },
504 { 64, -176, 404, 3808, 84, -88, },
505 { 64, -160, 348, 3812, 132, -100, },
506 { 64, -144, 292, 3816, 184, -116, }
507};
508
509static const u16
510xvsc_coeff_taps8[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_8] = {
511 {-5, 309, 1023, 1445, 1034, 317, -3, -24, },
512 {-6, 300, 1011, 1445, 1045, 326, -1, -24, },
513 {-7, 291, 1000, 1444, 1056, 336, 0, -24, },
514 {-9, 282, 988, 1444, 1067, 345, 2, -24, },
515 {-10, 274, 977, 1443, 1078, 354, 4, -24, },
516 {-11, 266, 965, 1441, 1089, 364, 6, -24, },
517 {-12, 258, 953, 1440, 1100, 373, 8, -24, },
518 {-13, 250, 942, 1438, 1110, 383, 10, -24, },
519 {-14, 242, 930, 1437, 1121, 393, 12, -24, },
520 {-15, 234, 918, 1434, 1131, 403, 14, -24, },
521 {-16, 226, 906, 1432, 1142, 413, 17, -24, },
522 {-17, 219, 894, 1430, 1152, 423, 19, -24, },
523 {-17, 211, 882, 1427, 1162, 433, 22, -24, },
524 {-18, 204, 870, 1424, 1172, 443, 24, -24, },
525 {-19, 197, 858, 1420, 1182, 454, 27, -24, },
526 {-19, 190, 846, 1417, 1191, 464, 30, -24, },
527 {-20, 183, 834, 1413, 1201, 475, 33, -24, },
528 {-20, 176, 822, 1409, 1210, 486, 36, -24, },
529 {-21, 170, 810, 1405, 1220, 497, 39, -24, },
530 {-21, 163, 798, 1401, 1229, 507, 42, -24, },
531 {-22, 157, 786, 1396, 1238, 518, 46, -24, },
532 {-22, 151, 774, 1392, 1247, 529, 49, -24, },
533 {-22, 144, 762, 1387, 1255, 540, 53, -24, },
534 {-23, 139, 750, 1382, 1264, 552, 57, -24, },
535 {-23, 133, 738, 1376, 1272, 563, 60, -24, },
536 {-23, 127, 726, 1371, 1280, 574, 64, -24, },
537 {-23, 121, 714, 1365, 1288, 586, 69, -24, },
538 {-23, 116, 703, 1359, 1296, 597, 73, -24, },
539 {-24, 111, 691, 1353, 1304, 609, 77, -24, },
540 {-24, 105, 679, 1346, 1312, 620, 81, -24, },
541 {-24, 100, 667, 1340, 1319, 632, 86, -24, },
542 {-24, 96, 655, 1333, 1326, 644, 91, -24, },
543 {-24, 91, 644, 1326, 1333, 655, 96, -24, },
544 {-24, 86, 632, 1319, 1340, 667, 100, -24, },
545 {-24, 81, 620, 1312, 1346, 679, 105, -24, },
546 {-24, 77, 609, 1304, 1353, 691, 111, -24, },
547 {-24, 73, 597, 1296, 1359, 703, 116, -23, },
548 {-24, 69, 586, 1288, 1365, 714, 121, -23, },
549 {-24, 64, 574, 1280, 1371, 726, 127, -23, },
550 {-24, 60, 563, 1272, 1376, 738, 133, -23, },
551 {-24, 57, 552, 1264, 1382, 750, 139, -23, },
552 {-24, 53, 540, 1255, 1387, 762, 144, -22, },
553 {-24, 49, 529, 1247, 1392, 774, 151, -22, },
554 {-24, 46, 518, 1238, 1396, 786, 157, -22, },
555 {-24, 42, 507, 1229, 1401, 798, 163, -21, },
556 {-24, 39, 497, 1220, 1405, 810, 170, -21, },
557 {-24, 36, 486, 1210, 1409, 822, 176, -20, },
558 {-24, 33, 475, 1201, 1413, 834, 183, -20, },
559 {-24, 30, 464, 1191, 1417, 846, 190, -19, },
560 {-24, 27, 454, 1182, 1420, 858, 197, -19, },
561 {-24, 24, 443, 1172, 1424, 870, 204, -18, },
562 {-24, 22, 433, 1162, 1427, 882, 211, -17, },
563 {-24, 19, 423, 1152, 1430, 894, 219, -17, },
564 {-24, 17, 413, 1142, 1432, 906, 226, -16, },
565 {-24, 14, 403, 1131, 1434, 918, 234, -15, },
566 {-24, 12, 393, 1121, 1437, 930, 242, -14, },
567 {-24, 10, 383, 1110, 1438, 942, 250, -13, },
568 {-24, 8, 373, 1100, 1440, 953, 258, -12, },
569 {-24, 6, 364, 1089, 1441, 965, 266, -11, },
570 {-24, 4, 354, 1078, 1443, 977, 274, -10, },
571 {-24, 2, 345, 1067, 1444, 988, 282, -9, },
572 {-24, 0, 336, 1056, 1444, 1000, 291, -7, },
573 {-24, -1, 326, 1045, 1445, 1011, 300, -6, },
574 {-24, -3, 317, 1034, 1445, 1023, 309, -5, },
575};
576
577static const u16
578xvsc_coeff_taps10[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_10] = {
579 {59, 224, 507, 790, 911, 793, 512, 227, 61, 13, },
580 {58, 220, 502, 786, 911, 797, 516, 231, 62, 13, },
581 {56, 216, 497, 783, 911, 800, 521, 235, 64, 13, },
582 {55, 213, 492, 779, 910, 804, 526, 238, 65, 13, },
583 {54, 209, 487, 775, 910, 807, 531, 242, 67, 14, },
584 {52, 206, 482, 772, 910, 810, 536, 246, 69, 14, },
585 {51, 202, 477, 768, 909, 813, 541, 250, 70, 14, },
586 {50, 199, 473, 764, 909, 817, 545, 254, 72, 14, },
587 {48, 195, 468, 760, 908, 820, 550, 258, 74, 15, },
588 {47, 192, 463, 756, 908, 823, 555, 262, 76, 15, },
589 {46, 188, 458, 752, 907, 826, 560, 266, 78, 15, },
590 {45, 185, 453, 748, 906, 829, 565, 270, 79, 16, },
591 {44, 182, 448, 744, 906, 832, 569, 274, 81, 16, },
592 {42, 179, 444, 740, 905, 835, 574, 278, 83, 16, },
593 {41, 175, 439, 736, 904, 837, 579, 282, 85, 17, },
594 {40, 172, 434, 732, 903, 840, 584, 286, 87, 17, },
595 {39, 169, 429, 728, 902, 843, 589, 290, 89, 18, },
596 {38, 166, 425, 724, 901, 846, 593, 294, 91, 18, },
597 {37, 163, 420, 720, 900, 848, 598, 298, 93, 18, },
598 {36, 160, 415, 716, 899, 851, 603, 302, 95, 19, },
599 {35, 157, 410, 711, 897, 854, 608, 307, 98, 19, },
600 {34, 154, 406, 707, 896, 856, 612, 311, 100, 20, },
601 {33, 151, 401, 703, 895, 859, 617, 315, 102, 20, },
602 {33, 148, 396, 698, 893, 861, 622, 320, 104, 21, },
603 {32, 145, 392, 694, 892, 863, 626, 324, 107, 21, },
604 {31, 142, 387, 690, 890, 866, 631, 328, 109, 22, },
605 {30, 140, 382, 685, 889, 868, 636, 333, 111, 23, },
606 {29, 137, 378, 681, 887, 870, 640, 337, 114, 23, },
607 {28, 134, 373, 677, 886, 872, 645, 342, 116, 24, },
608 {28, 131, 369, 672, 884, 874, 649, 346, 119, 24, },
609 {27, 129, 364, 668, 882, 876, 654, 350, 121, 25, },
610 {26, 126, 359, 663, 880, 878, 659, 355, 124, 26, },
611 {26, 124, 355, 659, 878, 880, 663, 359, 126, 26, },
612 {25, 121, 350, 654, 876, 882, 668, 364, 129, 27, },
613 {24, 119, 346, 649, 874, 884, 672, 369, 131, 28, },
614 {24, 116, 342, 645, 872, 886, 677, 373, 134, 28, },
615 {23, 114, 337, 640, 870, 887, 681, 378, 137, 29, },
616 {23, 111, 333, 636, 868, 889, 685, 382, 140, 30, },
617 {22, 109, 328, 631, 866, 890, 690, 387, 142, 31, },
618 {21, 107, 324, 626, 863, 892, 694, 392, 145, 32, },
619 {21, 104, 320, 622, 861, 893, 698, 396, 148, 33, },
620 {20, 102, 315, 617, 859, 895, 703, 401, 151, 33, },
621 {20, 100, 311, 612, 856, 896, 707, 406, 154, 34, },
622 {19, 98, 307, 608, 854, 897, 711, 410, 157, 35, },
623 {19, 95, 302, 603, 851, 899, 716, 415, 160, 36, },
624 {18, 93, 298, 598, 848, 900, 720, 420, 163, 37, },
625 {18, 91, 294, 593, 846, 901, 724, 425, 166, 38, },
626 {18, 89, 290, 589, 843, 902, 728, 429, 169, 39, },
627 {17, 87, 286, 584, 840, 903, 732, 434, 172, 40, },
628 {17, 85, 282, 579, 837, 904, 736, 439, 175, 41, },
629 {16, 83, 278, 574, 835, 905, 740, 444, 179, 42, },
630 {16, 81, 274, 569, 832, 906, 744, 448, 182, 44, },
631 {16, 79, 270, 565, 829, 906, 748, 453, 185, 45, },
632 {15, 78, 266, 560, 826, 907, 752, 458, 188, 46, },
633 {15, 76, 262, 555, 823, 908, 756, 463, 192, 47, },
634 {15, 74, 258, 550, 820, 908, 760, 468, 195, 48, },
635 {14, 72, 254, 545, 817, 909, 764, 473, 199, 50, },
636 {14, 70, 250, 541, 813, 909, 768, 477, 202, 51, },
637 {14, 69, 246, 536, 810, 910, 772, 482, 206, 52, },
638 {14, 67, 242, 531, 807, 910, 775, 487, 209, 54, },
639 {13, 65, 238, 526, 804, 910, 779, 492, 213, 55, },
640 {13, 64, 235, 521, 800, 911, 783, 497, 216, 56, },
641 {13, 62, 231, 516, 797, 911, 786, 502, 220, 58, },
642 {13, 61, 227, 512, 793, 911, 790, 507, 224, 59, },
643};
644
645static const u16
646xvsc_coeff_taps12[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_12] = {
647 {48, 143, 307, 504, 667, 730, 669, 507, 310, 145, 49, 18, },
648 {47, 141, 304, 501, 665, 730, 670, 510, 313, 147, 50, 18, },
649 {46, 138, 301, 498, 663, 730, 672, 513, 316, 149, 51, 18, },
650 {45, 136, 298, 495, 661, 730, 674, 516, 319, 151, 52, 18, },
651 {44, 134, 295, 492, 659, 730, 676, 519, 322, 153, 53, 18, },
652 {44, 132, 292, 489, 657, 730, 677, 522, 325, 155, 54, 18, },
653 {43, 130, 289, 486, 655, 729, 679, 525, 328, 157, 55, 19, },
654 {42, 129, 287, 483, 653, 729, 681, 528, 331, 160, 56, 19, },
655 {41, 127, 284, 480, 651, 729, 683, 531, 334, 162, 57, 19, },
656 {40, 125, 281, 477, 648, 729, 684, 534, 337, 164, 58, 19, },
657 {40, 123, 278, 474, 646, 728, 686, 537, 340, 166, 59, 20, },
658 {39, 121, 275, 471, 644, 728, 687, 539, 343, 169, 60, 20, },
659 {38, 119, 272, 468, 642, 727, 689, 542, 346, 171, 61, 20, },
660 {37, 117, 269, 465, 640, 727, 690, 545, 349, 173, 62, 20, },
661 {37, 115, 266, 461, 638, 727, 692, 548, 353, 175, 63, 21, },
662 {36, 114, 264, 458, 635, 726, 693, 551, 356, 178, 65, 21, },
663 {35, 112, 261, 455, 633, 726, 695, 554, 359, 180, 66, 21, },
664 {35, 110, 258, 452, 631, 725, 696, 556, 362, 183, 67, 21, },
665 {34, 108, 255, 449, 628, 724, 698, 559, 365, 185, 68, 22, },
666 {33, 107, 252, 446, 626, 724, 699, 562, 368, 187, 69, 22, },
667 {33, 105, 250, 443, 624, 723, 700, 565, 371, 190, 71, 22, },
668 {32, 103, 247, 440, 621, 723, 702, 567, 374, 192, 72, 23, },
669 {32, 101, 244, 437, 619, 722, 703, 570, 377, 195, 73, 23, },
670 {31, 100, 241, 433, 617, 721, 704, 573, 380, 197, 75, 23, },
671 {31, 98, 239, 430, 614, 720, 705, 576, 383, 200, 76, 24, },
672 {30, 97, 236, 427, 612, 720, 707, 578, 387, 202, 77, 24, },
673 {29, 95, 233, 424, 609, 719, 708, 581, 390, 205, 79, 24, },
674 {29, 93, 231, 421, 607, 718, 709, 584, 393, 207, 80, 25, },
675 {28, 92, 228, 418, 604, 717, 710, 586, 396, 210, 81, 25, },
676 {28, 90, 225, 415, 602, 716, 711, 589, 399, 212, 83, 26, },
677 {27, 89, 223, 412, 599, 715, 712, 591, 402, 215, 84, 26, },
678 {27, 87, 220, 408, 597, 714, 713, 594, 405, 217, 86, 27, },
679 {27, 86, 217, 405, 594, 713, 714, 597, 408, 220, 87, 27, },
680 {26, 84, 215, 402, 591, 712, 715, 599, 412, 223, 89, 27, },
681 {26, 83, 212, 399, 589, 711, 716, 602, 415, 225, 90, 28, },
682 {25, 81, 210, 396, 586, 710, 717, 604, 418, 228, 92, 28, },
683 {25, 80, 207, 393, 584, 709, 718, 607, 421, 231, 93, 29, },
684 {24, 79, 205, 390, 581, 708, 719, 609, 424, 233, 95, 29, },
685 {24, 77, 202, 387, 578, 707, 720, 612, 427, 236, 97, 30, },
686 {24, 76, 200, 383, 576, 705, 720, 614, 430, 239, 98, 31, },
687 {23, 75, 197, 380, 573, 704, 721, 617, 433, 241, 100, 31, },
688 {23, 73, 195, 377, 570, 703, 722, 619, 437, 244, 101, 32, },
689 {23, 72, 192, 374, 567, 702, 723, 621, 440, 247, 103, 32, },
690 {22, 71, 190, 371, 565, 700, 723, 624, 443, 250, 105, 33, },
691 {22, 69, 187, 368, 562, 699, 724, 626, 446, 252, 107, 33, },
692 {22, 68, 185, 365, 559, 698, 724, 628, 449, 255, 108, 34, },
693 {21, 67, 183, 362, 556, 696, 725, 631, 452, 258, 110, 35, },
694 {21, 66, 180, 359, 554, 695, 726, 633, 455, 261, 112, 35, },
695 {21, 65, 178, 356, 551, 693, 726, 635, 458, 264, 114, 36, },
696 {21, 63, 175, 353, 548, 692, 727, 638, 461, 266, 115, 37, },
697 {20, 62, 173, 349, 545, 690, 727, 640, 465, 269, 117, 37, },
698 {20, 61, 171, 346, 542, 689, 727, 642, 468, 272, 119, 38, },
699 {20, 60, 169, 343, 539, 687, 728, 644, 471, 275, 121, 39, },
700 {20, 59, 166, 340, 537, 686, 728, 646, 474, 278, 123, 40, },
701 {19, 58, 164, 337, 534, 684, 729, 648, 477, 281, 125, 40, },
702 {19, 57, 162, 334, 531, 683, 729, 651, 480, 284, 127, 41, },
703 {19, 56, 160, 331, 528, 681, 729, 653, 483, 287, 129, 42, },
704 {19, 55, 157, 328, 525, 679, 729, 655, 486, 289, 130, 43, },
705 {18, 54, 155, 325, 522, 677, 730, 657, 489, 292, 132, 44, },
706 {18, 53, 153, 322, 519, 676, 730, 659, 492, 295, 134, 44, },
707 {18, 52, 151, 319, 516, 674, 730, 661, 495, 298, 136, 45, },
708 {18, 51, 149, 316, 513, 672, 730, 663, 498, 301, 138, 46, },
709 {18, 50, 147, 313, 510, 670, 730, 665, 501, 304, 141, 47, },
710 {18, 49, 145, 310, 507, 669, 730, 667, 504, 307, 143, 48, },
711};
712
713#define XV_VSCALER_CTRL_WIDTH_HWREG_VFLTCOEFF (16)
714#define XV_VSCALER_CTRL_DEPTH_HWREG_VFLTCOEFF (384)
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735struct xscaler_device {
736 struct xvip_device xvip;
737
738 struct media_pad pads[2];
739 struct v4l2_mbus_framefmt formats[2];
740 struct v4l2_mbus_framefmt default_formats[2];
741 const struct xvip_video_format *vip_formats[2];
742
743 u32 num_hori_taps;
744 u32 num_vert_taps;
745 u32 max_num_phases;
746 u32 pix_per_clk;
747 u32 max_pixels;
748 u32 max_lines;
749 u32 H_phases[XV_HSCALER_MAX_LINE_WIDTH];
750 short hscaler_coeff[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS];
751 short vscaler_coeff[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_MAX_V_TAPS];
752 bool is_polyphase;
753
754 struct gpio_desc *rst_gpio;
755};
756
757static inline struct xscaler_device *to_scaler(struct v4l2_subdev *subdev)
758{
759 return container_of(subdev, struct xscaler_device, xvip.subdev);
760}
761
762static void
763xv_hscaler_calculate_phases(struct xscaler_device *xscaler,
764 u32 width_in, u32 width_out, u32 pixel_rate)
765{
766 unsigned int loop_width;
767 unsigned int x, s;
768 int offset = 0;
769 int xwrite_pos = 0;
770 bool output_write_en;
771 bool get_new_pix;
772 u64 phaseH;
773 u32 array_idx = 0;
774 int nr_rds;
775 int nr_rds_clck;
776 unsigned int nphases = xscaler->max_num_phases;
777 unsigned int nppc = xscaler->pix_per_clk;
778 unsigned int shift = XHSC_STEP_PRECISION_SHIFT - ilog2(nphases);
779
780 loop_width = max_t(u32, width_in, width_out);
781 loop_width = ALIGN(loop_width + nppc - 1, nppc);
782
783 for (x = 0; x < loop_width; x++) {
784 nr_rds_clck = 0;
785 for (s = 0; s < nppc; s++) {
786 phaseH = (offset >> shift) & (nphases - 1);
787 get_new_pix = false;
788 output_write_en = false;
789 if ((offset >> XHSC_STEP_PRECISION_SHIFT) != 0) {
790
791 get_new_pix = true;
792 offset -= (1 << XHSC_STEP_PRECISION_SHIFT);
793 array_idx++;
794 }
795
796 if (((offset >> XHSC_STEP_PRECISION_SHIFT) == 0) &&
797 (xwrite_pos < width_out)) {
798
799 offset += pixel_rate;
800 output_write_en = true;
801 xwrite_pos++;
802 }
803
804
805 xscaler->H_phases[x] |= (phaseH <<
806 (s * XHSC_HPHASE_MULTIPLIER));
807 xscaler->H_phases[x] |= (array_idx <<
808 (XHSC_HPHASE_SHIFT_BY_6 +
809 (s * XHSC_HPHASE_MULTIPLIER)));
810 if (output_write_en) {
811 xscaler->H_phases[x] |=
812 (XV_HSCALER_PHASESH_V_OUTPUT_WR_EN <<
813 (s * XHSC_HPHASE_MULTIPLIER));
814 }
815
816 if (get_new_pix)
817 nr_rds_clck++;
818 }
819 if (array_idx >= nppc)
820 array_idx &= (nppc - 1);
821
822 nr_rds += nr_rds_clck;
823 if (nr_rds >= nppc)
824 nr_rds -= nppc;
825 }
826}
827
828static void
829xv_hscaler_load_ext_coeff(struct xscaler_device *xscaler,
830 const short *coeff, u32 ntaps)
831{
832 unsigned int i, j, pad, offset;
833 u32 nphases = xscaler->max_num_phases;
834
835
836 pad = XV_HSCALER_MAX_H_TAPS - ntaps;
837 offset = pad >> 1;
838 dev_dbg(xscaler->xvip.dev,
839 "%s : Pad = %d Offset = %d Nphases = %d ntaps = %d",
840 __func__, pad, offset, nphases, ntaps);
841
842
843 for (i = 0; i < nphases; i++) {
844 for (j = 0; j < ntaps; ++j)
845 xscaler->hscaler_coeff[i][j + offset] =
846 coeff[i * ntaps + j];
847 }
848
849 if (pad) {
850 for (i = 0; i < nphases; i++) {
851
852 for (j = 0; j < offset; j++)
853 xscaler->hscaler_coeff[i][j] = 0;
854
855 j = ntaps + offset;
856 for (; j < XV_HSCALER_MAX_H_TAPS; j++)
857 xscaler->hscaler_coeff[i][j] = 0;
858 }
859 }
860}
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885static int
886xv_hscaler_select_coeff(struct xscaler_device *xscaler,
887 u32 width_in, u32 width_out)
888{
889 const short *coeff;
890 u16 hscale_ratio;
891 u32 ntaps = xscaler->num_hori_taps;
892
893
894
895
896
897 if (width_out < width_in) {
898 hscale_ratio = ((width_in * 10) / width_out);
899
900 switch (xscaler->num_hori_taps) {
901 case XV_HSCALER_TAPS_6:
902 coeff = &xhsc_coeff_taps6[0][0];
903 ntaps = XV_HSCALER_TAPS_6;
904 break;
905 case XV_HSCALER_TAPS_8:
906 if (hscale_ratio > 15) {
907 coeff = &xhsc_coeff_taps8[0][0];
908 ntaps = XV_HSCALER_TAPS_8;
909 } else {
910 coeff = &xhsc_coeff_taps6[0][0];
911 ntaps = XV_HSCALER_TAPS_6;
912 }
913 break;
914 case XV_HSCALER_TAPS_10:
915 if (hscale_ratio > 25) {
916 coeff = &xhsc_coeff_taps10[0][0];
917 ntaps = XV_HSCALER_TAPS_10;
918 } else if (hscale_ratio > 15) {
919 coeff = &xhsc_coeff_taps8[0][0];
920 ntaps = XV_HSCALER_TAPS_8;
921 } else {
922 coeff = &xhsc_coeff_taps6[0][0];
923 ntaps = XV_HSCALER_TAPS_6;
924 }
925 break;
926 case XV_HSCALER_TAPS_12:
927 if (hscale_ratio > 35) {
928 coeff = &xhsc_coeff_taps12[0][0];
929 ntaps = XV_HSCALER_TAPS_12;
930 } else if (hscale_ratio > 25) {
931 coeff = &xhsc_coeff_taps10[0][0];
932 ntaps = XV_HSCALER_TAPS_10;
933 } else if (hscale_ratio > 15) {
934 coeff = &xhsc_coeff_taps8[0][0];
935 ntaps = XV_HSCALER_TAPS_8;
936 } else {
937 coeff = &xhsc_coeff_taps6[0][0];
938 ntaps = XV_HSCALER_TAPS_6;
939 }
940 break;
941 default:
942 dev_err(xscaler->xvip.dev,
943 "Unsupported H-scaler number of taps = %d",
944 xscaler->num_hori_taps);
945 return -EINVAL;
946 }
947 } else {
948 dev_dbg(xscaler->xvip.dev, "H-scaler : scale up 6 tap");
949 coeff = &xhsc_coeff_taps6[0][0];
950 ntaps = XV_HSCALER_TAPS_6;
951 }
952 xv_hscaler_load_ext_coeff(xscaler, coeff, ntaps);
953 return 0;
954}
955
956static void xv_hscaler_set_coeff(struct xscaler_device *xscaler)
957{
958 int val, i, j, offset, rd_indx;
959 u32 ntaps = xscaler->num_hori_taps;
960 u32 nphases = xscaler->max_num_phases;
961 u32 base_addr;
962
963 offset = (XV_HSCALER_MAX_H_TAPS - ntaps) / 2;
964 base_addr = V_HSCALER_OFF + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE;
965 for (i = 0; i < nphases; i++) {
966 for (j = 0; j < ntaps / 2; j++) {
967 rd_indx = j * 2 + offset;
968 val = (xscaler->hscaler_coeff[i][rd_indx + 1] <<
969 XSCALER_BITSHIFT_16) |
970 (xscaler->hscaler_coeff[i][rd_indx] &
971 XHSC_MASK_LOW_16BITS);
972 xvip_write(&xscaler->xvip, base_addr +
973 ((i * ntaps / 2 + j) * 4), val);
974 }
975 }
976}
977
978static void
979xv_vscaler_load_ext_coeff(struct xscaler_device *xscaler,
980 const short *coeff, u32 ntaps)
981{
982 int i, j, pad, offset;
983 u32 nphases = xscaler->max_num_phases;
984
985
986 pad = XV_VSCALER_MAX_V_TAPS - ntaps;
987 offset = pad ? (pad >> 1) : 0;
988
989 dev_dbg(xscaler->xvip.dev,
990 "%s : Pad = %d Offset = %d Nphases = %d ntaps = %d",
991 __func__, pad, offset, nphases, ntaps);
992
993
994 for (i = 0; i < nphases; i++) {
995 for (j = 0; j < ntaps; ++j)
996 xscaler->vscaler_coeff[i][j + offset] =
997 coeff[i * ntaps + j];
998 }
999
1000 if (pad) {
1001 for (i = 0; i < nphases; i++) {
1002
1003 for (j = 0; j < offset; j++)
1004 xscaler->vscaler_coeff[i][j] = 0;
1005 }
1006
1007 for (j = (ntaps + offset); j < XV_VSCALER_MAX_V_TAPS; j++)
1008 xscaler->vscaler_coeff[i][j] = 0;
1009 }
1010}
1011
1012static void xv_vscaler_set_coeff(struct xscaler_device *xscaler)
1013{
1014 u32 nphases = xscaler->max_num_phases;
1015 u32 ntaps = xscaler->num_vert_taps;
1016 int val, i, j, offset, rd_indx;
1017 u32 base_addr;
1018
1019 offset = (XV_VSCALER_MAX_V_TAPS - ntaps) / 2;
1020 base_addr = V_VSCALER_OFF + XV_VSCALER_CTRL_ADDR_HWREG_VFLTCOEFF_BASE;
1021
1022 for (i = 0; i < nphases; i++) {
1023 for (j = 0; j < ntaps / 2; j++) {
1024 rd_indx = j * 2 + offset;
1025 val = (xscaler->vscaler_coeff[i][rd_indx + 1] <<
1026 XSCALER_BITSHIFT_16) |
1027 (xscaler->vscaler_coeff[i][rd_indx] &
1028 XVSC_MASK_LOW_16BITS);
1029 xvip_write(&xscaler->xvip,
1030 base_addr + ((i * ntaps / 2 + j) * 4), val);
1031 }
1032 }
1033}
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058static int
1059xv_vscaler_select_coeff(struct xscaler_device *xscaler,
1060 u32 height_in, u32 height_out)
1061{
1062 const short *coeff;
1063 u16 vscale_ratio;
1064 u32 ntaps = xscaler->num_vert_taps;
1065
1066
1067
1068
1069
1070
1071 if (height_out < height_in) {
1072 vscale_ratio = ((height_in * 10) / height_out);
1073
1074 switch (xscaler->num_vert_taps) {
1075 case XV_VSCALER_TAPS_6:
1076 coeff = &xvsc_coeff_taps6[0][0];
1077 ntaps = XV_VSCALER_TAPS_6;
1078 break;
1079 case XV_VSCALER_TAPS_8:
1080 if (vscale_ratio > 15) {
1081 coeff = &xvsc_coeff_taps8[0][0];
1082 ntaps = XV_VSCALER_TAPS_8;
1083 } else {
1084 coeff = &xvsc_coeff_taps6[0][0];
1085 ntaps = XV_VSCALER_TAPS_6;
1086 }
1087 break;
1088 case XV_VSCALER_TAPS_10:
1089 if (vscale_ratio > 25) {
1090 coeff = &xvsc_coeff_taps10[0][0];
1091 ntaps = XV_VSCALER_TAPS_10;
1092 } else if (vscale_ratio > 15) {
1093 coeff = &xvsc_coeff_taps8[0][0];
1094 ntaps = XV_VSCALER_TAPS_8;
1095 } else {
1096 coeff = &xvsc_coeff_taps6[0][0];
1097 ntaps = XV_VSCALER_TAPS_6;
1098 }
1099 break;
1100 case XV_VSCALER_TAPS_12:
1101 if (vscale_ratio > 35) {
1102 coeff = &xvsc_coeff_taps12[0][0];
1103 ntaps = XV_VSCALER_TAPS_12;
1104 } else if (vscale_ratio > 25) {
1105 coeff = &xvsc_coeff_taps10[0][0];
1106 ntaps = XV_VSCALER_TAPS_10;
1107 } else if (vscale_ratio > 15) {
1108 coeff = &xvsc_coeff_taps8[0][0];
1109 ntaps = XV_VSCALER_TAPS_8;
1110 } else {
1111 coeff = &xvsc_coeff_taps6[0][0];
1112 ntaps = XV_VSCALER_TAPS_6;
1113 }
1114 break;
1115 default:
1116 dev_err(xscaler->xvip.dev,
1117 "Unsupported V-scaler number of taps = %d",
1118 xscaler->num_vert_taps);
1119 return -EINVAL;
1120 }
1121 } else {
1122 dev_dbg(xscaler->xvip.dev, "V-scaler : scale up 6 tap");
1123 coeff = &xvsc_coeff_taps6[0][0];
1124 ntaps = XV_VSCALER_TAPS_6;
1125 }
1126
1127 xv_vscaler_load_ext_coeff(xscaler, coeff, ntaps);
1128 return 0;
1129}
1130
1131
1132
1133
1134
1135static inline void
1136xv_procss_disable_block(struct xvip_device *xvip, u32 channel, u32 ip_block)
1137{
1138 xvip_clr(xvip, ((channel - 1) * XGPIO_CHAN_OFFSET) +
1139 XGPIO_DATA_OFFSET + S_AXIS_RESET_OFF,
1140 ip_block);
1141}
1142
1143static inline void
1144xv_procss_enable_block(struct xvip_device *xvip, u32 channel, u32 ip_block)
1145{
1146 xvip_set(xvip, ((channel - 1) * XGPIO_CHAN_OFFSET) +
1147 XGPIO_DATA_OFFSET + S_AXIS_RESET_OFF,
1148 ip_block);
1149}
1150
1151static void xscaler_reset(struct xscaler_device *xscaler)
1152{
1153 xv_procss_disable_block(&xscaler->xvip, XGPIO_CH_RESET_SEL,
1154 XGPIO_RESET_MASK_ALL_BLOCKS);
1155 xv_procss_enable_block(&xscaler->xvip, XGPIO_CH_RESET_SEL,
1156 XGPIO_RESET_MASK_IP_AXIS);
1157}
1158
1159static int
1160xv_vscaler_setup_video_fmt(struct xscaler_device *xscaler, u32 code_in)
1161{
1162 u32 video_in;
1163
1164 switch (code_in) {
1165 case MEDIA_BUS_FMT_VYYUYY8_1X24:
1166 dev_dbg(xscaler->xvip.dev,
1167 "Vscaler Input Media Format YUV 420");
1168 video_in = XVIDC_CSF_YCRCB_420;
1169 break;
1170 case MEDIA_BUS_FMT_UYVY8_1X16:
1171 dev_dbg(xscaler->xvip.dev,
1172 "Vscaler Input Media Format YUV 422");
1173 video_in = XVIDC_CSF_YCRCB_422;
1174 break;
1175 case MEDIA_BUS_FMT_VUY8_1X24:
1176 dev_dbg(xscaler->xvip.dev,
1177 "Vscaler Input Media Format YUV 444");
1178 video_in = XVIDC_CSF_YCRCB_444;
1179 break;
1180 case MEDIA_BUS_FMT_RBG888_1X24:
1181 dev_dbg(xscaler->xvip.dev,
1182 "Vscaler Input Media Format RGB");
1183 video_in = XVIDC_CSF_RGB;
1184 break;
1185 default:
1186 dev_err(xscaler->xvip.dev,
1187 "Vscaler Unsupported Input Media Format 0x%x",
1188 code_in);
1189 return -EINVAL;
1190 }
1191 xvip_write(&xscaler->xvip, V_VSCALER_OFF +
1192 XV_VSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA,
1193 video_in);
1194
1195
1196
1197
1198 if (video_in == XVIDC_CSF_YCRCB_420)
1199 return XVIDC_CSF_YCRCB_422;
1200 return video_in;
1201}
1202
1203static int xv_hscaler_setup_video_fmt(struct xscaler_device *xscaler,
1204 u32 code_out, u32 vsc_out)
1205{
1206 u32 video_out;
1207
1208 switch (vsc_out) {
1209 case XVIDC_CSF_YCRCB_422:
1210 dev_dbg(xscaler->xvip.dev,
1211 "Hscaler Input Media Format is YUV 422");
1212 break;
1213 case XVIDC_CSF_YCRCB_444:
1214 dev_dbg(xscaler->xvip.dev,
1215 "Hscaler Input Media Format is YUV 444");
1216 break;
1217 case XVIDC_CSF_RGB:
1218 dev_dbg(xscaler->xvip.dev,
1219 "Hscaler Input Media Format is RGB");
1220 break;
1221 default:
1222 dev_err(xscaler->xvip.dev,
1223 "Hscaler got unsupported format from Vscaler");
1224 return -EINVAL;
1225 }
1226
1227 xvip_write(&xscaler->xvip, V_HSCALER_OFF +
1228 XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA,
1229 vsc_out);
1230
1231 switch (code_out) {
1232 case MEDIA_BUS_FMT_VYYUYY8_1X24:
1233 dev_dbg(xscaler->xvip.dev,
1234 "Hscaler Output Media Format YUV 420\n");
1235 video_out = XVIDC_CSF_YCRCB_420;
1236 break;
1237 case MEDIA_BUS_FMT_UYVY8_1X16:
1238 dev_dbg(xscaler->xvip.dev,
1239 "Hscaler Output Media Format YUV 422\n");
1240 video_out = XVIDC_CSF_YCRCB_422;
1241 break;
1242 case MEDIA_BUS_FMT_VUY8_1X24:
1243 dev_dbg(xscaler->xvip.dev,
1244 "Hscaler Output Media Format YUV 444\n");
1245 video_out = XVIDC_CSF_YCRCB_444;
1246 break;
1247 case MEDIA_BUS_FMT_RBG888_1X24:
1248 dev_dbg(xscaler->xvip.dev,
1249 "Hscaler Output Media Format RGB\n");
1250 video_out = XVIDC_CSF_RGB;
1251 break;
1252 default:
1253 dev_err(xscaler->xvip.dev,
1254 "Hscaler Unsupported Output Media Format 0x%x",
1255 code_out);
1256 return -EINVAL;
1257 }
1258 xvip_write(&xscaler->xvip, V_HSCALER_OFF +
1259 XV_HSCALER_CTRL_ADDR_HWREG_COLORMODEOUT_DATA,
1260 video_out);
1261 return 0;
1262}
1263
1264static void
1265xv_hscaler_set_phases(struct xscaler_device *xscaler)
1266{
1267 u32 loop_width;
1268 u32 index, val;
1269 u32 offset, i, lsb, msb;
1270
1271 loop_width = xscaler->max_pixels / xscaler->pix_per_clk;
1272 offset = V_HSCALER_OFF + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE;
1273
1274 switch (xscaler->pix_per_clk) {
1275 case XSCALER_PPC_1:
1276
1277
1278
1279
1280
1281
1282
1283 index = 0;
1284 for (i = 0; i < loop_width; i += 2) {
1285 lsb = xscaler->H_phases[i] & XHSC_MASK_LOW_16BITS;
1286 msb = xscaler->H_phases[i + 1] & XHSC_MASK_LOW_16BITS;
1287 val = (msb << 16 | lsb);
1288 xvip_write(&xscaler->xvip, offset + (index * 4), val);
1289 ++index;
1290 }
1291 dev_dbg(xscaler->xvip.dev,
1292 "%s : Operating in 1 PPC design", __func__);
1293 return;
1294 case XSCALER_PPC_2:
1295
1296
1297
1298
1299 for (i = 0; i < loop_width; i++) {
1300 val = (xscaler->H_phases[i] &
1301 XHSC_MASK_LOW_32BITS);
1302 xvip_write(&xscaler->xvip, offset + (i * 4), val);
1303 }
1304 dev_dbg(xscaler->xvip.dev,
1305 "%s : Operating in 2 PPC design", __func__);
1306 return;
1307 }
1308}
1309
1310static int xscaler_s_stream(struct v4l2_subdev *subdev, int enable)
1311{
1312 struct xscaler_device *xscaler = to_scaler(subdev);
1313 u32 width_in, width_out;
1314 u32 height_in, height_out;
1315 u32 code_in, code_out;
1316 u32 pixel_rate;
1317 u32 line_rate;
1318 int ret;
1319
1320 if (!enable) {
1321 dev_dbg(xscaler->xvip.dev, "%s: Stream Off", __func__);
1322
1323 gpiod_set_value_cansleep(xscaler->rst_gpio,
1324 XSCALER_RESET_ASSERT);
1325 gpiod_set_value_cansleep(xscaler->rst_gpio,
1326 XSCALER_RESET_DEASSERT);
1327 xscaler_reset(xscaler);
1328 memset(xscaler->H_phases, 0, sizeof(xscaler->H_phases));
1329 return 0;
1330 }
1331
1332 dev_dbg(xscaler->xvip.dev, "%s: Stream On", __func__);
1333
1334
1335 width_in = xscaler->formats[XVIP_PAD_SINK].width;
1336 height_in = xscaler->formats[XVIP_PAD_SINK].height;
1337 code_in = xscaler->formats[XVIP_PAD_SINK].code;
1338
1339
1340 width_out = xscaler->formats[XVIP_PAD_SOURCE].width;
1341 height_out = xscaler->formats[XVIP_PAD_SOURCE].height;
1342 code_out = xscaler->formats[XVIP_PAD_SOURCE].code;
1343
1344
1345
1346
1347
1348 line_rate = (height_in * STEP_PRECISION) / height_out;
1349
1350 if (xscaler->is_polyphase) {
1351 ret = xv_vscaler_select_coeff(xscaler, height_in, height_out);
1352 if (ret < 0)
1353 return ret;
1354 xv_vscaler_set_coeff(xscaler);
1355 }
1356
1357 xvip_write(&xscaler->xvip, V_VSCALER_OFF +
1358 XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTIN_DATA, height_in);
1359 xvip_write(&xscaler->xvip, V_VSCALER_OFF +
1360 XV_VSCALER_CTRL_ADDR_HWREG_WIDTH_DATA, width_in);
1361 xvip_write(&xscaler->xvip, V_VSCALER_OFF +
1362 XV_VSCALER_CTRL_ADDR_HWREG_HEIGHTOUT_DATA, height_out);
1363 xvip_write(&xscaler->xvip, V_VSCALER_OFF +
1364 XV_VSCALER_CTRL_ADDR_HWREG_LINERATE_DATA, line_rate);
1365 ret = xv_vscaler_setup_video_fmt(xscaler, code_in);
1366 if (ret < 0)
1367 return ret;
1368
1369
1370 pixel_rate = (width_in * STEP_PRECISION) / width_out;
1371
1372 xvip_write(&xscaler->xvip, V_HSCALER_OFF +
1373 XV_HSCALER_CTRL_ADDR_HWREG_HEIGHT_DATA, height_out);
1374 xvip_write(&xscaler->xvip, V_HSCALER_OFF +
1375 XV_HSCALER_CTRL_ADDR_HWREG_WIDTHIN_DATA, width_in);
1376 xvip_write(&xscaler->xvip, V_HSCALER_OFF +
1377 XV_HSCALER_CTRL_ADDR_HWREG_WIDTHOUT_DATA, width_out);
1378 xvip_write(&xscaler->xvip, V_HSCALER_OFF +
1379 XV_HSCALER_CTRL_ADDR_HWREG_PIXELRATE_DATA, pixel_rate);
1380 ret = xv_hscaler_setup_video_fmt(xscaler, code_out, ret);
1381 if (ret < 0)
1382 return ret;
1383
1384 if (xscaler->is_polyphase) {
1385 ret = xv_hscaler_select_coeff(xscaler, width_in, width_out);
1386 if (ret < 0)
1387 return ret;
1388 xv_hscaler_set_coeff(xscaler);
1389 }
1390
1391 xv_hscaler_calculate_phases(xscaler, width_in, width_out, pixel_rate);
1392 xv_hscaler_set_phases(xscaler);
1393
1394
1395 xvip_write(&xscaler->xvip, V_HSCALER_OFF +
1396 XV_HSCALER_CTRL_ADDR_AP_CTRL, XSCALER_STREAM_ON);
1397 xvip_write(&xscaler->xvip, V_VSCALER_OFF +
1398 XV_VSCALER_CTRL_ADDR_AP_CTRL, XSCALER_STREAM_ON);
1399 xv_procss_enable_block(&xscaler->xvip, XGPIO_CH_RESET_SEL,
1400 XGPIO_RESET_MASK_VIDEO_IN);
1401 return 0;
1402}
1403
1404
1405
1406
1407
1408static int xscaler_enum_frame_size(struct v4l2_subdev *subdev,
1409 struct v4l2_subdev_pad_config *cfg,
1410 struct v4l2_subdev_frame_size_enum *fse)
1411{
1412 struct v4l2_mbus_framefmt *format;
1413
1414 format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad);
1415 if (fse->index || fse->code != format->code)
1416 return -EINVAL;
1417
1418 fse->min_width = XSCALER_MIN_WIDTH;
1419 fse->max_width = XSCALER_MAX_WIDTH;
1420 fse->min_height = XSCALER_MIN_HEIGHT;
1421 fse->max_height = XSCALER_MAX_HEIGHT;
1422
1423 return 0;
1424}
1425
1426static struct v4l2_mbus_framefmt *
1427__xscaler_get_pad_format(struct xscaler_device *xscaler,
1428 struct v4l2_subdev_pad_config *cfg,
1429 unsigned int pad, u32 which)
1430{
1431 switch (which) {
1432 case V4L2_SUBDEV_FORMAT_TRY:
1433 return v4l2_subdev_get_try_format(&xscaler->xvip.subdev, cfg,
1434 pad);
1435 case V4L2_SUBDEV_FORMAT_ACTIVE:
1436 return &xscaler->formats[pad];
1437 default:
1438 return NULL;
1439 }
1440}
1441
1442static int xscaler_get_format(struct v4l2_subdev *subdev,
1443 struct v4l2_subdev_pad_config *cfg,
1444 struct v4l2_subdev_format *fmt)
1445{
1446 struct xscaler_device *xscaler = to_scaler(subdev);
1447
1448 fmt->format = *__xscaler_get_pad_format(xscaler, cfg, fmt->pad,
1449 fmt->which);
1450
1451 return 0;
1452}
1453
1454static int xscaler_set_format(struct v4l2_subdev *subdev,
1455 struct v4l2_subdev_pad_config *cfg,
1456 struct v4l2_subdev_format *fmt)
1457{
1458 struct xscaler_device *xscaler = to_scaler(subdev);
1459 struct v4l2_mbus_framefmt *format;
1460
1461 format = __xscaler_get_pad_format(xscaler, cfg, fmt->pad, fmt->which);
1462 *format = fmt->format;
1463
1464 format->width = clamp_t(unsigned int, fmt->format.width,
1465 XSCALER_MIN_WIDTH, XSCALER_MAX_WIDTH);
1466 format->height = clamp_t(unsigned int, fmt->format.height,
1467 XSCALER_MIN_HEIGHT, XSCALER_MAX_HEIGHT);
1468 fmt->format = *format;
1469 return 0;
1470}
1471
1472
1473
1474
1475
1476static int
1477xscaler_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
1478{
1479 struct xscaler_device *xscaler = to_scaler(subdev);
1480 struct v4l2_mbus_framefmt *format;
1481
1482
1483 format = v4l2_subdev_get_try_format(subdev, fh->pad, XVIP_PAD_SINK);
1484 *format = xscaler->default_formats[XVIP_PAD_SINK];
1485
1486 format = v4l2_subdev_get_try_format(subdev, fh->pad, XVIP_PAD_SOURCE);
1487 *format = xscaler->default_formats[XVIP_PAD_SOURCE];
1488
1489 return 0;
1490}
1491
1492static int
1493xscaler_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
1494{
1495 return 0;
1496}
1497
1498static struct v4l2_subdev_video_ops xscaler_video_ops = {
1499 .s_stream = xscaler_s_stream,
1500};
1501
1502static struct v4l2_subdev_pad_ops xscaler_pad_ops = {
1503 .enum_mbus_code = xvip_enum_mbus_code,
1504 .enum_frame_size = xscaler_enum_frame_size,
1505 .get_fmt = xscaler_get_format,
1506 .set_fmt = xscaler_set_format,
1507};
1508
1509static struct v4l2_subdev_ops xscaler_ops = {
1510 .video = &xscaler_video_ops,
1511 .pad = &xscaler_pad_ops,
1512};
1513
1514static const struct v4l2_subdev_internal_ops xscaler_internal_ops = {
1515 .open = xscaler_open,
1516 .close = xscaler_close,
1517};
1518
1519
1520
1521
1522
1523static const struct media_entity_operations xscaler_media_ops = {
1524 .link_validate = v4l2_subdev_link_validate,
1525};
1526
1527
1528
1529
1530
1531static int xscaler_parse_of(struct xscaler_device *xscaler)
1532{
1533 struct device *dev = xscaler->xvip.dev;
1534 struct device_node *node = xscaler->xvip.dev->of_node;
1535 const struct xvip_video_format *vip_format;
1536 struct device_node *ports;
1537 struct device_node *port;
1538 int ret;
1539 u32 port_id, dt_ppc;
1540
1541 ports = of_get_child_by_name(node, "ports");
1542 if (!ports)
1543 ports = node;
1544
1545
1546 for_each_child_of_node(ports, port) {
1547 if (port->name && (of_node_cmp(port->name, "port") == 0)) {
1548 vip_format = xvip_of_get_format(port);
1549 if (IS_ERR(vip_format)) {
1550 dev_err(dev, "invalid format in DT");
1551 return PTR_ERR(vip_format);
1552 }
1553
1554 ret = of_property_read_u32(port, "reg", &port_id);
1555 if (ret < 0) {
1556 dev_err(dev, "No reg in DT");
1557 return ret;
1558 }
1559
1560 if (port_id != 0 && port_id != 1) {
1561 dev_err(dev, "Invalid reg in DT");
1562 return -EINVAL;
1563 }
1564 xscaler->vip_formats[port_id] = vip_format;
1565 }
1566 }
1567
1568 ret = of_property_read_u32(node, "xlnx,num-hori-taps",
1569 &xscaler->num_hori_taps);
1570 if (ret < 0)
1571 return ret;
1572
1573 switch (xscaler->num_hori_taps) {
1574 case XV_HSCALER_TAPS_2:
1575 case XV_HSCALER_TAPS_4:
1576 xscaler->is_polyphase = false;
1577 break;
1578 case XV_HSCALER_TAPS_6:
1579 case XV_HSCALER_TAPS_8:
1580 case XV_HSCALER_TAPS_10:
1581 case XV_HSCALER_TAPS_12:
1582 xscaler->is_polyphase = true;
1583 break;
1584 default:
1585 dev_err(dev, "Unsupported num-hori-taps %d",
1586 xscaler->num_hori_taps);
1587 return -EINVAL;
1588 }
1589
1590 ret = of_property_read_u32(node, "xlnx,num-vert-taps",
1591 &xscaler->num_vert_taps);
1592 if (ret < 0)
1593 return ret;
1594
1595
1596
1597
1598
1599 switch (xscaler->num_vert_taps) {
1600 case XV_HSCALER_TAPS_2:
1601 case XV_VSCALER_TAPS_4:
1602 if (xscaler->num_vert_taps != xscaler->num_hori_taps) {
1603 dev_err(dev,
1604 "H-scaler taps %d mismatches V-scaler taps %d",
1605 xscaler->num_hori_taps,
1606 xscaler->num_vert_taps);
1607 return -EINVAL;
1608 }
1609 break;
1610 case XV_VSCALER_TAPS_6:
1611 case XV_VSCALER_TAPS_8:
1612 case XV_VSCALER_TAPS_10:
1613 case XV_VSCALER_TAPS_12:
1614 xscaler->is_polyphase = true;
1615 break;
1616 default:
1617 dev_err(dev, "Unsupported num-vert-taps %d",
1618 xscaler->num_vert_taps);
1619 return -EINVAL;
1620 }
1621
1622 ret = of_property_read_u32(node, "xlnx,pix-per-clk", &dt_ppc);
1623 if (ret < 0)
1624 return ret;
1625
1626
1627 if (dt_ppc != XSCALER_PPC_1 && dt_ppc != XSCALER_PPC_2) {
1628 dev_err(xscaler->xvip.dev,
1629 "Unsupported xlnx,pix-per-clk(%d) value in DT", dt_ppc);
1630 return -EINVAL;
1631 }
1632 xscaler->pix_per_clk = dt_ppc;
1633
1634
1635 xscaler->rst_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
1636 if (IS_ERR(xscaler->rst_gpio)) {
1637 if (PTR_ERR(xscaler->rst_gpio) != -EPROBE_DEFER)
1638 dev_err(dev, "Reset GPIO not setup in DT");
1639 return PTR_ERR(xscaler->rst_gpio);
1640 }
1641
1642 return 0;
1643}
1644
1645static int xscaler_probe(struct platform_device *pdev)
1646{
1647 struct xscaler_device *xscaler;
1648 struct v4l2_subdev *subdev;
1649 struct v4l2_mbus_framefmt *default_format;
1650 int ret;
1651
1652 xscaler = devm_kzalloc(&pdev->dev, sizeof(*xscaler), GFP_KERNEL);
1653 if (!xscaler)
1654 return -ENOMEM;
1655
1656 xscaler->xvip.dev = &pdev->dev;
1657
1658 ret = xscaler_parse_of(xscaler);
1659 if (ret < 0)
1660 return ret;
1661
1662
1663 xscaler->max_num_phases = XSCALER_MAX_PHASES;
1664 xscaler->max_lines = XSCALER_MAX_HEIGHT;
1665 xscaler->max_pixels = XSCALER_MAX_WIDTH;
1666
1667 ret = xvip_init_resources(&xscaler->xvip);
1668 if (ret < 0)
1669 return ret;
1670
1671
1672 gpiod_set_value_cansleep(xscaler->rst_gpio, XSCALER_RESET_DEASSERT);
1673
1674 xscaler_reset(xscaler);
1675
1676
1677 subdev = &xscaler->xvip.subdev;
1678 v4l2_subdev_init(subdev, &xscaler_ops);
1679 subdev->dev = &pdev->dev;
1680 subdev->internal_ops = &xscaler_internal_ops;
1681 strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
1682 v4l2_set_subdevdata(subdev, xscaler);
1683 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1684
1685
1686 default_format = &xscaler->default_formats[XVIP_PAD_SINK];
1687 default_format->code = xscaler->vip_formats[XVIP_PAD_SINK]->code;
1688 default_format->field = V4L2_FIELD_NONE;
1689 default_format->colorspace = V4L2_COLORSPACE_SRGB;
1690 default_format->width = XSCALER_DEF_IN_WIDTH;
1691 default_format->height = XSCALER_DEF_IN_HEIGHT;
1692 xscaler->formats[XVIP_PAD_SINK] = *default_format;
1693
1694 default_format = &xscaler->default_formats[XVIP_PAD_SOURCE];
1695 *default_format = xscaler->default_formats[XVIP_PAD_SINK];
1696 default_format->code = xscaler->vip_formats[XVIP_PAD_SOURCE]->code;
1697 default_format->width = XSCALER_DEF_OUT_WIDTH;
1698 default_format->height = XSCALER_DEF_OUT_HEIGHT;
1699 xscaler->formats[XVIP_PAD_SOURCE] = *default_format;
1700
1701 xscaler->pads[XVIP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1702 xscaler->pads[XVIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1703 subdev->entity.ops = &xscaler_media_ops;
1704
1705 ret = media_entity_pads_init(&subdev->entity, 2, xscaler->pads);
1706 if (ret < 0)
1707 goto error;
1708
1709 platform_set_drvdata(pdev, xscaler);
1710
1711 ret = v4l2_async_register_subdev(subdev);
1712 if (ret < 0) {
1713 dev_err(&pdev->dev, "failed to register subdev");
1714 goto error;
1715 }
1716 dev_info(xscaler->xvip.dev, "Num Hori Taps %d",
1717 xscaler->num_hori_taps);
1718 dev_info(xscaler->xvip.dev, "Num Vert Taps %d",
1719 xscaler->num_vert_taps);
1720 dev_info(&pdev->dev, "VPSS Scaler Probe Successful");
1721 return 0;
1722
1723error:
1724 media_entity_cleanup(&subdev->entity);
1725 xvip_cleanup_resources(&xscaler->xvip);
1726 return ret;
1727}
1728
1729static int xscaler_remove(struct platform_device *pdev)
1730{
1731 struct xscaler_device *xscaler = platform_get_drvdata(pdev);
1732 struct v4l2_subdev *subdev = &xscaler->xvip.subdev;
1733
1734 v4l2_async_unregister_subdev(subdev);
1735 media_entity_cleanup(&subdev->entity);
1736 xvip_cleanup_resources(&xscaler->xvip);
1737
1738 return 0;
1739}
1740
1741static const struct of_device_id xscaler_of_id_table[] = {
1742 { .compatible = "xlnx,v-vpss-scaler" },
1743 { }
1744};
1745MODULE_DEVICE_TABLE(of, xscaler_of_id_table);
1746
1747static struct platform_driver xscaler_driver = {
1748 .driver = {
1749 .name = "xilinx-vpss-scaler",
1750 .of_match_table = xscaler_of_id_table,
1751 },
1752 .probe = xscaler_probe,
1753 .remove = xscaler_remove,
1754};
1755
1756module_platform_driver(xscaler_driver);
1757MODULE_DESCRIPTION("Xilinx Scaler VPSS Driver");
1758MODULE_LICENSE("GPL v2");
1759