2370 lines
65 KiB
C
2370 lines
65 KiB
C
/*
|
|
* Allwinner SoCs g2d driver.
|
|
*
|
|
* Copyright (C) 2016 Allwinner.
|
|
*
|
|
* This file is licensed under the terms of the GNU General Public
|
|
* License version 2. This program is licensed "as is" without any
|
|
* warranty of any kind, whether express or implied.
|
|
*/
|
|
#include "g2d_bsp.h"
|
|
#include "g2d_regs_v2.h"
|
|
#include <linux/types.h>
|
|
#include <linux/stddef.h>
|
|
|
|
static unsigned long base_addr;
|
|
/* byte input */
|
|
#define read_bvalue(offset) get_bvalue(base_addr + offset)
|
|
/* byte output */
|
|
#define write_bvalue(offset, value) put_bvalue(base_addr + offset, value)
|
|
/* half word input */
|
|
#define read_hvalue(offset) get_hvalue(base_addr + offset)
|
|
/* half word output */
|
|
#define write_hvalue(offset, value) put_hvalue(base_addr + offset, value)
|
|
/* word input */
|
|
#define read_wvalue(offset) get_wvalue(base_addr + offset)
|
|
/* word output */
|
|
#define write_wvalue(offset, value) put_wvalue(base_addr + offset, value)
|
|
|
|
__s32 g2d_fc_set(__u32 sel, __u32 color_value);
|
|
__s32 g2d_format_trans(__s32 data_fmt, __s32 pixel_seq);
|
|
__s32 rgb2Ycbcr_709[12] = {
|
|
0x0bb, 0x0275, 0x03f, 0x4200, 0xFFFFFF99, 0xFFFFFEA6, 0x01c2, 0x20200,
|
|
0x01c2, 0xFFFFFE67, 0xFFFFFFD7, 0x20200, };
|
|
__s32 Ycbcr2rgb_709[12] = {
|
|
0x04a8, 0x0, 0x072c, 0xFFFC1F7D, 0x04a8, 0xFFFFFF26, 0xFFFFFDDD,
|
|
0x133F8, 0x04a8, 0x0876, 0, 0xFFFB7AA0, };
|
|
__s32 lan2coefftab32_full[512] = {
|
|
0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc, 0xff083dfc,
|
|
0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa, 0xfe1433fb,
|
|
0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc,
|
|
0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd, 0xfb2f19fd,
|
|
0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff, 0xfb390dff,
|
|
0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400, 0xfe3f0300,
|
|
0xff400100,
|
|
/* counter = 1 */
|
|
0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc,
|
|
0xff083dfc, 0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa,
|
|
0xfe1433fb, 0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb,
|
|
0xfc2127fc, 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
|
|
0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff,
|
|
0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400,
|
|
0xfe3f0300, 0xff400100,
|
|
/* counter = 2 */
|
|
0xff053804, 0xff063803, 0xff083801, 0xff093701, 0xff0a3700,
|
|
0xff0c3500, 0xff0e34ff, 0xff1033fe, 0xff1232fd, 0xfe1431fd,
|
|
0xfe162ffd, 0xfe182dfd, 0xfd1b2cfc, 0xfd1d2afc, 0xfd1f28fc,
|
|
0xfd2126fc, 0xfd2323fd, 0xfc2621fd, 0xfc281ffd, 0xfc2a1dfd,
|
|
0xfc2c1bfd, 0xfd2d18fe, 0xfd2f16fe, 0xfd3114fe, 0xfd3212ff,
|
|
0xfe3310ff, 0xff340eff, 0x00350cff, 0x00360a00, 0x01360900,
|
|
0x02370700, 0x03370600,
|
|
/* counter = 3 */
|
|
0xff083207, 0xff093206, 0xff0a3205, 0xff0c3203, 0xff0d3103,
|
|
0xff0e3102, 0xfe113001, 0xfe132f00, 0xfe142e00, 0xfe162dff,
|
|
0xfe182bff, 0xfe192aff, 0xfe1b29fe, 0xfe1d27fe, 0xfe1f25fe,
|
|
0xfd2124fe, 0xfe2222fe, 0xfe2421fd, 0xfe251ffe, 0xfe271dfe,
|
|
0xfe291bfe, 0xff2a19fe, 0xff2b18fe, 0xff2d16fe, 0x002e14fe,
|
|
0x002f12ff, 0x013010ff, 0x02300fff, 0x03310dff, 0x04310cff,
|
|
0x05310a00, 0x06310900,
|
|
/* counter = 4 */
|
|
0xff0a2e09, 0xff0b2e08, 0xff0c2e07, 0xff0e2d06, 0xff0f2d05,
|
|
0xff102d04, 0xff122c03, 0xfe142c02, 0xfe152b02, 0xfe172a01,
|
|
0xfe182901, 0xfe1a2800, 0xfe1b2700, 0xfe1d2500, 0xff1e24ff,
|
|
0xfe2023ff, 0xff2121ff, 0xff2320fe, 0xff241eff, 0x00251dfe,
|
|
0x00261bff, 0x00281afe, 0x012818ff, 0x012a16ff, 0x022a15ff,
|
|
0x032b13ff, 0x032c12ff, 0x052c10ff, 0x052d0fff, 0x062d0d00,
|
|
0x072d0c00, 0x082d0b00,
|
|
/* counter = 5 */
|
|
0xff0c2a0b, 0xff0d2a0a, 0xff0e2a09, 0xff0f2a08, 0xff102a07,
|
|
0xff112a06, 0xff132905, 0xff142904, 0xff162803, 0xff172703,
|
|
0xff182702, 0xff1a2601, 0xff1b2501, 0xff1c2401, 0xff1e2300,
|
|
0xff1f2200, 0x00202000, 0x00211f00, 0x01221d00, 0x01231c00,
|
|
0x01251bff, 0x02251aff, 0x032618ff, 0x032717ff, 0x042815ff,
|
|
0x052814ff, 0x052913ff, 0x06291100, 0x072a10ff, 0x082a0e00,
|
|
0x092a0d00, 0x0a2a0c00,
|
|
/* counter = 6 */
|
|
0xff0d280c, 0xff0e280b, 0xff0f280a, 0xff102809, 0xff112808,
|
|
0xff122708, 0xff142706, 0xff152705, 0xff162605, 0xff172604,
|
|
0xff192503, 0xff1a2403, 0x001b2302, 0x001c2202, 0x001d2201,
|
|
0x001e2101, 0x011f1f01, 0x01211e00, 0x01221d00, 0x02221c00,
|
|
0x02231b00, 0x03241900, 0x04241800, 0x04251700, 0x052616ff,
|
|
0x06261400, 0x072713ff, 0x08271100, 0x08271100, 0x09271000,
|
|
0x0a280e00, 0x0b280d00,
|
|
/* counter = 7 */
|
|
0xff0e260d, 0xff0f260c, 0xff10260b, 0xff11260a, 0xff122609,
|
|
0xff132608, 0xff142508, 0xff152507, 0x00152506, 0x00172405,
|
|
0x00182305, 0x00192304, 0x001b2203, 0x001c2103, 0x011d2002,
|
|
0x011d2002, 0x011f1f01, 0x021f1e01, 0x02201d01, 0x03211c00,
|
|
0x03221b00, 0x04221a00, 0x04231801, 0x05241700, 0x06241600,
|
|
0x07241500, 0x08251300, 0x09251200, 0x09261100, 0x0a261000,
|
|
0x0b260f00, 0x0c260e00,
|
|
/* counter = 8 */
|
|
0xff0e250e, 0xff0f250d, 0xff10250c, 0xff11250b, 0x0011250a,
|
|
0x00132409, 0x00142408, 0x00152407, 0x00162307, 0x00172306,
|
|
0x00182206, 0x00192205, 0x011a2104, 0x011b2004, 0x011c2003,
|
|
0x021c1f03, 0x021e1e02, 0x031e1d02, 0x03201c01, 0x04201b01,
|
|
0x04211a01, 0x05221900, 0x05221801, 0x06231700, 0x07231600,
|
|
0x07241500, 0x08241400, 0x09241300, 0x0a241200, 0x0b241100,
|
|
0x0c241000, 0x0d240f00,
|
|
/* counter = 9 */
|
|
0x000e240e, 0x000f240d, 0x0010240c, 0x0011240b, 0x0013230a,
|
|
0x0013230a, 0x00142309, 0x00152308, 0x00162208, 0x00172207,
|
|
0x01182106, 0x01192105, 0x011a2005, 0x021b1f04, 0x021b1f04,
|
|
0x021d1e03, 0x031d1d03, 0x031e1d02, 0x041e1c02, 0x041f1b02,
|
|
0x05201a01, 0x05211901, 0x06211801, 0x07221700, 0x07221601,
|
|
0x08231500, 0x09231400, 0x0a231300, 0x0a231300, 0x0b231200,
|
|
0x0c231100, 0x0d231000,
|
|
/* counter = 10 */
|
|
0x000f220f, 0x0010220e, 0x0011220d, 0x0012220c, 0x0013220b,
|
|
0x0013220b, 0x0015210a, 0x0015210a, 0x01162108, 0x01172008,
|
|
0x01182007, 0x02191f06, 0x02191f06, 0x021a1e06, 0x031a1e05,
|
|
0x031c1d04, 0x041c1c04, 0x041d1c03, 0x051d1b03, 0x051e1a03,
|
|
0x061f1902, 0x061f1902, 0x07201801, 0x08201701, 0x08211601,
|
|
0x09211501, 0x0a211500, 0x0b211400, 0x0b221300, 0x0c221200,
|
|
0x0d221100, 0x0e221000,
|
|
/* counter = 11 */
|
|
0x0010210f, 0x0011210e, 0x0011210e, 0x0012210d, 0x0013210c,
|
|
0x0014200c, 0x0114200b, 0x0115200a, 0x01161f0a, 0x01171f09,
|
|
0x02171f08, 0x02181e08, 0x03181e07, 0x031a1d06, 0x031a1d06,
|
|
0x041b1c05, 0x041c1c04, 0x051c1b04, 0x051d1a04, 0x061d1a03,
|
|
0x071d1903, 0x071e1803, 0x081e1802, 0x081f1702, 0x091f1602,
|
|
0x0a201501, 0x0b1f1501, 0x0b201401, 0x0c211300, 0x0d211200,
|
|
0x0e201200, 0x0e211100,
|
|
/* counter = 12 */
|
|
0x00102010, 0x0011200f, 0x0012200e, 0x0013200d, 0x0013200d,
|
|
0x01141f0c, 0x01151f0b, 0x01151f0b, 0x01161f0a, 0x02171e09,
|
|
0x02171e09, 0x03181d08, 0x03191d07, 0x03191d07, 0x041a1c06,
|
|
0x041b1c05, 0x051b1b05, 0x051c1b04, 0x061c1a04, 0x071d1903,
|
|
0x071d1903, 0x081d1803, 0x081e1703, 0x091e1702, 0x0a1f1601,
|
|
0x0a1f1502, 0x0b1f1501, 0x0c1f1401, 0x0d201300, 0x0d201300,
|
|
0x0e201200, 0x0f201100,
|
|
/* counter = 13 */
|
|
0x00102010, 0x0011200f, 0x00121f0f, 0x00131f0e, 0x00141f0d,
|
|
0x01141f0c, 0x01141f0c, 0x01151e0c, 0x02161e0a, 0x02171e09,
|
|
0x03171d09, 0x03181d08, 0x03181d08, 0x04191c07, 0x041a1c06,
|
|
0x051a1b06, 0x051b1b05, 0x061b1a05, 0x061c1a04, 0x071c1904,
|
|
0x081c1903, 0x081d1803, 0x091d1703, 0x091e1702, 0x0a1e1602,
|
|
0x0b1e1502, 0x0c1e1501, 0x0c1f1401, 0x0d1f1400, 0x0e1f1300,
|
|
0x0e1f1201, 0x0f1f1200,
|
|
/* counter = 14 */
|
|
0x00111e11, 0x00121e10, 0x00131e0f, 0x00131e0f, 0x01131e0e,
|
|
0x01141d0e, 0x02151d0c, 0x02151d0c, 0x02161d0b, 0x03161c0b,
|
|
0x03171c0a, 0x04171c09, 0x04181b09, 0x05181b08, 0x05191b07,
|
|
0x06191a07, 0x061a1a06, 0x071a1906, 0x071b1905, 0x081b1805,
|
|
0x091b1804, 0x091c1704, 0x0a1c1703, 0x0a1c1604, 0x0b1d1602,
|
|
0x0c1d1502, 0x0c1d1502, 0x0d1d1402, 0x0e1d1401, 0x0e1e1301,
|
|
0x0f1e1300, 0x101e1200,
|
|
/* counter = 15 */
|
|
0x00111e11, 0x00121e10, 0x00131d10, 0x01131d0f, 0x01141d0e,
|
|
0x01141d0e, 0x02151c0d, 0x02151c0d, 0x03161c0b, 0x03161c0b,
|
|
0x04171b0a, 0x04171b0a, 0x05171b09, 0x05181a09, 0x06181a08,
|
|
0x06191a07, 0x07191907, 0x071a1906, 0x081a1806, 0x081a1806,
|
|
0x091a1805, 0x0a1b1704, 0x0a1b1704, 0x0b1c1603, 0x0b1c1603,
|
|
0x0c1c1503, 0x0d1c1502, 0x0d1d1402, 0x0e1d1401, 0x0f1d1301,
|
|
0x0f1d1301, 0x101e1200,
|
|
/* counter = 16 */
|
|
};
|
|
|
|
__s32 linearcoefftab32[32] = {
|
|
0x00004000, 0x00023e00, 0x00043c00, 0x00063a00, 0x00083800,
|
|
0x000a3600, 0x000c3400, 0x000e3200, 0x00103000, 0x00122e00,
|
|
0x00142c00, 0x00162a00, 0x00182800, 0x001a2600, 0x001c2400,
|
|
0x001e2200, 0x00202000, 0x00221e00, 0x00241c00, 0x00261a00,
|
|
0x00281800, 0x002a1600, 0x002c1400, 0x002e1200, 0x00301000,
|
|
0x00320e00, 0x00340c00, 0x00360a00, 0x00380800, 0x003a0600,
|
|
0x003c0400, 0x003e0200, };
|
|
__s32 g2d_bsp_open(void)
|
|
{
|
|
write_wvalue(G2D_SCLK_GATE, 0x3);
|
|
write_wvalue(G2D_HCLK_GATE, 0x3);
|
|
write_wvalue(G2D_AHB_RESET, 0x3);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_bsp_close(void)
|
|
{
|
|
write_wvalue(G2D_AHB_RESET, 0x0);
|
|
write_wvalue(G2D_HCLK_GATE, 0x0);
|
|
write_wvalue(G2D_SCLK_GATE, 0x0);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_bsp_reset(void)
|
|
{
|
|
write_wvalue(G2D_AHB_RESET, 0x0);
|
|
write_wvalue(G2D_AHB_RESET, 0x3);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_mixer_reset(void)
|
|
{
|
|
__u32 reg_val;
|
|
|
|
reg_val = read_wvalue(G2D_AHB_RESET);
|
|
write_wvalue(G2D_AHB_RESET, reg_val & 0xfffffffe);
|
|
write_wvalue(G2D_AHB_RESET, reg_val & 0xffffffff);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_rot_reset(void)
|
|
{
|
|
__u32 reg_val;
|
|
|
|
reg_val = read_wvalue(G2D_AHB_RESET);
|
|
write_wvalue(G2D_AHB_RESET, reg_val & 0xfffffffd);
|
|
write_wvalue(G2D_AHB_RESET, reg_val & 0xffffffff);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_scan_order_fun(__u32 scan_order)
|
|
{
|
|
__u32 tmp;
|
|
|
|
tmp = read_wvalue(G2D_MIXER_CTL);
|
|
tmp |= ((scan_order >> 24) & 0xf0);
|
|
write_wvalue(G2D_MIXER_CTL, tmp);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* G2D IRQ query funct
|
|
* if the mission finish IRQ flag was set to 1, then clear the flag
|
|
* and return 1
|
|
* if the IRQ was set to 0, then return 0
|
|
*/
|
|
__s32 mixer_irq_query(void)
|
|
{
|
|
__u32 tmp;
|
|
|
|
tmp = read_wvalue(G2D_MIXER_INT);
|
|
if (tmp & 0x1) {
|
|
write_wvalue(G2D_MIXER_INT, tmp);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* G2D IRQ query funct
|
|
* if the mission finish IRQ flag was set to 1, then clear the flag
|
|
* and return 1
|
|
* if the IRQ was set to 0, then return 0
|
|
*/
|
|
__s32 rot_irq_query(void)
|
|
{
|
|
__u32 tmp;
|
|
|
|
tmp = read_wvalue(ROT_INT);
|
|
if (tmp & 0x1) {
|
|
write_wvalue(ROT_INT, tmp);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
__s32 mixer_irq_enable(void)
|
|
{
|
|
write_wvalue(G2D_MIXER_INT, 0x10);
|
|
return 0;
|
|
}
|
|
|
|
__s32 rot_irq_enable(void)
|
|
{
|
|
write_wvalue(ROT_INT, 0x10000);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_irq_disable(void)
|
|
{
|
|
write_wvalue(G2D_MIXER_INT, 0x0);
|
|
return 0;
|
|
}
|
|
|
|
__s32 rot_irq_disable(void)
|
|
{
|
|
write_wvalue(ROT_INT, 0x0);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_sclk_div(__u32 div)
|
|
{
|
|
__u32 reg_val;
|
|
|
|
reg_val = read_wvalue(G2D_SCLK_DIV);
|
|
reg_val &= 0xfffffff0;
|
|
reg_val |= (div & 0xf);
|
|
write_wvalue(G2D_SCLK_DIV, reg_val);
|
|
return 0;
|
|
}
|
|
|
|
__s32 rot_sclk_div(__u32 div)
|
|
{
|
|
__u32 reg_val;
|
|
|
|
reg_val = read_wvalue(G2D_SCLK_DIV);
|
|
reg_val &= 0xffffff0f;
|
|
reg_val |= (div & 0xf) << 4;
|
|
write_wvalue(G2D_SCLK_DIV, reg_val);
|
|
return 0;
|
|
}
|
|
|
|
__s32 porter_duff(__u32 cmd)
|
|
{
|
|
switch (cmd) {
|
|
case G2D_BLD_CLEAR:
|
|
write_wvalue(BLD_CTL, 0x00000000);
|
|
break;
|
|
case G2D_BLD_COPY:
|
|
write_wvalue(BLD_CTL, 0x00010001);
|
|
break;
|
|
case G2D_BLD_DST:
|
|
write_wvalue(BLD_CTL, 0x01000100);
|
|
break;
|
|
case G2D_BLD_SRCOVER:
|
|
write_wvalue(BLD_CTL, 0x03010301);
|
|
break;
|
|
case G2D_BLD_DSTOVER:
|
|
write_wvalue(BLD_CTL, 0x01030103);
|
|
break;
|
|
case G2D_BLD_SRCIN:
|
|
write_wvalue(BLD_CTL, 0x00020002);
|
|
break;
|
|
case G2D_BLD_DSTIN:
|
|
write_wvalue(BLD_CTL, 0x02000200);
|
|
break;
|
|
case G2D_BLD_SRCOUT:
|
|
write_wvalue(BLD_CTL, 0x00030003);
|
|
break;
|
|
case G2D_BLD_DSTOUT:
|
|
write_wvalue(BLD_CTL, 0x03000300);
|
|
break;
|
|
case G2D_BLD_SRCATOP:
|
|
write_wvalue(BLD_CTL, 0x03020302);
|
|
break;
|
|
case G2D_BLD_DSTATOP:
|
|
write_wvalue(BLD_CTL, 0x02030203);
|
|
break;
|
|
case G2D_BLD_XOR:
|
|
write_wvalue(BLD_CTL, 0x03030303);
|
|
break;
|
|
default:
|
|
write_wvalue(BLD_CTL, 0x03010301);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* @csc_no: CSC ID, G2D support three CSC,
|
|
* -1 will return to indicate inappropriate CSC number.
|
|
* @csc_sel: CSC format, G2D support the ITU-R 601. ITU-R 709. standard trans-
|
|
* form between RGB and YUV colorspace.
|
|
*/
|
|
__s32 g2d_csc_reg_set(__u32 csc_no, g2d_csc_sel csc_sel)
|
|
{
|
|
__u32 i;
|
|
__u32 csc_base_addr;
|
|
__u32 tmp;
|
|
|
|
switch (csc_no) {
|
|
case 0:
|
|
csc_base_addr = G2D_BLD + 0x110;
|
|
tmp = read_wvalue(BLD_CSC_CTL);
|
|
tmp |= 0x1;
|
|
write_wvalue(BLD_CSC_CTL, tmp);
|
|
break;
|
|
case 1:
|
|
csc_base_addr = G2D_BLD + 0x140;
|
|
tmp = read_wvalue(BLD_CSC_CTL);
|
|
tmp |= 0x1 << 1;
|
|
write_wvalue(BLD_CSC_CTL, tmp);
|
|
break;
|
|
case 2:
|
|
csc_base_addr = G2D_BLD + 0x170;
|
|
tmp = read_wvalue(BLD_CSC_CTL);
|
|
tmp |= 0x1 << 2;
|
|
write_wvalue(BLD_CSC_CTL, tmp);
|
|
break;
|
|
default:
|
|
|
|
/* __wrn("sel wrong csc no.\n"); */
|
|
return -1;
|
|
}
|
|
switch (csc_sel) {
|
|
case G2D_RGB2YUV_709:
|
|
for (i = 0; i < 12; i++)
|
|
write_wvalue(csc_base_addr + (i << 2),
|
|
rgb2Ycbcr_709[i]);
|
|
break;
|
|
case G2D_YUV2RGB_709:
|
|
for (i = 0; i < 12; i++)
|
|
write_wvalue(csc_base_addr + (i << 2),
|
|
Ycbcr2rgb_709[i]);
|
|
break;
|
|
case G2D_RGB2YUV_601:
|
|
for (i = 0; i < 12; i++)
|
|
;
|
|
|
|
/* write_wvalue(csc_base_addr + (i<<2), */
|
|
/* rgb2Ycbcr_601[i]); */
|
|
break;
|
|
case G2D_YUV2RGB_601:
|
|
for (i = 0; i < 12; i++)
|
|
;
|
|
|
|
/* write_wvalue(csc_base_addr + (i<<2), */
|
|
/* Ycbcr2rgb_601[i]); */
|
|
break;
|
|
default:
|
|
|
|
/* __wrn("wrong csc standard\n"); */
|
|
return -2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* set colorkey para.
|
|
*/
|
|
__s32 ck_para_set(g2d_ck *para)
|
|
{
|
|
__u32 tmp = 0x0;
|
|
|
|
if (para->match_rule)
|
|
tmp = 0x7;
|
|
write_wvalue(BLD_KEY_CON, tmp);
|
|
write_wvalue(BLD_KEY_MAX, para->max_color & 0x00ffffff);
|
|
write_wvalue(BLD_KEY_MIN, para->min_color & 0x00ffffff);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
__s32 g2d_byte_cal(__u32 format, __u32 *ycnt, __u32 *ucnt, __u32 *vcnt)
|
|
{
|
|
*ycnt = 0;
|
|
*ucnt = 0;
|
|
*vcnt = 0;
|
|
if (format <= G2D_FORMAT_BGRX8888)
|
|
*ycnt = 4;
|
|
|
|
else if (format <= G2D_FORMAT_BGR888)
|
|
*ycnt = 3;
|
|
|
|
else if (format <= G2D_FORMAT_BGRA5551)
|
|
*ycnt = 2;
|
|
|
|
else if (format <= G2D_FORMAT_BGRA1010102)
|
|
*ycnt = 4;
|
|
|
|
else if (format <= 0x23) {
|
|
*ycnt = 2;
|
|
}
|
|
|
|
else if (format <= 0x25) {
|
|
*ycnt = 1;
|
|
*ucnt = 2;
|
|
}
|
|
|
|
else if (format == 0x26) {
|
|
*ycnt = 1;
|
|
*ucnt = 1;
|
|
*vcnt = 1;
|
|
}
|
|
|
|
else if (format <= 0x29) {
|
|
*ycnt = 1;
|
|
*ucnt = 2;
|
|
}
|
|
|
|
else if (format == 0x2a) {
|
|
*ycnt = 1;
|
|
*ucnt = 1;
|
|
*vcnt = 1;
|
|
}
|
|
|
|
else if (format <= 0x2d) {
|
|
*ycnt = 1;
|
|
*ucnt = 2;
|
|
}
|
|
|
|
else if (format == 0x2e) {
|
|
*ycnt = 1;
|
|
*ucnt = 1;
|
|
*vcnt = 1;
|
|
}
|
|
|
|
else if (format == 0x30)
|
|
*ycnt = 1;
|
|
|
|
else if (format <= 0x36) {
|
|
*ycnt = 2;
|
|
*ucnt = 4;
|
|
}
|
|
|
|
else if (format <= 0x39)
|
|
*ycnt = 6;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
__u32 cal_align(__u32 width, __u32 align)
|
|
{
|
|
switch (align) {
|
|
case 0:
|
|
return width;
|
|
case 8:
|
|
return (width + 7) >> 3 << 3;
|
|
case 16:
|
|
return (width + 15) >> 4 << 4;
|
|
case 32:
|
|
return (width + 31) >> 5 << 5;
|
|
case 64:
|
|
return (width + 63) >> 6 << 6;
|
|
case 128:
|
|
return (width + 127) >> 7 << 7;
|
|
default:
|
|
return (width + 31) >> 5 << 5;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @sel:layer no.
|
|
*/
|
|
__s32 g2d_vlayer_set(__u32 sel, g2d_image_enh *image)
|
|
{
|
|
unsigned long long addr0, addr1, addr2;
|
|
__u32 tmp;
|
|
__u32 ycnt, ucnt, vcnt;
|
|
__u32 pitch0, pitch1, pitch2;
|
|
__u32 ch, cw, cy, cx;
|
|
|
|
switch (sel) {
|
|
case 0:
|
|
|
|
/* base_addr = G2D_V0; */
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
tmp = ((image->alpha & 0xff) << 24);
|
|
if (image->bpremul)
|
|
tmp |= (0x1 << 17);
|
|
tmp |= (image->format << 8);
|
|
tmp |= (image->mode << 1);
|
|
tmp |= 1;
|
|
write_wvalue(V0_ATTCTL, tmp);
|
|
tmp =
|
|
(((image->clip_rect.h ==
|
|
0 ? 0 : image->clip_rect.h -
|
|
1) & 0x1fff) << 16) | ((image->clip_rect.w ==
|
|
0 ? 0 : image->clip_rect.w -
|
|
1) & 0x1fff);
|
|
write_wvalue(V0_MBSIZE, tmp);
|
|
|
|
/* offset is set to 0, ovl size is set to layer size */
|
|
write_wvalue(V0_SIZE, tmp);
|
|
write_wvalue(V0_COOR, 0);
|
|
if ((image->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0)
|
|
&& (image->format <= G2D_FORMAT_YUV422_PLANAR)) {
|
|
cw = image->width >> 1;
|
|
ch = image->height;
|
|
cx = image->clip_rect.x >> 1;
|
|
cy = image->clip_rect.y;
|
|
}
|
|
|
|
else if ((image->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0)
|
|
&& (image->format <= G2D_FORMAT_YUV420_PLANAR)) {
|
|
cw = image->width >> 1;
|
|
ch = image->height >> 1;
|
|
cx = image->clip_rect.x >> 1;
|
|
cy = image->clip_rect.y >> 1;
|
|
}
|
|
|
|
else if ((image->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0)
|
|
&& (image->format <= G2D_FORMAT_YUV411_PLANAR)) {
|
|
cw = image->width >> 2;
|
|
ch = image->height;
|
|
cx = image->clip_rect.x >> 2;
|
|
cy = image->clip_rect.y;
|
|
}
|
|
|
|
else {
|
|
cw = 0;
|
|
ch = 0;
|
|
cx = 0;
|
|
cy = 0;
|
|
}
|
|
g2d_byte_cal(image->format, &ycnt, &ucnt, &vcnt);
|
|
pitch0 = cal_align(ycnt * image->width, image->align[0]);
|
|
write_wvalue(V0_PITCH0, pitch0);
|
|
pitch1 = cal_align(ucnt * cw, image->align[1]);
|
|
write_wvalue(V0_PITCH1, pitch1);
|
|
pitch2 = cal_align(vcnt * cw, image->align[2]);
|
|
write_wvalue(V0_PITCH2, pitch2);
|
|
pr_info("video chn set pitch ok!\n");
|
|
G2D_INFO_MSG("VInPITCH: %d, %d, %d\n",
|
|
pitch0, pitch1, pitch2);
|
|
G2D_INFO_MSG("VInAddrB: 0x%x, 0x%x, 0x%x\n",
|
|
image->laddr[0], image->laddr[1], image->laddr[2]);
|
|
addr0 =
|
|
image->laddr[0] + ((__u64) image->haddr[0] << 32) +
|
|
pitch0 * image->clip_rect.y + ycnt * image->clip_rect.x;
|
|
write_wvalue(V0_LADD0, addr0 & 0xffffffff);
|
|
addr1 =
|
|
image->laddr[1] + ((__u64) image->haddr[1] << 32) + pitch1 * cy +
|
|
ucnt * cx;
|
|
write_wvalue(V0_LADD1, addr1 & 0xffffffff);
|
|
addr2 =
|
|
image->laddr[2] + ((__u64) image->haddr[2] << 32) + pitch2 * cy +
|
|
vcnt * cx;
|
|
write_wvalue(V0_LADD2, addr2 & 0xffffffff);
|
|
tmp = ((addr0 >> 32) & 0xff) | ((addr1 >> 32) & 0xff) << 8 |
|
|
((addr2 >> 32) & 0xff) << 16;
|
|
write_wvalue(V0_HADD, tmp);
|
|
G2D_INFO_MSG("VInAddrA: 0x%llx, 0x%llx, 0x%llx\n",
|
|
addr0, addr1, addr2);
|
|
if (image->bbuff == 0)
|
|
g2d_fc_set((sel + VI_LAYER_NUMBER), image->color);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_uilayer_set(__u32 sel, g2d_image_enh *img)
|
|
{
|
|
__u64 addr0;
|
|
__u32 base_addr_u, tmp;
|
|
__u32 ycnt, ucnt, vcnt;
|
|
__u32 pitch0;
|
|
|
|
switch (sel) {
|
|
case 0:
|
|
base_addr_u = G2D_UI0;
|
|
break;
|
|
case 1:
|
|
base_addr_u = G2D_UI1;
|
|
break;
|
|
case 2:
|
|
base_addr_u = G2D_UI2;
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
tmp = (img->alpha & 0xff) << 24;
|
|
if (img->bpremul)
|
|
tmp |= 0x1 << 17;
|
|
tmp |= img->format << 8;
|
|
tmp |= img->mode << 1;
|
|
tmp |= 1;
|
|
write_wvalue(base_addr_u, tmp);
|
|
tmp =
|
|
(((img->clip_rect.h ==
|
|
0 ? 0 : img->clip_rect.h -
|
|
1) & 0x1fff) << 16) | ((img->clip_rect.w ==
|
|
0 ? 0 : img->clip_rect.w - 1) & 0x1fff);
|
|
write_wvalue(base_addr_u + 0x4, tmp);
|
|
write_wvalue(base_addr_u + 0x1C, tmp);
|
|
write_wvalue(base_addr_u + 0x8, 0);
|
|
g2d_byte_cal(img->format, &ycnt, &ucnt, &vcnt);
|
|
pitch0 = cal_align(ycnt * img->width, img->align[0]);
|
|
write_wvalue(base_addr_u + 0xC, pitch0);
|
|
addr0 =
|
|
img->laddr[0] + ((__u64) img->haddr[0] << 32) +
|
|
pitch0 * img->clip_rect.y + ycnt * img->clip_rect.x;
|
|
write_wvalue(base_addr_u + 0x10, addr0 & 0xffffffff);
|
|
write_wvalue(base_addr_u + 0x18, (addr0 >> 32) & 0xff);
|
|
if (img->bbuff == 0)
|
|
g2d_fc_set((sel + VI_LAYER_NUMBER), img->color);
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_wb_set(g2d_image_enh *image)
|
|
{
|
|
__u64 addr0, addr1, addr2;
|
|
__u32 tmp;
|
|
__u32 ycnt, ucnt, vcnt;
|
|
__u32 pitch0, pitch1, pitch2;
|
|
__u32 ch, cw, cy, cx;
|
|
|
|
write_wvalue(WB_ATT, image->format);
|
|
tmp =
|
|
(((image->clip_rect.h ==
|
|
0 ? 0 : image->clip_rect.h -
|
|
1) & 0x1fff) << 16) | ((image->clip_rect.w ==
|
|
0 ? 0 : image->clip_rect.w -
|
|
1) & 0x1fff);
|
|
write_wvalue(WB_SIZE, tmp);
|
|
/*write to the bld out reg */
|
|
G2D_INFO_MSG("BLD_CH_OSIZE W: 0x%x\n", image->clip_rect.w);
|
|
G2D_INFO_MSG("BLD_CH_OSIZE H: 0x%x\n", image->clip_rect.h);
|
|
write_wvalue(BLD_SIZE, tmp);
|
|
/* set outdata premul */
|
|
tmp = read_wvalue(BLD_OUT_COLOR);
|
|
|
|
if (image->bpremul)
|
|
write_wvalue(BLD_OUT_COLOR, tmp | 0x1);
|
|
|
|
else
|
|
write_wvalue(BLD_OUT_COLOR, tmp & 0x2);
|
|
if ((image->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0)
|
|
&& (image->format <= G2D_FORMAT_YUV422_PLANAR)) {
|
|
cw = image->width >> 1;
|
|
ch = image->height;
|
|
cx = image->clip_rect.x >> 1;
|
|
cy = image->clip_rect.y;
|
|
}
|
|
|
|
else if ((image->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0)
|
|
&& (image->format <= G2D_FORMAT_YUV420_PLANAR)) {
|
|
cw = image->width >> 1;
|
|
ch = image->height >> 1;
|
|
cx = image->clip_rect.x >> 1;
|
|
cy = image->clip_rect.y >> 1;
|
|
}
|
|
|
|
else if ((image->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0)
|
|
&& (image->format <= G2D_FORMAT_YUV411_PLANAR)) {
|
|
cw = image->width >> 2;
|
|
ch = image->height;
|
|
cx = image->clip_rect.x >> 2;
|
|
cy = image->clip_rect.y;
|
|
}
|
|
|
|
else {
|
|
cw = 0;
|
|
ch = 0;
|
|
cx = 0;
|
|
cy = 0;
|
|
}
|
|
g2d_byte_cal(image->format, &ycnt, &ucnt, &vcnt);
|
|
pitch0 = cal_align(ycnt * image->width, image->align[0]);
|
|
write_wvalue(WB_PITCH0, pitch0);
|
|
pitch1 = cal_align(ucnt * cw, image->align[1]);
|
|
write_wvalue(WB_PITCH1, pitch1);
|
|
pitch2 = cal_align(vcnt * cw, image->align[2]);
|
|
write_wvalue(WB_PITCH2, pitch2);
|
|
addr0 =
|
|
image->laddr[0] + ((__u64) image->haddr[0] << 32) +
|
|
pitch0 * image->clip_rect.y + ycnt * image->clip_rect.x;
|
|
write_wvalue(WB_LADD0, addr0 & 0xffffffff);
|
|
write_wvalue(WB_HADD0, (addr0 >> 32) & 0xff);
|
|
addr1 =
|
|
image->laddr[1] + ((__u64) image->haddr[1] << 32) + pitch1 * cy +
|
|
ucnt * cx;
|
|
write_wvalue(WB_LADD1, addr1 & 0xffffffff);
|
|
write_wvalue(WB_HADD1, (addr1 >> 32) & 0xff);
|
|
addr2 =
|
|
image->laddr[2] + ((__u64) image->haddr[2] << 32) + pitch2 * cy +
|
|
vcnt * cx;
|
|
write_wvalue(WB_LADD2, addr2 & 0xffffffff);
|
|
write_wvalue(WB_HADD2, (addr2 >> 32) & 0xff);
|
|
G2D_INFO_MSG("WbAddr: 0x%llx, 0x%llx, 0x%llx\n", addr0, addr1, addr2);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* fillcolor set
|
|
* @sel:layer_no, 0--Layer Video,1--Layer UI0,2--Layer UI1,3--Layer UI2
|
|
* @color_value:fill color value
|
|
*/
|
|
__s32 g2d_fc_set(__u32 sel, __u32 color_value)
|
|
{
|
|
__u32 tmp;
|
|
|
|
G2D_INFO_MSG("FILLCOLOR: sel: %d, color: 0x%x\n", sel, color_value);
|
|
|
|
if (sel == 0) {
|
|
/* Layer Video */
|
|
tmp = read_wvalue(V0_ATTCTL);
|
|
tmp |= (0x1 << 4);
|
|
write_wvalue(V0_ATTCTL, tmp);
|
|
write_wvalue(V0_FILLC, color_value);
|
|
}
|
|
if (sel == 1) {
|
|
/* Layer UI0 */
|
|
tmp = read_wvalue(UI0_ATTR);
|
|
tmp |= (0x1 << 4);
|
|
write_wvalue(UI0_ATTR, tmp);
|
|
write_wvalue(UI0_FILLC, color_value);
|
|
}
|
|
if (sel == 2) {
|
|
/* Layer UI1 */
|
|
tmp = read_wvalue(UI1_ATTR);
|
|
tmp |= (0x1 << 4);
|
|
write_wvalue(UI1_ATTR, tmp);
|
|
write_wvalue(UI1_FILLC, color_value);
|
|
}
|
|
if (sel == 3) {
|
|
/* Layer UI2 */
|
|
tmp = read_wvalue(UI2_ATTR);
|
|
tmp |= (0x1 << 4);
|
|
write_wvalue(UI2_ATTR, tmp);
|
|
write_wvalue(UI2_FILLC, color_value);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* ROP2 cmd register set
|
|
* Index0 is selected
|
|
* dst mapping ch0'
|
|
* src mapping ch1'
|
|
*/
|
|
__s32 g2d_rop2_set(__u32 rop_cmd)
|
|
{
|
|
if (rop_cmd == G2D_BLT_BLACKNESS) {
|
|
/* blackness */
|
|
/* tmpue = 0x1<<18; */
|
|
write_wvalue(ROP_INDEX0, 0x40000);
|
|
} else if (rop_cmd == G2D_BLT_NOTMERGEPEN) {
|
|
/* ~(dst | src) */
|
|
/* tmpue = (0x1<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(ROP_INDEX0, 0x41440);
|
|
} else if (rop_cmd == G2D_BLT_MASKNOTPEN) {
|
|
/* ~src&dst */
|
|
/* tmpue = (0x1<<4) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(ROP_INDEX0, 0x41010);
|
|
} else if (rop_cmd == G2D_BLT_NOTCOPYPEN) {
|
|
/* ~src */
|
|
/* tmpue = (0x1<<4) | (0x2<<6) | (0x2<<11) |
|
|
* (0x1<<18) | (0x1<<17);
|
|
*/
|
|
write_wvalue(ROP_INDEX0, 0x61090);
|
|
} else if (rop_cmd == G2D_BLT_MASKPENNOT) {
|
|
/* src&~dst */
|
|
/* tmpue = (0x1<<3) | (0x0<<10) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(ROP_INDEX0, 0x41008);
|
|
} else if (rop_cmd == G2D_BLT_NOT) {
|
|
/* ~dst */
|
|
/* tmpue = (0x1<<3) | (0x2<<6) | (0x2<<11) |
|
|
* (0x1<<18) | (0x1<<16);
|
|
*/
|
|
write_wvalue(ROP_INDEX0, 0x51088);
|
|
} else if (rop_cmd == G2D_BLT_XORPEN) {
|
|
/* src xor dst */
|
|
/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(ROP_INDEX0, 0x41080);
|
|
} else if (rop_cmd == G2D_BLT_NOTMASKPEN) {
|
|
/* ~(src & dst) */
|
|
/* tmpue = (0x0<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(ROP_INDEX0, 0x41400);
|
|
} else if (rop_cmd == G2D_BLT_MASKPEN) {
|
|
/* src&dst */
|
|
/* tmpue = (0x0<<6) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(ROP_INDEX0, 0x41000);
|
|
} else if (rop_cmd == G2D_BLT_NOTXORPEN) {
|
|
/* ~(src xor dst) */
|
|
/* tmpue = (0x2<<6) | (0x1<<10) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(ROP_INDEX0, 0x41480);
|
|
} else if (rop_cmd == G2D_BLT_NOP) {
|
|
/* dst */
|
|
/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
|
|
write_wvalue(ROP_INDEX0, 0x51080);
|
|
} else if (rop_cmd == G2D_BLT_MERGENOTPEN) {
|
|
/* ~dst or src */
|
|
/* tmpue = (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
|
|
/* write_wvalue(ROP_INDEX0, 0x40A20); */
|
|
write_wvalue(ROP_INDEX0, 0x41048);
|
|
} else if (rop_cmd == G2D_BLT_COPYPEN) {
|
|
/* src */
|
|
/* tmpue = (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
|
|
write_wvalue(ROP_INDEX0, 0x61080);
|
|
} else if (rop_cmd == G2D_BLT_MERGEPENNOT) {
|
|
/* src or ~dst */
|
|
/* tmpue = (0x1<<3)| (0x1<<6) | (0x2<<11) | (0x1<<18) */
|
|
write_wvalue(ROP_INDEX0, 0x41048);
|
|
} else if (rop_cmd == G2D_BLT_MERGEPEN) {
|
|
/* src or dst */
|
|
/* tmpue = (0x1<<6) | (0x1<<18) | (0x2<<11); */
|
|
write_wvalue(ROP_INDEX0, 0x41040);
|
|
} else if (rop_cmd == G2D_BLT_WHITENESS) {
|
|
/* whiteness */
|
|
/* tmpue = (0x1<<18) | (0x1<<15); */
|
|
write_wvalue(ROP_INDEX0, 0x48000);
|
|
} else
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* ROP3 cmd register set
|
|
* dst mapping ch0'
|
|
* src mapping ch1'
|
|
* ptn mapping ch2'
|
|
* -1 return meaning that the operate is not supported by now
|
|
*/
|
|
__s32 g2d_rop3_set(__u32 sel, __u32 rop3_cmd)
|
|
{
|
|
__u32 addr;
|
|
|
|
if (sel == 0)
|
|
addr = ROP_INDEX0;
|
|
else if (sel == 1)
|
|
addr = ROP_INDEX1;
|
|
|
|
else
|
|
return -1;
|
|
if (rop3_cmd == G2D_ROP3_BLACKNESS) {
|
|
/* blackness */
|
|
/* 0x1<<18; */
|
|
write_wvalue(addr, 0x40000);
|
|
} else if (rop3_cmd == G2D_ROP3_NOTSRCERASE) {
|
|
/* (~src) AND (~dst) */
|
|
/* (0x1<<3) | (0x1<<4) | (0x1<<18) | (0x2<<11); */
|
|
write_wvalue(addr, 0x41018);
|
|
} else if (rop3_cmd == G2D_ROP3_NOTSRCCOPY) {
|
|
|
|
/* ~src */
|
|
/* (0x1<<4) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
|
|
write_wvalue(addr, 0x51090);
|
|
} else if (rop3_cmd == G2D_ROP3_SRCERASE) {
|
|
/* src AND ~dst */
|
|
/* (0x1<<3) | (0x0<<6) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(addr, 0x41008);
|
|
} else if (rop3_cmd == G2D_ROP3_DSTINVERT) {
|
|
/* ~dst */
|
|
/* (0x1<<3) | (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<17); */
|
|
write_wvalue(addr, 0x61088);
|
|
} else if (rop3_cmd == G2D_ROP3_PATINVERT) {
|
|
/* ptn XOR dst */
|
|
/* (0x2<<6) | (0x2<<11) | (0x1<<17) */
|
|
write_wvalue(addr, 0x21080);
|
|
} else if (rop3_cmd == G2D_ROP3_SRCINVERT) {
|
|
/* src XOR dst */
|
|
/* (0x2<<6) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(addr, 0x41080);
|
|
} else if (rop3_cmd == G2D_ROP3_SRCAND) {
|
|
/* src AND dst */
|
|
/* (0x0<<6) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(addr, 0x41000);
|
|
} else if (rop3_cmd == G2D_ROP3_MERGEPAINT) {
|
|
/* ~src OR dst */
|
|
/* (0x1<<4) | (0x1<<6) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(addr, 0x41050);
|
|
} else if (rop3_cmd == G2D_ROP3_MERGECOPY) {
|
|
/* src AND pattern */
|
|
/* (0x2<<6) | (0x1<<16) */
|
|
write_wvalue(addr, 0x10080);
|
|
} else if (rop3_cmd == G2D_ROP3_SRCCOPY) {
|
|
/* src */
|
|
/* (0x2<<6) | (0x2<<11) | (0x1<<18) | (0x1<<16); */
|
|
write_wvalue(addr, 0x51080);
|
|
} else if (rop3_cmd == G2D_ROP3_SRCPAINT) {
|
|
/* src OR dst */
|
|
/* (0x1<<6) | (0x2<<11) | (0x1<<18); */
|
|
write_wvalue(addr, 0x41040);
|
|
} else if (rop3_cmd == G2D_ROP3_PATCOPY) {
|
|
/* ptn */
|
|
/* (0x1<<16) | (0x1<<17) | (0x2)<<11 */
|
|
write_wvalue(addr, 0x31000);
|
|
} else if (rop3_cmd == G2D_ROP3_PATPAINT) {
|
|
/* DPSnoo */
|
|
/* (0x1<<3) | (0x1<<6) | (0x1<<11) */
|
|
write_wvalue(addr, 0x848);
|
|
} else if (rop3_cmd == G2D_ROP3_WHITENESS) {
|
|
/* whiteness */
|
|
write_wvalue(addr, 0x48000);
|
|
} else
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* background color set
|
|
*/
|
|
__s32 g2d_bk_set(__u32 color)
|
|
{
|
|
write_wvalue(BLD_BK_COLOR, color & 0xffffffff);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* function : g2d_vsu_calc_fir_coef(unsigned int step)
|
|
* description : set fir coefficients
|
|
* parameters :
|
|
* step <horizontal scale ratio of vsu>
|
|
* return :
|
|
* offset (in word) of coefficient table
|
|
*/
|
|
static __u32 g2d_vsu_calc_fir_coef(__u32 step)
|
|
{
|
|
__u32 pt_coef;
|
|
__u32 scale_ratio, int_part, float_part, fir_coef_ofst;
|
|
|
|
scale_ratio = step >> (VSU_PHASE_FRAC_BITWIDTH - 3);
|
|
int_part = scale_ratio >> 3;
|
|
float_part = scale_ratio & 0x7;
|
|
fir_coef_ofst = (int_part == 0) ? VSU_ZOOM0_SIZE :
|
|
(int_part == 1) ? VSU_ZOOM0_SIZE + float_part :
|
|
(int_part ==
|
|
2) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
|
|
(float_part >> 1) : (int_part ==
|
|
3) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
|
|
VSU_ZOOM2_SIZE : (int_part ==
|
|
4) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
|
|
VSU_ZOOM2_SIZE + VSU_ZOOM3_SIZE : VSU_ZOOM0_SIZE +
|
|
VSU_ZOOM1_SIZE + VSU_ZOOM2_SIZE + VSU_ZOOM3_SIZE + VSU_ZOOM4_SIZE;
|
|
pt_coef = fir_coef_ofst * VSU_PHASE_NUM;
|
|
return pt_coef;
|
|
}
|
|
|
|
__s32 g2d_rop_by_pass(__u32 sel)
|
|
{
|
|
if (sel == 0)
|
|
write_wvalue(ROP_CTL, 0xF0);
|
|
|
|
else if (sel == 1)
|
|
write_wvalue(ROP_CTL, 0x55F0);
|
|
|
|
else if (sel == 2)
|
|
write_wvalue(ROP_CTL, 0xAAF0);
|
|
|
|
else
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
__s32 g2d_vsu_para_set(__u32 fmt, __u32 in_w, __u32 in_h, __u32 out_w,
|
|
__u32 out_h, __u8 alpha)
|
|
{
|
|
__u32 i;
|
|
__u64 tmp, temp;
|
|
__u32 yhstep, yvstep;
|
|
__u32 incw, inch;
|
|
__u32 yhcoef_offset, yvcoef_offset, chcoef_offset;
|
|
__u32 format;
|
|
|
|
if (fmt > G2D_FORMAT_IYUV422_Y1U0Y0V0)
|
|
write_wvalue(VS_CTRL, 0x10101);
|
|
|
|
else
|
|
write_wvalue(VS_CTRL, 0x00000101);
|
|
tmp = ((out_h - 1) << 16) | (out_w - 1);
|
|
write_wvalue(VS_OUT_SIZE, tmp);
|
|
write_wvalue(VS_GLB_ALPHA, alpha & 0xff);
|
|
write_wvalue(VS_Y_SIZE, ((in_h - 1) << 16) | (in_w - 1));
|
|
temp = in_w << VSU_PHASE_FRAC_BITWIDTH;
|
|
if (out_w)
|
|
do_div(temp, out_w);
|
|
|
|
/* temp = temp/out_w; */
|
|
else
|
|
temp = 0;
|
|
yhstep = temp;
|
|
write_wvalue(VS_Y_HSTEP, yhstep << 1);
|
|
temp = in_h << VSU_PHASE_FRAC_BITWIDTH;
|
|
if (out_h)
|
|
do_div(temp, out_h);
|
|
else
|
|
temp = 0;
|
|
yvstep = temp;
|
|
write_wvalue(VS_Y_VSTEP, yvstep << 1);
|
|
yhcoef_offset = g2d_vsu_calc_fir_coef(yhstep);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++) {
|
|
write_wvalue(VS_Y_HCOEF0 + (i << 2),
|
|
lan2coefftab32_full[yhcoef_offset + i]);
|
|
}
|
|
yvcoef_offset = g2d_vsu_calc_fir_coef(yvstep);
|
|
switch (fmt) {
|
|
case G2D_FORMAT_IYUV422_V0Y1U0Y0:
|
|
case G2D_FORMAT_IYUV422_Y1V0Y0U0:
|
|
case G2D_FORMAT_IYUV422_U0Y1V0Y0:
|
|
case G2D_FORMAT_IYUV422_Y1U0Y0V0:{
|
|
incw = (in_w + 1) >> 1;
|
|
inch = in_h;
|
|
format = VSU_FORMAT_YUV422;
|
|
write_wvalue(VS_C_SIZE,
|
|
((inch - 1) << 16) | (incw - 1));
|
|
|
|
/* chstep = yhstep>>1 cvstep = yvstep */
|
|
write_wvalue(VS_C_HSTEP, yhstep);
|
|
write_wvalue(VS_C_VSTEP, yvstep << 1);
|
|
chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_C_HCOEF0 + (i << 2),
|
|
lan2coefftab32_full[chcoef_offset
|
|
+ i]);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_Y_VCOEF0 + (i << 2),
|
|
linearcoefftab32[i]);
|
|
break;
|
|
}
|
|
case G2D_FORMAT_YUV422UVC_V1U1V0U0:
|
|
case G2D_FORMAT_YUV422UVC_U1V1U0V0:
|
|
case G2D_FORMAT_YUV422_PLANAR:{
|
|
incw = (in_w + 1) >> 1;
|
|
inch = in_h;
|
|
format = VSU_FORMAT_YUV420;
|
|
write_wvalue(VS_C_SIZE,
|
|
((inch - 1) << 16) | (incw - 1));
|
|
|
|
/* chstep = yhstep>>1 cvstep = yvstep>>1 */
|
|
write_wvalue(VS_C_HSTEP, yhstep);
|
|
write_wvalue(VS_C_VSTEP, yvstep << 1);
|
|
chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_C_HCOEF0 + (i << 2),
|
|
lan2coefftab32_full[chcoef_offset
|
|
+ i]);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_Y_VCOEF0 + (i << 2),
|
|
lan2coefftab32_full[yvcoef_offset
|
|
+ i]);
|
|
break;
|
|
}
|
|
case G2D_FORMAT_YUV420_PLANAR:
|
|
case G2D_FORMAT_YUV420UVC_V1U1V0U0:
|
|
case G2D_FORMAT_YUV420UVC_U1V1U0V0:{
|
|
incw = (in_w + 1) >> 1;
|
|
inch = (in_h + 1) >> 1;
|
|
format = VSU_FORMAT_YUV420;
|
|
write_wvalue(VS_C_SIZE,
|
|
((inch - 1) << 16) | (incw - 1));
|
|
write_wvalue(VS_C_HSTEP, yhstep);
|
|
write_wvalue(VS_C_VSTEP, yvstep);
|
|
chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_C_HCOEF0 + (i << 2),
|
|
lan2coefftab32_full[chcoef_offset
|
|
+ i]);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_Y_VCOEF0 + (i << 2),
|
|
lan2coefftab32_full[yvcoef_offset
|
|
+ i]);
|
|
break;
|
|
}
|
|
case G2D_FORMAT_YUV411_PLANAR:
|
|
case G2D_FORMAT_YUV411UVC_V1U1V0U0:
|
|
case G2D_FORMAT_YUV411UVC_U1V1U0V0:{
|
|
incw = (in_w + 3) >> 2;
|
|
inch = in_h;
|
|
format = VSU_FORMAT_YUV411;
|
|
write_wvalue(VS_C_SIZE,
|
|
((inch - 1) << 16) | (incw - 1));
|
|
|
|
/* chstep = yhstep>>2 cvstep = yvstep */
|
|
write_wvalue(VS_C_HSTEP, yhstep >> 1);
|
|
write_wvalue(VS_C_VSTEP, yvstep << 1);
|
|
chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 2);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_C_HCOEF0 + (i << 2),
|
|
lan2coefftab32_full[chcoef_offset
|
|
+ i]);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_Y_VCOEF0 + (i << 2),
|
|
lan2coefftab32_full[yvcoef_offset
|
|
+ i]);
|
|
break;
|
|
}
|
|
default:
|
|
format = VSU_FORMAT_RGB;
|
|
incw = in_w;
|
|
inch = in_h;
|
|
write_wvalue(VS_C_SIZE, ((inch - 1) << 16) | (incw - 1));
|
|
|
|
/* chstep = yhstep cvstep = yvstep */
|
|
write_wvalue(VS_C_HSTEP, yhstep << 1);
|
|
write_wvalue(VS_C_VSTEP, yvstep << 1);
|
|
chcoef_offset = g2d_vsu_calc_fir_coef(yhstep);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_C_HCOEF0 + (i << 2),
|
|
lan2coefftab32_full[chcoef_offset + i]);
|
|
for (i = 0; i < VSU_PHASE_NUM; i++)
|
|
write_wvalue(VS_Y_VCOEF0 + (i << 2),
|
|
linearcoefftab32[i]);
|
|
break;
|
|
}
|
|
if (fmt == VSU_FORMAT_YUV420) {
|
|
|
|
/**
|
|
* yhphase = 0;
|
|
* yvphase = 0;
|
|
* chphase = 0xFFFE0000;
|
|
* cvphase = 0xFFFE0000;
|
|
*/
|
|
write_wvalue(VS_Y_HPHASE, 0);
|
|
write_wvalue(VS_Y_VPHASE0, 0);
|
|
write_wvalue(VS_C_HPHASE, 0xFFFE0000);
|
|
write_wvalue(VS_C_VPHASE0, 0xFFFE0000);
|
|
}
|
|
|
|
else {
|
|
write_wvalue(VS_Y_HPHASE, 0);
|
|
write_wvalue(VS_Y_VPHASE0, 0);
|
|
write_wvalue(VS_C_HPHASE, 0);
|
|
write_wvalue(VS_C_VPHASE0, 0);
|
|
}
|
|
if (fmt >= G2D_FORMAT_IYUV422_Y1U0Y0V0)
|
|
write_wvalue(VS_CTRL, 0x10001);
|
|
|
|
else
|
|
write_wvalue(VS_CTRL, 0x00001);
|
|
return 0;
|
|
}
|
|
|
|
|
|
__s32 g2d_calc_coarse(__u32 format, __u32 inw, __u32 inh, __u32 outw,
|
|
__u32 outh, __u32 *midw, __u32 *midh)
|
|
{
|
|
__u32 tmp;
|
|
|
|
switch (format) {
|
|
case G2D_FORMAT_IYUV422_V0Y1U0Y0:
|
|
case G2D_FORMAT_IYUV422_Y1V0Y0U0:
|
|
case G2D_FORMAT_IYUV422_U0Y1V0Y0:
|
|
case G2D_FORMAT_IYUV422_Y1U0Y0V0:{
|
|
/* interleaved YUV422 format */
|
|
*midw = inw;
|
|
*midh = inh;
|
|
break;
|
|
}
|
|
case G2D_FORMAT_YUV422UVC_V1U1V0U0:
|
|
case G2D_FORMAT_YUV422UVC_U1V1U0V0:
|
|
case G2D_FORMAT_YUV422_PLANAR:{
|
|
if (inw >= (outw << 3)) {
|
|
*midw = outw << 3;
|
|
tmp = (*midw << 16) | inw;
|
|
write_wvalue(V0_HDS_CTL0, tmp);
|
|
tmp = (*midw << 15) | ((inw + 1) >> 1);
|
|
write_wvalue(V0_HDS_CTL1, tmp);
|
|
} else
|
|
*midw = inw;
|
|
if (inh >= (outh << 2)) {
|
|
*midh = (outh << 2);
|
|
tmp = (*midh << 16) | inh;
|
|
write_wvalue(V0_VDS_CTL0, tmp);
|
|
write_wvalue(V0_VDS_CTL1, tmp);
|
|
} else
|
|
*midh = inh;
|
|
break;
|
|
}
|
|
case G2D_FORMAT_YUV420_PLANAR:
|
|
case G2D_FORMAT_YUV420UVC_V1U1V0U0:
|
|
case G2D_FORMAT_YUV420UVC_U1V1U0V0:{
|
|
if (inw >= (outw << 3)) {
|
|
*midw = outw << 3;
|
|
tmp = (*midw << 16) | inw;
|
|
write_wvalue(V0_HDS_CTL0, tmp);
|
|
tmp = (*midw << 15) | ((inw + 1) >> 1);
|
|
write_wvalue(V0_HDS_CTL0, tmp);
|
|
} else
|
|
*midw = inw;
|
|
if (inh >= (outh << 2)) {
|
|
*midh = (outh << 2);
|
|
tmp = (*midh << 16) | inh;
|
|
write_wvalue(V0_VDS_CTL0, tmp);
|
|
tmp = (*midh << 15) | ((inh + 1) >> 1);
|
|
write_wvalue(V0_VDS_CTL1, tmp);
|
|
} else
|
|
*midh = inh;
|
|
break;
|
|
}
|
|
case G2D_FORMAT_YUV411_PLANAR:
|
|
case G2D_FORMAT_YUV411UVC_V1U1V0U0:
|
|
case G2D_FORMAT_YUV411UVC_U1V1U0V0:{
|
|
if (inw >= (outw << 3)) {
|
|
*midw = outw << 3;
|
|
tmp = ((*midw) << 16) | inw;
|
|
write_wvalue(V0_HDS_CTL0, tmp);
|
|
tmp = ((*midw) << 14) | ((inw + 3) >> 2);
|
|
write_wvalue(V0_HDS_CTL1, tmp);
|
|
} else
|
|
*midw = inw;
|
|
if (inh >= (outh << 2)) {
|
|
*midh = (outh << 2);
|
|
tmp = ((*midh) << 16) | inh;
|
|
write_wvalue(V0_VDS_CTL0, tmp);
|
|
write_wvalue(V0_VDS_CTL1, tmp);
|
|
} else
|
|
*midh = inh;
|
|
break;
|
|
}
|
|
default:
|
|
if (inw >= (outw << 3)) {
|
|
*midw = outw << 3;
|
|
tmp = ((*midw) << 16) | inw;
|
|
write_wvalue(V0_HDS_CTL0, tmp);
|
|
write_wvalue(V0_HDS_CTL1, tmp);
|
|
} else
|
|
*midw = inw;
|
|
if (inh >= (outh << 2)) {
|
|
*midh = (outh << 2);
|
|
tmp = ((*midh) << 16) | inh;
|
|
write_wvalue(V0_VDS_CTL0, tmp);
|
|
write_wvalue(V0_VDS_CTL1, tmp);
|
|
} else
|
|
*midh = inh;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* sel: 0-->pipe0 1-->pipe1 other:error
|
|
*/
|
|
__s32 g2d_bldin_set(__u32 sel, g2d_rect rect, int premul)
|
|
{
|
|
__u32 tmp;
|
|
__u32 offset;
|
|
|
|
if (sel == 0) {
|
|
offset = 0;
|
|
tmp = read_wvalue(BLD_EN_CTL);
|
|
tmp |= 0x1 << 8;
|
|
write_wvalue(BLD_EN_CTL, tmp);
|
|
if (premul) {
|
|
tmp = read_wvalue(BLD_PREMUL_CTL);
|
|
tmp |= 0x1;
|
|
write_wvalue(BLD_PREMUL_CTL, tmp);
|
|
}
|
|
} else if (sel == 1) {
|
|
offset = 0x4;
|
|
tmp = read_wvalue(BLD_EN_CTL);
|
|
tmp |= 0x1 << 9;
|
|
write_wvalue(BLD_EN_CTL, tmp);
|
|
if (premul) {
|
|
tmp = read_wvalue(BLD_PREMUL_CTL);
|
|
tmp |= 0x1 << 1;
|
|
write_wvalue(BLD_PREMUL_CTL, tmp);
|
|
}
|
|
} else
|
|
return -1;
|
|
tmp = ((rect.h - 1) << 16) | (rect.w - 1);
|
|
|
|
G2D_INFO_MSG("BLD_CH_ISIZE W: 0x%x\n", rect.w);
|
|
G2D_INFO_MSG("BLD_CH_ISIZE H: 0x%x\n", rect.h);
|
|
|
|
write_wvalue(BLD_CH_ISIZE0 + offset, tmp);
|
|
tmp =
|
|
((rect.y <= 0 ? 0 : rect.y - 1) << 16) | (rect.x <=
|
|
0 ? 0 : rect.x - 1);
|
|
|
|
G2D_INFO_MSG("BLD_CH_ISIZE X: 0x%x\n", rect.x);
|
|
G2D_INFO_MSG("BLD_CH_ISIZE Y: 0x%x\n", rect.y);
|
|
|
|
write_wvalue(BLD_CH_OFFSET0 + offset, tmp);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* set the bld color space based on the format
|
|
* if the format is UI, then set the bld in RGB color space
|
|
* if the format is Video, then set the bld in YUV color space
|
|
*/
|
|
__s32 g2d_bld_cs_set(__u32 format)
|
|
{
|
|
__u32 tmp;
|
|
|
|
if (format <= G2D_FORMAT_BGRA1010102) {
|
|
tmp = read_wvalue(BLD_OUT_COLOR);
|
|
tmp &= 0xFFFFFFFD;
|
|
write_wvalue(BLD_OUT_COLOR, tmp);
|
|
} else if (format <= G2D_FORMAT_YUV411_PLANAR) {
|
|
tmp = read_wvalue(BLD_OUT_COLOR);
|
|
tmp |= 0x1 << 1;
|
|
write_wvalue(BLD_OUT_COLOR, tmp);
|
|
} else
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
__s32 mixer_fillrectangle(g2d_fillrect *para)
|
|
{
|
|
g2d_image_enh src_tmp, dst_tmp;
|
|
g2d_image_enh *src = &src_tmp;
|
|
g2d_image_enh *dst = &dst_tmp;
|
|
__s32 result;
|
|
|
|
g2d_mixer_reset();
|
|
if (para->flag == G2D_FIL_NONE) {
|
|
pr_info("fc only!\n");
|
|
dst->bbuff = 1;
|
|
dst->color = para->color;
|
|
dst->format =
|
|
g2d_format_trans(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
dst->laddr[0] = para->dst_image.addr[0];
|
|
dst->laddr[1] = para->dst_image.addr[1];
|
|
dst->laddr[2] = para->dst_image.addr[2];
|
|
dst->width = para->dst_image.w;
|
|
dst->height = para->dst_image.h;
|
|
dst->clip_rect.x = para->dst_rect.x;
|
|
dst->clip_rect.y = para->dst_rect.y;
|
|
dst->clip_rect.w = para->dst_rect.w;
|
|
dst->clip_rect.h = para->dst_rect.h;
|
|
dst->gamut = G2D_BT709;
|
|
dst->alpha = para->alpha;
|
|
dst->mode = 0;
|
|
result = g2d_fillrectangle(dst, dst->color);
|
|
return result;
|
|
}
|
|
dst->bbuff = 1;
|
|
dst->color = para->color;
|
|
dst->format =
|
|
g2d_format_trans(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
dst->laddr[0] = para->dst_image.addr[0];
|
|
dst->laddr[1] = para->dst_image.addr[1];
|
|
dst->laddr[2] = para->dst_image.addr[2];
|
|
dst->width = para->dst_image.w;
|
|
dst->height = para->dst_image.h;
|
|
dst->clip_rect.x = para->dst_rect.x;
|
|
dst->clip_rect.y = para->dst_rect.y;
|
|
dst->clip_rect.w = para->dst_rect.w;
|
|
dst->clip_rect.h = para->dst_rect.h;
|
|
dst->gamut = G2D_BT709;
|
|
dst->alpha = para->alpha;
|
|
if (para->flag & G2D_FIL_PIXEL_ALPHA)
|
|
dst->mode = G2D_PIXEL_ALPHA;
|
|
if (para->flag & G2D_FIL_PLANE_ALPHA)
|
|
dst->mode = G2D_GLOBAL_ALPHA;
|
|
if (para->flag & G2D_FIL_MULTI_ALPHA)
|
|
dst->mode = G2D_MIXER_ALPHA;
|
|
src->bbuff = 0;
|
|
src->color = para->color;
|
|
src->format = dst->format;
|
|
src->gamut = G2D_BT709;
|
|
src->format = 0;
|
|
dst->laddr[0] = para->dst_image.addr[0];
|
|
src->width = para->dst_image.w;
|
|
src->height = para->dst_image.h;
|
|
src->clip_rect.x = para->dst_rect.x;
|
|
src->clip_rect.y = para->dst_rect.y;
|
|
src->clip_rect.w = para->dst_rect.w;
|
|
src->clip_rect.h = para->dst_rect.h;
|
|
result = g2d_bsp_bld(src, dst, G2D_BLD_DSTOVER, NULL);
|
|
return result;
|
|
}
|
|
|
|
__s32 g2d_fillrectangle(g2d_image_enh *dst, __u32 color_value)
|
|
{
|
|
g2d_rect rect0;
|
|
__u32 tmp;
|
|
__s32 result;
|
|
|
|
g2d_bsp_reset();
|
|
/* set the input layer */
|
|
g2d_vlayer_set(0, dst);
|
|
/* set the fill color value */
|
|
g2d_fc_set(0, color_value);
|
|
if (dst->format >= G2D_FORMAT_IYUV422_V0Y1U0Y0) {
|
|
g2d_vsu_para_set(dst->format, dst->clip_rect.w,
|
|
dst->clip_rect.h, dst->clip_rect.w,
|
|
dst->clip_rect.h, 0xff);
|
|
g2d_csc_reg_set(1, G2D_RGB2YUV_709);
|
|
}
|
|
|
|
/* for interleaved test */
|
|
if ((dst->format >= G2D_FORMAT_IYUV422_V0Y1U0Y0)
|
|
&& (dst->format <= G2D_FORMAT_IYUV422_Y1U0Y0V0)) {
|
|
g2d_csc_reg_set(0, G2D_RGB2YUV_709);
|
|
g2d_csc_reg_set(2, G2D_RGB2YUV_709);
|
|
write_wvalue(BLD_CSC_CTL, 0x2);
|
|
g2d_bk_set(0xff123456);
|
|
porter_duff(G2D_BLD_SRCOVER);
|
|
write_wvalue(BLD_FILLC0, 0x00108080);
|
|
write_wvalue(BLD_FILLC1, 0x00108080);
|
|
write_wvalue(UI0_FILLC, 0xffffffff);
|
|
write_wvalue(UI1_FILLC, 0xffffffff);
|
|
}
|
|
rect0.x = 0;
|
|
rect0.y = 0;
|
|
rect0.w = dst->clip_rect.w;
|
|
rect0.h = dst->clip_rect.h;
|
|
g2d_bldin_set(0, rect0, dst->bpremul);
|
|
g2d_bld_cs_set(dst->format);
|
|
|
|
/* ROP sel ch0 pass */
|
|
write_wvalue(ROP_CTL, 0xf0);
|
|
g2d_wb_set(dst);
|
|
|
|
/* start the module */
|
|
mixer_irq_enable();
|
|
tmp = read_wvalue(G2D_MIXER_CTL);
|
|
tmp |= 0x80000000;
|
|
G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
|
|
write_wvalue(G2D_MIXER_CTL, tmp);
|
|
|
|
result = g2d_wait_cmd_finish();
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* src:source
|
|
* ptn:pattern
|
|
* dst:destination
|
|
* mask:mask
|
|
* if mask is set to NULL, do ROP3 among src, ptn, and dst using the
|
|
* fore_flag
|
|
*/
|
|
__s32 g2d_bsp_maskblt(g2d_image_enh *src, g2d_image_enh *ptn,
|
|
g2d_image_enh *mask, g2d_image_enh *dst,
|
|
__u32 back_flag, __u32 fore_flag)
|
|
{
|
|
__u32 tmp;
|
|
g2d_rect rect0;
|
|
bool b_pre;
|
|
__s32 result;
|
|
|
|
/* int b_pre; */
|
|
g2d_bsp_reset();
|
|
if (dst == NULL)
|
|
return -1;
|
|
if (dst->format > G2D_FORMAT_BGRA1010102)
|
|
return -2;
|
|
g2d_vlayer_set(0, dst);
|
|
if (src != NULL) {
|
|
src->clip_rect.w = dst->clip_rect.w;
|
|
src->clip_rect.h = dst->clip_rect.h;
|
|
g2d_uilayer_set(0, src);
|
|
}
|
|
if (ptn != NULL) {
|
|
ptn->clip_rect.w = dst->clip_rect.w;
|
|
ptn->clip_rect.h = dst->clip_rect.h;
|
|
g2d_uilayer_set(1, ptn);
|
|
}
|
|
if (mask != NULL) {
|
|
mask->clip_rect.w = dst->clip_rect.w;
|
|
mask->clip_rect.h = dst->clip_rect.h;
|
|
g2d_uilayer_set(2, mask);
|
|
|
|
/* set the ROP4 */
|
|
write_wvalue(ROP_CTL, 0x1);
|
|
g2d_rop3_set(0, back_flag & 0xff);
|
|
g2d_rop3_set(1, fore_flag & 0xff);
|
|
} else {
|
|
write_wvalue(ROP_CTL, 0x0);
|
|
g2d_rop3_set(0, back_flag);
|
|
}
|
|
b_pre = dst->bpremul;
|
|
if (src)
|
|
b_pre |= src->bpremul;
|
|
if (ptn)
|
|
b_pre |= ptn->bpremul;
|
|
if (b_pre) {
|
|
/* some layer is not premul */
|
|
if (!src->bpremul) {
|
|
tmp = read_wvalue(UI0_ATTR);
|
|
tmp |= 0x1 << 16;
|
|
write_wvalue(UI0_ATTR, tmp);
|
|
}
|
|
if (!dst->bpremul) {
|
|
tmp = read_wvalue(V0_ATTCTL);
|
|
tmp |= 0x1 << 16;
|
|
write_wvalue(V0_ATTCTL, tmp);
|
|
}
|
|
if (!ptn->bpremul) {
|
|
tmp = read_wvalue(UI1_ATTR);
|
|
tmp |= 0x1 << 16;
|
|
write_wvalue(UI1_ATTR, tmp);
|
|
}
|
|
|
|
/* set bld in premul data */
|
|
write_wvalue(BLD_PREMUL_CTL, 0x1);
|
|
}
|
|
|
|
/*set bld para */
|
|
rect0.x = 0;
|
|
rect0.y = 0;
|
|
rect0.w = dst->clip_rect.w;
|
|
rect0.h = dst->clip_rect.h;
|
|
g2d_bldin_set(0, rect0, dst->bpremul);
|
|
g2d_wb_set(dst);
|
|
|
|
/* start the module */
|
|
mixer_irq_enable();
|
|
tmp = read_wvalue(G2D_MIXER_CTL);
|
|
tmp |= 0x80000000;
|
|
G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
|
|
write_wvalue(G2D_MIXER_CTL, tmp);
|
|
|
|
result = g2d_wait_cmd_finish();
|
|
return result;
|
|
}
|
|
|
|
__s32 g2d_format_trans(__s32 data_fmt, __s32 pixel_seq)
|
|
{
|
|
/* transform the g2d format 2 enhance format */
|
|
switch (data_fmt) {
|
|
case G2D_FMT_ARGB_AYUV8888:
|
|
return G2D_FORMAT_ARGB8888;
|
|
case G2D_FMT_BGRA_VUYA8888:
|
|
return G2D_FORMAT_BGRA8888;
|
|
case G2D_FMT_ABGR_AVUY8888:
|
|
return G2D_FORMAT_ABGR8888;
|
|
case G2D_FMT_RGBA_YUVA8888:
|
|
return G2D_FORMAT_RGBA8888;
|
|
case G2D_FMT_XRGB8888:
|
|
return G2D_FORMAT_XRGB8888;
|
|
case G2D_FMT_BGRX8888:
|
|
return G2D_FORMAT_BGRX8888;
|
|
case G2D_FMT_XBGR8888:
|
|
return G2D_FORMAT_XBGR8888;
|
|
case G2D_FMT_RGBX8888:
|
|
return G2D_FORMAT_RGBX8888;
|
|
case G2D_FMT_ARGB4444:
|
|
return G2D_FORMAT_ARGB4444;
|
|
case G2D_FMT_ABGR4444:
|
|
return G2D_FORMAT_ABGR4444;
|
|
case G2D_FMT_RGBA4444:
|
|
return G2D_FORMAT_RGBA4444;
|
|
case G2D_FMT_BGRA4444:
|
|
return G2D_FORMAT_BGRA4444;
|
|
case G2D_FMT_ARGB1555:
|
|
return G2D_FORMAT_ARGB1555;
|
|
case G2D_FMT_ABGR1555:
|
|
return G2D_FORMAT_ABGR1555;
|
|
case G2D_FMT_RGBA5551:
|
|
return G2D_FORMAT_RGBA5551;
|
|
case G2D_FMT_BGRA5551:
|
|
return G2D_FORMAT_BGRA5551;
|
|
case G2D_FMT_RGB565:
|
|
return G2D_FORMAT_RGB565;
|
|
case G2D_FMT_BGR565:
|
|
return G2D_FORMAT_BGR565;
|
|
case G2D_FMT_IYUV422:
|
|
if (pixel_seq == G2D_SEQ_VYUY)
|
|
return G2D_FORMAT_IYUV422_V0Y1U0Y0;
|
|
if (pixel_seq == G2D_SEQ_YVYU)
|
|
return G2D_FORMAT_IYUV422_Y1V0Y0U0;
|
|
return -1;
|
|
case G2D_FMT_PYUV422UVC:
|
|
if (pixel_seq == G2D_SEQ_VUVU)
|
|
return G2D_FORMAT_YUV422UVC_V1U1V0U0;
|
|
return G2D_FORMAT_YUV422UVC_U1V1U0V0;
|
|
case G2D_FMT_PYUV420UVC:
|
|
if (pixel_seq == G2D_SEQ_VUVU)
|
|
return G2D_FORMAT_YUV420UVC_V1U1V0U0;
|
|
return G2D_FORMAT_YUV420UVC_U1V1U0V0;
|
|
case G2D_FMT_PYUV411UVC:
|
|
if (pixel_seq == G2D_SEQ_VUVU)
|
|
return G2D_FORMAT_YUV411UVC_V1U1V0U0;
|
|
return G2D_FORMAT_YUV411UVC_U1V1U0V0;
|
|
case G2D_FMT_PYUV422:
|
|
return G2D_FORMAT_YUV422_PLANAR;
|
|
case G2D_FMT_PYUV420:
|
|
return G2D_FORMAT_YUV420_PLANAR;
|
|
case G2D_FMT_PYUV411:
|
|
return G2D_FORMAT_YUV411_PLANAR;
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
__s32 mixer_stretchblt(g2d_stretchblt *para,
|
|
enum g2d_scan_order scan_order)
|
|
{
|
|
g2d_image_enh src_tmp, dst_tmp, tmp_tmp;
|
|
g2d_image_enh *src = &src_tmp, *dst = &dst_tmp;
|
|
g2d_image_enh *tmp_img = &tmp_tmp;
|
|
g2d_ck ck_para_tmp;
|
|
g2d_ck *ck_para = &ck_para_tmp;
|
|
__s32 ycnt, ucnt, vcnt;
|
|
__s32 result;
|
|
|
|
g2d_mixer_reset();
|
|
memset(src, 0, sizeof(g2d_image_enh));
|
|
memset(dst, 0, sizeof(g2d_image_enh));
|
|
memset(tmp_img, 0, sizeof(g2d_image_enh));
|
|
memset(ck_para, 0, sizeof(g2d_ck));
|
|
|
|
src->bbuff = 1;
|
|
src->color = para->color;
|
|
src->format =
|
|
g2d_format_trans(para->src_image.format,
|
|
para->src_image.pixel_seq);
|
|
src->laddr[0] = para->src_image.addr[0];
|
|
src->laddr[1] = para->src_image.addr[1];
|
|
src->laddr[2] = para->src_image.addr[2];
|
|
src->width = para->src_image.w;
|
|
src->height = para->src_image.h;
|
|
src->clip_rect.x = para->src_rect.x;
|
|
src->clip_rect.y = para->src_rect.y;
|
|
src->clip_rect.w = para->src_rect.w;
|
|
src->clip_rect.h = para->src_rect.h;
|
|
src->gamut = G2D_BT709;
|
|
src->alpha = para->alpha;
|
|
dst->bbuff = 1;
|
|
dst->color = para->color;
|
|
dst->format =
|
|
g2d_format_trans(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
dst->laddr[0] = para->dst_image.addr[0];
|
|
dst->laddr[1] = para->dst_image.addr[1];
|
|
dst->laddr[2] = para->dst_image.addr[2];
|
|
dst->width = para->dst_image.w;
|
|
dst->height = para->dst_image.h;
|
|
dst->clip_rect.x = para->dst_rect.x;
|
|
dst->clip_rect.y = para->dst_rect.y;
|
|
dst->clip_rect.w = para->dst_rect.w;
|
|
dst->clip_rect.h = para->dst_rect.h;
|
|
dst->gamut = G2D_BT709;
|
|
dst->alpha = para->alpha;
|
|
if (para->flag == G2D_BLT_NONE) {
|
|
/* not ROT case */
|
|
dst->format = g2d_format_trans(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
if (scan_order == G2D_SM_DTLR)
|
|
result = g2d_bsp_bitblt(src, dst, G2D_BLT_NONE |
|
|
G2D_SM_DTLR_1);
|
|
else
|
|
result = g2d_bsp_bitblt(src, dst, G2D_BLT_NONE);
|
|
|
|
return result;
|
|
|
|
} else {
|
|
|
|
tmp_img->bbuff = 1;
|
|
tmp_img->color = para->color;
|
|
tmp_img->format =
|
|
g2d_format_trans(para->src_image.format,
|
|
para->src_image.pixel_seq);
|
|
g2d_byte_cal(src->format, &ycnt, &ucnt, &vcnt);
|
|
tmp_img->laddr[0] =
|
|
para->src_image.addr[0] +
|
|
src->width * src->height * ycnt;
|
|
tmp_img->laddr[1] = para->src_image.addr[1];
|
|
tmp_img->laddr[2] = para->src_image.addr[2];
|
|
tmp_img->width = para->dst_image.w;
|
|
tmp_img->height = para->dst_image.h;
|
|
tmp_img->clip_rect.x = para->dst_rect.x;
|
|
tmp_img->clip_rect.y = para->dst_rect.x;
|
|
tmp_img->gamut = G2D_BT709;
|
|
tmp_img->alpha = para->alpha;
|
|
if (para->flag & G2D_BLT_SRC_PREMULTIPLY) {
|
|
src->bpremul = 1;
|
|
tmp_img->bpremul = 1;
|
|
dst->bpremul = 1;
|
|
}
|
|
if (para->flag & G2D_BLT_PIXEL_ALPHA) {
|
|
src->mode = G2D_PIXEL_ALPHA;
|
|
tmp_img->mode = G2D_PIXEL_ALPHA;
|
|
dst->mode = G2D_PIXEL_ALPHA;
|
|
}
|
|
if (para->flag & G2D_BLT_PLANE_ALPHA) {
|
|
src->mode = G2D_GLOBAL_ALPHA;
|
|
tmp_img->mode = G2D_GLOBAL_ALPHA;
|
|
dst->mode = G2D_GLOBAL_ALPHA;
|
|
}
|
|
if (para->flag & G2D_BLT_MULTI_ALPHA) {
|
|
src->mode = G2D_MIXER_ALPHA;
|
|
tmp_img->mode = G2D_MIXER_ALPHA;
|
|
dst->mode = G2D_MIXER_ALPHA;
|
|
}
|
|
ck_para->match_rule = 0;
|
|
ck_para->max_color = para->color;
|
|
ck_para->min_color = para->color;
|
|
if (para->flag & 0xfe0) {
|
|
switch (para->flag & 0xfe0) {
|
|
case G2D_BLT_FLIP_HORIZONTAL:
|
|
pr_info("HFLIP\n");
|
|
g2d_bsp_bitblt(src, tmp_img, G2D_ROT_H);
|
|
break;
|
|
case G2D_BLT_FLIP_VERTICAL:
|
|
pr_info("VFLIP\n");
|
|
g2d_bsp_bitblt(src, tmp_img, G2D_ROT_V);
|
|
break;
|
|
case G2D_BLT_ROTATE90:
|
|
pr_info("ROT90\n");
|
|
g2d_bsp_bitblt(src, tmp_img,
|
|
G2D_ROT_90);
|
|
break;
|
|
case G2D_BLT_ROTATE180:
|
|
pr_info("ROT180\n");
|
|
g2d_bsp_bitblt(src, tmp_img,
|
|
G2D_ROT_180);
|
|
break;
|
|
case G2D_BLT_ROTATE270:
|
|
pr_info("ROT270\n");
|
|
g2d_bsp_bitblt(src, tmp_img,
|
|
G2D_ROT_270);
|
|
break;
|
|
case G2D_BLT_MIRROR45:
|
|
pr_info("ROT45\n");
|
|
g2d_bsp_bitblt(src, tmp_img,
|
|
G2D_ROT_90 | G2D_ROT_H);
|
|
break;
|
|
case G2D_BLT_MIRROR135:
|
|
pr_info("ROT135\n");
|
|
g2d_bsp_bitblt(src, tmp_img,
|
|
G2D_ROT_90 | G2D_ROT_V);
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
result = g2d_bsp_bitblt(tmp_img, dst, G2D_BLT_NONE);
|
|
} else
|
|
result = g2d_bsp_bitblt(src, dst, G2D_BLT_NONE);
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
__s32 mixer_blt(g2d_blt *para, enum g2d_scan_order scan_order)
|
|
{
|
|
g2d_image_enh src_tmp, dst_tmp, tmp_tmp;
|
|
g2d_image_enh *src = &src_tmp;
|
|
g2d_image_enh *dst = &dst_tmp;
|
|
g2d_image_enh *tmp_img = &tmp_tmp;
|
|
g2d_ck ck_para_tmp;
|
|
g2d_ck *ck_para = &ck_para_tmp;
|
|
__s32 ycnt, ucnt, vcnt;
|
|
|
|
memset(src, 0, sizeof(g2d_image_enh));
|
|
memset(dst, 0, sizeof(g2d_image_enh));
|
|
memset(tmp_img, 0, sizeof(g2d_image_enh));
|
|
memset(ck_para, 0, sizeof(g2d_ck));
|
|
|
|
G2D_INFO_MSG("Input_G2D_Format: 0x%x\n", para->src_image.format);
|
|
G2D_INFO_MSG("BITBLT_flag: 0x%x\n", para->flag);
|
|
G2D_INFO_MSG("inPICWidth: %d\n", para->src_image.w);
|
|
G2D_INFO_MSG("inPICHeight: %d\n", para->src_image.h);
|
|
G2D_INFO_MSG("inRectX: %d\n", para->src_rect.x);
|
|
G2D_INFO_MSG("inRectY: %d\n", para->src_rect.y);
|
|
G2D_INFO_MSG("inRectW: %d\n", para->src_rect.w);
|
|
G2D_INFO_MSG("inRectH: %d\n", para->src_rect.h);
|
|
G2D_INFO_MSG("Output_G2D_Format: 0x%x\n", para->dst_image.format);
|
|
G2D_INFO_MSG("outPICWidth: %d\n", para->dst_image.w);
|
|
G2D_INFO_MSG("outPICHeight: %d\n", para->dst_image.h);
|
|
G2D_INFO_MSG("outRectX: %d\n", para->dst_x);
|
|
G2D_INFO_MSG("outRectY: %d\n", para->dst_y);
|
|
src->bbuff = 1;
|
|
src->color = para->color;
|
|
src->format =
|
|
g2d_format_trans(para->src_image.format,
|
|
para->src_image.pixel_seq);
|
|
src->laddr[0] = para->src_image.addr[0];
|
|
src->laddr[1] = para->src_image.addr[1];
|
|
src->laddr[2] = para->src_image.addr[2];
|
|
src->width = para->src_image.w;
|
|
src->height = para->src_image.h;
|
|
src->clip_rect.x = para->src_rect.x;
|
|
src->clip_rect.y = para->src_rect.y;
|
|
src->clip_rect.w = para->src_rect.w;
|
|
src->clip_rect.h = para->src_rect.h;
|
|
src->gamut = G2D_BT709;
|
|
src->alpha = para->alpha;
|
|
dst->bbuff = 1;
|
|
dst->format =
|
|
g2d_format_trans(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
dst->laddr[0] = para->dst_image.addr[0];
|
|
dst->laddr[1] = para->dst_image.addr[1];
|
|
dst->laddr[2] = para->dst_image.addr[2];
|
|
dst->width = para->dst_image.w;
|
|
dst->height = para->dst_image.h;
|
|
dst->clip_rect.x = para->dst_x;
|
|
dst->clip_rect.y = para->dst_y;
|
|
dst->clip_rect.w = src->clip_rect.w;
|
|
dst->clip_rect.h = src->clip_rect.h;
|
|
dst->gamut = G2D_BT709;
|
|
dst->alpha = para->alpha;
|
|
|
|
G2D_INFO_MSG("inPICaddr0: 0x%x\n", src->laddr[0]);
|
|
G2D_INFO_MSG("inPICaddr1: 0x%x\n", src->laddr[1]);
|
|
G2D_INFO_MSG("inPICaddr2: 0x%x\n", src->laddr[2]);
|
|
G2D_INFO_MSG("outPICaddr0: 0x%x\n", dst->laddr[0]);
|
|
G2D_INFO_MSG("outPICaddr1: 0x%x\n", dst->laddr[1]);
|
|
G2D_INFO_MSG("outPICaddr2: 0x%x\n", dst->laddr[2]);
|
|
|
|
if ((para->flag == G2D_BLT_NONE) ||
|
|
(para->flag == G2D_BLT_FLIP_HORIZONTAL) ||
|
|
(para->flag == G2D_BLT_FLIP_VERTICAL) ||
|
|
(para->flag == G2D_BLT_ROTATE90) ||
|
|
(para->flag == G2D_BLT_ROTATE180) ||
|
|
(para->flag == G2D_BLT_ROTATE270) ||
|
|
(para->flag == G2D_BLT_MIRROR45) ||
|
|
(para->flag == G2D_BLT_MIRROR135)) {
|
|
/* ROT case */
|
|
switch (para->flag) {
|
|
case G2D_BLT_NONE:
|
|
if (scan_order == G2D_SM_DTLR)
|
|
g2d_bsp_bitblt(src, dst,
|
|
G2D_BLT_NONE | G2D_SM_DTLR_1);
|
|
else
|
|
g2d_bsp_bitblt(src, dst, G2D_BLT_NONE);
|
|
return 0;
|
|
case G2D_BLT_FLIP_HORIZONTAL:
|
|
g2d_bsp_bitblt(src, dst, G2D_ROT_H);
|
|
return 0;
|
|
case G2D_BLT_FLIP_VERTICAL:
|
|
g2d_bsp_bitblt(src, dst, G2D_ROT_V);
|
|
return 0;
|
|
case G2D_BLT_ROTATE90:
|
|
g2d_bsp_bitblt(src, dst, G2D_ROT_90);
|
|
return 0;
|
|
case G2D_BLT_ROTATE180:
|
|
g2d_bsp_bitblt(src, dst, G2D_ROT_180);
|
|
return 0;
|
|
case G2D_BLT_ROTATE270:
|
|
g2d_bsp_bitblt(src, dst, G2D_ROT_270);
|
|
return 0;
|
|
case G2D_BLT_MIRROR45:
|
|
g2d_bsp_bitblt(src, dst, G2D_ROT_90 | G2D_ROT_H);
|
|
return 0;
|
|
case G2D_BLT_MIRROR135:
|
|
g2d_bsp_bitblt(src, dst, G2D_ROT_90 | G2D_ROT_V);
|
|
return 0;
|
|
default:
|
|
return -1;
|
|
}
|
|
} else {
|
|
tmp_img->bbuff = 1;
|
|
tmp_img->format = src->format;
|
|
tmp_img->color = para->color;
|
|
tmp_img->format = src->format;
|
|
g2d_byte_cal(src->format, &ycnt, &ucnt, &vcnt);
|
|
tmp_img->laddr[0] =
|
|
para->src_image.addr[0] + src->height * src->width * ycnt;
|
|
tmp_img->width = para->dst_image.w;
|
|
tmp_img->height = para->dst_image.h;
|
|
tmp_img->clip_rect.x = para->dst_x;
|
|
tmp_img->clip_rect.y = para->dst_y;
|
|
tmp_img->gamut = G2D_BT709;
|
|
tmp_img->alpha = para->alpha;
|
|
|
|
G2D_INFO_MSG("tmpPICaddr0: 0x%x\n", tmp_img->laddr[0]);
|
|
|
|
if (para->flag & G2D_BLT_SRC_PREMULTIPLY)
|
|
dst->bpremul = 1;
|
|
if (para->flag & G2D_BLT_PIXEL_ALPHA)
|
|
dst->mode = G2D_PIXEL_ALPHA;
|
|
if (para->flag & G2D_BLT_PLANE_ALPHA)
|
|
dst->mode = G2D_GLOBAL_ALPHA;
|
|
if (para->flag & G2D_BLT_MULTI_ALPHA)
|
|
dst->mode = G2D_MIXER_ALPHA;
|
|
if (para->flag & G2D_BLT_SRC_PREMULTIPLY) {
|
|
src->bpremul = 1;
|
|
tmp_img->bpremul = 1;
|
|
}
|
|
if (para->flag & G2D_BLT_PIXEL_ALPHA) {
|
|
src->mode = G2D_PIXEL_ALPHA;
|
|
tmp_img->mode = G2D_PIXEL_ALPHA;
|
|
}
|
|
if (para->flag & G2D_BLT_PLANE_ALPHA) {
|
|
src->mode = G2D_GLOBAL_ALPHA;
|
|
tmp_img->mode = G2D_GLOBAL_ALPHA;
|
|
}
|
|
if (para->flag & G2D_BLT_MULTI_ALPHA) {
|
|
src->mode = G2D_MIXER_ALPHA;
|
|
tmp_img->mode = G2D_MIXER_ALPHA;
|
|
}
|
|
ck_para->match_rule = 0;
|
|
ck_para->max_color = para->color;
|
|
ck_para->min_color = para->color;
|
|
if (para->flag & 0xfe0) {
|
|
switch (para->flag & 0xfe0) {
|
|
case G2D_BLT_FLIP_HORIZONTAL:
|
|
pr_info("HFLIP\n");
|
|
g2d_bsp_bitblt(src, tmp_img, G2D_ROT_H);
|
|
break;
|
|
case G2D_BLT_FLIP_VERTICAL:
|
|
pr_info("VFLIP\n");
|
|
g2d_bsp_bitblt(src, tmp_img, G2D_ROT_V);
|
|
break;
|
|
case G2D_BLT_ROTATE90:
|
|
pr_info("ROT90\n");
|
|
g2d_bsp_bitblt(src, tmp_img, G2D_ROT_90);
|
|
break;
|
|
case G2D_BLT_ROTATE180:
|
|
pr_info("ROT180\n");
|
|
g2d_bsp_bitblt(src, tmp_img, G2D_ROT_180);
|
|
break;
|
|
case G2D_BLT_ROTATE270:
|
|
pr_info("ROT270\n");
|
|
g2d_bsp_bitblt(src, tmp_img, G2D_ROT_270);
|
|
break;
|
|
case G2D_BLT_MIRROR45:
|
|
pr_info("ROT45\n");
|
|
g2d_bsp_bitblt(src, tmp_img,
|
|
G2D_ROT_90 | G2D_ROT_H);
|
|
break;
|
|
case G2D_BLT_MIRROR135:
|
|
pr_info("ROT135\n");
|
|
g2d_bsp_bitblt(src, tmp_img,
|
|
G2D_ROT_90 | G2D_ROT_V);
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
G2D_INFO_MSG("tmpRectX: %d\n",
|
|
tmp_img->clip_rect.x);
|
|
G2D_INFO_MSG("tmpRectY: %d\n", tmp_img->clip_rect.y);
|
|
G2D_INFO_MSG("tmpRectW: %d\n", tmp_img->clip_rect.w);
|
|
G2D_INFO_MSG("tmpRectH: %d\n", tmp_img->clip_rect.h);
|
|
pr_info("begin BLD OPER!\n");
|
|
dst->clip_rect.w = tmp_img->clip_rect.w;
|
|
dst->clip_rect.h = tmp_img->clip_rect.h;
|
|
|
|
/*g2d_bsp_bitblt(tmp_img, dst, G2D_BLT_NONE); */
|
|
g2d_bsp_bld(tmp_img, dst, G2D_BLD_DSTOVER, NULL);
|
|
} else {
|
|
/*g2d_bsp_bitblt(tmp_img, dst, G2D_BLT_NONE); */
|
|
g2d_bsp_bld(src, dst, G2D_BLD_DSTOVER, NULL);
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
__s32 g2d_bsp_bitblt(g2d_image_enh *src, g2d_image_enh *dst, __u32 flag)
|
|
{
|
|
g2d_rect rect0, rect1;
|
|
bool bpre;
|
|
__u32 ycnt, ucnt, vcnt;
|
|
__u32 pitch0, pitch1, pitch2;
|
|
__u64 addr0, addr1, addr2;
|
|
__u32 midw, midh;
|
|
__u32 tmp;
|
|
__s32 result;
|
|
|
|
g2d_bsp_reset();
|
|
if (dst == NULL)
|
|
return -1;
|
|
if (src == NULL)
|
|
return -2;
|
|
G2D_INFO_MSG("BITBLT_flag: 0x%x\n", flag);
|
|
if (G2D_BLT_NONE == (flag & 0x0fffffff)) {
|
|
G2D_INFO_MSG("Input info:---------------------------------\n");
|
|
G2D_INFO_MSG("Src_fd: %d\n", src->fd);
|
|
G2D_INFO_MSG("Format: 0x%x\n", src->format);
|
|
G2D_INFO_MSG("BITBLT_alpha_mode: 0x%x\n", src->mode);
|
|
G2D_INFO_MSG("BITBLT_alpha_val: 0x%x\n", src->alpha);
|
|
G2D_INFO_MSG("inClipRectX: %d\n", src->clip_rect.x);
|
|
G2D_INFO_MSG("inClipRectY: %d\n", src->clip_rect.y);
|
|
G2D_INFO_MSG("inClipRectW: %d\n", src->clip_rect.w);
|
|
G2D_INFO_MSG("inClipRectH: %d\n", src->clip_rect.h);
|
|
|
|
G2D_INFO_MSG("Output info:--------------------------------\n");
|
|
G2D_INFO_MSG("Dst_fd: %d\n", dst->fd);
|
|
G2D_INFO_MSG("Format: 0x%x\n", dst->format);
|
|
G2D_INFO_MSG("outClipRectX: %d\n", dst->clip_rect.x);
|
|
G2D_INFO_MSG("outClipRectY: %d\n", dst->clip_rect.y);
|
|
G2D_INFO_MSG("outClipRectW: %d\n", dst->clip_rect.w);
|
|
G2D_INFO_MSG("outClipRectH: %d\n", dst->clip_rect.h);
|
|
/*single src opt */
|
|
g2d_vlayer_set(0, src);
|
|
if (src->mode) {
|
|
/* need abp process */
|
|
g2d_uilayer_set(2, dst);
|
|
}
|
|
if ((src->format >= G2D_FORMAT_IYUV422_V0Y1U0Y0) ||
|
|
(src->clip_rect.w != dst->clip_rect.w) ||
|
|
(src->clip_rect.h != dst->clip_rect.h)) {
|
|
g2d_calc_coarse(src->format, src->clip_rect.w,
|
|
src->clip_rect.h, dst->clip_rect.w,
|
|
dst->clip_rect.h, &midw, &midh);
|
|
g2d_vsu_para_set(src->format, midw, midh,
|
|
dst->clip_rect.w, dst->clip_rect.h,
|
|
0xff);
|
|
}
|
|
write_wvalue(ROP_CTL, 0xf0);
|
|
/*set bld para */
|
|
rect0.x = 0;
|
|
rect0.y = 0;
|
|
rect0.w = dst->clip_rect.w;
|
|
rect0.h = dst->clip_rect.h;
|
|
g2d_bldin_set(0, rect0, dst->bpremul);
|
|
g2d_bld_cs_set(src->format);
|
|
if (src->mode) {
|
|
/* need abp process */
|
|
rect1.x = 0;
|
|
rect1.y = 0;
|
|
rect1.w = dst->clip_rect.w;
|
|
rect1.h = dst->clip_rect.h;
|
|
g2d_bldin_set(1, rect1, dst->bpremul);
|
|
}
|
|
if ((src->format <= G2D_FORMAT_BGRA1010102) &&
|
|
(dst->format > G2D_FORMAT_BGRA1010102)) {
|
|
g2d_csc_reg_set(2, G2D_RGB2YUV_709);
|
|
}
|
|
if ((src->format > G2D_FORMAT_BGRA1010102) &&
|
|
(dst->format <= G2D_FORMAT_BGRA1010102)) {
|
|
g2d_csc_reg_set(2, G2D_YUV2RGB_709);
|
|
}
|
|
g2d_wb_set(dst);
|
|
}
|
|
|
|
else if (flag & 0xff) {
|
|
/* ROP2 operate */
|
|
if ((src->format > G2D_FORMAT_BGRA1010102) | (dst->format >
|
|
G2D_FORMAT_BGRA1010102))
|
|
return -3;
|
|
g2d_uilayer_set(0, dst);
|
|
g2d_vlayer_set(0, src);
|
|
|
|
/* bpre = 0; */
|
|
bpre = false;
|
|
if (src->bpremul || dst->bpremul) {
|
|
bpre = true;
|
|
/* bpre = 1; */
|
|
/* some layer is premul */
|
|
if (!src->bpremul) {
|
|
tmp = read_wvalue(V0_ATTCTL);
|
|
tmp |= 0x1 << 16;
|
|
write_wvalue(V0_ATTCTL, tmp);
|
|
}
|
|
if (!dst->bpremul) {
|
|
tmp = read_wvalue(UI0_ATTR);
|
|
tmp |= 0x1 << 16;
|
|
write_wvalue(UI0_ATTR, tmp);
|
|
}
|
|
}
|
|
if ((src->clip_rect.w != dst->clip_rect.w)
|
|
|| (src->clip_rect.h != dst->clip_rect.h)) {
|
|
g2d_calc_coarse(src->format, src->clip_rect.w,
|
|
src->clip_rect.h, dst->clip_rect.w,
|
|
dst->clip_rect.h, &midw, &midh);
|
|
g2d_vsu_para_set(src->format, midw, midh,
|
|
dst->clip_rect.w, dst->clip_rect.h,
|
|
0xff);
|
|
}
|
|
write_wvalue(ROP_CTL, 0x0);
|
|
g2d_rop2_set(flag & 0xff);
|
|
tmp = read_wvalue(ROP_INDEX0);
|
|
tmp |= 0x2;
|
|
write_wvalue(ROP_INDEX0, tmp);
|
|
|
|
/*set bld para */
|
|
rect0.x = 0;
|
|
rect0.y = 0;
|
|
rect0.w = dst->clip_rect.w;
|
|
rect0.h = dst->clip_rect.h;
|
|
g2d_bldin_set(0, rect0, bpre);
|
|
g2d_wb_set(dst);
|
|
}
|
|
|
|
else if (flag & 0xff00) {
|
|
/* ROT operate */
|
|
tmp = 1;
|
|
if (flag & G2D_ROT_H)
|
|
tmp |= 0x1 << 7;
|
|
if (flag & G2D_ROT_V)
|
|
tmp |= 0x1 << 6;
|
|
if ((flag & 0xf00) == G2D_ROT_90)
|
|
tmp |= 0x1 << 4;
|
|
if ((flag & 0xf00) == G2D_ROT_180)
|
|
tmp |= 0x2 << 4;
|
|
if ((flag & 0xf00) == G2D_ROT_270)
|
|
tmp |= 0x3 << 4;
|
|
if ((flag & 0xf00) == G2D_ROT_0)
|
|
tmp |= 0x0 << 4;
|
|
|
|
G2D_INFO_MSG("ROT input info: ----------------------------\n");
|
|
G2D_INFO_MSG("Src_fd: %d\n", src->fd);
|
|
G2D_INFO_MSG("Format: 0x%x\n", src->format);
|
|
G2D_INFO_MSG("Flag: 0x%x\n", flag);
|
|
G2D_INFO_MSG("inClipRectX: %d\n", src->clip_rect.x);
|
|
G2D_INFO_MSG("inClipRectY: %d\n", src->clip_rect.y);
|
|
G2D_INFO_MSG("inClipRectW: %d\n", src->clip_rect.w);
|
|
G2D_INFO_MSG("inClipRectH: %d\n", src->clip_rect.h);
|
|
|
|
write_wvalue(ROT_CTL, tmp);
|
|
write_wvalue(ROT_IFMT, src->format & 0x3F);
|
|
write_wvalue(ROT_ISIZE,
|
|
((((src->clip_rect.h -
|
|
1) & 0x1fff) << 16)) | ((src->clip_rect.w -
|
|
1) & 0x1fff));
|
|
|
|
G2D_INFO_MSG("ROT_IFMT: 0x%x\n", read_wvalue(ROT_IFMT));
|
|
G2D_INFO_MSG("ROT_ISIZE: 0x%x\n", read_wvalue(ROT_ISIZE));
|
|
G2D_INFO_MSG("SRC_align: %d, %d, %d\n",
|
|
src->align[0], src->align[1], src->align[2]);
|
|
G2D_INFO_MSG("DST_align: %d, %d, %d\n",
|
|
dst->align[0], dst->align[1], dst->align[2]);
|
|
|
|
g2d_byte_cal(src->format, &ycnt, &ucnt, &vcnt);
|
|
pitch0 = cal_align(ycnt * src->width, src->align[0]);
|
|
write_wvalue(ROT_IPITCH0, pitch0);
|
|
pitch1 = cal_align(ucnt * (src->width >> 1), src->align[1]);
|
|
write_wvalue(ROT_IPITCH1, pitch1);
|
|
pitch2 = cal_align(vcnt * (src->width >> 1), src->align[2]);
|
|
write_wvalue(ROT_IPITCH2, pitch2);
|
|
|
|
G2D_INFO_MSG("ROT_InPITCH: %d, %d, %d\n",
|
|
pitch0, pitch1, pitch2);
|
|
addr0 =
|
|
src->laddr[0] + ((__u64) src->haddr[0] << 32) +
|
|
pitch0 * src->clip_rect.y + ycnt * src->clip_rect.x;
|
|
write_wvalue(ROT_ILADD0, addr0 & 0xffffffff);
|
|
write_wvalue(ROT_IHADD0, (addr0 >> 32) & 0xff);
|
|
addr1 =
|
|
src->laddr[1] + ((__u64) src->haddr[1] << 32) +
|
|
pitch1 * src->clip_rect.y + ucnt * src->clip_rect.x;
|
|
write_wvalue(ROT_ILADD1, addr1 & 0xffffffff);
|
|
write_wvalue(ROT_IHADD1, (addr1 >> 32) & 0xff);
|
|
addr2 =
|
|
src->laddr[2] + ((__u64) src->haddr[2] << 32) +
|
|
pitch2 * src->clip_rect.y + vcnt * src->clip_rect.x;
|
|
write_wvalue(ROT_ILADD2, addr2 & 0xffffffff);
|
|
write_wvalue(ROT_IHADD2, (addr2 >> 32) & 0xff);
|
|
|
|
if (((flag & 0xf00) == G2D_ROT_90) | ((flag & 0xf00) ==
|
|
G2D_ROT_270)) {
|
|
dst->clip_rect.w = src->clip_rect.h;
|
|
dst->clip_rect.h = src->clip_rect.w;
|
|
}
|
|
|
|
else {
|
|
dst->clip_rect.w = src->clip_rect.w;
|
|
dst->clip_rect.h = src->clip_rect.h;
|
|
}
|
|
write_wvalue(ROT_OSIZE,
|
|
((((dst->clip_rect.h -
|
|
1) & 0x1fff) << 16)) | ((dst->clip_rect.w -
|
|
1) & 0x1fff));
|
|
/* YUV output fmt only support 420 */
|
|
if (src->format == G2D_FORMAT_YUV422UVC_V1U1V0U0)
|
|
dst->format = G2D_FORMAT_YUV420UVC_V1U1V0U0;
|
|
else if (src->format == G2D_FORMAT_YUV422UVC_U1V1U0V0)
|
|
dst->format = G2D_FORMAT_YUV420UVC_U1V1U0V0;
|
|
else if (src->format == G2D_FORMAT_YUV422_PLANAR)
|
|
dst->format = G2D_FORMAT_YUV420_PLANAR;
|
|
else
|
|
dst->format = src->format;
|
|
|
|
g2d_byte_cal(dst->format, &ycnt, &ucnt, &vcnt);
|
|
G2D_INFO_MSG("ROT output info: ----------------------------\n");
|
|
G2D_INFO_MSG("Dst_fd: %d\n", dst->fd);
|
|
G2D_INFO_MSG("Format: 0x%x\n", dst->format);
|
|
|
|
pitch0 = cal_align(ycnt * dst->width, dst->align[0]);
|
|
write_wvalue(ROT_OPITCH0, pitch0);
|
|
pitch1 = cal_align(ucnt * (dst->width >> 1), dst->align[1]);
|
|
write_wvalue(ROT_OPITCH1, pitch1);
|
|
pitch2 = cal_align(vcnt * (dst->width >> 1), dst->align[2]);
|
|
write_wvalue(ROT_OPITCH2, pitch2);
|
|
|
|
G2D_INFO_MSG("ROT_OutPITCH: %d, %d, %d\n",
|
|
pitch0, pitch1, pitch2);
|
|
G2D_INFO_MSG("outClipRectX: %d\n", dst->clip_rect.x);
|
|
G2D_INFO_MSG("outClipRectY: %d\n", dst->clip_rect.y);
|
|
G2D_INFO_MSG("outClipRectW: %d\n", dst->clip_rect.w);
|
|
G2D_INFO_MSG("outClipRectH: %d\n", dst->clip_rect.h);
|
|
addr0 =
|
|
dst->laddr[0] + ((__u64) dst->haddr[0] << 32) +
|
|
pitch0 * dst->clip_rect.y + ycnt * dst->clip_rect.x;
|
|
write_wvalue(ROT_OLADD0, addr0 & 0xffffffff);
|
|
write_wvalue(ROT_OHADD0, (addr0 >> 32) & 0xff);
|
|
addr1 =
|
|
dst->laddr[1] + ((__u64) dst->haddr[1] << 32) +
|
|
pitch1 * dst->clip_rect.y + ucnt * dst->clip_rect.x;
|
|
write_wvalue(ROT_OLADD1, addr1 & 0xffffffff);
|
|
write_wvalue(ROT_OHADD1, (addr1 >> 32) & 0xff);
|
|
addr2 =
|
|
dst->laddr[2] + ((__u64) dst->haddr[2] << 32) +
|
|
pitch2 * dst->clip_rect.y + vcnt * dst->clip_rect.x;
|
|
write_wvalue(ROT_OLADD2, addr2 & 0xffffffff);
|
|
write_wvalue(ROT_OHADD2, (addr2 >> 32) & 0xff);
|
|
|
|
G2D_INFO_MSG("DST_ADDR0: 0x%x\n", dst->laddr[0]);
|
|
G2D_INFO_MSG("DST_ADDR1: 0x%x\n", dst->laddr[1]);
|
|
G2D_INFO_MSG("DST_ADDR2: 0x%x\n", dst->laddr[2]);
|
|
|
|
/* start the module */
|
|
rot_irq_enable();
|
|
tmp = read_wvalue(ROT_CTL);
|
|
tmp |= (0x1 << 31);
|
|
G2D_INFO_MSG("init_module: 0x%x\n", tmp);
|
|
write_wvalue(ROT_CTL, tmp);
|
|
|
|
result = g2d_wait_cmd_finish();
|
|
|
|
return result;
|
|
}
|
|
g2d_scan_order_fun(flag & 0xf0000000);
|
|
|
|
/* start the module */
|
|
mixer_irq_enable();
|
|
tmp = read_wvalue(G2D_MIXER_CTL);
|
|
tmp |= 0x80000000;
|
|
G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
|
|
write_wvalue(G2D_MIXER_CTL, tmp);
|
|
|
|
result = g2d_wait_cmd_finish();
|
|
return result;
|
|
}
|
|
|
|
__s32 g2d_bsp_bld(g2d_image_enh *src, g2d_image_enh *dst, __u32 flag,
|
|
g2d_ck *ck_para)
|
|
{
|
|
g2d_rect rect0, rect1;
|
|
__u32 tmp;
|
|
__s32 result;
|
|
|
|
if (dst == NULL)
|
|
return -1;
|
|
g2d_mixer_reset();
|
|
g2d_vlayer_set(0, dst);
|
|
g2d_uilayer_set(2, src);
|
|
if ((dst->format > G2D_FORMAT_BGRA1010102) &&
|
|
(src->format <= G2D_FORMAT_BGRA1010102))
|
|
g2d_csc_reg_set(1, G2D_RGB2YUV_709);
|
|
write_wvalue(ROP_CTL, 0xF0);
|
|
|
|
rect0.x = 0;
|
|
rect0.y = 0;
|
|
rect0.w = dst->clip_rect.w;
|
|
rect0.h = dst->clip_rect.h;
|
|
|
|
rect1.x = 0;
|
|
rect1.y = 0;
|
|
rect1.w = src->clip_rect.w;
|
|
rect1.h = src->clip_rect.h;
|
|
g2d_bldin_set(0, rect0, dst->bpremul);
|
|
g2d_bldin_set(1, rect1, src->bpremul);
|
|
|
|
G2D_INFO_MSG("BLD_FLAG: 0x%x\n", flag);
|
|
|
|
porter_duff(flag & 0xFFF);
|
|
if (flag & G2D_CK_SRC)
|
|
write_wvalue(BLD_KEY_CTL, 0x3);
|
|
|
|
else if (flag & G2D_CK_DST)
|
|
write_wvalue(BLD_KEY_CTL, 0x1);
|
|
if (ck_para != NULL)
|
|
ck_para_set(ck_para);
|
|
g2d_wb_set(dst);
|
|
g2d_bld_cs_set(dst->format);
|
|
|
|
/* start the modult */
|
|
mixer_irq_enable();
|
|
tmp = read_wvalue(G2D_MIXER_CTL);
|
|
tmp |= 0x80000000;
|
|
G2D_INFO_MSG("INIT_MODULE: 0x%x\n", tmp);
|
|
write_wvalue(G2D_MIXER_CTL, tmp);
|
|
|
|
result = g2d_wait_cmd_finish();
|
|
return result;
|
|
}
|
|
|
|
__s32 g2d_get_clk_cnt(__u32 *clk)
|
|
{
|
|
__s32 ret;
|
|
|
|
ret = read_wvalue(G2D_MIXER_CLK);
|
|
if (ret != 0)
|
|
return -1;
|
|
|
|
/* clear clk cnt */
|
|
write_wvalue(G2D_MIXER_CLK, 0);
|
|
return 0;
|
|
}
|
|
|
|
__u32 mixer_set_reg_base(unsigned long addr)
|
|
{
|
|
base_addr = addr;
|
|
return 0;
|
|
}
|
|
|