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