Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2017 Jernej Skrabec <jernej.skrabec@siol.net>
0003  *
0004  * Coefficients are taken from BSP driver, which is:
0005  * Copyright (C) 2014-2015 Allwinner
0006  *
0007  * This file is licensed under the terms of the GNU General Public
0008  * License version 2.  This program is licensed "as is" without any
0009  * warranty of any kind, whether express or implied.
0010  */
0011 
0012 #include "sun8i_ui_scaler.h"
0013 #include "sun8i_vi_scaler.h"
0014 
0015 static const u32 lan2coefftab16[240] = {
0016     0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
0017     0xff0f37fb, 0xfe1433fb, 0xfd192ffb, 0xfd1f29fb,
0018     0xfc2424fc, 0xfb291ffd, 0xfb2f19fd, 0xfb3314fe,
0019     0xfb370fff, 0xfb3b0a00, 0xfc3e0600, 0xfe3f0300,
0020 
0021     0xff053804, 0xff083801, 0xff0a3700, 0xff0e34ff,
0022     0xff1232fd, 0xfe162ffd, 0xfd1b2cfc, 0xfd1f28fc,
0023     0xfd2323fd, 0xfc281ffd, 0xfc2c1bfd, 0xfd2f16fe,
0024     0xfd3212ff, 0xff340eff, 0x00360a00, 0x02370700,
0025 
0026     0xff083207, 0xff0a3205, 0xff0d3103, 0xfe113001,
0027     0xfe142e00, 0xfe182bff, 0xfe1b29fe, 0xfe1f25fe,
0028     0xfe2222fe, 0xfe251ffe, 0xfe291bfe, 0xff2b18fe,
0029     0x002e14fe, 0x013010ff, 0x03310dff, 0x05310a00,
0030 
0031     0xff0a2e09, 0xff0c2e07, 0xff0f2d05, 0xff122c03,
0032     0xfe152b02, 0xfe182901, 0xfe1b2700, 0xff1e24ff,
0033     0xff2121ff, 0xff241eff, 0x00261bff, 0x012818ff,
0034     0x022a15ff, 0x032c12ff, 0x052d0fff, 0x072d0c00,
0035 
0036     0xff0c2a0b, 0xff0e2a09, 0xff102a07, 0xff132905,
0037     0xff162803, 0xff182702, 0xff1b2501, 0xff1e2300,
0038     0x00202000, 0x01221d00, 0x01251bff, 0x032618ff,
0039     0x042815ff, 0x052913ff, 0x072a10ff, 0x092a0d00,
0040 
0041     0xff0d280c, 0xff0f280a, 0xff112808, 0xff142706,
0042     0xff162605, 0xff192503, 0x001b2302, 0x001d2201,
0043     0x011f1f01, 0x01221d00, 0x02231b00, 0x04241800,
0044     0x052616ff, 0x072713ff, 0x08271100, 0x0a280e00,
0045 
0046     0xff0e260d, 0xff10260b, 0xff122609, 0xff142508,
0047     0x00152506, 0x00182305, 0x001b2203, 0x011d2002,
0048     0x011f1f01, 0x02201d01, 0x03221b00, 0x04231801,
0049     0x06241600, 0x08251300, 0x09261100, 0x0b260f00,
0050 
0051     0xff0e250e, 0xff10250c, 0x0011250a, 0x00142408,
0052     0x00162307, 0x00182206, 0x011a2104, 0x011c2003,
0053     0x021e1e02, 0x03201c01, 0x04211a01, 0x05221801,
0054     0x07231600, 0x08241400, 0x0a241200, 0x0c241000,
0055 
0056     0x000e240e, 0x0010240c, 0x0013230a, 0x00142309,
0057     0x00162208, 0x01182106, 0x011a2005, 0x021b1f04,
0058     0x031d1d03, 0x041e1c02, 0x05201a01, 0x06211801,
0059     0x07221601, 0x09231400, 0x0a231300, 0x0c231100,
0060 
0061     0x000f220f, 0x0011220d, 0x0013220b, 0x0015210a,
0062     0x01162108, 0x01182007, 0x02191f06, 0x031a1e05,
0063     0x041c1c04, 0x051d1b03, 0x061f1902, 0x07201801,
0064     0x08211601, 0x0a211500, 0x0b221300, 0x0d221100,
0065 
0066     0x0010210f, 0x0011210e, 0x0013210c, 0x0114200b,
0067     0x01161f0a, 0x02171f08, 0x03181e07, 0x031a1d06,
0068     0x041c1c04, 0x051d1a04, 0x071d1903, 0x081e1802,
0069     0x091f1602, 0x0b1f1501, 0x0c211300, 0x0e201200,
0070 
0071     0x00102010, 0x0012200e, 0x0013200d, 0x01151f0b,
0072     0x01161f0a, 0x02171e09, 0x03191d07, 0x041a1c06,
0073     0x051b1b05, 0x061c1a04, 0x071d1903, 0x081e1703,
0074     0x0a1f1601, 0x0b1f1501, 0x0d201300, 0x0e201200,
0075 
0076     0x00102010, 0x00121f0f, 0x00141f0d, 0x01141f0c,
0077     0x02161e0a, 0x03171d09, 0x03181d08, 0x041a1c06,
0078     0x051b1b05, 0x061c1a04, 0x081c1903, 0x091d1703,
0079     0x0a1e1602, 0x0c1e1501, 0x0d1f1400, 0x0e1f1201,
0080 
0081     0x00111e11, 0x00131e0f, 0x01131e0e, 0x02151d0c,
0082     0x02161d0b, 0x03171c0a, 0x04181b09, 0x05191b07,
0083     0x061a1a06, 0x071b1905, 0x091b1804, 0x0a1c1703,
0084     0x0b1d1602, 0x0c1d1502, 0x0e1d1401, 0x0f1e1300,
0085 
0086     0x00111e11, 0x00131d10, 0x01141d0e, 0x02151c0d,
0087     0x03161c0b, 0x04171b0a, 0x05171b09, 0x06181a08,
0088     0x07191907, 0x081a1806, 0x091a1805, 0x0a1b1704,
0089     0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
0090 };
0091 
0092 static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
0093 {
0094     int vi_num = mixer->cfg->vi_num;
0095 
0096     if (mixer->cfg->is_de3)
0097         return DE3_VI_SCALER_UNIT_BASE +
0098                DE3_VI_SCALER_UNIT_SIZE * vi_num +
0099                DE3_UI_SCALER_UNIT_SIZE * (channel - vi_num);
0100     else
0101         return DE2_VI_SCALER_UNIT_BASE +
0102                DE2_VI_SCALER_UNIT_SIZE * vi_num +
0103                DE2_UI_SCALER_UNIT_SIZE * (channel - vi_num);
0104 }
0105 
0106 static int sun8i_ui_scaler_coef_index(unsigned int step)
0107 {
0108     unsigned int scale, int_part, float_part;
0109 
0110     scale = step >> (SUN8I_UI_SCALER_SCALE_FRAC - 3);
0111     int_part = scale >> 3;
0112     float_part = scale & 0x7;
0113 
0114     switch (int_part) {
0115     case 0:
0116         return 0;
0117     case 1:
0118         return float_part;
0119     case 2:
0120         return 8 + (float_part >> 1);
0121     case 3:
0122         return 12;
0123     case 4:
0124         return 13;
0125     default:
0126         return 14;
0127     }
0128 }
0129 
0130 void sun8i_ui_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
0131 {
0132     u32 val, base;
0133 
0134     if (WARN_ON(layer < mixer->cfg->vi_num))
0135         return;
0136 
0137     base = sun8i_ui_scaler_base(mixer, layer);
0138 
0139     if (enable)
0140         val = SUN8I_SCALER_GSU_CTRL_EN |
0141               SUN8I_SCALER_GSU_CTRL_COEFF_RDY;
0142     else
0143         val = 0;
0144 
0145     regmap_write(mixer->engine.regs, SUN8I_SCALER_GSU_CTRL(base), val);
0146 }
0147 
0148 void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
0149                u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
0150                u32 hscale, u32 vscale, u32 hphase, u32 vphase)
0151 {
0152     u32 insize, outsize;
0153     int i, offset;
0154     u32 base;
0155 
0156     if (WARN_ON(layer < mixer->cfg->vi_num))
0157         return;
0158 
0159     base = sun8i_ui_scaler_base(mixer, layer);
0160 
0161     hphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
0162     vphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
0163     hscale <<= SUN8I_UI_SCALER_SCALE_FRAC - 16;
0164     vscale <<= SUN8I_UI_SCALER_SCALE_FRAC - 16;
0165 
0166     insize = SUN8I_UI_SCALER_SIZE(src_w, src_h);
0167     outsize = SUN8I_UI_SCALER_SIZE(dst_w, dst_h);
0168 
0169     regmap_write(mixer->engine.regs,
0170              SUN8I_SCALER_GSU_OUTSIZE(base), outsize);
0171     regmap_write(mixer->engine.regs,
0172              SUN8I_SCALER_GSU_INSIZE(base), insize);
0173     regmap_write(mixer->engine.regs,
0174              SUN8I_SCALER_GSU_HSTEP(base), hscale);
0175     regmap_write(mixer->engine.regs,
0176              SUN8I_SCALER_GSU_VSTEP(base), vscale);
0177     regmap_write(mixer->engine.regs,
0178              SUN8I_SCALER_GSU_HPHASE(base), hphase);
0179     regmap_write(mixer->engine.regs,
0180              SUN8I_SCALER_GSU_VPHASE(base), vphase);
0181     offset = sun8i_ui_scaler_coef_index(hscale) *
0182             SUN8I_UI_SCALER_COEFF_COUNT;
0183     for (i = 0; i < SUN8I_UI_SCALER_COEFF_COUNT; i++)
0184         regmap_write(mixer->engine.regs,
0185                  SUN8I_SCALER_GSU_HCOEFF(base, i),
0186                  lan2coefftab16[offset + i]);
0187 }