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