1908 lines
54 KiB
C
1908 lines
54 KiB
C
/* g2d_bsp.c
|
|
*
|
|
* Copyright (c) 2011 Allwinnertech Co., Ltd.
|
|
* 2011 Yupu Tang
|
|
*
|
|
* G2D driver
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "g2d_regs.h"
|
|
#include "g2d_bsp.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 csc0coeff[12] = {
|
|
|
|
0x4a7, 0x1e6f, 0x1cbf, 0x877,
|
|
0x4a7, 0x00, 0x662, 0x3211,
|
|
0x4a7, 0x812, 0x00, 0x2eb1
|
|
};
|
|
__s32 csc1coeff[12] = {
|
|
|
|
0x4a7, 0x1e6f, 0x1cbf, 0x877,
|
|
0x4a7, 0x00, 0x662, 0x3211,
|
|
0x4a7, 0x812, 0x00, 0x2eb1
|
|
};
|
|
|
|
__s32 csc2coeff[12] = {
|
|
|
|
0x204, 0x107, 0x64, 0x100, /* YG,YR,YB,YC */
|
|
0x1ED6, 0x1F69, 0x1C1, 0x800, /* UG,UR,UB,UC */
|
|
0x1E87, 0x1C1, 0x1FB8, 0x800, /* VG,VR,VB,VC */
|
|
};
|
|
|
|
__s32 csc2coeff_VUVU[12] = {
|
|
|
|
0x204, 0x107, 0x64, 0x100, /* YG,YR,YB,YC */
|
|
0x1E87, 0x1C1, 0x1FB8, 0x800, /* VG,VR,VB,VC */
|
|
0x1ED6, 0x1F69, 0x1C1, 0x800, /* UG,UR,UB,UC */
|
|
};
|
|
|
|
__s32 scalercoeff[64] = {
|
|
|
|
/* Horizontal Filtering Coefficient(0x200-0x27c) */
|
|
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,
|
|
|
|
/* Vertical Filtering Coefficient(0x280-0x2fc) */
|
|
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,
|
|
};
|
|
|
|
/* Set the Color Space Converter Coefficient Parameter */
|
|
void csc_coeff_set(void)
|
|
{
|
|
__u32 i, j;
|
|
|
|
/* 0x180-0x1ac */
|
|
for (i = 0, j = 0; i < 12; i++, j += 4)
|
|
write_wvalue(G2D_CSC01_ADDR_REG + j,
|
|
(((csc1coeff[i] & 0xFFFF) << 16) |
|
|
(csc0coeff[i] & 0xFFFF)));
|
|
|
|
/* 0x1c0-0x1ec */
|
|
for (i = 0, j = 0; i < 12; i++, j += 4)
|
|
write_wvalue(G2D_CSC2_ADDR_REG + j, csc2coeff[i]&0xFFFF);
|
|
|
|
}
|
|
|
|
/* Set the Scaling Horizontal/Vertical Filtering Coefficient Parameter */
|
|
void scaler_coeff_set(void)
|
|
{
|
|
__u32 i, j;
|
|
|
|
/* 0x200-0x2fc */
|
|
for (i = 0, j = 0; i < 64; i++, j += 4)
|
|
write_wvalue(G2D_SCALER_HFILTER_REG + j, scalercoeff[i]);
|
|
|
|
}
|
|
|
|
__u32 mixer_set_reg_base(unsigned long addr)
|
|
{
|
|
base_addr = addr;
|
|
return 0;
|
|
}
|
|
|
|
/* clear most of the registers value to default */
|
|
__u32 mixer_reg_init(void)
|
|
{
|
|
__u32 i;
|
|
|
|
for (i = 0; i <= 0x148; i += 4)
|
|
write_wvalue(i, 0);
|
|
write_wvalue(G2D_SCAN_ORDER_REG, 0x15FF0000);
|
|
|
|
/* initial the color space converter parameter */
|
|
csc_coeff_set();
|
|
|
|
/* initial the scaler coefficient parameter */
|
|
scaler_coeff_set();
|
|
|
|
return 0;
|
|
}
|
|
|
|
__u32 mixer_set_fillcolor(__u32 color, __u32 sel)
|
|
{
|
|
__u32 value;
|
|
|
|
if (sel == 1) {
|
|
value = read_wvalue(G2D_DMA1_CONTROL_REG) | G2D_FILL_ENABLE;
|
|
write_wvalue(G2D_DMA1_CONTROL_REG, value);
|
|
write_wvalue(G2D_DMA1_FILLCOLOR_REG, color);
|
|
} else if (sel == 2) {
|
|
value = read_wvalue(G2D_DMA2_CONTROL_REG) | G2D_FILL_ENABLE;
|
|
write_wvalue(G2D_DMA2_CONTROL_REG, value);
|
|
write_wvalue(G2D_DMA2_FILLCOLOR_REG, color);
|
|
} else if (sel == 3) {
|
|
value = read_wvalue(G2D_DMA3_CONTROL_REG) | G2D_FILL_ENABLE;
|
|
write_wvalue(G2D_DMA3_CONTROL_REG, value);
|
|
write_wvalue(G2D_DMA3_FILLCOLOR_REG, color);
|
|
} else {
|
|
value = read_wvalue(G2D_DMA0_CONTROL_REG) | G2D_FILL_ENABLE;
|
|
write_wvalue(G2D_DMA0_CONTROL_REG, value);
|
|
write_wvalue(G2D_DMA0_FILLCOLOR_REG, color);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
__u32 mixer_bpp_count(__u32 format)
|
|
{
|
|
__u32 bpp = 32;
|
|
|
|
switch (format) {
|
|
case G2D_FMT_1BPP_MONO:
|
|
case G2D_FMT_1BPP_PALETTE:
|
|
bpp = 1;
|
|
break;
|
|
|
|
case G2D_FMT_2BPP_MONO:
|
|
case G2D_FMT_2BPP_PALETTE:
|
|
bpp = 2;
|
|
break;
|
|
|
|
case G2D_FMT_4BPP_MONO:
|
|
case G2D_FMT_4BPP_PALETTE:
|
|
bpp = 4;
|
|
break;
|
|
|
|
case G2D_FMT_8BPP_MONO:
|
|
case G2D_FMT_8BPP_PALETTE:
|
|
case G2D_FMT_PYUV422UVC:
|
|
case G2D_FMT_PYUV420UVC:
|
|
case G2D_FMT_PYUV411UVC:
|
|
case G2D_FMT_PYUV422:
|
|
case G2D_FMT_PYUV420:
|
|
case G2D_FMT_PYUV411:
|
|
case G2D_FMT_PYUV422UVC_MB16:
|
|
case G2D_FMT_PYUV420UVC_MB16:
|
|
case G2D_FMT_PYUV411UVC_MB16:
|
|
case G2D_FMT_PYUV422UVC_MB32:
|
|
case G2D_FMT_PYUV420UVC_MB32:
|
|
case G2D_FMT_PYUV411UVC_MB32:
|
|
case G2D_FMT_PYUV422UVC_MB64:
|
|
case G2D_FMT_PYUV420UVC_MB64:
|
|
case G2D_FMT_PYUV411UVC_MB64:
|
|
case G2D_FMT_PYUV422UVC_MB128:
|
|
case G2D_FMT_PYUV420UVC_MB128:
|
|
case G2D_FMT_PYUV411UVC_MB128:
|
|
bpp = 8;
|
|
break;
|
|
|
|
case G2D_FMT_IYUV422:
|
|
case G2D_FMT_RGB565:
|
|
case G2D_FMT_BGR565:
|
|
case G2D_FMT_ARGB1555:
|
|
case G2D_FMT_ABGR1555:
|
|
case G2D_FMT_RGBA5551:
|
|
case G2D_FMT_BGRA5551:
|
|
case G2D_FMT_ARGB4444:
|
|
case G2D_FMT_ABGR4444:
|
|
case G2D_FMT_RGBA4444:
|
|
case G2D_FMT_BGRA4444:
|
|
bpp = 16;
|
|
break;
|
|
|
|
case G2D_FMT_ARGB_AYUV8888:
|
|
case G2D_FMT_BGRA_VUYA8888:
|
|
case G2D_FMT_ABGR_AVUY8888:
|
|
case G2D_FMT_RGBA_YUVA8888:
|
|
case G2D_FMT_XRGB8888:
|
|
case G2D_FMT_BGRX8888:
|
|
case G2D_FMT_XBGR8888:
|
|
case G2D_FMT_RGBX8888:
|
|
bpp = 32;
|
|
break;
|
|
|
|
default:
|
|
bpp = 32;
|
|
break;
|
|
}
|
|
return bpp;
|
|
|
|
}
|
|
|
|
__u32 mixer_in_fmtseq_set(__u32 format, __u32 pixel_seq)
|
|
{
|
|
__u32 val = 32;
|
|
|
|
switch (format) {
|
|
case G2D_FMT_1BPP_MONO:
|
|
case G2D_FMT_1BPP_PALETTE:
|
|
if (pixel_seq == G2D_SEQ_1BPP_LITTER_LITTER)
|
|
val = 0x3A;
|
|
else if (pixel_seq == G2D_SEQ_1BPP_BIG_LITTER)
|
|
val = 0x1A;
|
|
else if (pixel_seq == G2D_SEQ_1BPP_LITTER_BIG)
|
|
val = 0x2A;
|
|
else
|
|
val = 0xA;
|
|
break;
|
|
|
|
case G2D_FMT_2BPP_MONO:
|
|
case G2D_FMT_2BPP_PALETTE:
|
|
if (pixel_seq == G2D_SEQ_2BPP_LITTER_LITTER)
|
|
val = 0x39;
|
|
else if (pixel_seq == G2D_SEQ_2BPP_BIG_LITTER)
|
|
val = 0x19;
|
|
else if (pixel_seq == G2D_SEQ_2BPP_LITTER_BIG)
|
|
val = 0x29;
|
|
else
|
|
val = 0x9;
|
|
break;
|
|
|
|
case G2D_FMT_4BPP_MONO:
|
|
case G2D_FMT_4BPP_PALETTE:
|
|
if (pixel_seq == G2D_SEQ_P01234567)
|
|
val = 0x38;
|
|
else if (pixel_seq == G2D_SEQ_P67452301)
|
|
val = 0x18;
|
|
else if (pixel_seq == G2D_SEQ_P10325476)
|
|
val = 0x28;
|
|
else
|
|
val = 0x8;
|
|
break;
|
|
|
|
case G2D_FMT_8BPP_MONO:
|
|
case G2D_FMT_8BPP_PALETTE:
|
|
if (pixel_seq == G2D_SEQ_P0123)
|
|
val = 0x17;
|
|
else
|
|
val = 0x7;
|
|
break;
|
|
|
|
case G2D_FMT_PYUV422UVC:
|
|
case G2D_FMT_PYUV420UVC:
|
|
case G2D_FMT_PYUV411UVC:
|
|
case G2D_FMT_PYUV422UVC_MB16:
|
|
case G2D_FMT_PYUV420UVC_MB16:
|
|
case G2D_FMT_PYUV411UVC_MB16:
|
|
case G2D_FMT_PYUV422UVC_MB32:
|
|
case G2D_FMT_PYUV420UVC_MB32:
|
|
case G2D_FMT_PYUV411UVC_MB32:
|
|
case G2D_FMT_PYUV422UVC_MB64:
|
|
case G2D_FMT_PYUV420UVC_MB64:
|
|
case G2D_FMT_PYUV411UVC_MB64:
|
|
case G2D_FMT_PYUV422UVC_MB128:
|
|
case G2D_FMT_PYUV420UVC_MB128:
|
|
case G2D_FMT_PYUV411UVC_MB128:
|
|
val = 0x6;
|
|
break;
|
|
|
|
case G2D_FMT_IYUV422:
|
|
if (pixel_seq == G2D_SEQ_YVYU)
|
|
val = 0x14;
|
|
else
|
|
val = 0x4;
|
|
break;
|
|
case G2D_FMT_RGB565:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x13;
|
|
else
|
|
val = 0x3;
|
|
break;
|
|
case G2D_FMT_BGR565:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x93;
|
|
else
|
|
val = 0x83;
|
|
break;
|
|
case G2D_FMT_ARGB1555:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x12;
|
|
else
|
|
val = 0x2;
|
|
break;
|
|
case G2D_FMT_ABGR1555:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x92;
|
|
else
|
|
val = 0x82;
|
|
break;
|
|
case G2D_FMT_RGBA5551:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0xb2;
|
|
else
|
|
val = 0xa2;
|
|
break;
|
|
case G2D_FMT_BGRA5551:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x32;
|
|
else
|
|
val = 0x22;
|
|
break;
|
|
case G2D_FMT_ARGB4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x11;
|
|
else
|
|
val = 0x01;
|
|
break;
|
|
case G2D_FMT_ABGR4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x91;
|
|
else
|
|
val = 0x81;
|
|
break;
|
|
case G2D_FMT_RGBA4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0xb1;
|
|
else
|
|
val = 0xa1;
|
|
break;
|
|
case G2D_FMT_BGRA4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x31;
|
|
else
|
|
val = 0x21;
|
|
break;
|
|
case G2D_FMT_ARGB_AYUV8888:
|
|
case G2D_FMT_XRGB8888:
|
|
val = 0x0;
|
|
break;
|
|
case G2D_FMT_BGRA_VUYA8888:
|
|
case G2D_FMT_BGRX8888:
|
|
val = 0x20;
|
|
break;
|
|
case G2D_FMT_ABGR_AVUY8888:
|
|
case G2D_FMT_XBGR8888:
|
|
val = 0x80;
|
|
break;
|
|
case G2D_FMT_RGBA_YUVA8888:
|
|
case G2D_FMT_RGBX8888:
|
|
val = 0xa0;
|
|
break;
|
|
|
|
default:
|
|
val = 0;
|
|
break;
|
|
}
|
|
return val << 8;
|
|
|
|
}
|
|
|
|
__u32 mixer_in_csc_set(__u32 format)
|
|
{
|
|
__u32 val = 0;
|
|
|
|
switch (format) {
|
|
case G2D_FMT_IYUV422:
|
|
val = 0x11;
|
|
break;
|
|
case G2D_FMT_PYUV422UVC:
|
|
case G2D_FMT_PYUV422UVC_MB16:
|
|
case G2D_FMT_PYUV422UVC_MB32:
|
|
case G2D_FMT_PYUV422UVC_MB64:
|
|
case G2D_FMT_PYUV422UVC_MB128:
|
|
val = 0x21;
|
|
break;
|
|
case G2D_FMT_PYUV420UVC:
|
|
case G2D_FMT_PYUV420UVC_MB16:
|
|
case G2D_FMT_PYUV420UVC_MB32:
|
|
case G2D_FMT_PYUV420UVC_MB64:
|
|
case G2D_FMT_PYUV420UVC_MB128:
|
|
val = 0x31;
|
|
break;
|
|
case G2D_FMT_PYUV411UVC:
|
|
case G2D_FMT_PYUV411UVC_MB16:
|
|
case G2D_FMT_PYUV411UVC_MB32:
|
|
case G2D_FMT_PYUV411UVC_MB64:
|
|
case G2D_FMT_PYUV411UVC_MB128:
|
|
val = 0x41;
|
|
break;
|
|
|
|
default:
|
|
val = 0;
|
|
break;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
__u32 mixer_out_fmtseq_set(__u32 format, __u32 pixel_seq)
|
|
{
|
|
__u32 val = 0;
|
|
|
|
switch (format) {
|
|
case G2D_FMT_1BPP_MONO:
|
|
if (pixel_seq == G2D_SEQ_1BPP_LITTER_LITTER)
|
|
val = 0x38A;
|
|
else if (pixel_seq == G2D_SEQ_1BPP_BIG_LITTER)
|
|
val = 0x18A;
|
|
else if (pixel_seq == G2D_SEQ_1BPP_LITTER_BIG)
|
|
val = 0x28A;
|
|
else
|
|
val = 0x8A;
|
|
break;
|
|
|
|
case G2D_FMT_2BPP_MONO:
|
|
if (pixel_seq == G2D_SEQ_2BPP_LITTER_LITTER)
|
|
val = 0x389;
|
|
else if (pixel_seq == G2D_SEQ_2BPP_BIG_LITTER)
|
|
val = 0x189;
|
|
else if (pixel_seq == G2D_SEQ_2BPP_LITTER_BIG)
|
|
val = 0x289;
|
|
else
|
|
val = 0x89;
|
|
break;
|
|
|
|
case G2D_FMT_4BPP_MONO:
|
|
if (pixel_seq == G2D_SEQ_P01234567)
|
|
val = 0x388;
|
|
else if (pixel_seq == G2D_SEQ_P67452301)
|
|
val = 0x188;
|
|
else if (pixel_seq == G2D_SEQ_P10325476)
|
|
val = 0x288;
|
|
else
|
|
val = 0x88;
|
|
break;
|
|
|
|
case G2D_FMT_8BPP_MONO:
|
|
if (pixel_seq == G2D_SEQ_P0123)
|
|
val = 0x187;
|
|
else
|
|
val = 0x87;
|
|
break;
|
|
case G2D_FMT_PYUV422:
|
|
val = 0x86;
|
|
break;
|
|
case G2D_FMT_PYUV422UVC:
|
|
val = 0x85;
|
|
break;
|
|
case G2D_FMT_PYUV420UVC:
|
|
val = 0x8b;
|
|
break;
|
|
case G2D_FMT_PYUV420:
|
|
val = 0x8c;
|
|
break;
|
|
case G2D_FMT_PYUV411UVC:
|
|
val = 0x8d;
|
|
break;
|
|
case G2D_FMT_PYUV411:
|
|
val = 0x8e;
|
|
break;
|
|
case G2D_FMT_IYUV422:
|
|
if (pixel_seq == G2D_SEQ_YVYU)
|
|
val = 0x184;
|
|
else
|
|
val = 0x84;
|
|
break;
|
|
case G2D_FMT_RGB565:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x183;
|
|
else
|
|
val = 0x3;
|
|
break;
|
|
case G2D_FMT_BGR565:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x983;
|
|
else
|
|
val = 0x883;
|
|
break;
|
|
case G2D_FMT_ARGB1555:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x182;
|
|
else
|
|
val = 0x82;
|
|
break;
|
|
case G2D_FMT_ABGR1555:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x982;
|
|
else
|
|
val = 0x882;
|
|
break;
|
|
case G2D_FMT_RGBA5551:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0xb82;
|
|
else
|
|
val = 0xa82;
|
|
break;
|
|
case G2D_FMT_BGRA5551:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x382;
|
|
else
|
|
val = 0x282;
|
|
break;
|
|
case G2D_FMT_ARGB4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x181;
|
|
else
|
|
val = 0x81;
|
|
break;
|
|
case G2D_FMT_ABGR4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x981;
|
|
else
|
|
val = 0x881;
|
|
break;
|
|
case G2D_FMT_RGBA4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0xb81;
|
|
else
|
|
val = 0xa81;
|
|
break;
|
|
case G2D_FMT_BGRA4444:
|
|
if (pixel_seq == G2D_SEQ_P01)
|
|
val = 0x381;
|
|
else
|
|
val = 0x281;
|
|
break;
|
|
case G2D_FMT_ARGB_AYUV8888:
|
|
case G2D_FMT_XRGB8888:
|
|
val = 0x80;
|
|
break;
|
|
case G2D_FMT_BGRA_VUYA8888:
|
|
case G2D_FMT_BGRX8888:
|
|
val = 0x280;
|
|
break;
|
|
case G2D_FMT_ABGR_AVUY8888:
|
|
case G2D_FMT_XBGR8888:
|
|
val = 0x880;
|
|
break;
|
|
case G2D_FMT_RGBA_YUVA8888:
|
|
case G2D_FMT_RGBX8888:
|
|
val = 0xa80;
|
|
break;
|
|
|
|
default:
|
|
val = 80;
|
|
break;
|
|
}
|
|
return val;
|
|
|
|
}
|
|
|
|
__u64 mixer_get_addr(__u32 buffer_addr, __u32 format, __u32 stride,
|
|
__u32 x, __u32 y)
|
|
{
|
|
__u32 bpp = 0;
|
|
__u64 addr = 0;
|
|
|
|
bpp = mixer_bpp_count(format);
|
|
addr = (__u64) (buffer_addr) * 8 +
|
|
(__u64) ((stride * y + x) * bpp); /* bits */
|
|
|
|
return addr;
|
|
}
|
|
|
|
__u32 mixer_get_irq(void)
|
|
{
|
|
__u32 reg_val = 0;
|
|
|
|
reg_val = read_wvalue(G2D_STATUS_REG);
|
|
|
|
return reg_val;
|
|
}
|
|
|
|
__u32 mixer_get_irq0(void)
|
|
{
|
|
__u32 reg_val = 0;
|
|
|
|
reg_val = read_wvalue(G2D_CMDQ_STS_REG);
|
|
|
|
return reg_val;
|
|
}
|
|
|
|
__u32 mixer_clear_init(void)
|
|
{
|
|
|
|
write_wvalue(G2D_STATUS_REG, 0x300);
|
|
write_wvalue(G2D_CONTROL_REG, 0x0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
__u32 mixer_clear_init0(void)
|
|
{
|
|
|
|
write_wvalue(G2D_CMDQ_STS_REG, 0x100);
|
|
write_wvalue(G2D_CMDQ_CTL_REG, 0x0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
__u32 mixer_set_rotate_reg(__u32 flag)
|
|
{
|
|
__u32 rot = 0;
|
|
|
|
if (flag & G2D_BLT_FLIP_HORIZONTAL)
|
|
rot = 0x10;
|
|
else if (flag & G2D_BLT_FLIP_VERTICAL)
|
|
rot = 0x20;
|
|
else if (flag & G2D_BLT_ROTATE90)
|
|
rot = 0x50;
|
|
else if (flag & G2D_BLT_ROTATE180)
|
|
rot = 0x30;
|
|
else if (flag & G2D_BLT_ROTATE270)
|
|
rot = 0x60;
|
|
else if (flag & G2D_BLT_MIRROR45)
|
|
rot = 0x70;
|
|
else if (flag & G2D_BLT_MIRROR135)
|
|
rot = 0x40;
|
|
else
|
|
rot = 0;
|
|
|
|
return rot;
|
|
}
|
|
|
|
__s32 mixer_fillrectangle(g2d_fillrect *para)
|
|
{
|
|
__u32 reg_val = 0;
|
|
__u64 addr_val;
|
|
__s32 result = 0;
|
|
|
|
mixer_reg_init();/* initial mixer register */
|
|
|
|
/* channel0 is the fill surface */
|
|
write_wvalue(G2D_DMA0_SIZE_REG,
|
|
(para->dst_rect.w - 1) | ((para->dst_rect.h - 1) << 16));
|
|
|
|
/* globe alpha mode */
|
|
if (para->flag & G2D_FIL_PLANE_ALPHA)
|
|
reg_val |= (para->alpha << 24) | 0x4;
|
|
else if (para->flag & G2D_FIL_MULTI_ALPHA)
|
|
reg_val |= (para->alpha << 24) | 0x8;
|
|
reg_val |= 0x1;
|
|
write_wvalue(G2D_DMA0_CONTROL_REG, reg_val);
|
|
mixer_set_fillcolor(para->color, 0);
|
|
if ((para->flag & G2D_FIL_PLANE_ALPHA)
|
|
|| (para->flag & G2D_FIL_PIXEL_ALPHA)
|
|
|| (para->flag & G2D_FIL_MULTI_ALPHA)) {
|
|
/* channel3 is the dst surface */
|
|
addr_val =
|
|
mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format, para->dst_image.w,
|
|
para->dst_rect.x, para->dst_rect.y);
|
|
reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val << 24);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA3_STRIDE_REG,
|
|
para->dst_image.w *
|
|
mixer_bpp_count(para->dst_image.format));
|
|
write_wvalue(G2D_DMA3_SIZE_REG,
|
|
(para->dst_rect.w -
|
|
1) | ((para->dst_rect.h - 1) << 16));
|
|
reg_val = read_wvalue(G2D_DMA3_CONTROL_REG);
|
|
|
|
/* palette format */
|
|
if (para->dst_image.format > 0x19)
|
|
reg_val |= 0x2;
|
|
reg_val |=
|
|
G2D_IDMA_ENABLE | mixer_in_fmtseq_set(para->dst_image.
|
|
format,
|
|
para->dst_image.
|
|
pixel_seq);
|
|
write_wvalue(G2D_DMA3_CONTROL_REG, reg_val);
|
|
write_wvalue(G2D_CK_CONTROL_REG, 0x1);
|
|
}
|
|
write_wvalue(G2D_ROP_INDEX0_REG, 0x840);
|
|
|
|
/* output surface is the dst surface */
|
|
write_wvalue(G2D_OUTPUT_SIZE_REG,
|
|
(para->dst_rect.w - 1) | ((para->dst_rect.h - 1) << 16));
|
|
|
|
addr_val =
|
|
mixer_get_addr(para->dst_image.addr[0], para->dst_image.format,
|
|
para->dst_image.w, para->dst_rect.x,
|
|
para->dst_rect.y);
|
|
reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
|
|
|
|
write_wvalue(G2D_OUTPUT0_STRIDE_REG,
|
|
para->dst_image.w *
|
|
mixer_bpp_count(para->dst_image.format));
|
|
write_wvalue(G2D_OUTPUT_CONTROL_REG,
|
|
mixer_out_fmtseq_set(para->dst_image.format,
|
|
para->dst_image.pixel_seq));
|
|
|
|
/* start */
|
|
write_wvalue(G2D_CONTROL_REG, 0);
|
|
write_wvalue(G2D_CONTROL_REG, 0x303);
|
|
result = g2d_wait_cmd_finish();
|
|
|
|
return result;
|
|
}
|
|
|
|
__s32 mixer_blt(g2d_blt *para, enum g2d_scan_order scan_order)
|
|
{
|
|
__u32 bppnum = 0;
|
|
__u32 reg_val = 0;
|
|
__u64 addr_val;
|
|
__s32 result = 0;
|
|
__u32 i, j;
|
|
|
|
mixer_reg_init(); /* initial mixer register */
|
|
if ((para->dst_image.format > 0x16) && (para->dst_image.format < 0x1A)
|
|
&& (para->dst_image.pixel_seq == G2D_SEQ_VUVU)) {
|
|
for (i = 0, j = 0; i < 12; i++, j += 4)
|
|
write_wvalue(G2D_CSC2_ADDR_REG + j,
|
|
csc2coeff_VUVU[i] & 0xFFFF);
|
|
/* 0x1c0-0x1ec */
|
|
}
|
|
|
|
/* src surface */
|
|
addr_val =
|
|
mixer_get_addr(para->src_image.addr[0], para->src_image.format,
|
|
para->src_image.w, para->src_rect.x,
|
|
para->src_rect.y);
|
|
reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA0_STRIDE_REG,
|
|
para->src_image.w *
|
|
mixer_bpp_count(para->src_image.format));
|
|
write_wvalue(G2D_DMA0_SIZE_REG,
|
|
(para->src_rect.w - 1) | ((para->src_rect.h - 1) << 16));
|
|
reg_val = read_wvalue(G2D_DMA0_CONTROL_REG);
|
|
reg_val |=
|
|
mixer_in_fmtseq_set(para->src_image.format,
|
|
para->src_image.pixel_seq) | G2D_IDMA_ENABLE;
|
|
|
|
/* rgbx/bgrx/xrgb/xbgr format */
|
|
if ((para->src_image.format > 0x03) && (para->src_image.format < 0x08))
|
|
reg_val |= (0xFF << 24) | 0x4;
|
|
|
|
/* palette format */
|
|
if ((para->src_image.format > 0x1C) && (para->src_image.format < 0x21))
|
|
reg_val |= 0x2;
|
|
|
|
/* globe alpha mode */
|
|
if (para->flag & G2D_BLT_PLANE_ALPHA)
|
|
reg_val |= (para->alpha << 24) | 0x4;
|
|
else if (para->flag & G2D_BLT_MULTI_ALPHA)
|
|
reg_val |= (para->alpha << 24) | 0x8;
|
|
|
|
/* rotate/mirror */
|
|
reg_val |= mixer_set_rotate_reg(para->flag);
|
|
write_wvalue(G2D_DMA0_CONTROL_REG, reg_val);
|
|
reg_val = mixer_in_csc_set(para->src_image.format);
|
|
write_wvalue(G2D_CSC0_CONTROL_REG, reg_val);
|
|
reg_val = mixer_in_csc_set(para->dst_image.format);
|
|
write_wvalue(G2D_CSC1_CONTROL_REG, reg_val);
|
|
|
|
/* pyuv422/420/411uvc */
|
|
if ((para->src_image.format > 0x16) &&
|
|
(para->src_image.format < 0x1A)) {
|
|
if (para->src_image.format == G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->src_image.format == G2D_FMT_PYUV420UVC)
|
|
addr_val =
|
|
(__u64) para->src_image.addr[1] * 8 +
|
|
(__u64) ((para->src_image.w *
|
|
(para->src_rect.y / 2) +
|
|
para->src_rect.x) * bppnum);
|
|
else
|
|
addr_val =
|
|
(__u64) para->src_image.addr[1] * 8 +
|
|
(__u64) ((para->src_image.w * para->src_rect.y +
|
|
para->src_rect.x) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
reg_val |= ((addr_val >> 32) & 0xF) << 8;/* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA1_STRIDE_REG, para->src_image.w * bppnum);
|
|
write_wvalue(G2D_DMA1_SIZE_REG,
|
|
(para->src_rect.w -
|
|
1) | ((para->src_rect.h - 1) << 16));
|
|
reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
|
|
reg_val |= (5 << 8) | G2D_IDMA_ENABLE;
|
|
|
|
/* rotate/mirror */
|
|
reg_val |= mixer_set_rotate_reg(para->flag);
|
|
write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
|
|
}
|
|
mixer_micro_block_set(para);
|
|
write_wvalue(G2D_DMA1_FILLCOLOR_REG, 0xFFFFFFFF);
|
|
write_wvalue(G2D_DMA2_FILLCOLOR_REG, 0xFFFFFFFF);
|
|
|
|
if ((para->flag & G2D_BLT_PIXEL_ALPHA)
|
|
|| (para->flag & G2D_BLT_PLANE_ALPHA)
|
|
|| (para->flag & G2D_BLT_MULTI_ALPHA)
|
|
|| (para->flag & G2D_BLT_SRC_COLORKEY)
|
|
|| (para->flag & G2D_BLT_DST_COLORKEY)) {
|
|
/* pyuv422/420/411uvc */
|
|
if ((para->dst_image.format > 0x16)
|
|
&& (para->dst_image.format < 0x1A)) {
|
|
if (para->dst_image.format == G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->dst_image.format == G2D_FMT_PYUV420UVC)
|
|
addr_val =
|
|
(__u64) para->dst_image.addr[1] * 8 +
|
|
(__u64) ((para->dst_image.w *
|
|
(para->dst_y / 2) +
|
|
para->dst_x) * bppnum);
|
|
else
|
|
addr_val =
|
|
(__u64) para->dst_image.addr[1] * 8 +
|
|
(__u64) ((para->dst_image.w * para->dst_y +
|
|
para->dst_x) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val >> 32) & 0xF) << 16;
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
/* low addr in bits */
|
|
reg_val = addr_val & 0xFFFFFFFF;
|
|
write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA2_STRIDE_REG,
|
|
para->dst_image.w * bppnum);
|
|
write_wvalue(G2D_DMA2_SIZE_REG,
|
|
(para->src_rect.w -
|
|
1) | ((para->src_rect.h - 1) << 16));
|
|
reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
|
|
reg_val |= (5 << 8) | G2D_IDMA_ENABLE;
|
|
write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
/* channel3 is dst surface */
|
|
addr_val =
|
|
mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format, para->dst_image.w,
|
|
para->dst_x, para->dst_y);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
reg_val |= ((addr_val >> 32) & 0xF) << 24;/*high addr in bits*/
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA3_STRIDE_REG,
|
|
para->dst_image.w *
|
|
mixer_bpp_count(para->dst_image.format));
|
|
if ((para->flag & G2D_BLT_ROTATE90)
|
|
|| (para->flag & G2D_BLT_ROTATE270))
|
|
write_wvalue(G2D_DMA3_SIZE_REG,
|
|
(para->src_rect.h -
|
|
1) | ((para->src_rect.w - 1) << 16));
|
|
else
|
|
write_wvalue(G2D_DMA3_SIZE_REG,
|
|
(para->src_rect.w -
|
|
1) | ((para->src_rect.h - 1) << 16));
|
|
reg_val = read_wvalue(G2D_DMA3_CONTROL_REG);
|
|
reg_val |=
|
|
mixer_in_fmtseq_set(para->dst_image.format,
|
|
para->dst_image.
|
|
pixel_seq) | G2D_IDMA_ENABLE;
|
|
|
|
/* rgbx/bgrx/xrgb/xbgr format */
|
|
if ((para->dst_image.format > 0x03)
|
|
&& (para->dst_image.format < 0x08)) {
|
|
reg_val |= (0xFF << 24) | 0x4;
|
|
}
|
|
write_wvalue(G2D_DMA3_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
/* colorkey */
|
|
if (para->flag & G2D_BLT_SRC_COLORKEY) {
|
|
reg_val = 0x3;
|
|
} else if (para->flag & G2D_BLT_DST_COLORKEY) {
|
|
reg_val = 0x5;
|
|
} else if ((para->flag & G2D_BLT_PIXEL_ALPHA)
|
|
|| (para->flag & G2D_BLT_PLANE_ALPHA)
|
|
|| (para->flag & G2D_BLT_MULTI_ALPHA)) {
|
|
reg_val = 0x1;
|
|
} else {
|
|
reg_val = 0x0;
|
|
}
|
|
write_wvalue(G2D_CK_CONTROL_REG, reg_val);
|
|
write_wvalue(G2D_CK_MINCOLOR_REG, para->color);
|
|
write_wvalue(G2D_CK_MAXCOLOR_REG, para->color);
|
|
|
|
/* output surface is the dst surface */
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270)) {
|
|
write_wvalue(G2D_OUTPUT_SIZE_REG,
|
|
(para->src_rect.h -
|
|
1) | ((para->src_rect.w - 1) << 16));
|
|
} else {
|
|
write_wvalue(G2D_OUTPUT_SIZE_REG,
|
|
(para->src_rect.w -
|
|
1) | ((para->src_rect.h - 1) << 16));
|
|
}
|
|
addr_val =
|
|
mixer_get_addr(para->dst_image.addr[0], para->dst_image.format,
|
|
para->dst_image.w, para->dst_x, para->dst_y);
|
|
reg_val = (addr_val >> 32) & 0xF; /* high addr in bits */
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_OUTPUT0_STRIDE_REG,
|
|
para->dst_image.w *
|
|
mixer_bpp_count(para->dst_image.format));
|
|
reg_val =
|
|
mixer_out_fmtseq_set(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
write_wvalue(G2D_OUTPUT_CONTROL_REG, reg_val);
|
|
|
|
if ((para->dst_image.format > 0x16) &&
|
|
(para->dst_image.format < 0x1D)) {
|
|
if ((para->dst_image.format == G2D_FMT_PYUV411UVC)
|
|
|| (para->dst_image.format == G2D_FMT_PYUV422)
|
|
|| (para->dst_image.format == G2D_FMT_PYUV420))
|
|
bppnum = 4;
|
|
else if (para->dst_image.format == G2D_FMT_PYUV411)
|
|
bppnum = 2;
|
|
else
|
|
bppnum = 8;
|
|
if ((para->dst_image.format == G2D_FMT_PYUV420UVC)
|
|
|| (para->dst_image.format == G2D_FMT_PYUV420))
|
|
addr_val =
|
|
(__u64) para->dst_image.addr[1] * 8 +
|
|
(__u64) ((para->dst_image.w * (para->dst_y / 2) +
|
|
para->dst_x) * bppnum);
|
|
else
|
|
addr_val =
|
|
(__u64) para->dst_image.addr[1] * 8 +
|
|
(__u64) ((para->dst_image.w * para->dst_y +
|
|
para->dst_x) * bppnum);
|
|
reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
|
|
reg_val |= ((addr_val >> 32) & 0xF) << 8;/* high addr in bits */
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_OUTPUT1_STRIDE_REG,
|
|
para->dst_image.w * bppnum);
|
|
if (para->dst_image.format == G2D_FMT_PYUV420)
|
|
addr_val =
|
|
(__u64) para->dst_image.addr[2] * 8 +
|
|
(__u64) ((para->dst_image.w * (para->dst_y / 2) +
|
|
para->dst_x) * bppnum);
|
|
else if ((para->dst_image.format == G2D_FMT_PYUV422)
|
|
|| (para->dst_image.format == G2D_FMT_PYUV411))
|
|
addr_val =
|
|
(__u64) para->dst_image.addr[2] * 8 +
|
|
(__u64) ((para->dst_image.w * para->dst_y +
|
|
para->dst_x) * bppnum);
|
|
else
|
|
addr_val = 0;
|
|
reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
|
|
reg_val |= ((addr_val >> 32) & 0xF) << 16;/*high addr in bits*/
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val & 0xFFFFFFFF; /* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT2_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_OUTPUT2_STRIDE_REG,
|
|
para->dst_image.w * bppnum);
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
}
|
|
if ((para->dst_image.format > 0x11) && (para->dst_image.format < 0x1D))
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
if ((para->flag & G2D_BLT_PIXEL_ALPHA) | (para->
|
|
flag & G2D_BLT_PLANE_ALPHA) |
|
|
(para->flag & G2D_BLT_MULTI_ALPHA) | (para->
|
|
flag & G2D_BLT_SRC_COLORKEY) |
|
|
(para->flag & G2D_BLT_DST_COLORKEY))
|
|
write_wvalue(G2D_OALPHA_CONTROL_REG, 0x80);
|
|
/* 0x40: A2 area keep the dst alpha,0x80: A2 area keep the
|
|
* src+dst(1-src) alpha value
|
|
*/
|
|
mixer_premultiply_set(para->flag);
|
|
/*scan order */
|
|
write_wvalue(G2D_SCAN_ORDER_REG, (scan_order & 0x3) << 8);
|
|
|
|
/* start */
|
|
write_wvalue(G2D_CONTROL_REG, 0x0);
|
|
write_wvalue(G2D_CONTROL_REG, 0x303);
|
|
result = g2d_wait_cmd_finish();
|
|
|
|
return result;
|
|
}
|
|
|
|
__s32 mixer_stretchblt(g2d_stretchblt *para, enum g2d_scan_order scan_order)
|
|
{
|
|
__u32 bppnum = 0;
|
|
__u32 reg_val = 0;
|
|
__u32 reg_tmp = 0;
|
|
__u64 addr_val;
|
|
__u32 cnt, sinw, soutw, scaler_inx, scaler_iny, scaler_outx;
|
|
__u32 scaler_outy, i;
|
|
__s32 result = 0;
|
|
|
|
mixer_reg_init();/* initial mixer register */
|
|
|
|
/* src surface */
|
|
write_wvalue(G2D_DMA0_STRIDE_REG,
|
|
para->src_image.w *
|
|
mixer_bpp_count(para->src_image.format));
|
|
reg_val = read_wvalue(G2D_DMA0_CONTROL_REG);
|
|
reg_val |=
|
|
mixer_in_fmtseq_set(para->src_image.format,
|
|
para->src_image.pixel_seq) | G2D_IDMA_ENABLE;
|
|
|
|
/* rgbx/bgrx/xrgb/xbgr format */
|
|
if ((para->src_image.format > 0x03) &&
|
|
(para->src_image.format < 0x08)) {
|
|
reg_val |= (0xFF<<24)|0x4;
|
|
}
|
|
|
|
/* palette format */
|
|
if (para->src_image.format > 0x1C)
|
|
reg_val |= 0x2;
|
|
/* globe alpha mode */
|
|
if (para->flag & G2D_BLT_PLANE_ALPHA)
|
|
reg_val |= (para->alpha<<24)|0x4;
|
|
else if (para->flag & G2D_BLT_MULTI_ALPHA)
|
|
reg_val |= (para->alpha<<24)|0x8;
|
|
|
|
/* rotate/mirror */
|
|
reg_val |= mixer_set_rotate_reg(para->flag);
|
|
write_wvalue(G2D_DMA0_CONTROL_REG, reg_val);
|
|
reg_val = mixer_in_csc_set(para->src_image.format);
|
|
write_wvalue(G2D_CSC0_CONTROL_REG, reg_val);
|
|
reg_val = mixer_in_csc_set(para->dst_image.format);
|
|
write_wvalue(G2D_CSC1_CONTROL_REG, reg_val);
|
|
|
|
/* sacler setting */
|
|
write_wvalue(G2D_SCALER_CONTROL_REG,
|
|
G2D_SCALER_4TAP4 | G2D_SCALER_ENABLE);
|
|
write_wvalue(G2D_SCALER_HPHASE_REG, 0);
|
|
write_wvalue(G2D_SCALER_VPHASE_REG, 0);
|
|
write_wvalue(G2D_ROP_INDEX0_REG, 0x840);
|
|
|
|
/* channel3 is dst surface */
|
|
write_wvalue(G2D_DMA3_STRIDE_REG,
|
|
para->dst_image.w *
|
|
mixer_bpp_count(para->dst_image.format));
|
|
reg_val = read_wvalue(G2D_DMA3_CONTROL_REG);
|
|
reg_val |=
|
|
mixer_in_fmtseq_set(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
if ((para->flag & G2D_BLT_PIXEL_ALPHA)
|
|
|| (para->flag & G2D_BLT_PLANE_ALPHA)
|
|
|| (para->flag & G2D_BLT_MULTI_ALPHA)
|
|
|| (para->flag & G2D_BLT_SRC_COLORKEY)
|
|
|| (para->flag & G2D_BLT_DST_COLORKEY))
|
|
reg_val |= G2D_IDMA_ENABLE;
|
|
|
|
/* rgbx/bgrx/xrgb/xbgr format */
|
|
if ((para->src_image.format > 0x03) && (para->src_image.format < 0x08))
|
|
reg_val |= (0xFF<<24)|0x4;
|
|
write_wvalue(G2D_DMA3_CONTROL_REG, reg_val);
|
|
|
|
/* colorkey */
|
|
if (para->flag & G2D_BLT_SRC_COLORKEY)
|
|
|
|
reg_val = 0x3;
|
|
else if (para->flag & G2D_BLT_DST_COLORKEY)
|
|
|
|
reg_val = 0x5;
|
|
else if ((para->flag & G2D_BLT_PIXEL_ALPHA)
|
|
|| (para->flag & G2D_BLT_PLANE_ALPHA)
|
|
|| (para->flag & G2D_BLT_MULTI_ALPHA))
|
|
reg_val = 1;
|
|
else
|
|
reg_val = 0x0;
|
|
write_wvalue(G2D_CK_CONTROL_REG, reg_val);
|
|
write_wvalue(G2D_CK_MINCOLOR_REG, para->color);
|
|
write_wvalue(G2D_CK_MAXCOLOR_REG, para->color);
|
|
|
|
write_wvalue(G2D_OUTPUT0_STRIDE_REG,
|
|
para->dst_image.w *
|
|
mixer_bpp_count(para->dst_image.format));
|
|
reg_val =
|
|
mixer_out_fmtseq_set(para->dst_image.format,
|
|
para->dst_image.pixel_seq);
|
|
write_wvalue(G2D_OUTPUT_CONTROL_REG, reg_val);
|
|
if ((para->flag & G2D_BLT_PIXEL_ALPHA) | (para->
|
|
flag & G2D_BLT_PLANE_ALPHA) |
|
|
(para->flag & G2D_BLT_MULTI_ALPHA) | (para->
|
|
flag & G2D_BLT_SRC_COLORKEY) |
|
|
(para->flag & G2D_BLT_DST_COLORKEY))
|
|
write_wvalue(G2D_OALPHA_CONTROL_REG, 0x80);
|
|
/* 0x40: A2 area keep the dst alpha,0x80: A2 area keep the
|
|
* src+dst(1-src) alpha value
|
|
*/
|
|
mixer_premultiply_set(para->flag);
|
|
|
|
/* output width lager than 1024 pixel width */
|
|
if (para->dst_rect.w > 0x400) {
|
|
/* scaler up divide the output into 1024 pixel width part */
|
|
cnt = para->dst_rect.w / 1024;
|
|
cnt = (para->dst_rect.w % 1024) ? cnt : cnt - 1;
|
|
sinw = (para->src_rect.w / para->dst_rect.w) << 10;
|
|
sinw |=
|
|
((para->src_rect.w % para->dst_rect.w) << 10) /
|
|
para->dst_rect.w;
|
|
if ((para->flag & G2D_BLT_ROTATE90)
|
|
|| (para->flag & G2D_BLT_ROTATE270)) {
|
|
sinw = (para->src_rect.h / para->dst_rect.w) << 10;
|
|
sinw |=
|
|
((para->src_rect.h % para->dst_rect.w) << 10) /
|
|
para->dst_rect.w;
|
|
}
|
|
scaler_inx = para->src_rect.x;
|
|
scaler_iny = para->src_rect.y;
|
|
scaler_outx = para->dst_rect.x;
|
|
scaler_outy = para->dst_rect.y;
|
|
for (i = 0; i < cnt; i++) {
|
|
/* DMA0 */
|
|
addr_val =
|
|
mixer_get_addr(para->src_image.addr[0],
|
|
para->src_image.format,
|
|
para->src_image.w, scaler_inx,
|
|
para->src_rect.y);
|
|
reg_val = (addr_val >> 32) & 0xF;/* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
|
|
if (sinw < 1)
|
|
sinw = 1;
|
|
write_wvalue(G2D_DMA0_SIZE_REG, (sinw - 1) |
|
|
((para->src_rect.h - 1)<<16));
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270))
|
|
write_wvalue(G2D_DMA0_SIZE_REG,
|
|
(para->src_rect.w - 1) |
|
|
((sinw - 1)<<16));
|
|
|
|
/* DMA1 pyuv422/420/411uvc */
|
|
if ((para->src_image.format > 0x16) &&
|
|
(para->src_image.format < 0x1A)) {
|
|
if (para->src_image.format ==
|
|
G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->src_image.format ==
|
|
G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
(para->src_rect.y/2) +
|
|
scaler_inx) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
para->src_rect.y +
|
|
scaler_inx) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<8;
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
/* low addr in bits */
|
|
reg_val = addr_val&0xFFFFFFFF;
|
|
write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA1_STRIDE_REG,
|
|
para->src_image.w * bppnum);
|
|
if (sinw < 1)
|
|
sinw = 1;
|
|
write_wvalue(G2D_DMA1_SIZE_REG, (sinw - 1) |
|
|
((para->src_rect.h - 1)<<16));
|
|
reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
|
|
reg_val |= (5 << 8) | G2D_IDMA_ENABLE;
|
|
|
|
/* rotate/mirror */
|
|
reg_val |= mixer_set_rotate_reg(para->flag);
|
|
write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
/* scaler setting */
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270)) {
|
|
write_wvalue(G2D_SCALER_SIZE_REG,
|
|
(para->dst_rect.h - 1) | ((0x400 - 1)<<16));
|
|
reg_val = (para->src_rect.w/para->dst_rect.h)<<16;
|
|
reg_tmp = (para->src_rect.w%para->dst_rect.h);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.h;
|
|
write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
|
|
reg_val = (sinw/0x400)<<16;
|
|
reg_tmp = (sinw%0x400);
|
|
reg_val |= (reg_tmp<<16)/0x400;
|
|
write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
|
|
} else {
|
|
write_wvalue(G2D_SCALER_SIZE_REG,
|
|
(0x400 - 1) | ((para->dst_rect.h - 1)<<16));
|
|
reg_val = (sinw/0x400)<<16;
|
|
reg_tmp = (sinw%0x400);
|
|
reg_val |= (reg_tmp<<16)/0x400;
|
|
write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
|
|
|
|
reg_val = (para->src_rect.h/para->dst_rect.h)<<16;
|
|
reg_tmp = (para->src_rect.h%para->dst_rect.h);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.h;
|
|
write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
|
|
}
|
|
if ((para->flag & G2D_BLT_PIXEL_ALPHA) ||
|
|
(para->flag & G2D_BLT_PLANE_ALPHA) ||
|
|
(para->flag & G2D_BLT_MULTI_ALPHA) ||
|
|
(para->flag & G2D_BLT_SRC_COLORKEY) ||
|
|
(para->flag & G2D_BLT_DST_COLORKEY)) {
|
|
/* DMA2 pyuv422/420/411uvc */
|
|
if ((para->dst_image.format > 0x16) &&
|
|
(para->dst_image.format < 0x1A)) {
|
|
if (para->dst_image.format ==
|
|
G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->dst_image.format ==
|
|
G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
(para->dst_rect.y / 2) +
|
|
scaler_outx) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
para->dst_rect.y +
|
|
scaler_outx) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<16;
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
/* low addr in bits */
|
|
reg_val = addr_val&0xFFFFFFFF;
|
|
write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA2_STRIDE_REG,
|
|
para->dst_image.w*bppnum);
|
|
write_wvalue(G2D_DMA2_SIZE_REG, (0x400 - 1) |
|
|
((para->dst_rect.h - 1)<<16));
|
|
reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
|
|
reg_val |= (5<<8) | G2D_IDMA_ENABLE;
|
|
write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
/* DMA3 */
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format,
|
|
para->dst_image.w, scaler_outx,
|
|
para->dst_rect.y);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
reg_val = reg_val & 0xF0FFFFFF;
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<24;
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA3_SIZE_REG, (0x400 - 1) |
|
|
((para->dst_rect.h - 1)<<16));
|
|
}
|
|
/* OUT */
|
|
write_wvalue(G2D_OUTPUT_SIZE_REG, (0x400 - 1) |
|
|
((para->dst_rect.h - 1)<<16));
|
|
if ((para->flag & G2D_BLT_ROTATE180))
|
|
scaler_outx = para->dst_rect.w - 0x400;
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format,
|
|
para->dst_image.w, scaler_outx,
|
|
scaler_outy);
|
|
if ((para->flag & G2D_BLT_ROTATE270))
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format,
|
|
para->dst_image.w,
|
|
scaler_outx-0x400,
|
|
scaler_outy);
|
|
reg_val = (addr_val>>32)&0xF;/* high addr in bits */
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
|
|
|
|
/* OUT1 */
|
|
if ((para->dst_image.format > 0x16) &&
|
|
(para->dst_image.format < 0x1A)) {
|
|
if (para->dst_image.format ==
|
|
G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->dst_image.format ==
|
|
G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
(scaler_outy/2) +
|
|
scaler_outx) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
scaler_outy +
|
|
scaler_outx) * bppnum);
|
|
reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<8;
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
/* low addr in bits */
|
|
reg_val = addr_val&0xFFFFFFFF;
|
|
write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_OUTPUT1_STRIDE_REG,
|
|
para->dst_image.w*bppnum);
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
}
|
|
if ((para->dst_image.format > 0x11) &&
|
|
(para->dst_image.format < 0x1D))
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
|
|
scaler_inx += sinw;
|
|
if ((para->flag & G2D_BLT_ROTATE90)) {
|
|
scaler_outx += 0x400;
|
|
scaler_iny += sinw;
|
|
scaler_inx = para->src_rect.x;
|
|
} else if ((para->flag & G2D_BLT_ROTATE270)) {
|
|
scaler_outx = para->dst_rect.x;
|
|
scaler_iny += sinw;
|
|
scaler_inx = para->src_rect.x;
|
|
} else if ((para->flag & G2D_BLT_ROTATE180)) {
|
|
scaler_outy = para->dst_rect.y;
|
|
scaler_outx = para->dst_rect.x -
|
|
para->dst_image.w;
|
|
} else {
|
|
scaler_outy = para->dst_rect.y;
|
|
scaler_outx += 0x400;
|
|
}
|
|
|
|
/* start */
|
|
write_wvalue(G2D_CONTROL_REG, 0x0);
|
|
write_wvalue(G2D_CONTROL_REG, 0x303);
|
|
result |= g2d_wait_cmd_finish();
|
|
if (result != 0)
|
|
return result;
|
|
}
|
|
|
|
/* last block */
|
|
soutw = para->dst_rect.w - 0x400*cnt;
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270))
|
|
sinw = para->src_rect.h - sinw*cnt;
|
|
else
|
|
sinw = para->src_rect.w - sinw*cnt;
|
|
|
|
/* DMA0 */
|
|
addr_val = mixer_get_addr(para->src_image.addr[0],
|
|
para->src_image.format, para->src_image.w,
|
|
scaler_inx, para->src_rect.y);
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270))
|
|
addr_val = mixer_get_addr(para->src_image.addr[0],
|
|
para->src_image.format,
|
|
para->src_image.w,
|
|
scaler_inx, scaler_iny);
|
|
reg_val = (addr_val>>32)&0xF;/* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA0_SIZE_REG,
|
|
(sinw - 1) | ((para->src_rect.h - 1)<<16));
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270))
|
|
write_wvalue(G2D_DMA0_SIZE_REG,
|
|
(para->src_rect.w - 1) | ((sinw - 1)<<16));
|
|
|
|
/* DMA1 pyuv422/420/411uvc */
|
|
if ((para->src_image.format > 0x16) &&
|
|
(para->src_image.format < 0x1A)) {
|
|
if (para->src_image.format ==
|
|
G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->src_image.format == G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
(para->src_rect.y/2) +
|
|
scaler_inx) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
para->src_rect.y +
|
|
scaler_inx) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
reg_val |= ((addr_val>>32)&0xF)<<8;/*high addr in bits*/
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA1_STRIDE_REG,
|
|
para->src_image.w * bppnum);
|
|
if (sinw < 1)
|
|
sinw = 1;
|
|
write_wvalue(G2D_DMA1_SIZE_REG,
|
|
(sinw - 1) | ((para->src_rect.h - 1)<<16));
|
|
reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
|
|
reg_val |= (5<<8) | G2D_IDMA_ENABLE;
|
|
|
|
/* rotate/mirror */
|
|
reg_val |= mixer_set_rotate_reg(para->flag);
|
|
write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
/* scaler setting */
|
|
if (soutw < 1)
|
|
soutw = 1;
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270)) {
|
|
write_wvalue(G2D_SCALER_SIZE_REG,
|
|
(para->dst_rect.h - 1) | ((soutw - 1)<<16));
|
|
reg_val = (para->src_rect.w/para->dst_rect.h)<<16;
|
|
reg_tmp = (para->src_rect.w%para->dst_rect.h);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.h;
|
|
write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
|
|
reg_val = (sinw/soutw)<<16;
|
|
reg_tmp = (sinw%soutw);
|
|
reg_val |= (reg_tmp<<16)/soutw;
|
|
write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
|
|
} else {
|
|
write_wvalue(G2D_SCALER_SIZE_REG,
|
|
(soutw - 1) | ((para->dst_rect.h - 1)<<16));
|
|
reg_val = (sinw/soutw)<<16;
|
|
reg_tmp = (sinw%soutw);
|
|
reg_val |= (reg_tmp<<16)/soutw;
|
|
write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
|
|
|
|
reg_val = (para->src_rect.h/para->dst_rect.h)<<16;
|
|
reg_tmp = (para->src_rect.h%para->dst_rect.h);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.h;
|
|
write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
|
|
}
|
|
if ((para->flag & G2D_BLT_PIXEL_ALPHA) ||
|
|
(para->flag & G2D_BLT_PLANE_ALPHA) ||
|
|
(para->flag & G2D_BLT_MULTI_ALPHA) ||
|
|
(para->flag & G2D_BLT_SRC_COLORKEY) ||
|
|
(para->flag & G2D_BLT_DST_COLORKEY)) {
|
|
/* DMA2 pyuv422/420/411uvc */
|
|
if ((para->dst_image.format > 0x16) &&
|
|
(para->dst_image.format < 0x1A)) {
|
|
if (para->dst_image.format == G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->dst_image.format == G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
(para->dst_rect.y/2) +
|
|
scaler_outx) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
para->dst_rect.y +
|
|
scaler_outx)*bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
/*high addr in bits*/
|
|
reg_val |= ((addr_val>>32)&0xF)<<16;
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA2_STRIDE_REG,
|
|
para->dst_image.w*bppnum);
|
|
if (soutw < 1)
|
|
soutw = 1;
|
|
write_wvalue(G2D_DMA2_SIZE_REG,
|
|
(soutw - 1) | ((para->dst_rect.h - 1)<<16));
|
|
reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
|
|
reg_val |= (5<<8) | G2D_IDMA_ENABLE;
|
|
write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
/* DMA3 */
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format, para->dst_image.w,
|
|
scaler_outx, para->dst_rect.y);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
reg_val = reg_val&0xF0FFFFFF;
|
|
reg_val |= ((addr_val>>32)&0xF)<<24;/* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA3_SIZE_REG,
|
|
(soutw - 1) | ((para->dst_rect.h - 1)<<16));
|
|
}
|
|
/* OUT */
|
|
write_wvalue(G2D_OUTPUT_SIZE_REG,
|
|
(soutw - 1) | ((para->dst_rect.h - 1)<<16));
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270))
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format,
|
|
para->dst_image.w,
|
|
scaler_outx, scaler_outy);
|
|
else
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format, para->dst_image.w,
|
|
scaler_outx, para->dst_rect.y);
|
|
reg_val = (addr_val>>32)&0xF;/* high addr in bits */
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
|
|
|
|
/* OUT1 */
|
|
if ((para->dst_image.format > 0x16) &&
|
|
(para->dst_image.format < 0x1A)) {
|
|
if (para->dst_image.format == G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->dst_image.format == G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
(para->dst_rect.y/2) +
|
|
scaler_outx)*bppnum);
|
|
else
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
para->dst_rect.y +
|
|
scaler_outx) * bppnum);
|
|
reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<8;
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_OUTPUT1_STRIDE_REG,
|
|
para->dst_image.w*bppnum);
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
}
|
|
if ((para->dst_image.format > 0x11) &&
|
|
(para->dst_image.format < 0x1D))
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
|
|
/*scan order*/
|
|
write_wvalue(G2D_SCAN_ORDER_REG, (scan_order & 0x3) << 8);
|
|
/* start */
|
|
write_wvalue(G2D_CONTROL_REG, 0x0);
|
|
write_wvalue(G2D_CONTROL_REG, 0x303);
|
|
result |= g2d_wait_cmd_finish();
|
|
}
|
|
|
|
/* output width smaller than 1024 pixel width */
|
|
else {
|
|
addr_val = mixer_get_addr(para->src_image.addr[0],
|
|
para->src_image.format, para->src_image.w,
|
|
para->src_rect.x, para->src_rect.y);
|
|
reg_val = (addr_val>>32)&0xF;/* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA0_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA0_SIZE_REG,
|
|
(para->src_rect.w - 1) | ((para->src_rect.h - 1)<<16));
|
|
|
|
if ((para->flag & G2D_BLT_ROTATE90) ||
|
|
(para->flag & G2D_BLT_ROTATE270)) {
|
|
write_wvalue(G2D_SCALER_SIZE_REG,
|
|
(para->dst_rect.h - 1) |
|
|
((para->dst_rect.w - 1)<<16));
|
|
reg_val = (para->src_rect.w/para->dst_rect.h)<<16;
|
|
reg_tmp = (para->src_rect.w%para->dst_rect.h);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.h;
|
|
write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
|
|
reg_val = (para->src_rect.h/para->dst_rect.w)<<16;
|
|
reg_tmp = (para->src_rect.h%para->dst_rect.w);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.w;
|
|
write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
|
|
} else {
|
|
write_wvalue(G2D_SCALER_SIZE_REG,
|
|
(para->dst_rect.w - 1) |
|
|
((para->dst_rect.h - 1)<<16));
|
|
reg_val = (para->src_rect.w/para->dst_rect.w)<<16;
|
|
reg_tmp = (para->src_rect.w%para->dst_rect.w);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.w;
|
|
write_wvalue(G2D_SCALER_HFACTOR_REG, reg_val);
|
|
reg_val = (para->src_rect.h/para->dst_rect.h)<<16;
|
|
reg_tmp = (para->src_rect.h%para->dst_rect.h);
|
|
reg_val |= (reg_tmp<<16)/para->dst_rect.h;
|
|
write_wvalue(G2D_SCALER_VFACTOR_REG, reg_val);
|
|
}
|
|
/* pyuv422/420/411uvc */
|
|
if ((para->src_image.format > 0x16) &&
|
|
(para->src_image.format < 0x1A)) {
|
|
if (para->src_image.format == G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->src_image.format == G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
(para->src_rect.y/2) +
|
|
para->src_rect.x) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
para->src_rect.y +
|
|
para->src_rect.x) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<8;
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA1_STRIDE_REG,
|
|
para->src_image.w*bppnum);
|
|
write_wvalue(G2D_DMA1_SIZE_REG,
|
|
(para->src_rect.w - 1) |
|
|
((para->src_rect.h - 1)<<16));
|
|
reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
|
|
reg_val |= (5<<8) | G2D_IDMA_ENABLE;
|
|
reg_val |= mixer_set_rotate_reg(para->flag);
|
|
write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
|
|
}
|
|
if ((para->flag & G2D_BLT_PIXEL_ALPHA) ||
|
|
(para->flag & G2D_BLT_PLANE_ALPHA) ||
|
|
(para->flag & G2D_BLT_MULTI_ALPHA) ||
|
|
(para->flag & G2D_BLT_SRC_COLORKEY) ||
|
|
(para->flag & G2D_BLT_DST_COLORKEY)) {
|
|
/* pyuv422/420/411uvc */
|
|
if ((para->dst_image.format > 0x16) &&
|
|
(para->dst_image.format < 0x1A)) {
|
|
if (para->dst_image.format == G2D_FMT_PYUV411UVC)
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if (para->dst_image.format == G2D_FMT_PYUV420UVC)
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
(para->dst_rect.y/2) +
|
|
para->dst_rect.x) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
para->dst_rect.y +
|
|
para->dst_rect.x) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<16;
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA2_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA2_STRIDE_REG,
|
|
para->dst_image.w * bppnum);
|
|
write_wvalue(G2D_DMA2_SIZE_REG,
|
|
(para->dst_rect.w - 1) |
|
|
((para->dst_rect.h - 1)<<16));
|
|
reg_val = read_wvalue(G2D_DMA2_CONTROL_REG);
|
|
reg_val |= (5<<8) | G2D_IDMA_ENABLE;
|
|
write_wvalue(G2D_DMA2_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format, para->dst_image.w,
|
|
para->dst_rect.x, para->dst_rect.y);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
reg_val |= ((addr_val>>32)&0xF)<<24;/* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA3_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_DMA3_SIZE_REG,
|
|
(para->dst_rect.w - 1) |
|
|
((para->dst_rect.h - 1)<<16));
|
|
}
|
|
/* output surface is the dst surface */
|
|
write_wvalue(G2D_OUTPUT_SIZE_REG,
|
|
(para->dst_rect.w - 1) |
|
|
((para->dst_rect.h - 1)<<16));
|
|
addr_val = mixer_get_addr(para->dst_image.addr[0],
|
|
para->dst_image.format, para->dst_image.w,
|
|
para->dst_rect.x, para->dst_rect.y);
|
|
reg_val = (addr_val>>32)&0xF;/* high addr in bits */
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT0_LADDR_REG, reg_val);
|
|
|
|
if ((para->dst_image.format > 0x16) &&
|
|
(para->dst_image.format < 0x1D)) {
|
|
if ((para->dst_image.format == G2D_FMT_PYUV411UVC) ||
|
|
(para->dst_image.format == G2D_FMT_PYUV422) ||
|
|
(para->dst_image.format == G2D_FMT_PYUV420))
|
|
bppnum = 4;
|
|
else if (para->dst_image.format == G2D_FMT_PYUV411)
|
|
bppnum = 2;
|
|
else
|
|
bppnum = 8;
|
|
if ((para->dst_image.format == G2D_FMT_PYUV420UVC) ||
|
|
(para->dst_image.format == G2D_FMT_PYUV420))
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
(para->dst_rect.y/2) +
|
|
para->dst_rect.x) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->dst_image.addr[1] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
para->dst_rect.y +
|
|
para->dst_rect.x) * bppnum);
|
|
reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<8;
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT1_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_OUTPUT1_STRIDE_REG,
|
|
para->dst_image.w * bppnum);
|
|
if (para->dst_image.format == G2D_FMT_PYUV420)
|
|
addr_val = (__u64)para->dst_image.addr[2] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
(para->dst_rect.y/2) +
|
|
para->dst_rect.x) * bppnum);
|
|
else if ((para->dst_image.format == G2D_FMT_PYUV422) ||
|
|
(para->dst_image.format == G2D_FMT_PYUV411))
|
|
addr_val = (__u64)para->dst_image.addr[2] * 8 +
|
|
(__u64)((para->dst_image.w *
|
|
para->dst_rect.y +
|
|
para->dst_rect.x) * bppnum);
|
|
else
|
|
addr_val = 0;
|
|
reg_val = read_wvalue(G2D_OUTPUT_HADDR_REG);
|
|
/* high addr in bits */
|
|
reg_val |= ((addr_val>>32)&0xF)<<16;
|
|
write_wvalue(G2D_OUTPUT_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_OUTPUT2_LADDR_REG, reg_val);
|
|
write_wvalue(G2D_OUTPUT2_STRIDE_REG,
|
|
para->dst_image.w * bppnum);
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
}
|
|
if ((para->dst_image.format > 0x11) &&
|
|
(para->dst_image.format < 0x1D))
|
|
write_wvalue(G2D_CSC2_CONTROL_REG, 0x1);
|
|
|
|
/*scan order*/
|
|
write_wvalue(G2D_SCAN_ORDER_REG, (scan_order & 0x3) << 8);
|
|
|
|
/* start */
|
|
write_wvalue(G2D_CONTROL_REG, 0x0);
|
|
write_wvalue(G2D_CONTROL_REG, 0x303);
|
|
result = g2d_wait_cmd_finish();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
__u32 mixer_set_palette(g2d_palette *para)
|
|
{
|
|
__u32 *pdest_end;
|
|
__u32 *psrc_cur;
|
|
__u32 *pdest_cur;
|
|
|
|
if (para->size > 0x400)
|
|
para->size = 0x400;
|
|
psrc_cur = para->pbuffer;
|
|
pdest_cur = (__u32 *)(base_addr+G2D_PALETTE_TAB_REG);
|
|
pdest_end = pdest_cur + (para->size>>2);
|
|
|
|
while (pdest_cur < pdest_end)
|
|
*(volatile __u32 *)pdest_cur++ = *psrc_cur++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
__s32 mixer_cmdq(__u32 addr)
|
|
{
|
|
__s32 result = 0;
|
|
|
|
write_wvalue(G2D_CONTROL_REG, 0x0);
|
|
write_wvalue(G2D_CMDQ_ADDR_REG, addr);
|
|
|
|
/* start */
|
|
write_wvalue(G2D_CMDQ_STS_REG, 0x100);
|
|
write_wvalue(G2D_CMDQ_CTL_REG, 0x0);
|
|
write_wvalue(G2D_CMDQ_CTL_REG, 0x103);
|
|
result = g2d_wait_cmd_finish();
|
|
|
|
return result;
|
|
}
|
|
|
|
__u32 mixer_premultiply_set(__u32 flag)
|
|
{
|
|
__u32 reg_val;
|
|
|
|
reg_val = read_wvalue(G2D_CK_CONTROL_REG);
|
|
|
|
/* src premultiply, dst non-premultiply,
|
|
* dst_c = src_c + dst_c*(1-src_a)/A;A = src_a + dst_a*(1-src_a)
|
|
*/
|
|
if (flag&G2D_BLT_SRC_PREMULTIPLY) {
|
|
reg_val |= (0x3<<6);
|
|
write_wvalue(G2D_CK_CONTROL_REG, reg_val);
|
|
}
|
|
|
|
/* src non-premultiply, dst(out) premultiply,
|
|
* dst_c = src_c*src_a + dst_c*dst_a(1-src_a);
|
|
* A = src_a + dst_a*(1-src_a)
|
|
*/
|
|
else if (flag&G2D_BLT_DST_PREMULTIPLY) {
|
|
reg_val |= (0x7<<5);
|
|
write_wvalue(G2D_CK_CONTROL_REG, reg_val);
|
|
write_wvalue(G2D_OALPHA_CONTROL_REG, 0xAA);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
__u32 mixer_micro_block_set(g2d_blt *para)
|
|
{
|
|
__u32 reg_val, bppnum;
|
|
__u64 addr_val;
|
|
|
|
if (para->src_image.format > 0x20) {
|
|
if ((para->src_image.format == G2D_FMT_PYUV411UVC_MB16) ||
|
|
(para->src_image.format == G2D_FMT_PYUV411UVC_MB32) ||
|
|
(para->src_image.format == G2D_FMT_PYUV411UVC_MB64) ||
|
|
(para->src_image.format == G2D_FMT_PYUV411UVC_MB128))
|
|
bppnum = 4;
|
|
else
|
|
bppnum = 8;
|
|
if ((para->src_image.format == G2D_FMT_PYUV420UVC_MB16) ||
|
|
(para->src_image.format == G2D_FMT_PYUV420UVC_MB32) ||
|
|
(para->src_image.format == G2D_FMT_PYUV420UVC_MB64) ||
|
|
(para->src_image.format == G2D_FMT_PYUV420UVC_MB128))
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
(para->src_rect.y/2) +
|
|
para->src_rect.x) * bppnum);
|
|
else
|
|
addr_val = (__u64)para->src_image.addr[1] * 8 +
|
|
(__u64)((para->src_image.w *
|
|
para->src_rect.y +
|
|
para->src_rect.x) * bppnum);
|
|
reg_val = read_wvalue(G2D_DMA_HADDR_REG);
|
|
reg_val |= ((addr_val>>32)&0xF)<<8;/* high addr in bits */
|
|
write_wvalue(G2D_DMA_HADDR_REG, reg_val);
|
|
reg_val = addr_val&0xFFFFFFFF;/* low addr in bits */
|
|
write_wvalue(G2D_DMA1_LADDR_REG, reg_val);
|
|
|
|
write_wvalue(G2D_DMA1_STRIDE_REG, para->src_image.w*bppnum);
|
|
write_wvalue(G2D_DMA1_SIZE_REG,
|
|
(para->src_rect.w - 1) | ((para->src_rect.h - 1)<<16));
|
|
reg_val = read_wvalue(G2D_DMA1_CONTROL_REG);
|
|
reg_val |= (5<<8) | G2D_IDMA_ENABLE;
|
|
|
|
/* rotate/mirror */
|
|
reg_val |= mixer_set_rotate_reg(para->flag);
|
|
write_wvalue(G2D_DMA1_CONTROL_REG, reg_val);
|
|
if (para->src_image.format > 0x23 &&
|
|
para->src_image.format < 0x27)
|
|
reg_val = 0x29<<17;
|
|
else if (para->src_image.format > 0x26 &&
|
|
para->src_image.format < 0x2A)
|
|
reg_val = 0x32<<17;
|
|
else if (para->src_image.format > 0x29 &&
|
|
para->src_image.format < 0x2D)
|
|
reg_val = 0x3b<<17;
|
|
else
|
|
reg_val = 0x20<<17;
|
|
write_wvalue(G2D_DMA0_CONTROL_REG, (reg_val |
|
|
(read_wvalue(G2D_DMA0_CONTROL_REG)&0xff81ffff)));
|
|
write_wvalue(G2D_DMA1_CONTROL_REG, (reg_val |
|
|
(read_wvalue(G2D_DMA1_CONTROL_REG)&0xff81ffff)));
|
|
write_wvalue(G2D_DMA0_MBCTL_REG,
|
|
(para->src_rect.y&0xFFFF)<<16|
|
|
(para->src_rect.x&0xFFFF));
|
|
write_wvalue(G2D_DMA1_MBCTL_REG,
|
|
(para->src_rect.y&0xFFFF)<<16|
|
|
(para->src_rect.x&0xFFFF));
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|