fix rgb / yuv switch rga sync error bug
[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 uint32_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     w_ratio = (msg->src.act_w << 16) / msg->dst.act_w;\r
95     h_ratio = (msg->src.act_h << 16) / msg->dst.act_h;\r
96    \r
97     memcpy(msg1, msg, sizeof(struct rga_req));\r
98 \r
99     msg->dst.format = msg->src.format;\r
100 \r
101     /*pre_scale_w cal*/\r
102     if ((w_ratio >= (2<<16)) && (w_ratio < (4<<16))) {            \r
103         daw = (msg->src.act_w + 1) >> 1;\r
104         if((IS_YUV_420(msg->dst.format)) && (daw & 1)) {\r
105             msg->src.act_w = (daw - 1) << 1;                                                    \r
106         }        \r
107     }\r
108     else if ((w_ratio >= (4<<16)) && (w_ratio < (8<<16))) {\r
109         daw = (msg->src.act_w + 3) >> 2;            \r
110         if((IS_YUV_420(msg->dst.format)) && (daw & 1)) {\r
111             msg->src.act_w = (daw - 1) << 2;                                                    \r
112         }\r
113     }\r
114     else if ((w_ratio >= (8<<16)) && (w_ratio < (16<<16))) {\r
115         daw = (msg->src.act_w + 7) >> 3;\r
116         if((IS_YUV_420(msg->dst.format)) && (daw & 1)) {\r
117             msg->src.act_w = (daw - 1) << 3;                                                    \r
118         }\r
119     }\r
120 \r
121     pl = (RGA_pixel_width_init(msg->src.format));\r
122     stride = (pl * daw + 3) & (~3);\r
123     msg->dst.act_w = daw;\r
124     msg->dst.vir_w = stride / pl;\r
125 \r
126     /*pre_scale_h cal*/        \r
127     if ((h_ratio >= (2<<16)) && (h_ratio < (4<<16))) {            \r
128         dah = (msg->src.act_h + 1) >> 1;            \r
129         if((IS_YUV(msg->dst.format)) && (dah & 1)) {\r
130             msg->src.act_h = (dah - 1) << 1;                                                    \r
131         }            \r
132     }\r
133     else if ((h_ratio >= (4<<16)) && (h_ratio < (8<<16))) {\r
134         dah = (msg->src.act_h + 3) >> 2;            \r
135         if((IS_YUV(msg->dst.format)) && (dah & 1)) {\r
136             msg->src.act_h = (dah - 1) << 2;                                                    \r
137         }\r
138     }\r
139     else if ((h_ratio >= (8<<16)) && (h_ratio < (16<<16))) {\r
140         dah = (msg->src.act_h + 7) >> 3;\r
141         if((IS_YUV(msg->dst.format)) && (dah & 1)) {\r
142             msg->src.act_h = (dah - 1) << 3;                                                    \r
143         }\r
144     }\r
145 \r
146     printk("test_2\n");\r
147     \r
148     msg->dst.act_h = dah;\r
149     msg->dst.vir_h = dah;\r
150             \r
151     msg->dst.yrgb_addr = (u32)rga_service.pre_scale_buf;\r
152     msg->dst.uv_addr = msg->dst.yrgb_addr + stride * dah;\r
153     msg->dst.v_addr = msg->dst.uv_addr + ((stride * dah) >> 1);\r
154 \r
155     msg->render_mode = pre_scaling_mode;\r
156 \r
157     msg1->src.yrgb_addr = msg->dst.yrgb_addr;\r
158     msg1->src.uv_addr = msg->dst.uv_addr;\r
159     msg1->src.v_addr = msg->dst.v_addr;\r
160 \r
161     msg1->src.act_w = msg->dst.act_w;\r
162     msg1->src.act_h = msg->dst.act_h;\r
163     msg1->src.vir_w = msg->dst.vir_w;\r
164     msg1->src.vir_h = msg->dst.vir_h;\r
165             \r
166     return 0;\r
167 }\r
168 \r
169 \r