]> rtime.felk.cvut.cz Git - zynq/linux.git/blob - drivers/gpu/drm/xlnx/xlnx_scaler.c
8460b169129243bafc62c2fdac18d4ceaef044e1
[zynq/linux.git] / drivers / gpu / drm / xlnx / xlnx_scaler.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * VPSS SCALER DRM bridge driver
4  *
5  * Copyright (C) 2017-2018 Xilinx, Inc.
6  *
7  * Author: Venkateshwar rao G <vgannava@xilinx.com>
8  *         Rohit Athavale <rathavale@xilinx.com>
9  */
10
11 /*
12  * Overview:
13  * This experimentatl driver works as a bridge driver and
14  * reused the code from V4L2.
15  * TODO:
16  * Need to implement in a modular approach to share driver code between
17  * V4L2 and DRM frameworks.
18  * Should be integrated with plane.
19  */
20
21 #include <linux/device.h>
22 #include <linux/err.h>
23 #include <linux/gpio/consumer.h>
24 #include <linux/io.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>
29
30 #include "xlnx_bridge.h"
31
32 #define XSCALER_MAX_WIDTH               (3840)
33 #define XSCALER_MAX_HEIGHT              (2160)
34 #define XSCALER_MAX_PHASES              (64)
35
36 /* Video subsytems block offset */
37 #define S_AXIS_RESET_OFF                (0x00010000)
38 #define V_HSCALER_OFF                   (0x00000000)
39 #define V_VSCALER_OFF                   (0x00020000)
40
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)
50
51 #define XGPIO_ISR_OFFSET                (0x120)
52 #define XGPIO_IER_OFFSET                (0x128)
53 #define XGPIO_CHAN_OFFSET               (8)
54 #define STEP_PRECISION                  (65536)
55
56 /* SCALER POWER MACROS */
57 #define XSCALER_RESET_ASSERT            (0x1)
58 #define XSCALER_RESET_DEASSERT          (0x0)
59
60 /* Video IP PPC */
61 #define XSCALER_PPC_1                   (1)
62 #define XSCALER_PPC_2                   (2)
63
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)
69
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)
82
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)
91
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)
95
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)
100
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)
114
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)
121
122 /* H-scaler masks */
123 #define XV_HSCALER_PHASESH_V_OUTPUT_WR_EN               BIT(8)
124
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)
137
138 /* H-scaler coefficients for 6, 8, 10 and 12 tap filters */
139 static const u16
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, }
205 };
206
207 static const u16
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, },
273 };
274
275 static const u16
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, },
341 };
342
343 static const u16
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, },
409 };
410
411 /* V-scaler coefficients for 6, 8, 10 and 12 tap filters */
412 static const u16
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, }
478 };
479
480 static const u16
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, },
546 };
547
548 static const u16
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, },
614 };
615
616 static const u16
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, },
682 };
683
684 enum xilinx_scaler_vid_reg_fmts {
685         XVIDC_CSF_RGB = 0,
686         XVIDC_CSF_YCRCB_444,
687         XVIDC_CSF_YCRCB_422,
688         XVIDC_CSF_YCRCB_420,
689 };
690
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,
696 };
697
698 /**
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
720  */
721 struct xilinx_scaler {
722         void __iomem *base;
723         struct device *dev;
724         struct xlnx_bridge bridge;
725         u32 width_in;
726         u32 height_in;
727         u32 width_out;
728         u32 height_out;
729         u32 fmt_in;
730         u32 fmt_out;
731         u32 num_hori_taps;
732         u32 num_vert_taps;
733         u32 max_num_phases;
734         u32 pix_per_clk;
735         u32 max_pixels;
736         u32 max_lines;
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];
740         bool is_polyphase;
741         struct gpio_desc *rst_gpio;
742 };
743
744 static inline void xilinx_scaler_write(void __iomem *base, u32 offset, u32 val)
745 {
746         writel(val, base + offset);
747 }
748
749 static inline u32 xilinx_scaler_read(void __iomem *base, u32 offset)
750 {
751         return readl(base + offset);
752 }
753
754 static inline void xilinx_scaler_clr(void __iomem *base, u32 offset, u32 clr)
755 {
756         xilinx_scaler_write(base, offset,
757                             xilinx_scaler_read(base, offset) & ~clr);
758 }
759
760 static inline void xilinx_scaler_set(void __iomem *base, u32 offset, u32 set)
761 {
762         xilinx_scaler_write(base, offset,
763                             xilinx_scaler_read(base, offset) | set);
764 }
765
766 static inline void
767 xilinx_scaler_disable_block(struct xilinx_scaler *scaler, u32 channel,
768                             u32 ip_block)
769 {
770         xilinx_scaler_clr(scaler->base, ((channel - 1) * XGPIO_CHAN_OFFSET) +
771                           XGPIO_DATA_OFFSET + S_AXIS_RESET_OFF, ip_block);
772 }
773
774 static inline void
775 xilinx_scaler_enable_block(struct xilinx_scaler *scaler, u32 channel,
776                            u32 ip_block)
777 {
778         xilinx_scaler_set(scaler->base, ((channel - 1) * XGPIO_CHAN_OFFSET) +
779                           XGPIO_DATA_OFFSET + S_AXIS_RESET_OFF, ip_block);
780 }
781
782 /**
783  * bridge_to_layer - Gets the parent structure
784  * @bridge: pointer to the member.
785  *
786  * Return: parent structure pointer
787  */
788 static inline struct xilinx_scaler *bridge_to_layer(struct xlnx_bridge *bridge)
789 {
790         return container_of(bridge, struct xilinx_scaler, bridge);
791 }
792
793 /**
794  * xilinx_scaler_reset - Resets scaler block
795  * @scaler: Pointer to scaler device structure
796  *
797  * This function resets scaler block
798  */
799 static void xilinx_scaler_reset(struct xilinx_scaler *scaler)
800 {
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);
805 }
806
807 /**
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
813  */
814 static void
815 xv_hscaler_calculate_phases(struct xilinx_scaler *scaler,
816                             u32 width_in, u32 width_out, u32 pixel_rate)
817 {
818         unsigned int loop_width;
819         unsigned int x, s;
820         int offset = 0;
821         int xwrite_pos = 0;
822         bool output_write_en;
823         bool get_new_pix;
824         u64 phaseH;
825         u32 array_idx = 0;
826         int nr_rds;
827         int nr_rds_clck;
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);
831
832         loop_width = max_t(u32, width_in, width_out);
833         loop_width = ALIGN(loop_width + nppc - 1, nppc);
834
835         for (x = 0; x < loop_width; x++) {
836                 nr_rds_clck = 0;
837                 for (s = 0; s < nppc; s++) {
838                         phaseH = (offset >> shift) & (nphases - 1);
839                         get_new_pix = false;
840                         output_write_en = false;
841                         if ((offset >> XHSC_STEP_PRECISION_SHIFT) != 0) {
842                                 get_new_pix = true;
843                                 offset -= (1 << XHSC_STEP_PRECISION_SHIFT);
844                                 array_idx++;
845                         }
846
847                         if (((offset >> XHSC_STEP_PRECISION_SHIFT) == 0) &&
848                             xwrite_pos < width_out) {
849                                 offset += pixel_rate;
850                                 output_write_en = true;
851                                 xwrite_pos++;
852                         }
853
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));
863                         }
864
865                         if (get_new_pix)
866                                 nr_rds_clck++;
867                 }
868                 if (array_idx >= nppc)
869                         array_idx &= (nppc - 1);
870
871                 nr_rds += nr_rds_clck;
872                 if (nr_rds >= nppc)
873                         nr_rds -= nppc;
874         }
875 }
876
877 /**
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
882  *
883  * This function loads h-scaler coefficients.
884  */
885 static void
886 xv_hscaler_load_ext_coeff(struct xilinx_scaler *scaler,
887                           const short *coeff, u32 ntaps)
888 {
889         unsigned int i, j, pad, offset;
890         u32 nphases = scaler->max_num_phases;
891
892         /* Determine if coefficient needs padding (effective vs. max taps) */
893         pad = XV_HSCALER_MAX_H_TAPS - ntaps;
894         offset = pad >> 1;
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];
900         }
901
902         if (pad) {
903                 for (i = 0; i < nphases; i++) {
904                         for (j = 0; j < offset; j++)
905                                 scaler->hscaler_coeff[i][j] = 0;
906                         j = ntaps + offset;
907                         for (; j < XV_HSCALER_MAX_H_TAPS; j++)
908                                 scaler->hscaler_coeff[i][j] = 0;
909                 }
910         }
911 }
912
913 /**
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
918  *
919  * There are instances when a N-tap filter might operate in an M-tap
920  * configuration where N > M.
921  *
922  * For example :
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
925  * coefficients.
926  *
927  * While upscaling the driver will program 6-tap filter coefficients
928  * in any N-tap configurations (for N >= 6).
929  *
930  * This selection is adopted by the as it gives optimal
931  * video output determined by repeated testing of the IP
932  *
933  * Return: Will return 0 if successful. Returns -EINVAL on an unsupported
934  * H-scaler number of taps.
935  */
936 static int
937 xv_hscaler_select_coeff(struct xilinx_scaler *scaler,
938                         u32 width_in, u32 width_out)
939 {
940         const short *coeff;
941         u16 hscale_ratio;
942         u32 ntaps = scaler->num_hori_taps;
943
944         /*
945          * Scale Down Mode will use dynamic filter selection logic
946          * Scale Up Mode (including 1:1) will always use 6 tap filter
947          */
948         if (width_out < width_in) {
949                 hscale_ratio = ((width_in * 10) / width_out);
950
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;
955                         break;
956                 case XV_HSCALER_TAPS_8:
957                         if (hscale_ratio > 15) {
958                                 coeff = &xhsc_coeff_taps8[0][0];
959                                 ntaps = XV_HSCALER_TAPS_8;
960                         } else {
961                                 coeff = &xhsc_coeff_taps6[0][0];
962                                 ntaps = XV_HSCALER_TAPS_6;
963                         }
964                         break;
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;
972                         } else {
973                                 coeff = &xhsc_coeff_taps6[0][0];
974                                 ntaps = XV_HSCALER_TAPS_6;
975                         }
976                         break;
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;
987                         } else {
988                                 coeff = &xhsc_coeff_taps6[0][0];
989                                 ntaps = XV_HSCALER_TAPS_6;
990                         }
991                         break;
992                 default:
993                         dev_info(scaler->dev, "Unsupported H-scaler number of taps\n");
994                         return -EINVAL;
995                 }
996         } else {
997                 coeff = &xhsc_coeff_taps6[0][0];
998                 ntaps = XV_HSCALER_TAPS_6;
999         }
1000         xv_hscaler_load_ext_coeff(scaler, coeff, ntaps);
1001         return 0;
1002 }
1003
1004 /**
1005  * xv_hscaler_set_coeff - Sets h-scaler coefficients
1006  * @scaler: Pointer to scaler device structure
1007  *
1008  * This function sets coefficients of h-scaler.
1009  */
1010 static void xv_hscaler_set_coeff(struct xilinx_scaler *scaler)
1011 {
1012         int val, i, j, offset, rd_indx;
1013         u32 ntaps = scaler->num_hori_taps;
1014         u32 nphases = scaler->max_num_phases;
1015         u32 base_addr;
1016
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);
1028                 }
1029         }
1030 }
1031
1032 /**
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
1037  *
1038  * This function loads v-scaler coefficients.
1039  */
1040 static void
1041 xv_vscaler_load_ext_coeff(struct xilinx_scaler *scaler,
1042                           const short *coeff, u32 ntaps)
1043 {
1044         int i, j, pad, offset;
1045         u32 nphases = scaler->max_num_phases;
1046
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];
1055         }
1056         if (pad) {
1057                 /* effective taps < max_taps */
1058                 for (i = 0; i < nphases; i++) {
1059                         /* pad left */
1060                         for (j = 0; j < offset; j++)
1061                                 scaler->vscaler_coeff[i][j] = 0;
1062                 }
1063                 /* pad right */
1064                 for (j = (ntaps + offset); j < XV_VSCALER_MAX_V_TAPS; j++)
1065                         scaler->vscaler_coeff[i][j] = 0;
1066         }
1067 }
1068
1069 /**
1070  * xv_vscaler_set_coeff - Sets v-scaler coefficients
1071  * @scaler: Pointer to scaler device structure
1072  *
1073  * This function sets coefficients of v-scaler.
1074  */
1075 static void xv_vscaler_set_coeff(struct xilinx_scaler *scaler)
1076 {
1077         u32 nphases = scaler->max_num_phases;
1078         u32 ntaps = scaler->num_vert_taps;
1079         int val, i, j, offset, rd_indx;
1080         u32 base_addr;
1081
1082         offset = (XV_VSCALER_MAX_V_TAPS - ntaps) / 2;
1083         base_addr = V_VSCALER_OFF + XV_VSCALER_CTRL_ADDR_HWREG_VFLTCOEFF_BASE;
1084
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);
1094                 }
1095         }
1096 }
1097
1098 /**
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
1103  *
1104  * There are instances when a N-tap filter might operate in an M-tap
1105  * configuration where N > M.
1106  *
1107  * For example :
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
1110  * coefficients.
1111  *
1112  * While upscaling the driver will program 6-tap filter coefficients
1113  * in any N-tap configurations (for N >= 6).
1114  *
1115  * This selection is adopted by the as it gives optimal
1116  * video output determined by repeated testing of the IP
1117  *
1118  * Return: Will return 0 if successful. Returns -EINVAL on an unsupported
1119  * V-scaler number of taps.
1120  */
1121 static int
1122 xv_vscaler_select_coeff(struct xilinx_scaler *scaler,
1123                         u32 height_in, u32 height_out)
1124 {
1125         const short *coeff;
1126         u16 vscale_ratio;
1127         u32 ntaps = scaler->num_vert_taps;
1128
1129         /*
1130          * Scale Down Mode will use dynamic filter selection logic
1131          * Scale Up Mode (including 1:1) will always use 6 tap filter
1132          */
1133
1134         if (height_out < height_in) {
1135                 vscale_ratio = ((height_in * 10) / height_out);
1136
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;
1141                         break;
1142                 case XV_VSCALER_TAPS_8:
1143                         if (vscale_ratio > 15) {
1144                                 coeff = &xvsc_coeff_taps8[0][0];
1145                                 ntaps = XV_VSCALER_TAPS_8;
1146                         } else {
1147                                 coeff = &xvsc_coeff_taps6[0][0];
1148                                 ntaps = XV_VSCALER_TAPS_6;
1149                         }
1150                         break;
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;
1158                         } else {
1159                                 coeff = &xvsc_coeff_taps6[0][0];
1160                                 ntaps = XV_VSCALER_TAPS_6;
1161                         }
1162                         break;
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;
1173                         } else {
1174                                 coeff = &xvsc_coeff_taps6[0][0];
1175                                 ntaps = XV_VSCALER_TAPS_6;
1176                         }
1177                         break;
1178                 default:
1179                         return -EINVAL;
1180                 }
1181         } else {
1182                 coeff = &xvsc_coeff_taps6[0][0];
1183                 ntaps = XV_VSCALER_TAPS_6;
1184         }
1185
1186         xv_vscaler_load_ext_coeff(scaler, coeff, ntaps);
1187         return 0;
1188 }
1189
1190 /**
1191  * xv_hscaler_set_phases - Sets phases of h-scaler
1192  * @scaler: Pointer to scaler device structure
1193  *
1194  * This function sets phases of h-scaler.
1195  */
1196 static void
1197 xv_hscaler_set_phases(struct xilinx_scaler *scaler)
1198 {
1199         u32 loop_width;
1200         u32 index, val;
1201         u32 offset, i, lsb, msb;
1202
1203         loop_width = scaler->max_pixels / scaler->pix_per_clk;
1204         offset = V_HSCALER_OFF + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE;
1205
1206         switch (scaler->pix_per_clk) {
1207         case XSCALER_PPC_1:
1208                 index = 0;
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 +
1214                                 (index * 4), val);
1215                         ++index;
1216                 }
1217                 return;
1218         case XSCALER_PPC_2:
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 +
1222                                 (i * 4), val);
1223                 }
1224                 return;
1225         }
1226 }
1227
1228 /**
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
1232  *
1233  * This function set the given format of v-scaler
1234  *
1235  * Return: format value on success. -EINVAL for invalid format.
1236  *
1237  */
1238 static int
1239 xv_vscaler_setup_video_fmt(struct xilinx_scaler *scaler, u32 code_in)
1240 {
1241         u32 video_in;
1242
1243         switch (code_in) {
1244         case MEDIA_BUS_FMT_UYVY8_1X16:
1245                 video_in = XVIDC_CSF_YCRCB_422;
1246                 break;
1247         case MEDIA_BUS_FMT_VUY8_1X24:
1248                 video_in = XVIDC_CSF_YCRCB_444;
1249                 break;
1250         case MEDIA_BUS_FMT_RGB888_1X24:
1251                 video_in = XVIDC_CSF_RGB;
1252                 break;
1253         case MEDIA_BUS_FMT_VYYUYY8_1X24:
1254                 video_in = XVIDC_CSF_YCRCB_420;
1255                 break;
1256         default:
1257                 dev_info(scaler->dev, "Vscaler Unsupported media fmt\n");
1258                 return -EINVAL;
1259         }
1260         xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1261                             XV_VSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA,
1262                             video_in);
1263         return video_in;
1264 }
1265
1266 /**
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
1271  *
1272  * This function set the given video format of h-scaler
1273  *
1274  * Return: format value on success. -EINVAL for invalid format.
1275  *
1276  */
1277 static int xv_hscaler_setup_video_fmt(struct xilinx_scaler *scaler,
1278                                       u32 code_out, u32 vsc_out)
1279 {
1280         u32 video_out;
1281
1282         switch (vsc_out) {
1283         case XVIDC_CSF_YCRCB_422:
1284                 break;
1285         case XVIDC_CSF_YCRCB_444:
1286                 break;
1287         case XVIDC_CSF_RGB:
1288                 break;
1289         case XVIDC_CSF_YCRCB_420:
1290                 break;
1291         default:
1292                 dev_info(scaler->dev, "unsupported format from Vscaler");
1293                 return -EINVAL;
1294         }
1295
1296         xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1297                 XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA,
1298                 vsc_out);
1299
1300         switch (code_out) {
1301         case MEDIA_BUS_FMT_UYVY8_1X16:
1302                 video_out = XVIDC_CSF_YCRCB_422;
1303                 break;
1304         case MEDIA_BUS_FMT_VUY8_1X24:
1305                 video_out = XVIDC_CSF_YCRCB_444;
1306                 break;
1307         case MEDIA_BUS_FMT_RGB888_1X24:
1308                 video_out = XVIDC_CSF_RGB;
1309                 break;
1310         case MEDIA_BUS_FMT_VYYUYY8_1X24:
1311                 video_out = XVIDC_CSF_YCRCB_420;
1312                 break;
1313         default:
1314                 dev_info(scaler->dev, "Hscaler Unsupported Out media fmt\n");
1315                 return -EINVAL;
1316         }
1317         xilinx_scaler_write(scaler->base, V_HSCALER_OFF +
1318                             XV_HSCALER_CTRL_ADDR_HWREG_COLORMODEOUT_DATA,
1319                             video_out);
1320         return 0;
1321 }
1322
1323 /**
1324  * xilinx_scaler_parse_of - Parse device tree information
1325  * @scaler: Pointer to scaler device structure
1326  *
1327  * This function reads the device tree contents
1328  *
1329  * Return: 0 on success. -EINVAL for invalid value.
1330  *
1331  */
1332 static int xilinx_scaler_parse_of(struct xilinx_scaler *scaler)
1333 {
1334         int ret;
1335         u32 dt_ppc;
1336         struct device_node *node = scaler->dev->of_node;
1337
1338         ret = of_property_read_u32(node, "xlnx,h-scaler-taps",
1339                                    &scaler->num_hori_taps);
1340         if (ret < 0) {
1341                 dev_info(scaler->dev, "h-scaler-taps not present in DT\n");
1342                 return ret;
1343         }
1344         switch (scaler->num_hori_taps) {
1345         case XV_HSCALER_TAPS_2:
1346         case XV_HSCALER_TAPS_4:
1347                 scaler->is_polyphase = false;
1348                 break;
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;
1354                 break;
1355         default:
1356                 return -EINVAL;
1357         }
1358
1359         ret = of_property_read_u32(node, "xlnx,v-scaler-taps",
1360                                    &scaler->num_vert_taps);
1361         if (ret < 0) {
1362                 dev_info(scaler->dev, "v-scaler-taps not present in DT\n");
1363                 return ret;
1364         }
1365
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)
1370                         return -EINVAL;
1371                 break;
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;
1377                 break;
1378         default:
1379                 return -EINVAL;
1380         }
1381
1382         ret = of_property_read_u32(node, "xlnx,samples-per-clk", &dt_ppc);
1383         if (ret < 0) {
1384                 dev_info(scaler->dev, "PPC is missing in DT\n");
1385                 return ret;
1386         }
1387         if (dt_ppc != XSCALER_PPC_1 && dt_ppc != XSCALER_PPC_2) {
1388                 dev_info(scaler->dev, "Unsupported ppc: %d", dt_ppc);
1389                 return -EINVAL;
1390         }
1391         scaler->pix_per_clk = dt_ppc;
1392
1393         /* Reset GPIO */
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);
1399         }
1400
1401         return 0;
1402 }
1403
1404 /**
1405  * xilinx_scaler_stream - Set up v-scaler and h-scaler for streaming
1406  * @scaler: Pointer to scaler device structure
1407  *
1408  * This function sets up the required configuration of v-scaler and h-scaler
1409  *
1410  * Return: 0 on success. Returns -EINVAL on failure conditions.
1411  */
1412 static int xilinx_scaler_stream(struct xilinx_scaler *scaler)
1413 {
1414         u32 fmt_in, fmt_out;
1415         u32 pixel_rate;
1416         u32 line_rate;
1417         int ret;
1418
1419         fmt_in = scaler->fmt_in;
1420         fmt_out = scaler->fmt_out;
1421         line_rate = (scaler->height_in * STEP_PRECISION) / scaler->height_out;
1422
1423         if (scaler->is_polyphase) {
1424                 ret = xv_vscaler_select_coeff(scaler, scaler->height_in,
1425                                               scaler->height_out);
1426                 if (ret < 0) {
1427                         dev_info(scaler->dev, "Failed: vscaler select coeff\n");
1428                         return ret;
1429                 }
1430                 xv_vscaler_set_coeff(scaler);
1431         }
1432         xilinx_scaler_write(scaler->base, V_VSCALER_OFF +
1433                             XV_VSCALER_CTRL_ADDR_HWREG_LINERATE_DATA,
1434                             line_rate);
1435         ret = xv_vscaler_setup_video_fmt(scaler, scaler->fmt_in);
1436         if (ret < 0) {
1437                 dev_info(scaler->dev, "Failed: vscaler setup video format\n");
1438                 return ret;
1439         }
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,
1443                             pixel_rate);
1444         ret = xv_hscaler_setup_video_fmt(scaler, scaler->fmt_out, ret);
1445         if (ret < 0) {
1446                 dev_info(scaler->dev, "Failed: vscaler setup video format\n");
1447                 return ret;
1448         }
1449         if (scaler->is_polyphase) {
1450                 ret = xv_hscaler_select_coeff(scaler, scaler->width_in,
1451                                               scaler->width_out);
1452                 if (ret < 0) {
1453                         dev_info(scaler->dev, "Failed: hscaler select coeff\n");
1454                         return ret;
1455                 }
1456                 xv_hscaler_set_coeff(scaler);
1457         }
1458         xv_hscaler_calculate_phases(scaler, scaler->width_in,
1459                                     scaler->width_out, pixel_rate);
1460         xv_hscaler_set_phases(scaler);
1461         return 0;
1462 }
1463
1464 /**
1465  * xilinx_scaler_bridge_enable - enabes scaler sub-cores
1466  * @bridge: bridge instance
1467  *
1468  * This function enables the scaler sub-cores
1469  *
1470  * Return: 0 on success. Return -EINVAL on failure conditions.
1471  *
1472  */
1473 static int xilinx_scaler_bridge_enable(struct xlnx_bridge *bridge)
1474 {
1475         int ret;
1476         struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1477
1478         ret = xilinx_scaler_stream(scaler);
1479         if (ret)
1480                 return ret;
1481
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);
1488         return ret;
1489 }
1490
1491 /**
1492  * xilinx_scaler_bridge_disable - disables scaler sub-cores
1493  * @bridge: bridge instance
1494  *
1495  * This function disables the scaler sub-cores
1496  */
1497 static void xilinx_scaler_bridge_disable(struct xlnx_bridge *bridge)
1498 {
1499         struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1500
1501         xilinx_scaler_disable_block(scaler, XGPIO_CH_RESET_SEL,
1502                                     XGPIO_RESET_MASK_ALL_BLOCKS);
1503 }
1504
1505 /**
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
1511  *
1512  * This function sets the input parameters of scaler
1513  * Return: 0 on success. -EINVAL for invalid parameters.
1514  */
1515 static int xilinx_scaler_bridge_set_input(struct xlnx_bridge *bridge,
1516                                           u32 width, u32 height, u32 bus_fmt)
1517 {
1518         struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1519
1520         if (width > scaler->max_pixels || height > scaler->max_lines)
1521                 return -EINVAL;
1522
1523         scaler->height_in = height;
1524         scaler->width_in = width;
1525         scaler->fmt_in = bus_fmt;
1526
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));
1532
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);
1539
1540         return 0;
1541 }
1542
1543 /**
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
1548  *
1549  * This function provides the input video formats information scaler
1550  * Return: 0 on success.
1551  */
1552 static int xilinx_scaler_bridge_get_input_fmts(struct xlnx_bridge *bridge,
1553                                                const u32 **fmts, u32 *count)
1554 {
1555         *fmts = xilinx_scaler_video_fmts;
1556         *count = ARRAY_SIZE(xilinx_scaler_video_fmts);
1557         return 0;
1558 }
1559
1560 /**
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
1566  *
1567  * This function sets the output parameters of scaler
1568  * Return: 0 on success. -EINVAL for invalid parameters.
1569  */
1570 static int xilinx_scaler_bridge_set_output(struct xlnx_bridge *bridge,
1571                                            u32 width, u32 height, u32 bus_fmt)
1572 {
1573         struct xilinx_scaler *scaler = bridge_to_layer(bridge);
1574
1575         if (width > scaler->max_pixels || height > scaler->max_lines)
1576                 return -EINVAL;
1577
1578         scaler->height_out = height;
1579         scaler->width_out = width;
1580         scaler->fmt_out = bus_fmt;
1581
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);
1588         return 0;
1589 }
1590
1591 /**
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
1596  *
1597  * This function provides the output video formats information scaler
1598  * Return: 0 on success.
1599  */
1600 static int xilinx_scaler_bridge_get_output_fmts(struct xlnx_bridge *bridge,
1601                                                 const u32 **fmts, u32 *count)
1602 {
1603         *fmts = xilinx_scaler_video_fmts;
1604         *count = ARRAY_SIZE(xilinx_scaler_video_fmts);
1605         return 0;
1606 }
1607
1608 static int xilinx_scaler_probe(struct platform_device *pdev)
1609 {
1610         struct device *dev = &pdev->dev;
1611         struct resource *res;
1612         struct xilinx_scaler *scaler;
1613         int ret;
1614
1615         scaler = devm_kzalloc(dev, sizeof(*scaler), GFP_KERNEL);
1616         if (!scaler)
1617                 return -ENOMEM;
1618         scaler->dev = dev;
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");
1623                 return -ENOMEM;
1624         }
1625         platform_set_drvdata(pdev, scaler);
1626
1627         ret = xilinx_scaler_parse_of(scaler);
1628         if (ret < 0) {
1629                 dev_info(scaler->dev, "parse_of failed\n");
1630                 return ret;
1631         }
1632         scaler->max_num_phases = XSCALER_MAX_PHASES;
1633         scaler->max_lines = XSCALER_MAX_HEIGHT;
1634         scaler->max_pixels = XSCALER_MAX_WIDTH;
1635
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);
1639
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;
1647
1648         ret = xlnx_bridge_register(&scaler->bridge);
1649         if (ret) {
1650                 dev_info(scaler->dev, "Bridge registration failed\n");
1651                 return ret;
1652         }
1653         dev_info(scaler->dev, "xlnx drm scaler experimental driver probed\n");
1654
1655         return 0;
1656 }
1657
1658 static int xilinx_scaler_remove(struct platform_device *pdev)
1659 {
1660         struct xilinx_scaler *scaler = platform_get_drvdata(pdev);
1661
1662         xlnx_bridge_unregister(&scaler->bridge);
1663         return 0;
1664 }
1665
1666 static const struct of_device_id xilinx_scaler_of_match[] = {
1667         { .compatible = "xlnx,vpss-scaler"},
1668         { }
1669 };
1670 MODULE_DEVICE_TABLE(of, xilinx_scaler_of_match);
1671
1672 static struct platform_driver scaler_bridge_driver = {
1673         .probe = xilinx_scaler_probe,
1674         .remove = xilinx_scaler_remove,
1675         .driver = {
1676                 .name = "xlnx,scaler-bridge",
1677                 .of_match_table = xilinx_scaler_of_match,
1678         },
1679 };
1680
1681 module_platform_driver(scaler_bridge_driver);
1682
1683 MODULE_AUTHOR("Venkateshwar Rao <vgannava@xilinx.com>");
1684 MODULE_DESCRIPTION("Xilinx FPGA SCALER Bridge Driver");
1685 MODULE_LICENSE("GPL v2");