xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/rga/RGA_API.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun #include <linux/memory.h>
4*4882a593Smuzhiyun #include "RGA_API.h"
5*4882a593Smuzhiyun #include "rga.h"
6*4882a593Smuzhiyun //#include "rga_angle.h"
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #define IS_YUV_420(format) \
9*4882a593Smuzhiyun      ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \
10*4882a593Smuzhiyun       (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP))
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define IS_YUV_422(format) \
13*4882a593Smuzhiyun      ((format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \
14*4882a593Smuzhiyun       (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP))
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define IS_YUV(format) \
17*4882a593Smuzhiyun      ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \
18*4882a593Smuzhiyun       (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP) | \
19*4882a593Smuzhiyun       (format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \
20*4882a593Smuzhiyun       (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP))
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun extern rga_service_info rga_service;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun void
matrix_cal(const struct rga_req * msg,TILE_INFO * tile)27*4882a593Smuzhiyun matrix_cal(const struct rga_req *msg, TILE_INFO *tile)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun     uint64_t x_time, y_time;
30*4882a593Smuzhiyun     uint64_t sina, cosa;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun     int s_act_w, s_act_h, d_act_w, d_act_h;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun     s_act_w = msg->src.act_w;
35*4882a593Smuzhiyun     s_act_h = msg->src.act_h;
36*4882a593Smuzhiyun     d_act_w = msg->dst.act_w;
37*4882a593Smuzhiyun     d_act_h = msg->dst.act_h;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun     if (s_act_w == 1) s_act_w += 1;
40*4882a593Smuzhiyun     if (s_act_h == 1) s_act_h += 1;
41*4882a593Smuzhiyun     if (d_act_h == 1) d_act_h += 1;
42*4882a593Smuzhiyun     if (d_act_w == 1) d_act_w += 1;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun     x_time = ((s_act_w - 1)<<16) / (d_act_w - 1);
45*4882a593Smuzhiyun     y_time = ((s_act_h - 1)<<16) / (d_act_h - 1);
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun     sina = msg->sina;
48*4882a593Smuzhiyun     cosa = msg->cosa;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun     switch(msg->rotate_mode)
51*4882a593Smuzhiyun     {
52*4882a593Smuzhiyun         /* 16.16 x 16.16 */
53*4882a593Smuzhiyun         /* matrix[] is 64 bit wide */
54*4882a593Smuzhiyun         case 1 :
55*4882a593Smuzhiyun             tile->matrix[0] =  cosa*x_time;
56*4882a593Smuzhiyun             tile->matrix[1] = -sina*y_time;
57*4882a593Smuzhiyun             tile->matrix[2] =  sina*x_time;
58*4882a593Smuzhiyun             tile->matrix[3] =  cosa*y_time;
59*4882a593Smuzhiyun             break;
60*4882a593Smuzhiyun         case 2 :
61*4882a593Smuzhiyun             tile->matrix[0] = -(x_time<<16);
62*4882a593Smuzhiyun             tile->matrix[1] = 0;
63*4882a593Smuzhiyun             tile->matrix[2] = 0;
64*4882a593Smuzhiyun             tile->matrix[3] = (y_time<<16);
65*4882a593Smuzhiyun             break;
66*4882a593Smuzhiyun         case 3 :
67*4882a593Smuzhiyun             tile->matrix[0] = (x_time<<16);
68*4882a593Smuzhiyun             tile->matrix[1] = 0;
69*4882a593Smuzhiyun             tile->matrix[2] = 0;
70*4882a593Smuzhiyun             tile->matrix[3] = -(y_time<<16);
71*4882a593Smuzhiyun             break;
72*4882a593Smuzhiyun         default :
73*4882a593Smuzhiyun             tile->matrix[0] =  (uint64_t)1<<32;
74*4882a593Smuzhiyun             tile->matrix[1] =  0;
75*4882a593Smuzhiyun             tile->matrix[2] =  0;
76*4882a593Smuzhiyun             tile->matrix[3] =  (uint64_t)1<<32;
77*4882a593Smuzhiyun             break;
78*4882a593Smuzhiyun     }
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 
RGA_gen_two_pro(struct rga_req * msg,struct rga_req * msg1)82*4882a593Smuzhiyun int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun     struct rga_req *mp;
86*4882a593Smuzhiyun     uint32_t w_ratio, h_ratio;
87*4882a593Smuzhiyun     uint32_t stride;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun     uint32_t daw, dah;
90*4882a593Smuzhiyun     uint32_t pl;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun     daw = dah = 0;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun     mp = msg1;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun     if(msg->dst.act_w == 0)
97*4882a593Smuzhiyun     {
98*4882a593Smuzhiyun         printk("%s, [%d] rga dst act_w is zero\n", __FUNCTION__, __LINE__);
99*4882a593Smuzhiyun         return -EINVAL;
100*4882a593Smuzhiyun     }
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun     if (msg->dst.act_h == 0)
103*4882a593Smuzhiyun     {
104*4882a593Smuzhiyun         printk("%s, [%d] rga dst act_w is zero\n", __FUNCTION__, __LINE__);
105*4882a593Smuzhiyun         return -EINVAL;
106*4882a593Smuzhiyun     }
107*4882a593Smuzhiyun     w_ratio = (msg->src.act_w << 16) / msg->dst.act_w;
108*4882a593Smuzhiyun     h_ratio = (msg->src.act_h << 16) / msg->dst.act_h;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun     memcpy(msg1, msg, sizeof(struct rga_req));
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun     msg->dst.format = msg->src.format;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun     /*pre_scale_w cal*/
115*4882a593Smuzhiyun     if ((w_ratio >= (2<<16)) && (w_ratio < (4<<16))) {
116*4882a593Smuzhiyun         daw = (msg->src.act_w + 1) >> 1;
117*4882a593Smuzhiyun         if((IS_YUV_420(msg->dst.format)) && (daw & 1)) {
118*4882a593Smuzhiyun             daw -= 1;
119*4882a593Smuzhiyun             msg->src.act_w = daw << 1;
120*4882a593Smuzhiyun         }
121*4882a593Smuzhiyun     }
122*4882a593Smuzhiyun     else if ((w_ratio >= (4<<16)) && (w_ratio < (8<<16))) {
123*4882a593Smuzhiyun         daw = (msg->src.act_w + 3) >> 2;
124*4882a593Smuzhiyun         if((IS_YUV_420(msg->dst.format)) && (daw & 1)) {
125*4882a593Smuzhiyun             daw -= 1;
126*4882a593Smuzhiyun             msg->src.act_w = daw << 2;
127*4882a593Smuzhiyun         }
128*4882a593Smuzhiyun     }
129*4882a593Smuzhiyun     else if ((w_ratio >= (8<<16)) && (w_ratio < (16<<16))) {
130*4882a593Smuzhiyun         daw = (msg->src.act_w + 7) >> 3;
131*4882a593Smuzhiyun         if((IS_YUV_420(msg->dst.format)) && (daw & 1)) {
132*4882a593Smuzhiyun             daw -= 1;
133*4882a593Smuzhiyun             msg->src.act_w = daw << 3;
134*4882a593Smuzhiyun         }
135*4882a593Smuzhiyun     }
136*4882a593Smuzhiyun     else
137*4882a593Smuzhiyun     {
138*4882a593Smuzhiyun         daw = msg->src.act_w;
139*4882a593Smuzhiyun     }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun     pl = (RGA_pixel_width_init(msg->src.format));
142*4882a593Smuzhiyun     stride = (pl * daw + 3) & (~3);
143*4882a593Smuzhiyun     msg->dst.act_w = daw;
144*4882a593Smuzhiyun     msg->dst.vir_w = stride / pl;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun     /*pre_scale_h cal*/
147*4882a593Smuzhiyun     if ((h_ratio >= (2<<16)) && (h_ratio < (4<<16))) {
148*4882a593Smuzhiyun         dah = (msg->src.act_h + 1) >> 1;
149*4882a593Smuzhiyun         if((IS_YUV(msg->dst.format)) && (dah & 1)) {
150*4882a593Smuzhiyun             dah -= 1;
151*4882a593Smuzhiyun             msg->src.act_h = dah << 1;
152*4882a593Smuzhiyun         }
153*4882a593Smuzhiyun     }
154*4882a593Smuzhiyun     else if ((h_ratio >= (4<<16)) && (h_ratio < (8<<16))) {
155*4882a593Smuzhiyun         dah = (msg->src.act_h + 3) >> 2;
156*4882a593Smuzhiyun         if((IS_YUV(msg->dst.format)) && (dah & 1)) {
157*4882a593Smuzhiyun             dah -= 1;
158*4882a593Smuzhiyun             msg->src.act_h = dah << 2;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun         }
161*4882a593Smuzhiyun     }
162*4882a593Smuzhiyun     else if ((h_ratio >= (8<<16)) && (h_ratio < (16<<16))) {
163*4882a593Smuzhiyun         dah = (msg->src.act_h + 7) >> 3;
164*4882a593Smuzhiyun         if((IS_YUV(msg->dst.format)) && (dah & 1)) {
165*4882a593Smuzhiyun             dah -= 1;
166*4882a593Smuzhiyun             msg->src.act_h = dah << 3;
167*4882a593Smuzhiyun         }
168*4882a593Smuzhiyun     }
169*4882a593Smuzhiyun     else
170*4882a593Smuzhiyun     {
171*4882a593Smuzhiyun         dah = msg->src.act_h;
172*4882a593Smuzhiyun     }
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun     msg->dst.act_h = dah;
175*4882a593Smuzhiyun     msg->dst.vir_h = dah;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun     msg->dst.x_offset = 0;
178*4882a593Smuzhiyun     msg->dst.y_offset = 0;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun     msg->dst.yrgb_addr = (unsigned long)rga_service.pre_scale_buf;
181*4882a593Smuzhiyun     msg->dst.uv_addr = msg->dst.yrgb_addr + stride * dah;
182*4882a593Smuzhiyun     msg->dst.v_addr = msg->dst.uv_addr + ((stride * dah) >> 1);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun     msg->render_mode = pre_scaling_mode;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun     msg1->src.yrgb_addr = msg->dst.yrgb_addr;
187*4882a593Smuzhiyun     msg1->src.uv_addr = msg->dst.uv_addr;
188*4882a593Smuzhiyun     msg1->src.v_addr = msg->dst.v_addr;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun     msg1->src.act_w = msg->dst.act_w;
191*4882a593Smuzhiyun     msg1->src.act_h = msg->dst.act_h;
192*4882a593Smuzhiyun     msg1->src.vir_w = msg->dst.vir_w;
193*4882a593Smuzhiyun     msg1->src.vir_h = msg->dst.vir_h;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun     msg1->src.x_offset = 0;
196*4882a593Smuzhiyun     msg1->src.y_offset = 0;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun     return 0;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 
202