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