linux/drivers/media/platform/xilinx/xilinx-vpss-scaler.c
<<
>>
Prefs
   1/*
   2 * Xilinx VPSS Scaler
   3 *
   4 * Copyright (C) 2017 Xilinx, Inc.
   5 *
   6 * This software is licensed under the terms of the GNU General Public
   7 * License version 2, as published by the Free Software Foundation, and
   8 * may be copied, distributed, and modified under those terms.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  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/* Modify to defaults incase it is not configured from application */
  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/* Video subsytems block offset */
  56#define S_AXIS_RESET_OFF        (0x00010000)
  57#define V_HSCALER_OFF           (0x00000000)
  58#define V_VSCALER_OFF           (0x00020000)
  59
  60/* HW Reset Network GPIO Channel */
  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/* Video IP Formats */
  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/* Video IP PPC */
  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/* Mask definitions for Low and high 16 bits in a 32 bit number */
 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/* Mask definitions for Low and high 16 bits in a 32 bit number */
 118#define XVSC_MASK_LOW_16BITS            GENMASK(15, 0)
 119#define XVSC_MASK_HIGH_16BITS           GENMASK(31, 16)
 120
 121/* XSCALER POWER MACROS */
 122#define XSCALER_RESET_ASSERT    (0x1)
 123#define XSCALER_RESET_DEASSERT  (0x0)
 124
 125/* Scaler AP Control Registers */
 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/* H-scaler registers */
 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/* H-scaler coefficients for 6, 8, 10 and 12 tap filters */
 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/* H-scaler masks */
 425#define XV_HSCALER_PHASESH_V_OUTPUT_WR_EN                       BIT(8)
 426
 427/* V-scaler registers */
 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/* V-scaler coefficients for 6, 8, 10 and 12 tap filters */
 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 * struct xscaler_device - Xilinx Scaler device structure
 718 * @xvip: Xilinx Video IP device
 719 * @pads: Scaler sub-device media pads
 720 * @formats: V4L2 media bus formats at the sink and source pads
 721 * @default_formats: default V4L2 media bus formats
 722 * @vip_formats: Xilinx Video IP format retrieved from the DT
 723 * @num_hori_taps: number of horizontal taps
 724 * @num_vert_taps: number of vertical taps
 725 * @max_num_phases: maximum number of phases
 726 * @pix_per_clk: Pixels per Clock cycle the IP operates upon
 727 * @max_pixels: The maximum number of pixels that the H-scaler examines
 728 * @max_lines: The maximum number of lines that the V-scaler examines
 729 * @H_phases: The phases needed to program the H-scaler for different taps
 730 * @hscaler_coeff: The complete array of H-scaler coefficients
 731 * @vscaler_coeff: The complete array of V-scaler coefficients
 732 * @is_polyphase: Track if scaling algorithm is polyphase or not
 733 * @rst_gpio: GPIO reset line to bring VPSS Scaler out of reset
 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                                /* read a new input sample */
 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                                /* produce a new output sample */
 799                                offset += pixel_rate;
 800                                output_write_en = true;
 801                                xwrite_pos++;
 802                        }
 803
 804                        /* Needs updates for 4 PPC */
 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        /* Determine if coefficient needs padding (effective vs. max taps) */
 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        /* Load coefficients into scaler coefficient table */
 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) { /* effective taps < max_taps */
 850                for (i = 0; i < nphases; i++) {
 851                        /* pad left */
 852                        for (j = 0; j < offset; j++)
 853                                xscaler->hscaler_coeff[i][j] = 0;
 854                        /* pad right */
 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 * xv_hscaler_coeff_select - Selection of H-Scaler coefficients of operation
 864 * @xscaler: VPSS Scaler device information
 865 * @width_in: Width of input video
 866 * @width_out: Width of desired output video
 867 *
 868 * There are instances when a N-tap filter might operate in an M-tap
 869 * configuration where N > M.
 870 *
 871 * For example :
 872 * Depending on the ratio of scaling (while downscaling), a 12-tap
 873 * filter may operate with 10 tap coefficients and zero-pads the remaining
 874 * coefficients.
 875 *
 876 * While upscaling the driver will program 6-tap filter coefficients
 877 * in any N-tap configurations (for N >= 6).
 878 *
 879 * This selection is adopted by the as it gives optimal
 880 * video output determined by repeated testing of the IP
 881 *
 882 * Return: Will return 0 if successful. Returns -EINVAL on an unsupported
 883 * H-scaler number of taps.
 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         * Scale Down Mode will use dynamic filter selection logic
 895         * Scale Up Mode (including 1:1) will always use 6 tap filter
 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        /* Determine if coefficient needs padding (effective vs. max taps) */
 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        /* Load User defined coefficients into scaler coefficient table */
 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) { /* effective taps < max_taps */
1001                for (i = 0; i < nphases; i++) {
1002                        /* pad left */
1003                        for (j = 0; j < offset; j++)
1004                                xscaler->vscaler_coeff[i][j] = 0;
1005                }
1006                /* pad right */
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 * xv_vscaler_coeff_select - Selection of V-Scaler coefficients of operation
1037 * @xscaler: VPSS Scaler device information
1038 * @height_in: Height of input video
1039 * @height_out: Height of desired output video
1040 *
1041 * There are instances when a N-tap filter might operate in an M-tap
1042 * configuration where N > M.
1043 *
1044 * For example :
1045 * Depending on the ratio of scaling (while downscaling), a 10-tap
1046 * filter may operate with 6 tap coefficients and zero-pads the remaining
1047 * coefficients.
1048 *
1049 * While upscaling the driver will program 6-tap filter coefficients
1050 * in any N-tap configurations (for N >= 6).
1051 *
1052 * This selection is adopted by the as it gives optimal
1053 * video output determined by repeated testing of the IP
1054 *
1055 * Return: Will return 0 if successful. Returns -EINVAL on an unsupported
1056 * V-scaler number of taps.
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         * Scale Down Mode will use dynamic filter selection logic
1068         * Scale Up Mode (including 1:1) will always use 6 tap filter
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 * V4L2 Subdevice Video Operations
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         * Vscaler will upscale to YUV 422 before
1196         * Hscaler starts operation
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                 * phaseH is 64 bits but only lower 16 bits of each entry
1278                 * is valid .Form a 32 bit word with 16bit LSB from 2
1279                 * consecutive entries. Need 1 32b write to get 2 entries
1280                 * into IP registers (i is array loc and index is
1281                 * address offset)
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                 * PhaseH is 64bits but only lower 32b of each entry is valid
1297                 * Need 1 32b write to get each entry into IP registers
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                /* Reset the Global IP Reset through PS GPIO */
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        /* Extract Sink Pad Information */
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        /* Extract Source Pad Information */
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         * V Scaler is before H Scaler
1346         * V-Scaler_setup
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        /* H-Scaler_setup */
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        /* Start Scaler sub-cores */
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 * V4L2 Subdevice Pad Operations
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 * V4L2 Subdevice Operations
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        /* Initialize with default formats */
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 * Media Operations
1521 */
1522
1523static const struct media_entity_operations xscaler_media_ops = {
1524        .link_validate = v4l2_subdev_link_validate,
1525};
1526
1527/*
1528 * Platform Device Driver
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        /* Get the format description for each pad */
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         * For Bilinear and Bicubic case
1597         * number of vertical and horizontal taps must match
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        /* Driver only supports 1 PPC and 2 PPC */
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        /* Reset GPIO */
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        /* Initialize coefficient parameters */
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        /* Reset the Global IP Reset through a PS GPIO */
1672        gpiod_set_value_cansleep(xscaler->rst_gpio, XSCALER_RESET_DEASSERT);
1673        /* Reset internal GPIO within the IP */
1674        xscaler_reset(xscaler);
1675
1676        /* Initialize V4L2 subdevice and media entity */
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        /* Initialize default and active formats */
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        { /* end of table */ }
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