1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #include "vou_drv.h"
20 #include "hi_type.h"
21 #include "vou_reg.h"
22 #include "vou_def.h"
23 #include "vou_hal.h"
24 #include "vou_coef_org.h"
25
26 #define VO_DEV_MAX_NUM 2
27 #define VO_LAYER_MAX_NUM 2
28
29 #define VO_SD_VTTH_WATERLINE 100
30 #define VO_HD_VTTH_WATERLINE 240
31
32 #define VO_BACKGROUD_BLACK 0x8080
33 #define VO_BACKGROUD_GREEN 0x804D3A42
34 #define VO_BACKGROUD_WHITE 0x3fffffff
35 #define VO_BACKGROUD_DEFAULT VO_BACKGROUD_WHITE
36
37 /* vou interrupt mask type */
38 typedef enum {
39 VO_INTMSK_NONE = 0,
40 VO_INTMSK_DHD0_VTTHD1 = 0x1,
41 VO_INTMSK_DHD0_VTTHD2 = 0x2,
42 VO_INTMSK_DHD0_VTTHD3 = 0x4,
43 VO_INTMSK_DHD0_UFINT = 0x8,
44
45 VO_INTMSK_DHD1_VTTHD1 = 0x10,
46 VO_INTMSK_DHD1_VTTHD2 = 0x20,
47 VO_INTMSK_DHD1_VTTHD3 = 0x40,
48 VO_INTMSK_DHD1_UFINT = 0x80,
49
50 VO_INTMSK_DSD_VTTHD1 = 0x100,
51 VO_INTMSK_DSD_VTTHD2 = 0x200,
52 VO_INTMSK_DSD_VTTHD3 = 0x400,
53 VO_INTMSK_DSD_UFINT = 0x800,
54
55 VO_INTMSK_B0_ERR = 0x1000,
56 VO_INTMSK_B1_ERR = 0x2000,
57 VO_INTMSK_B2_ERR = 0x4000,
58
59 VO_INTMSK_WBC_DHDOVER = 0x8000,
60
61 VO_INTREPORT_ALL = 0xffffffff
62 } vo_int_mask;
63
64 typedef struct {
65 hi_bool enable;
66 hi_u32 bk_grd;
67 vo_intf_type intf_type;
68 vo_intf_sync out_sync;
69 hal_disp_pixel_format pixel_fmt;
70 } hal_dev_config;
71
72 typedef struct {
73 hi_u32 bk_grd;
74 } hal_layer_config;
75
76 typedef struct {
77 hi_s32 luma;
78 hi_s32 cont;
79 hi_s32 hue;
80 hi_s32 satu;
81 } hal_csc_value;
82
83 typedef struct {
84 hi_u32 base_phys;
85 hi_void *base_virt;
86 hi_u32 hor;
87 hi_u32 ver422;
88 hi_u32 ver420;
89 hi_u32 lut;
90 hi_u32 gam;
91 hi_u32 acc;
92 } hal_coef_addr;
93
94 vo_user_intfsync_info g_user_intfsync_info;
95
96 hal_disp_syncinfo g_sync_timing[VO_OUTPUT_BUTT] = {
97 /* synm, iop, itf, vact, vbb, vfb, hact, hbb, hfb, hmid,bvact,bvbb, bvfb, hpw, vpw,idv, ihs, ivs */
98 { 0, 0, 0, 288, 22, 2, 720, 132, 12, 1, 288, 23, 2, 126, 3, 0, 0, 0 }, /* 576I(PAL) */
99 { 0, 0, 0, 240, 18, 4, 720, 119, 19, 1, 240, 19, 4, 124, 3, 0, 0, 0 }, /* 480I(NTSC) */
100 { 0, 1, 1, 1080, 41, 4, 1920, 192, 638, 1, 1, 1, 1, 44, 5, 0, 0, 0 }, /* 1080P@24Hz */
101 { 0, 1, 1, 1080, 41, 4, 1920, 192, 528, 1, 1, 1, 1, 44, 5, 0, 0, 0 }, /* 1080P@25Hz */
102 { 0, 1, 1, 1080, 41, 4, 1920, 192, 88, 1, 1, 1, 1, 44, 5, 0, 0, 0 }, /* 1080P@30Hz */
103 { 0, 1, 1, 720, 25, 5, 1280, 260, 440, 1, 1, 1, 1, 40, 5, 0, 0, 0 }, /* 720P@50Hz */
104 { 0, 1, 1, 720, 25, 5, 1280, 260, 110, 1, 1, 1, 1, 40, 5, 0, 0, 0 }, /* 720P@60Hz */
105 { 0, 0, 1, 540, 20, 2, 1920, 192, 528, 1128, 540, 21, 2, 44, 5, 0, 0, 0 }, /* 1080I@50Hz */
106 { 0, 0, 1, 540, 20, 2, 1920, 192, 88, 908, 540, 21, 2, 44, 5, 0, 0, 0 }, /* 1080I@60Hz */
107 { 0, 1, 1, 1080, 41, 4, 1920, 192, 528, 1, 1, 1, 1, 44, 5, 0, 0, 0 }, /* 1080P@50Hz */
108 { 0, 1, 1, 1080, 41, 4, 1920, 192, 88, 1, 1, 1, 1, 44, 5, 0, 0, 0 }, /* 1080P@60Hz */
109 { 1, 1, 1, 576, 44, 5, 720, 132, 12, 1, 1, 1, 1, 64, 5, 0, 0, 0 }, /* 576P@50Hz */
110 { 1, 1, 1, 480, 36, 9, 720, 122, 16, 1, 1, 1, 1, 62, 6, 0, 0, 0 }, /* 480P@60Hz */
111 { 1, 1, 2, 600, 27, 1, 800, 216, 40, 1, 1, 1, 1, 128, 4, 0, 0, 0 }, /* 800*600@60Hz VGA@60Hz */
112 { 1, 1, 2, 768, 35, 3, 1024, 296, 24, 1, 1, 1, 1, 136, 6, 0, 1, 1 }, /* 1024x768@60Hz */
113 { 1, 1, 2, 1024, 41, 1, 1280, 360, 48, 1, 1, 1, 1, 112, 3, 0, 0, 0 }, /* 1280x1024@60Hz */
114 { 1, 1, 2, 768, 27, 3, 1366, 356, 70, 1, 1, 1, 1, 143, 3, 0, 0, 0 }, /* 1366x768@60Hz */
115 { 1, 1, 2, 900, 31, 3, 1440, 384, 80, 1, 1, 1, 1, 152, 6, 0, 1, 0 }, /* 1440x900@60Hz */
116 { 1, 1, 2, 800, 28, 3, 1280, 328, 72, 1, 1, 1, 1, 128, 6, 0, 1, 0 }, /* 1280*800@60Hz VGA@60Hz */
117 { 1, 1, 2, 1200, 49, 1, 1600, 496, 64, 1, 1, 1, 1, 192, 3, 0, 0, 0 }, /* 1600*1200@60Hz */
118 { 1, 1, 2, 1050, 36, 3, 1680, 456, 104, 1, 1, 1, 1, 176, 6, 0, 1, 0 }, /* 1680*1050@60Hz */
119 /* 1920*1200@60Hz CVT (reduced blanking) */
120 { 1, 1, 2, 1200, 32, 3, 1920, 112, 48, 1, 1, 1, 1, 32, 6, 0, 0, 1 },
121 { 1, 1, 2, 480, 35, 10, 640, 144, 16, 1, 1, 1, 1, 96, 2, 0, 1, 1 }, /* 640*480@60Hz CVT */
122 { 0, 0, 0, 288, 22, 2, 960, 176, 16, 1, 288, 23, 2, 168, 3, 0, 0, 0 }, /* 960H(PAL) */
123 { 0, 0, 0, 240, 18, 4, 960, 163, 21, 1, 240, 19, 4, 168, 3, 0, 0, 0 }, /* 960H(NTSC) */
124 { 0, 1, 1, 2160, 72, 8, 1920, 192, 88, 1, 1, 1, 1, 44, 5, 0, 0, 0 }, /* 1920*2160@30Hz */
125 { 1, 1, 2, 1440, 39, 2, 2560, 112, 48, 1, 1, 1, 1, 32, 5, 0, 0, 0 }, /* 2560*1440@30Hz */
126 { 1, 1, 2, 1440, 39, 2, 2560, 112, 48, 1, 1, 1, 1, 32, 5, 0, 0, 0 }, /* 2560*1440@60Hz */
127 /* 2560*1600@60Hz CVT (reduced blanking) */
128 { 0, 1, 2, 1600, 43, 3, 2560, 112, 48, 1, 1, 1, 1, 32, 6, 0, 0, 1 },
129 { 0, 1, 1, 2160, 82, 8, 3840, 384, 1276, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 3840*2160@24Hz */
130 { 0, 1, 1, 2160, 82, 8, 3840, 384, 1056, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 3840*2160@25Hz */
131 { 0, 1, 1, 2160, 82, 8, 3840, 384, 176, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 3840*2160@30Hz */
132 { 0, 1, 1, 2160, 82, 8, 3840, 384, 1056, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 3840*2160@50Hz */
133 { 0, 1, 1, 2160, 82, 8, 3840, 384, 176, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 3840*2160@60Hz */
134 { 0, 1, 1, 2160, 82, 8, 4096, 384, 1020, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 4096x2160@24 */
135 { 0, 1, 1, 2160, 82, 8, 4096, 216, 968, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 4096x2160@25 */
136 { 0, 1, 1, 2160, 82, 8, 4096, 216, 88, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 4096x2160@30 */
137 { 0, 1, 1, 2160, 82, 8, 4096, 216, 968, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 4096x2160@50 */
138 { 0, 1, 1, 2160, 82, 8, 4096, 216, 88, 1, 1, 1, 1, 88, 10, 0, 0, 0 }, /* 4096x2160@60 */
139 { 0, 1, 1, 240, 15, 9, 320, 65, 7, 1, 240, 14, 9, 1, 1, 0, 0, 0 }, /* 320X240@60 8bit LCD */
140 { 0, 1, 1, 240, 2, 2, 320, 5, 10, 1, 1, 1, 1, 10, 1, 0, 0, 0 }, /* 320X240@50 6bit LCD */
141 { 0, 1, 1, 320, 10, 4, 240, 30, 10, 1, 1, 1, 1, 10, 2, 0, 0, 0 }, /* 240X320@50 6bit LCD */
142 { 0, 1, 1, 320, 2, 2, 240, 20, 10, 1, 1, 1, 1, 2, 1, 0, 0, 0 }, /* 240X320@60 16bit LCD */
143 { 0, 1, 1, 600, 23, 12, 800, 210, 46, 1, 1, 1, 1, 2, 1, 0, 0, 0 }, /* 800X600@60 24bit LCD */
144 { 0, 1, 1, 1280, 24, 8, 720, 123, 99, 1, 1, 1, 1, 24, 4, 0, 0, 0 }, /* 720 x1280 at 60 hz */
145 { 0, 1, 1, 1920, 36, 16, 1080, 28, 130, 1, 1, 1, 1, 24, 4, 0, 0, 0 }, /* 1080 x1920 at 60 hz */
146 { 0, 1, 1, 960, 16, 16, 480, 30, 20, 1, 1, 1, 1, 10, 2, 0, 0, 0 }, /* 480 x960 at 60 hz */
147 { 0, 1, 1, 4320, 64, 16, 7680, 768, 552, 1, 1, 1, 1, 176, 20, 0, 0, 0 }, /* 7680x4320@30 */
148 {} /* user */
149 };
150
151 static hal_dev_config g_hal_dev_cfg[VO_DEV_MAX_NUM] = {
152 {
153 .enable = HI_FALSE,
154 .bk_grd = VO_BACKGROUD_DEFAULT,
155 .intf_type = VO_INTF_HDMI | VO_INTF_BT1120 | VO_INTF_BT656,
156 .out_sync = VO_OUTPUT_1080P60,
157 .pixel_fmt = HAL_INPUTFMT_Y_CB_CR_SEMIPLANAR_422,
158 }
159 };
160
161 #define max2(x, y) ((x) > (y) ? (x) : (y))
162 #define min2(x, y) ((x) < (y) ? (x) : (y))
163 #define clip_min(x, min) (((x) >= (min)) ? (x) : (min))
164
rgb_to_yuv_full(hi_u32 rgb)165 static hi_u32 rgb_to_yuv_full(hi_u32 rgb)
166 {
167 hi_u16 y, u, v;
168 hi_u16 r, g, b;
169 hi_u16 py_temp, pcb_temp, pcr_temp;
170
171 r = rgb_r(rgb);
172 g = rgb_g(rgb);
173 b = rgb_b(rgb);
174
175 /* to calculate rgb to yc, the numbers is from algorithm, not magic numbers */
176 py_temp = (hi_u16)(((r * 76 + g * 150 + b * 29) >> 8) * 4);
177 pcb_temp = (hi_u16)(clip_min(((((b * 130 - r * 44) - g * 86) >> 8) + 128), 0) * 4);
178 pcr_temp = (hi_u16)(clip_min(((((r * 130 - g * 109) - b * 21) >> 8) + 128), 0) * 4);
179 /* value 0 - 1023 */
180 y = max2(min2(py_temp, 1023), 0);
181 u = max2(min2(pcb_temp, 1023), 0);
182 v = max2(min2(pcr_temp, 1023), 0);
183
184 return yuv(y, u, v);
185 }
186
vo_drv_board_init(hi_void)187 hi_void vo_drv_board_init(hi_void)
188 {
189 hal_vo_init();
190 vo_drv_default_setting();
191 }
192
vo_drv_int_reg_up_mode(vo_hal_layer vo_layer,vo_int_mode int_mode)193 hi_void vo_drv_int_reg_up_mode(vo_hal_layer vo_layer, vo_int_mode int_mode)
194 {
195 hal_video_set_layer_up_mode(vo_layer, int_mode);
196 return;
197 }
198
vo_drv_set_dev_intf_type(hi_s32 vo_dev,vo_intf_type intf_type)199 hi_void vo_drv_set_dev_intf_type(hi_s32 vo_dev, vo_intf_type intf_type)
200 {
201 g_hal_dev_cfg[vo_dev].intf_type = intf_type;
202 return;
203 }
204
vo_drv_set_dev_bk_grd(hi_s32 vo_dev,hi_u32 bg_color)205 hi_void vo_drv_set_dev_bk_grd(hi_s32 vo_dev, hi_u32 bg_color)
206 {
207 g_hal_dev_cfg[vo_dev].bk_grd = bg_color;
208 return;
209 }
210
vo_drv_set_dev_out_sync(hi_s32 vo_dev,vo_intf_sync vo_out_mode)211 hi_void vo_drv_set_dev_out_sync(hi_s32 vo_dev, vo_intf_sync vo_out_mode)
212 {
213 g_hal_dev_cfg[vo_dev].out_sync = vo_out_mode;
214 return;
215 }
216
217 /* interrupt relative */
vo_drv_dev_int_enable(vo_hal_dev vo_dev,hi_bool enable)218 hi_void vo_drv_dev_int_enable(vo_hal_dev vo_dev, hi_bool enable)
219 {
220 vo_int_mask int_type;
221 vo_int_mask hifb_int_type = 0x0;
222
223 switch (vo_dev) {
224 case VO_DEV_DHD0:
225 int_type = VO_INTMSK_DHD0_VTTHD1;
226 hifb_int_type = VO_INTMSK_DHD0_VTTHD2 | VO_INTMSK_DHD0_VTTHD3;
227 break;
228
229 default:
230 return;
231 }
232
233 if (enable == HI_TRUE) {
234 hal_disp_set_int_mask(int_type);
235 hal_disp_set_int_mask1(hifb_int_type);
236 } else {
237 hal_disp_clr_int_mask(int_type);
238 hal_disp_clr_int_mask1(hifb_int_type);
239 }
240
241 return;
242 }
243
vo_drv_int_set_mode(hi_s32 vo_dev,vo_int_mode int_mode)244 hi_void vo_drv_int_set_mode(hi_s32 vo_dev, vo_int_mode int_mode)
245 {
246 hal_disp_set_vt_thd_mode(vo_dev, int_mode);
247 return;
248 }
249
vo_drv_layer_enable(vo_hal_layer vo_layer,hi_bool enable)250 hi_void vo_drv_layer_enable(vo_hal_layer vo_layer, hi_bool enable)
251 {
252 hal_layer_enable_layer(vo_layer, enable);
253 return;
254 }
255
vo_drv_def_layer_bind_dev(hi_void)256 hi_void vo_drv_def_layer_bind_dev(hi_void)
257 {
258 hal_cbm_set_cbm_mixer_prio(HAL_DISP_LAYER_VHD0, VO_MIX_PRIO0, HAL_CBMMIX1);
259 hal_cbm_set_cbm_mixer_prio(HAL_DISP_LAYER_GFX0, VO_MIX_PRIO1, HAL_CBMMIX1);
260 return;
261 }
262
vo_drv_set_dev_clk(vo_hal_dev vo_dev)263 hi_void vo_drv_set_dev_clk(vo_hal_dev vo_dev)
264 {
265 /* the numbers below is the default value of the register. */
266 hi_u32 ppc_sel = 0;
267 hi_u32 frac = 0;
268 hi_u32 postdiv1 = 2;
269 hi_u32 postdiv2 = 1;
270 hi_u32 fbdiv = 46;
271 hi_u32 refdiv = 1;
272 hi_u32 vdp_out_clk_sel = 0x0;
273 hi_u32 lcd_mclk_div = 0x015E4C3;
274 hi_u32 hdmiclk_div = 0x0;
275
276 if (g_hal_dev_cfg[vo_dev].out_sync == VO_OUTPUT_USER) {
277 if (g_user_intfsync_info.user_intfsync_attr.user_sync_pll.fbdiv == 0) { /* should not be 0 */
278 printf("please set g_user_intfsync_info value!\n");
279 return;
280 }
281 if (g_user_intfsync_info.user_intfsync_attr.clk_source == VO_CLK_SOURCE_PLL) {
282 vdp_out_clk_sel = 0x0; /* 0x0 register value for lcd */
283 sys_hal_set_vo_pll_fbdiv(g_user_intfsync_info.user_intfsync_attr.user_sync_pll.fbdiv);
284 sys_hal_set_vo_pll_frac(g_user_intfsync_info.user_intfsync_attr.user_sync_pll.frac);
285 sys_hal_set_vo_pll_refdiv(g_user_intfsync_info.user_intfsync_attr.user_sync_pll.refdiv);
286 sys_hal_set_vo_pll_postdiv2(g_user_intfsync_info.user_intfsync_attr.user_sync_pll.postdiv2);
287 sys_hal_set_vo_pll_postdiv1(g_user_intfsync_info.user_intfsync_attr.user_sync_pll.postdiv1);
288 } else if (g_user_intfsync_info.user_intfsync_attr.clk_source == VO_CLK_SOURCE_LCDMCLK) {
289 vdp_out_clk_sel = 0x6; /* 0x6 register value for lcd */
290 sys_hal_lcd_mclk_div(g_user_intfsync_info.user_intfsync_attr.lcd_mclk_div);
291 sys_hal_vo_lcd_clk_en(HI_TRUE);
292 } else {
293 printf("vo clk source is illegal\n");
294 return;
295 }
296
297 sys_hal_vo_out_clk_sel(vdp_out_clk_sel);
298 sys_hal_vo_hd_clk_sel(0); /* 0 clk sel */
299 sys_hal_vo_hd_out_pctrl(g_user_intfsync_info.clk_reverse);
300 sys_hal_vo_hd0_div_mode(g_user_intfsync_info.dev_div - 1);
301 sys_hal_vo_hd_hdmi_clk_div(g_user_intfsync_info.pre_div - 1);
302
303 return;
304 }
305
306 switch (g_hal_dev_cfg[vo_dev].out_sync) {
307 /* the number is pll register config, calculate from out sync */
308 case VO_OUTPUT_PAL:
309 case VO_OUTPUT_NTSC:
310 case VO_OUTPUT_576P50:
311 case VO_OUTPUT_480P60: {
312 /* 27MHz */
313 fbdiv = 72;
314 frac = 0;
315 refdiv = 2;
316 postdiv1 = 2;
317 postdiv2 = 1;
318
319 hdmiclk_div = 0xf;
320 break;
321 }
322 case VO_OUTPUT_1080P24:
323 case VO_OUTPUT_1080P25:
324 case VO_OUTPUT_1080P30:
325 case VO_OUTPUT_720P50:
326 case VO_OUTPUT_720P60:
327 case VO_OUTPUT_1080I50:
328 case VO_OUTPUT_1080I60:
329 case VO_OUTPUT_720x1280_60: {
330 /* 74.25MHz */
331 fbdiv = 99;
332 frac = 0;
333 refdiv = 2;
334 postdiv1 = 2;
335 postdiv2 = 1;
336
337 hdmiclk_div = 0x7;
338 break;
339 }
340 case VO_OUTPUT_1080P50:
341 case VO_OUTPUT_1080P60:
342 case VO_OUTPUT_1920x2160_30:
343 case VO_OUTPUT_1080x1920_60: {
344 /* 148.5MHz */
345 fbdiv = 99;
346 frac = 0;
347 refdiv = 2;
348 postdiv1 = 2;
349 postdiv2 = 1;
350
351 hdmiclk_div = 0x3;
352 break;
353 }
354 case VO_OUTPUT_640x480_60: {
355 /* 25.175MHz */
356 fbdiv = 67;
357 frac = 5035000;
358 refdiv = 2;
359 postdiv1 = 2;
360 postdiv2 = 1;
361
362 hdmiclk_div = 0xf;
363 break;
364 }
365
366 case VO_OUTPUT_800x600_60: {
367 /* 40MHz */
368 fbdiv = 160;
369 frac = 0;
370 refdiv = 3;
371 postdiv1 = 2;
372 postdiv2 = 1;
373
374 hdmiclk_div = 0xf;
375 break;
376 }
377 case VO_OUTPUT_1024x768_60: {
378 /* 65MHz */
379 fbdiv = 130;
380 frac = 0;
381 refdiv = 3;
382 postdiv1 = 2;
383 postdiv2 = 1;
384
385 hdmiclk_div = 0x7;
386 break;
387 }
388
389 case VO_OUTPUT_1280x1024_60: {
390 /* 108MHz */
391 fbdiv = 72;
392 frac = 0;
393 refdiv = 2;
394 postdiv1 = 2;
395 postdiv2 = 1;
396
397 hdmiclk_div = 0x3;
398 break;
399 }
400 case VO_OUTPUT_1366x768_60: {
401 /* 85.5MHz */
402 fbdiv = 114;
403 frac = 0;
404 refdiv = 2;
405 postdiv1 = 2;
406 postdiv2 = 1;
407
408 hdmiclk_div = 0x7;
409 break;
410 }
411 case VO_OUTPUT_1440x900_60: {
412 /* 106.5MHz */
413 fbdiv = 71;
414 frac = 0;
415 refdiv = 2;
416 postdiv1 = 2;
417 postdiv2 = 1;
418
419 hdmiclk_div = 0x3;
420 break;
421 }
422 case VO_OUTPUT_1280x800_60: {
423 /* 83.5MHz */
424 fbdiv = 167;
425 frac = 0;
426 refdiv = 3;
427 postdiv1 = 2;
428 postdiv2 = 1;
429
430 hdmiclk_div = 0x7;
431 break;
432 }
433 case VO_OUTPUT_1600x1200_60: {
434 /* 162MHz */
435 fbdiv = 162;
436 frac = 0;
437 refdiv = 3;
438 postdiv1 = 2;
439 postdiv2 = 1;
440
441 hdmiclk_div = 0x3;
442 break;
443 }
444 case VO_OUTPUT_1680x1050_60: {
445 /* 146.25MHz */
446 fbdiv = 146;
447 frac = 4195000;
448 refdiv = 3;
449 postdiv1 = 2;
450 postdiv2 = 1;
451
452 hdmiclk_div = 0x3;
453 break;
454 }
455 case VO_OUTPUT_1920x1200_60: {
456 /* 154MHz */
457 fbdiv = 154;
458 frac = 0;
459 refdiv = 3;
460 postdiv1 = 2;
461 postdiv2 = 1;
462
463 hdmiclk_div = 0x3;
464 break;
465 }
466 case VO_OUTPUT_320x240_60: {
467 /* lcd clk config */
468 vdp_out_clk_sel = 0x6;
469 lcd_mclk_div = 0x2aE4C3;
470 sys_hal_lcd_mclk_div(lcd_mclk_div);
471 sys_hal_vo_lcd_clk_en(HI_TRUE);
472 hdmiclk_div = 0x0;
473 break;
474 }
475 case VO_OUTPUT_320x240_50: {
476 /* lcd clk config */
477 vdp_out_clk_sel = 0x6;
478 lcd_mclk_div = 0x152306;
479 sys_hal_lcd_mclk_div(lcd_mclk_div);
480 sys_hal_vo_lcd_clk_en(HI_TRUE);
481 hdmiclk_div = 0x0;
482 break;
483 }
484 case VO_OUTPUT_240x320_50: {
485 /* lcd clk config */
486 vdp_out_clk_sel = 0x6;
487 lcd_mclk_div = 0x182ed6;
488 sys_hal_lcd_mclk_div(lcd_mclk_div);
489 sys_hal_vo_lcd_clk_en(HI_TRUE);
490 hdmiclk_div = 0x0;
491 break;
492 }
493 case VO_OUTPUT_240x320_60: {
494 /* lcd clk config */
495 vdp_out_clk_sel = 0x6;
496 lcd_mclk_div = 0x90c54;
497 sys_hal_lcd_mclk_div(lcd_mclk_div);
498 sys_hal_vo_lcd_clk_en(HI_TRUE);
499 hdmiclk_div = 0x0;
500 break;
501 }
502 case VO_OUTPUT_800x600_50: {
503 /* lcd clk config */
504 vdp_out_clk_sel = 0x6;
505 lcd_mclk_div = 0x3a9cc2;
506 sys_hal_lcd_mclk_div(lcd_mclk_div);
507 sys_hal_vo_lcd_clk_en(HI_TRUE);
508 hdmiclk_div = 0x0;
509 break;
510 }
511 case VO_OUTPUT_2560x1440_30: {
512 /* 120.8496MHz */
513 fbdiv = 119;
514 frac = 6295000;
515 refdiv = 3;
516 postdiv1 = 2;
517 postdiv2 = 1;
518
519 hdmiclk_div = 0x3;
520 break;
521 }
522 case VO_OUTPUT_2560x1440_60: {
523 /* 241.6992MHz */
524 fbdiv = 119;
525 frac = 6295000;
526 refdiv = 3;
527 postdiv1 = 2;
528 postdiv2 = 1;
529
530 hdmiclk_div = 0x1;
531 break;
532 }
533 case VO_OUTPUT_2560x1600_60: {
534 /* 268.6272MHz */
535 fbdiv = 537;
536 frac = 0;
537 refdiv = 12;
538 postdiv1 = 2;
539 postdiv2 = 1;
540
541 hdmiclk_div = 0x1;
542 break;
543 }
544 case VO_OUTPUT_3840x2160_24:
545 case VO_OUTPUT_3840x2160_25:
546 case VO_OUTPUT_3840x2160_30: {
547 /* 297MHz */
548 fbdiv = 99;
549 frac = 0;
550 refdiv = 2;
551 postdiv1 = 2;
552 postdiv2 = 1;
553
554 hdmiclk_div = 0x1;
555 break;
556 }
557 case VO_OUTPUT_3840x2160_60: {
558 /* 594MHz */
559 fbdiv = 99;
560 frac = 0;
561 refdiv = 2;
562 postdiv1 = 2;
563 postdiv2 = 1;
564
565 hdmiclk_div = 0x0;
566 break;
567 }
568 case VO_OUTPUT_7680x4320_30: {
569 /* 594MHz */
570 fbdiv = 99;
571 frac = 0;
572 refdiv = 2;
573 postdiv1 = 2;
574 postdiv2 = 1;
575
576 hdmiclk_div = 0x0;
577 break;
578 }
579 case VO_OUTPUT_480x960_60: {
580 fbdiv = 257;
581 frac = 0x9f559b;
582 refdiv = 4;
583 postdiv1 = 7;
584 postdiv2 = 7;
585
586 hdmiclk_div = 0x0;
587 break;
588 }
589 default: {
590 return;
591 }
592 }
593
594 sys_hal_vo_hd_clk_sel(ppc_sel);
595 sys_hal_vo_hd_hdmi_clk_div(hdmiclk_div);
596 sys_hal_vo_out_clk_sel(vdp_out_clk_sel);
597 sys_hal_set_vo_pll_fbdiv(fbdiv);
598 sys_hal_set_vo_pll_frac(frac);
599 sys_hal_set_vo_pll_refdiv(refdiv);
600 sys_hal_set_vo_pll_postdiv2(postdiv2);
601 sys_hal_set_vo_pll_postdiv1(postdiv1);
602 return;
603 }
604
vo_drv_get_dither_io_mode(hi_u32 dither_io_mode,hi_u32 * dither_mode,hi_u32 * i_data_width_dither,hi_u32 * o_data_width_dither)605 static hi_bool vo_drv_get_dither_io_mode(hi_u32 dither_io_mode,
606 hi_u32 *dither_mode,
607 hi_u32 *i_data_width_dither,
608 hi_u32 *o_data_width_dither)
609 {
610 if (dither_io_mode == DITHER_IO_MODE_12_10) {
611 *dither_mode = DITHER_MODE_10BIT;
612 *i_data_width_dither = DITHER_IWIDTH_MODE_12BIT;
613 *o_data_width_dither = DITHER_OWIDTH_MODE_10BIT;
614 } else if (dither_io_mode == DITHER_IO_MODE_12_8) {
615 *dither_mode = DITHER_MODE_8BIT;
616 *i_data_width_dither = DITHER_IWIDTH_MODE_12BIT;
617 *o_data_width_dither = DITHER_OWIDTH_MODE_8BIT;
618 } else if (dither_io_mode == DITHER_IO_MODE_10_8) {
619 *dither_mode = DITHER_MODE_8BIT;
620 *i_data_width_dither = DITHER_IWIDTH_MODE_10BIT;
621 *o_data_width_dither = DITHER_OWIDTH_MODE_8BIT;
622 } else if (dither_io_mode == DITHER_IO_MODE_10_6) {
623 *dither_mode = DITHER_MODE_8BIT;
624 *i_data_width_dither = DITHER_IWIDTH_MODE_10BIT;
625 *o_data_width_dither = DITHER_OWIDTH_MODE_6BIT;
626 } else if (dither_io_mode == DITHER_IO_MODE_9_6) {
627 *dither_mode = DITHER_MODE_8BIT;
628 *i_data_width_dither = DITHER_IWIDTH_MODE_9BIT;
629 *o_data_width_dither = DITHER_OWIDTH_MODE_6BIT;
630 } else if (dither_io_mode == DITHER_IO_MODE_8_6) {
631 *dither_mode = DITHER_MODE_8BIT;
632 *i_data_width_dither = DITHER_IWIDTH_MODE_8BIT;
633 *o_data_width_dither = DITHER_OWIDTH_MODE_6BIT;
634 } else if (dither_io_mode == 0) {
635 *dither_mode = DITHER_MODE_8BIT;
636 *i_data_width_dither = DITHER_IWIDTH_MODE_8BIT;
637 *o_data_width_dither = DITHER_OWIDTH_MODE_6BIT;
638 } else {
639 return HI_FALSE;
640 }
641
642 return HI_TRUE;
643 }
644
vo_drv_get_dither_sed(hal_disp_dihter_sed * tmp_sed)645 static hi_void vo_drv_get_dither_sed(hal_disp_dihter_sed *tmp_sed)
646 {
647 /* number is from algorithm, not magic number */
648 tmp_sed->dither_sed_y0 = 2147483647;
649 tmp_sed->dither_sed_u0 = 2147482647;
650 tmp_sed->dither_sed_v0 = 2147481647;
651 tmp_sed->dither_sed_w0 = 2147480647;
652 tmp_sed->dither_sed_y1 = tmp_sed->dither_sed_y0;
653 tmp_sed->dither_sed_u1 = tmp_sed->dither_sed_u0;
654 tmp_sed->dither_sed_v1 = tmp_sed->dither_sed_v0;
655 tmp_sed->dither_sed_w1 = tmp_sed->dither_sed_w0;
656 tmp_sed->dither_sed_y2 = tmp_sed->dither_sed_y0;
657 tmp_sed->dither_sed_u2 = tmp_sed->dither_sed_u0;
658 tmp_sed->dither_sed_v2 = tmp_sed->dither_sed_v0;
659 tmp_sed->dither_sed_w2 = tmp_sed->dither_sed_w0;
660 tmp_sed->dither_sed_y3 = tmp_sed->dither_sed_y0;
661 tmp_sed->dither_sed_u3 = tmp_sed->dither_sed_u0;
662 tmp_sed->dither_sed_v3 = tmp_sed->dither_sed_v0;
663 tmp_sed->dither_sed_w3 = tmp_sed->dither_sed_w0;
664
665 return;
666 }
667
vo_drv_set_dev_dither_mode(vo_hal_dev VoDev,vdp_dither_mode DitherMode,vdp_dither_cfg * pstCfg)668 hi_void vo_drv_set_dev_dither_mode(vo_hal_dev VoDev, vdp_dither_mode DitherMode, vdp_dither_cfg *pstCfg)
669 {
670 hal_disp_outputchannel vo_channel;
671 hal_disp_dihter_sed dither_sed;
672 hi_u32 dither_round_unlim;
673 hi_u32 i_data_width_dither = 0;
674 hi_u32 o_data_width_dither = 0;
675 hi_u32 dither_en;
676 hi_u32 dither_io_mode;
677 hi_u32 dither_mode = 0;
678 hi_u32 dither_round;
679 hi_u32 dither_domain_mode;
680 hi_u32 dither_tap_mode;
681 hi_u32 dither_thr_max = 0;
682 hi_u32 dither_thr_min = 0;
683 hi_bool ret = HI_FALSE;
684
685 dither_en = pstCfg->dither_en;
686 dither_round = pstCfg->dither_round;
687 dither_round_unlim = pstCfg->dither_round_unlim;
688 dither_domain_mode = pstCfg->dither_domain_mode;
689 dither_tap_mode = pstCfg->dither_tap_mode;
690 dither_io_mode = pstCfg->dither_io_mode;
691
692 ret = vo_drv_get_dither_io_mode(dither_io_mode, &dither_mode, &i_data_width_dither, &o_data_width_dither);
693 if (ret == HI_FALSE) {
694 return;
695 }
696
697 if (DitherMode == VDP_DITHER_MODE_TYP) {
698 vo_drv_get_dither_sed(&dither_sed);
699 dither_thr_max = 60000; /* 60000 max */
700 dither_thr_min = 120; /* 120 min */
701 } else {
702 return;
703 }
704
705 vo_channel = HAL_DISP_CHANNEL_DHD0;
706 hal_disp_set_dither_round_unlim(vo_channel, dither_round_unlim);
707 hal_disp_set_dither_data_in_out(vo_channel, i_data_width_dither, o_data_width_dither);
708 hal_disp_set_dither_en(vo_channel, dither_en);
709 hal_disp_set_dither_mode(vo_channel, dither_mode);
710 hal_disp_set_dither_round(vo_channel, dither_round);
711 hal_disp_set_dither_domain_mode(vo_channel, dither_domain_mode);
712 hal_disp_set_dither_tap_mode(vo_channel, dither_tap_mode);
713 hal_disp_set_dither_sed(vo_channel, &dither_sed);
714 hal_disp_set_dither_thr_min_max(vo_channel, dither_thr_min, dither_thr_max);
715 }
716
vo_drv_set_dev_dither_cfg(vo_hal_dev vo_dev,hi_u32 in_bit_width,hi_u32 out_bit_width)717 hi_void vo_drv_set_dev_dither_cfg(vo_hal_dev vo_dev, hi_u32 in_bit_width, hi_u32 out_bit_width)
718 {
719 vdp_dither_cfg dither_cfg;
720
721 if ((in_bit_width == 10) && (out_bit_width == 8)) { /* 10bit 8bit */
722 /* the numbers below are register config, not magic number. */
723 dither_cfg.dither_en = 1;
724 dither_cfg.dither_round = 1;
725 dither_cfg.dither_round_unlim = 1;
726 dither_cfg.dither_domain_mode = 1;
727 dither_cfg.dither_tap_mode = 1;
728 dither_cfg.dither_io_mode = DITHER_IO_MODE_12_8;
729
730 vo_drv_set_dev_dither_mode(vo_dev, VDP_DITHER_MODE_TYP, &dither_cfg);
731 hal_disp_set_dither_en(vo_dev, HI_TRUE);
732 hal_disp_set_dither_data_in_out(vo_dev, 0x4, 0x5); /* 4:12bit 5:10bit;3:8bit */
733 } else if ((in_bit_width == 10) && (out_bit_width == 6)) { /* 10bit 6bit */
734 /* the numbers below are register config, not magic number. */
735 dither_cfg.dither_en = 1;
736 dither_cfg.dither_round = 0;
737 dither_cfg.dither_round_unlim = 1;
738 dither_cfg.dither_domain_mode = 1;
739 dither_cfg.dither_tap_mode = 1;
740 dither_cfg.dither_io_mode = DITHER_IO_MODE_10_6;
741 vo_drv_set_dev_dither_mode(vo_dev, VDP_DITHER_MODE_TYP, &dither_cfg);
742 hal_disp_set_dither_en(vo_dev, HI_TRUE);
743 hal_disp_set_dither_data_in_out(vo_dev, 0x2, 0x1);
744 } else if (((in_bit_width == 10) && (out_bit_width == 10)) || /* 10bit */
745 ((in_bit_width == 8) && (out_bit_width == 8))) { /* 8bit */
746 hal_disp_set_dither_en(vo_dev, HI_FALSE);
747 }
748 }
749
vo_drv_get_dev_vtth(vo_hal_dev vo_dev)750 hi_u32 vo_drv_get_dev_vtth(vo_hal_dev vo_dev)
751 {
752 hi_u32 dev_vtth;
753
754 switch (g_hal_dev_cfg[vo_dev].out_sync) {
755 case VO_OUTPUT_3840x2160_60:
756 case VO_OUTPUT_3840x2160_50:
757 case VO_OUTPUT_4096x2160_60:
758 case VO_OUTPUT_4096x2160_50:
759 dev_vtth = 4 * VO_HD_VTTH_WATERLINE; /* 4 times of default */
760 break;
761 case VO_OUTPUT_2560x1600_60:
762 case VO_OUTPUT_3840x2160_24:
763 case VO_OUTPUT_3840x2160_25:
764 case VO_OUTPUT_3840x2160_30:
765 case VO_OUTPUT_4096x2160_24:
766 case VO_OUTPUT_4096x2160_25:
767 case VO_OUTPUT_4096x2160_30:
768 dev_vtth = 2 * VO_HD_VTTH_WATERLINE; /* 2 times of default */
769 break;
770 default:
771 dev_vtth = VO_HD_VTTH_WATERLINE;
772 }
773
774 return dev_vtth;
775 }
776
vo_drv_set_all_crg_clk(hi_bool clk_en)777 hi_void vo_drv_set_all_crg_clk(hi_bool clk_en)
778 {
779 hi_bool vo_clk_en = clk_en;
780
781 sys_hal_vo_cfg_clk_en(vo_clk_en);
782 sys_hal_vo_apb_clk_en(vo_clk_en);
783 sys_hal_vo_bus_clk_en(vo_clk_en);
784 return;
785 }
786
vo_drv_get_dev_intf_type(vo_hal_dev vo_dev)787 hi_u32 vo_drv_get_dev_intf_type(vo_hal_dev vo_dev)
788 {
789 return g_hal_dev_cfg[vo_dev].intf_type;
790 }
791
vo_drv_set_cbm_bkg(hi_s32 vo_dev)792 void vo_drv_set_cbm_bkg(hi_s32 vo_dev)
793 {
794 hal_disp_bkcolor bkg;
795 hi_u32 yuv_bk_grd;
796 hal_dev_config *hal_dev_cfg = &g_hal_dev_cfg[vo_dev];
797
798 vo_intf_type intf_type;
799 intf_type = hal_dev_cfg->intf_type;
800
801 if ((VO_INTF_LCD & intf_type) ||
802 (VO_INTF_LCD_6BIT & intf_type) ||
803 (VO_INTF_LCD_8BIT & intf_type) ||
804 (VO_INTF_LCD_16BIT & intf_type) ||
805 (VO_INTF_LCD_18BIT & intf_type) ||
806 (VO_INTF_LCD_24BIT & intf_type) ||
807 (VO_INTF_MIPI & intf_type) ||
808 (VO_INTF_MIPI_SLAVE & intf_type)) {
809 bkg.bkg_y = rgb_r(hal_dev_cfg->bk_grd);
810 bkg.bkg_cb = rgb_g(hal_dev_cfg->bk_grd);
811 bkg.bkg_cr = rgb_b(hal_dev_cfg->bk_grd);
812 bkg.bkg_y = bkg.bkg_y << 2; /* 2 to turn 8 to 10 value */
813 bkg.bkg_cb = bkg.bkg_cb << 2; /* 2 to turn 8 to 10 value */
814 bkg.bkg_cr = bkg.bkg_cr << 2; /* 2 to turn 8 to 10 value */
815 } else {
816 yuv_bk_grd = rgb_to_yuv_full(hal_dev_cfg->bk_grd);
817 bkg.bkg_y = yuv_y(yuv_bk_grd);
818 bkg.bkg_cb = yuv_u(yuv_bk_grd);
819 bkg.bkg_cr = yuv_v(yuv_bk_grd);
820 }
821
822 hal_cbm_set_cbm_bkg(HAL_CBMMIX1, &bkg);
823 }
824
vo_drv_get_intf_property(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,hal_disp_syncinv * inv)825 void vo_drv_get_intf_property(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, hal_disp_syncinv *inv)
826 {
827 hal_dev_config *hal_dev_cfg = &g_hal_dev_cfg[vo_dev];
828
829 memcpy(sync_info, &g_sync_timing[hal_dev_cfg->out_sync], sizeof(hal_disp_syncinfo));
830 inv->hs_inv = sync_info->ihs ? 1 : 0;
831 inv->vs_inv = sync_info->ivs ? 1 : 0;
832 inv->dv_inv = sync_info->idv ? 1 : 0;
833 }
834
vo_drv_set_intf_hdmi_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,hal_disp_syncinv * inv)835 void vo_drv_set_intf_hdmi_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, hal_disp_syncinv *inv)
836 {
837 const hi_bool hdmi_clk_en = 0x1;
838 const hi_u32 hd0_div_mod = 0x0;
839 hal_dev_config *hal_dev_cfg = &g_hal_dev_cfg[vo_dev];
840
841 sys_hal_vo_hdmi_clk_en(hdmi_clk_en);
842 sys_hal_vo_hd0_div_mode(hd0_div_mod);
843
844 if ((hal_dev_cfg->out_sync == VO_OUTPUT_576P50) ||
845 (hal_dev_cfg->out_sync == VO_OUTPUT_480P60)) {
846 inv->hs_inv = 1 - inv->hs_inv;
847 inv->vs_inv = 1 - inv->vs_inv;
848 }
849 }
850
vo_drv_set_intf_bt1120_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,hal_disp_syncinv * inv)851 void vo_drv_set_intf_bt1120_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, hal_disp_syncinv *inv)
852 {
853 const hi_u32 data_mode = 5;
854 sys_hal_vo_bt_clk_en(HI_TRUE);
855
856 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_BT1120);
857 hal_intf_bt_set_dfir_en(0x1);
858
859 sys_hal_lcd_data_mode(data_mode);
860 }
861
vo_drv_set_intf_bt656_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,hal_disp_syncinv * inv)862 void vo_drv_set_intf_bt656_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, hal_disp_syncinv *inv)
863 {
864 const hi_u32 data_mode = 6;
865 hi_u32 hd0_div_mode;
866 sys_hal_vo_bt_clk_en(HI_TRUE);
867
868 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_BT656);
869 hal_intf_bt_set_dfir_en(0x1);
870
871 hd0_div_mode = 1;
872 sys_hal_lcd_data_mode(data_mode);
873 sys_hal_vo_hd0_div_mode(hd0_div_mode);
874 }
875
vo_drv_set_intf_mipi_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,hal_disp_syncinv * inv)876 void vo_drv_set_intf_mipi_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, hal_disp_syncinv *inv)
877 {
878 U_INTF_LCD_CTRL LCD_CTRL;
879 const hi_bool mipi_clk_en = 0x1;
880 hal_dev_config *hal_dev_cfg = &g_hal_dev_cfg[vo_dev];
881
882 sys_hal_vo_mipi_clk_en(mipi_clk_en);
883
884 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_MIPI);
885 /* the numbers below are register config, not magic number. */
886 LCD_CTRL.bits.hdmi_mode = 1;
887 hal_disp_set_intf_ctrl(hal_dev_cfg->intf_type, &(LCD_CTRL.u32));
888 hal_intf_bt_set_dfir_en(0x1);
889 inv->hs_inv = 0;
890 inv->vs_inv = 0;
891 inv->dv_inv = 0;
892 }
893
vo_drv_set_intf_6bit_lcd_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,vo_intf_sync out_sync)894 void vo_drv_set_intf_6bit_lcd_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, vo_intf_sync out_sync)
895 {
896 hi_bool clk_reverse = HI_FALSE;
897 /* 2 4 register config */
898 const hi_u32 hd0_div_mode = 2;
899 const hi_u32 data_mode = 4;
900 U_INTF_LCD_CTRL LCD_CTRL;
901
902 clk_reverse = HI_TRUE;
903
904 sys_hal_vo_bt_clk_en(HI_TRUE);
905 /* the numbers below are register config, not magic number. */
906 LCD_CTRL.bits.lcd_serial_mode = 1;
907 LCD_CTRL.bits.lcd_serial_perd = 0;
908 LCD_CTRL.bits.lcd_parallel_order = 0;
909 LCD_CTRL.bits.lcd_data_inv = 0;
910 LCD_CTRL.bits.lcd_parallel_mode = 0;
911
912 sys_hal_lcd_data_mode(data_mode);
913 hal_disp_set_intf_ctrl(VO_INTF_LCD_6BIT, &(LCD_CTRL.u32));
914 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_LCD_6BIT);
915
916 if (out_sync != VO_OUTPUT_USER) {
917 hal_disp_set_lcd_serial_perd(LCD_CTRL.bits.lcd_serial_perd);
918 sys_hal_vo_hd_out_pctrl(clk_reverse);
919 sys_hal_vo_hd0_div_mode(hd0_div_mode);
920 }
921 }
922
vo_drv_set_intf_8bit_lcd_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,vo_intf_sync out_sync)923 void vo_drv_set_intf_8bit_lcd_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, vo_intf_sync out_sync)
924 {
925 hi_bool clk_reverse = HI_FALSE;
926 /* 3 3 register config */
927 const hi_u32 hd0_div_mode = 3;
928 const hi_u32 data_mode = 3;
929 U_INTF_LCD_CTRL LCD_CTRL;
930
931 clk_reverse = HI_TRUE;
932
933 sys_hal_vo_bt_clk_en(HI_TRUE);
934 /* the numbers below are register config, not magic number. */
935 LCD_CTRL.bits.hdmi_mode = 1;
936 LCD_CTRL.bits.lcd_serial_mode = 1;
937 LCD_CTRL.bits.lcd_serial_perd = 1;
938 LCD_CTRL.bits.lcd_parallel_order = 0;
939 LCD_CTRL.bits.lcd_data_inv = 0;
940 LCD_CTRL.bits.lcd_parallel_mode = 1;
941
942 sys_hal_lcd_data_mode(data_mode);
943 hal_disp_set_intf_ctrl(VO_INTF_LCD_8BIT, &(LCD_CTRL.u32));
944 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_LCD_8BIT);
945
946 if (out_sync != VO_OUTPUT_USER) {
947 hal_disp_set_lcd_serial_perd(LCD_CTRL.bits.lcd_serial_perd);
948 sys_hal_vo_hd_out_pctrl(clk_reverse);
949 sys_hal_vo_hd0_div_mode(hd0_div_mode);
950 }
951 }
952
vo_drv_set_intf_16bit_lcd_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,vo_intf_sync out_sync)953 void vo_drv_set_intf_16bit_lcd_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, vo_intf_sync out_sync)
954 {
955 hi_bool clk_reverse = HI_FALSE;
956 /* 2 0 register config */
957 const hi_u32 hd0_div_mode = 0;
958 const hi_u32 data_mode = 2;
959 U_INTF_LCD_CTRL LCD_CTRL;
960
961 clk_reverse = HI_TRUE;
962
963 sys_hal_vo_bt_clk_en(HI_TRUE);
964 /* the numbers below are register config, not magic number. */
965 LCD_CTRL.bits.lcd_serial_mode = 0;
966 LCD_CTRL.bits.lcd_serial_perd = 0;
967 LCD_CTRL.bits.lcd_parallel_order = 0;
968 LCD_CTRL.bits.lcd_data_inv = 0;
969 LCD_CTRL.bits.lcd_parallel_mode = 1;
970
971 sys_hal_lcd_data_mode(data_mode);
972 hal_disp_set_intf_ctrl(VO_INTF_LCD_16BIT, &(LCD_CTRL.u32));
973 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_LCD_16BIT);
974
975 if (out_sync != VO_OUTPUT_USER) {
976 hal_disp_set_lcd_serial_perd(LCD_CTRL.bits.lcd_serial_perd);
977 sys_hal_vo_hd_out_pctrl(clk_reverse);
978 sys_hal_vo_hd0_div_mode(hd0_div_mode);
979 }
980 }
981
vo_drv_set_intf_18bit_lcd_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,vo_intf_sync out_sync)982 void vo_drv_set_intf_18bit_lcd_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, vo_intf_sync out_sync)
983 {
984 hi_bool clk_reverse = HI_FALSE;
985 hi_u32 hd0_div_mode;
986 hi_u32 data_mode;
987 U_INTF_LCD_CTRL LCD_CTRL;
988 /* 0 1 register config */
989 hd0_div_mode = 0;
990 data_mode = 1;
991 clk_reverse = HI_TRUE;
992
993 sys_hal_vo_bt_clk_en(HI_TRUE);
994 /* the numbers below are register config, not magic number. */
995 LCD_CTRL.bits.lcd_serial_mode = 0;
996 LCD_CTRL.bits.lcd_serial_perd = 0;
997 LCD_CTRL.bits.lcd_parallel_order = 0;
998 LCD_CTRL.bits.lcd_data_inv = 0;
999 LCD_CTRL.bits.lcd_parallel_mode = 1;
1000
1001 sys_hal_lcd_data_mode(data_mode);
1002 hal_disp_set_intf_ctrl(VO_INTF_LCD_6BIT, &(LCD_CTRL.u32));
1003 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_LCD_18BIT);
1004
1005 if (out_sync != VO_OUTPUT_USER) {
1006 hal_disp_set_lcd_serial_perd(LCD_CTRL.bits.lcd_serial_perd);
1007 sys_hal_vo_hd_out_pctrl(clk_reverse);
1008 sys_hal_vo_hd0_div_mode(hd0_div_mode);
1009 }
1010 }
1011
vo_drv_set_intf_24bit_lcd_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,vo_intf_sync out_sync)1012 void vo_drv_set_intf_24bit_lcd_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, vo_intf_sync out_sync)
1013 {
1014 hi_bool clk_reverse = HI_FALSE;
1015 hi_u32 hd0_div_mode;
1016 hi_u32 data_mode;
1017 U_INTF_LCD_CTRL LCD_CTRL;
1018 /* 0 0 register config */
1019 hd0_div_mode = 0;
1020 data_mode = 0;
1021 clk_reverse = HI_FALSE;
1022
1023 sys_hal_vo_bt_clk_en(HI_TRUE);
1024 /* the numbers below are register config, not magic number. */
1025 LCD_CTRL.bits.lcd_serial_mode = 0;
1026 LCD_CTRL.bits.lcd_serial_perd = 0;
1027 LCD_CTRL.bits.lcd_parallel_order = 0;
1028 LCD_CTRL.bits.lcd_data_inv = 0;
1029 LCD_CTRL.bits.lcd_parallel_mode = 1;
1030
1031 sys_hal_lcd_data_mode(data_mode);
1032 hal_disp_set_intf_ctrl(VO_INTF_LCD_6BIT, &(LCD_CTRL.u32));
1033 hal_disp_set_intf_mux_sel(vo_dev, VO_INTF_LCD_24BIT);
1034
1035 if (out_sync != VO_OUTPUT_USER) {
1036 hal_disp_set_lcd_serial_perd(LCD_CTRL.bits.lcd_serial_perd);
1037 sys_hal_vo_hd_out_pctrl(clk_reverse);
1038 sys_hal_vo_hd0_div_mode(hd0_div_mode);
1039 }
1040 }
1041
vo_drv_set_intf_cfg(hi_s32 vo_dev,hal_disp_syncinfo * sync_info,hal_disp_syncinv * inv)1042 void vo_drv_set_intf_cfg(hi_s32 vo_dev, hal_disp_syncinfo *sync_info, hal_disp_syncinv *inv)
1043 {
1044 vo_intf_sync out_sync;
1045 hal_dev_config *hal_dev_cfg = &g_hal_dev_cfg[vo_dev];
1046 out_sync = hal_dev_cfg->out_sync;
1047
1048 if (VO_INTF_HDMI & hal_dev_cfg->intf_type) {
1049 vo_drv_set_intf_hdmi_cfg(vo_dev, sync_info, inv);
1050 }
1051
1052 if (VO_INTF_BT1120 & hal_dev_cfg->intf_type) {
1053 vo_drv_set_intf_bt1120_cfg(vo_dev, sync_info, inv);
1054 }
1055
1056 if (VO_INTF_BT656 & hal_dev_cfg->intf_type) {
1057 vo_drv_set_intf_bt656_cfg(vo_dev, sync_info, inv);
1058 }
1059
1060 if (VO_INTF_MIPI & hal_dev_cfg->intf_type) {
1061 vo_drv_set_intf_mipi_cfg(vo_dev, sync_info, inv);
1062 }
1063
1064 if (VO_INTF_LCD_6BIT & hal_dev_cfg->intf_type) {
1065 vo_drv_set_intf_6bit_lcd_cfg(vo_dev, sync_info, out_sync);
1066 }
1067
1068 if (VO_INTF_LCD_8BIT & hal_dev_cfg->intf_type) {
1069 vo_drv_set_intf_8bit_lcd_cfg(vo_dev, sync_info, out_sync);
1070 }
1071
1072 if (VO_INTF_LCD_16BIT & hal_dev_cfg->intf_type) {
1073 vo_drv_set_intf_16bit_lcd_cfg(vo_dev, sync_info, out_sync);
1074 }
1075
1076 if (VO_INTF_LCD_18BIT & hal_dev_cfg->intf_type) {
1077 vo_drv_set_intf_18bit_lcd_cfg(vo_dev, sync_info, out_sync);
1078 }
1079
1080 if (VO_INTF_LCD_24BIT & hal_dev_cfg->intf_type) {
1081 vo_drv_set_intf_24bit_lcd_cfg(vo_dev, sync_info, out_sync);
1082 }
1083 }
1084
vo_drv_set_dev_multichn(hi_s32 vo_dev)1085 void vo_drv_set_dev_multichn(hi_s32 vo_dev)
1086 {
1087 hal_multi_chn multi_chn_en;
1088
1089 multi_chn_en = HAL_MULTICHN_EN_1P1C;
1090 hal_disp_set_dev_multi_chn_en(vo_dev, multi_chn_en);
1091 }
1092
vo_drv_set_dev_clip_by_intf(hi_s32 vo_dev)1093 void vo_drv_set_dev_clip_by_intf(hi_s32 vo_dev)
1094 {
1095 if (VO_INTF_BT1120 & g_hal_dev_cfg[vo_dev].intf_type) {
1096 const hal_disp_clip clip_data = { 0x40, 0x40, 0x40, 0x3ac, 0x3c0, 0x3c0 }; /* clip register config */
1097 hal_disp_set_intf_clip(VO_INTF_BT1120, HI_TRUE, &clip_data);
1098 }
1099
1100 if (VO_INTF_BT656 & g_hal_dev_cfg[vo_dev].intf_type) {
1101 const hal_disp_clip clip_data = { 0x40, 0x40, 0x40, 0x3ac, 0x3c0, 0x3c0 }; /* clip register config */
1102 hal_disp_set_intf_clip(VO_INTF_BT656, HI_TRUE, &clip_data);
1103 }
1104 }
1105
vo_drv_set_dev_int_mode(hi_s32 vo_dev,hal_disp_syncinfo * sync_info)1106 void vo_drv_set_dev_int_mode(hi_s32 vo_dev, hal_disp_syncinfo *sync_info)
1107 {
1108 vo_int_mode int_mode;
1109 if (sync_info->iop == 0) {
1110 int_mode = VO_INT_MODE_FIELD;
1111 } else {
1112 int_mode = VO_INT_MODE_FRAME;
1113 }
1114 vo_drv_int_set_mode(vo_dev, int_mode);
1115 vo_drv_int_reg_up_mode(vo_dev, int_mode);
1116 }
1117
vo_drv_set_dev_dither(hi_s32 VoDev)1118 hi_void vo_drv_set_dev_dither(hi_s32 VoDev)
1119 {
1120 if ((VO_INTF_LCD_6BIT & g_hal_dev_cfg[VoDev].intf_type) ||
1121 (VO_INTF_LCD_16BIT & g_hal_dev_cfg[VoDev].intf_type) ||
1122 (VO_INTF_LCD_18BIT & g_hal_dev_cfg[VoDev].intf_type)) {
1123 vo_drv_set_dev_dither_cfg(VoDev, 10, 6); /* 10 to 6 */
1124 } else {
1125 vo_drv_set_dev_dither_cfg(VoDev, 10, 8); /* 10 to 8 */
1126 }
1127 }
1128
vo_drv_open(hi_s32 vo_dev)1129 hi_void vo_drv_open(hi_s32 vo_dev)
1130 {
1131 hal_disp_syncinfo sync_info;
1132 hi_u16 vtth_line;
1133 hal_disp_syncinv inv = {0};
1134
1135 vo_drv_set_all_crg_clk(HI_TRUE);
1136 hal_disp_set_intf_enable(vo_dev, HI_FALSE);
1137 sys_hal_vo_dev_clk_en(0, HI_TRUE);
1138 sys_hal_vo_dev_clk_en(1, HI_TRUE);
1139
1140 vo_drv_set_cbm_bkg(vo_dev);
1141
1142 /* set interface property */
1143 vo_drv_get_intf_property(vo_dev, &sync_info, &inv);
1144
1145 vo_drv_set_intf_cfg(vo_dev, &sync_info, &inv);
1146
1147 hal_disp_set_intf_sync(vo_dev, &sync_info, &inv);
1148
1149 vo_drv_set_dev_multichn(vo_dev);
1150
1151 vo_drv_set_dev_clip_by_intf(vo_dev);
1152 vo_drv_set_dev_int_mode(vo_dev, &sync_info);
1153
1154 vtth_line = sync_info.vact + sync_info.vfb + sync_info.vbb - vo_drv_get_dev_vtth(vo_dev);
1155 hal_disp_set_vt_thd(vo_dev, vtth_line);
1156 vo_drv_set_dev_dither(vo_dev);
1157
1158 hal_disp_set_intf_enable(vo_dev, HI_TRUE);
1159 vo_drv_dev_int_enable(vo_dev, HI_TRUE);
1160 hal_disp_set_reg_up(vo_dev);
1161 g_hal_dev_cfg[vo_dev].enable = HI_TRUE;
1162
1163 return;
1164 }
1165
vo_drv_close(hi_s32 vo_dev)1166 hi_void vo_drv_close(hi_s32 vo_dev)
1167 {
1168 hi_u32 i;
1169
1170 hal_disp_set_intf_enable(vo_dev, HI_FALSE);
1171 hal_disp_set_reg_up(vo_dev);
1172
1173 udelay(25 * 1000); /* delaye 25x1000 us */
1174
1175 hal_disp_set_intf_mux_sel(vo_dev, HAL_DISP_INTF_BUTT);
1176
1177 g_hal_dev_cfg[vo_dev].enable = HI_FALSE;
1178
1179 for (i = 0; i < VO_DEV_MAX_NUM; i++) {
1180 if (g_hal_dev_cfg[vo_dev].enable) {
1181 break;
1182 }
1183 }
1184
1185 if (i == VO_DEV_MAX_NUM) {
1186 vo_drv_set_all_crg_clk(HI_FALSE);
1187 }
1188
1189 return;
1190 }
1191
vo_drv_default_setting(hi_void)1192 hi_void vo_drv_default_setting(hi_void)
1193 {
1194 hal_layer_set_layer_galpha(HAL_DISP_LAYER_VHD0, 255); /* 255 max alpha */
1195
1196 vo_drv_layer_enable(HAL_DISP_LAYER_VHD0, HI_FALSE);
1197 return;
1198 }
1199
vo_drv_func_get_cvfir_pq_cfg(vo_zme_ds_info * ds_info,vo_zme_mode zme_mode,vo_zme_comm_pq_cfg * comm_pq_cfg)1200 hi_void vo_drv_func_get_cvfir_pq_cfg(vo_zme_ds_info *ds_info, vo_zme_mode zme_mode,
1201 vo_zme_comm_pq_cfg *comm_pq_cfg)
1202 {
1203 hi_u32 zme_vprec;
1204
1205 /* the zme num is from algorithm, not magic num */
1206 if (zme_mode == VO_ZME_TYP) {
1207 zme_vprec = ds_info->zme_vprec;
1208 comm_pq_cfg->vluma_offset = 0;
1209 comm_pq_cfg->vchroma_offset = 0;
1210 comm_pq_cfg->vbluma_offset = MIN_OFFSET * (hi_s32)zme_vprec / 2;
1211 comm_pq_cfg->vbchroma_offset = MIN_OFFSET * (hi_s32)zme_vprec / 2;
1212 comm_pq_cfg->vl_flatdect_mode = 1;
1213 comm_pq_cfg->vl_coringadj_en = 1;
1214 comm_pq_cfg->vl_gain = 32;
1215 comm_pq_cfg->vl_coring = 16;
1216 comm_pq_cfg->vc_flatdect_mode = 1;
1217 comm_pq_cfg->vc_coringadj_en = 1;
1218 comm_pq_cfg->vc_gain = 32;
1219 comm_pq_cfg->vc_coring = 16;
1220 comm_pq_cfg->lhfir_offset = 0;
1221 comm_pq_cfg->chfir_offset = 0;
1222 comm_pq_cfg->hl_flatdect_mode = 1;
1223 comm_pq_cfg->hl_coringadj_en = 1;
1224 comm_pq_cfg->hl_gain = 32;
1225 comm_pq_cfg->hl_coring = 16;
1226 comm_pq_cfg->hc_flatdect_mode = 1;
1227 comm_pq_cfg->hc_coringadj_en = 1;
1228 comm_pq_cfg->hc_gain = 32;
1229 comm_pq_cfg->hc_coring = 16;
1230 }
1231 }
1232
vo_drv_set_layer_cvfir_mode(hi_u32 layer,vo_zme_mode zme_mode,const vdp_v1_cvfir_cfg * cfg)1233 static hi_void vo_drv_set_layer_cvfir_mode(hi_u32 layer, vo_zme_mode zme_mode, const vdp_v1_cvfir_cfg *cfg)
1234 {
1235 hi_u32 vzme_ck_gt_en;
1236 hi_u32 out_pro;
1237 hi_u32 out_fmt;
1238 hi_u32 out_height;
1239 hi_u32 cvfir_en;
1240 hi_u32 cvmid_en;
1241 hi_u32 cvfir_mode;
1242 hi_u32 vratio;
1243 hi_u32 vchroma_offset;
1244 hi_u32 vbchroma_offset;
1245 vo_zme_ds_info ds_info = {0};
1246 vo_zme_comm_pq_cfg comm_pq_cfg = {0};
1247
1248 ds_info.zme_vprec = ZME_VPREC;
1249 ds_info.zme_hprec = ZME_HPREC;
1250
1251 vzme_ck_gt_en = cfg->ck_gt_en;
1252 cvfir_en = cfg->cvfir_en;
1253 cvfir_mode = cfg->cvfir_mode;
1254 cvmid_en = cfg->cvmid_en;
1255
1256 out_pro = cfg->out_pro;
1257 out_fmt = cfg->out_fmt;
1258 out_height = cfg->in_height;
1259 vratio = ds_info.zme_vprec;
1260
1261 vo_drv_func_get_cvfir_pq_cfg(&ds_info, zme_mode, &comm_pq_cfg);
1262
1263 vchroma_offset = comm_pq_cfg.vchroma_offset;
1264 vbchroma_offset = comm_pq_cfg.vbchroma_offset;
1265
1266 hal_video_cvfir_set_out_height(layer, out_height);
1267 hal_video_cvfir_set_out_fmt(layer, out_fmt);
1268 hal_video_cvfir_set_out_pro(layer, out_pro);
1269 hal_video_cvfir_set_vzme_ck_gt_en(layer, vzme_ck_gt_en);
1270
1271 hal_video_cvfir_set_cvfir_en(layer, cvfir_en);
1272 hal_video_cvfir_set_cvmid_en(layer, cvmid_en);
1273 hal_video_cvfir_set_cvfir_mode(layer, cvfir_mode);
1274 hal_video_cvfir_set_vratio(layer, vratio);
1275
1276 hal_video_cvfir_set_v_chroma_offset(layer, vchroma_offset);
1277 hal_video_cvfir_set_vb_chroma_offset(layer, vbchroma_offset);
1278 }
1279
vo_vid_set_zme_enable(hi_u32 layer,const vdp_vid_ip_cfg * vid_cfg)1280 hi_void vo_vid_set_zme_enable(hi_u32 layer, const vdp_vid_ip_cfg *vid_cfg)
1281 {
1282 /* the numbers below are register config from algorithm, not magic number. */
1283 vdp_v1_cvfir_cfg cvfir_cfg;
1284 cvfir_cfg.hfir_order = 0;
1285 cvfir_cfg.lhfir_en = 0;
1286 cvfir_cfg.chfir_en = 0;
1287 cvfir_cfg.lhmid_en = 0;
1288 cvfir_cfg.chmid_en = 0;
1289 cvfir_cfg.lhfir_mode = 0;
1290 cvfir_cfg.chfir_mode = 0;
1291 cvfir_cfg.hl_shootctrl_en = 0;
1292 cvfir_cfg.hl_shootctrl_mode = 0;
1293 cvfir_cfg.hc_shootctrl_en = 0;
1294 cvfir_cfg.hc_shootctrl_mode = 0;
1295 cvfir_cfg.lvfir_en = 0;
1296 cvfir_cfg.lvmid_en = 0;
1297 cvfir_cfg.lvfir_mode = 0;
1298 cvfir_cfg.vl_shootctrl_en = 0;
1299 cvfir_cfg.vl_shootctrl_mode = 0;
1300 cvfir_cfg.vc_shootctrl_en = 0;
1301 cvfir_cfg.vc_shootctrl_mode = 0;
1302
1303 /* CVFIR */
1304 cvfir_cfg.ck_gt_en = 0;
1305 cvfir_cfg.cvfir_en = 1;
1306 cvfir_cfg.cvmid_en = 0;
1307 cvfir_cfg.cvfir_mode = 0;
1308 cvfir_cfg.out_pro = VDP_RMODE_PROGRESSIVE;
1309 cvfir_cfg.out_fmt = VDP_PROC_FMT_SP_422;
1310 cvfir_cfg.in_width = vid_cfg->vid_iw;
1311 cvfir_cfg.in_height = vid_cfg->vid_ih;
1312 cvfir_cfg.out_width = vid_cfg->vid_ow;
1313 cvfir_cfg.out_height = vid_cfg->vid_oh;
1314 vo_drv_set_layer_cvfir_mode(layer, VO_ZME_TYP, &cvfir_cfg);
1315 }
1316
vo_drv_layer_csc_enable(vo_hal_layer vo_layer,hi_bool csc_en)1317 hi_void vo_drv_layer_csc_enable(vo_hal_layer vo_layer, hi_bool csc_en)
1318 {
1319 hal_layer_set_csc_en(vo_layer, csc_en);
1320 return;
1321 }
vo_drv_get_csc_matrix(hal_csc_mode csc_mode,const vo_csc_coef ** csc_tmp)1322 hi_s32 vo_drv_get_csc_matrix(hal_csc_mode csc_mode, const vo_csc_coef **csc_tmp)
1323 {
1324 switch (csc_mode) {
1325 case HAL_CSC_MODE_BT601_TO_BT601:
1326 case HAL_CSC_MODE_BT709_TO_BT709:
1327 case HAL_CSC_MODE_RGB_TO_RGB:
1328 *csc_tmp = &g_csc_init;
1329 break;
1330 case HAL_CSC_MODE_BT709_TO_BT601:
1331 *csc_tmp = &g_csc_yuv_to_yuv_709_601;
1332 break;
1333 case HAL_CSC_MODE_BT601_TO_BT709:
1334 *csc_tmp = &g_csc_yuv_to_yuv_601_709;
1335 break;
1336 case HAL_CSC_MODE_BT601_TO_RGB_PC:
1337 *csc_tmp = &g_csc_yuv601_to_rgb_pc;
1338 break;
1339 case HAL_CSC_MODE_BT709_TO_RGB_PC:
1340 *csc_tmp = &g_csc_yuv709_to_rgb_pc;
1341 break;
1342 case HAL_CSC_MODE_RGB_TO_BT601_PC:
1343 *csc_tmp = &g_csc_rgb_to_yuv601_pc;
1344 break;
1345 case HAL_CSC_MODE_RGB_TO_BT709_PC:
1346 *csc_tmp = &g_csc_rgb_to_yuv709_pc;
1347 break;
1348 case HAL_CSC_MODE_RGB_TO_BT601_TV:
1349 *csc_tmp = &g_csc_rgb_to_yuv601_tv;
1350 break;
1351 case HAL_CSC_MODE_RGB_TO_BT709_TV:
1352 *csc_tmp = &g_csc_rgb_to_yuv709_tv;
1353 break;
1354 default:
1355 return HI_FAILURE;
1356 }
1357
1358 return HI_SUCCESS;
1359 }
1360
vo_drv_get_hal_cscvalue(const vo_csc * csc,hal_csc_value * csc_value)1361 hi_void vo_drv_get_hal_cscvalue(const vo_csc *csc, hal_csc_value *csc_value)
1362 {
1363 csc_value->luma = (hi_s32)csc->luma * 64 / 100 - 32; /* x64/100 -32 to adjust the value */
1364 csc_value->cont = ((hi_s32)csc->contrast - 50) * 2 + 100; /* -50) * 2 + 100 to adjust the value */
1365 csc_value->hue = (hi_s32)csc->hue * 60 / 100; /* x60/100 to adjust the value */
1366 csc_value->satu = ((hi_s32)csc->satuature - 50) * 2 + 100; /* -50) * 2 + 100 to adjust the value */
1367 }
1368
vo_drv_set_csc_coef_y2r(const hal_csc_value * csc_value,const vo_csc_coef * csc_tmp,vo_csc_coef * csc_coef)1369 hi_void vo_drv_set_csc_coef_y2r(const hal_csc_value *csc_value, const vo_csc_coef *csc_tmp, vo_csc_coef *csc_coef)
1370 {
1371 hi_s32 luma;
1372 hi_s32 contrast;
1373 hi_s32 hue;
1374 hi_s32 satu;
1375
1376 luma = csc_value->luma;
1377 contrast = csc_value->cont;
1378 hue = csc_value->hue;
1379 satu = csc_value->satu;
1380
1381 /* 100 and 1000 is to adjust the coef */
1382 csc_coef->csc_coef00 = (contrast * csc_tmp->csc_coef00) / 100;
1383 csc_coef->csc_coef01 = (contrast * satu * ((csc_tmp->csc_coef01 * g_cos_table[hue] -
1384 csc_tmp->csc_coef02 * g_sin_table[hue]) / 1000)) / 10000;
1385 csc_coef->csc_coef02 = (contrast * satu * ((csc_tmp->csc_coef01 * g_sin_table[hue] +
1386 csc_tmp->csc_coef02 * g_cos_table[hue]) / 1000)) / 10000;
1387 csc_coef->csc_coef10 = (contrast * csc_tmp->csc_coef10) / 100;
1388 csc_coef->csc_coef11 = (contrast * satu * ((csc_tmp->csc_coef11 * g_cos_table[hue] -
1389 csc_tmp->csc_coef12 * g_sin_table[hue]) / 1000)) / 10000;
1390 csc_coef->csc_coef12 = (contrast * satu * ((csc_tmp->csc_coef11 * g_sin_table[hue] +
1391 csc_tmp->csc_coef12 * g_cos_table[hue]) / 1000)) / 10000;
1392 csc_coef->csc_coef20 = (contrast * csc_tmp->csc_coef20) / 100;
1393 csc_coef->csc_coef21 = (contrast * satu * ((csc_tmp->csc_coef21 * g_cos_table[hue] -
1394 csc_tmp->csc_coef22 * g_sin_table[hue]) / 1000)) / 10000;
1395 csc_coef->csc_coef22 = (contrast * satu * ((csc_tmp->csc_coef21 * g_sin_table[hue] +
1396 csc_tmp->csc_coef22 * g_cos_table[hue]) / 1000)) / 10000;
1397 csc_coef->csc_in_dc0 += (contrast != 0) ? (luma * 100 / contrast) : luma * 100;
1398 }
1399
vo_drv_set_csc_coef_r2y(const hal_csc_value * csc_value,const vo_csc_coef * csc_tmp,vo_csc_coef * csc_coef)1400 hi_void vo_drv_set_csc_coef_r2y(const hal_csc_value *csc_value, const vo_csc_coef *csc_tmp, vo_csc_coef *csc_coef)
1401 {
1402 hi_s32 luma;
1403 hi_s32 contrast;
1404 hi_s32 hue;
1405 hi_s32 satu;
1406
1407 luma = csc_value->luma;
1408 contrast = csc_value->cont;
1409 hue = csc_value->hue;
1410 satu = csc_value->satu;
1411
1412 /* 100 and 1000 is to adjust the coef */
1413 csc_coef->csc_coef00 = (contrast * csc_tmp->csc_coef00) / 100;
1414 csc_coef->csc_coef01 = (contrast * csc_tmp->csc_coef01) / 100;
1415 csc_coef->csc_coef02 = (contrast * csc_tmp->csc_coef02) / 100;
1416 csc_coef->csc_coef10 = (contrast * satu * ((csc_tmp->csc_coef10 * g_cos_table[hue] +
1417 csc_tmp->csc_coef20 * g_sin_table[hue]) / 1000)) / 10000;
1418 csc_coef->csc_coef11 = (contrast * satu * ((csc_tmp->csc_coef11 * g_cos_table[hue] +
1419 csc_tmp->csc_coef21 * g_sin_table[hue]) / 1000)) / 10000;
1420 csc_coef->csc_coef12 = (contrast * satu * ((csc_tmp->csc_coef12 * g_cos_table[hue] +
1421 csc_tmp->csc_coef22 * g_sin_table[hue]) / 1000)) / 10000;
1422 csc_coef->csc_coef20 = (contrast * satu * ((csc_tmp->csc_coef20 * g_cos_table[hue] -
1423 csc_tmp->csc_coef10 * g_sin_table[hue]) / 1000)) / 10000;
1424 csc_coef->csc_coef21 = (contrast * satu * ((csc_tmp->csc_coef21 * g_cos_table[hue] -
1425 csc_tmp->csc_coef11 * g_sin_table[hue]) / 1000)) / 10000;
1426 csc_coef->csc_coef22 = (contrast * satu * ((csc_tmp->csc_coef22 * g_cos_table[hue] -
1427 csc_tmp->csc_coef12 * g_sin_table[hue]) / 1000)) / 10000;
1428 csc_coef->csc_out_dc0 += luma;
1429 }
1430
vo_drv_calc_csc_matrix(const vo_csc * csc,hal_csc_mode csc_mode,vo_csc_coef * cst_coef)1431 hi_void vo_drv_calc_csc_matrix(const vo_csc *csc, hal_csc_mode csc_mode, vo_csc_coef *cst_coef)
1432 {
1433 const vo_csc_coef *csc_tmp = HI_NULL;
1434 hi_s32 ret;
1435 hal_csc_value csc_value = {0};
1436
1437 vo_drv_get_hal_cscvalue(csc, &csc_value);
1438
1439 ret = vo_drv_get_csc_matrix(csc_mode, &csc_tmp);
1440 if (ret != HI_SUCCESS) {
1441 return;
1442 }
1443
1444 cst_coef->csc_in_dc0 = csc_tmp->csc_in_dc0;
1445 cst_coef->csc_in_dc1 = csc_tmp->csc_in_dc1;
1446 cst_coef->csc_in_dc2 = csc_tmp->csc_in_dc2;
1447 cst_coef->csc_out_dc0 = csc_tmp->csc_out_dc0;
1448 cst_coef->csc_out_dc1 = csc_tmp->csc_out_dc1;
1449 cst_coef->csc_out_dc2 = csc_tmp->csc_out_dc2;
1450
1451 if ((csc_mode == HAL_CSC_MODE_BT601_TO_RGB_PC) || (csc_mode == HAL_CSC_MODE_BT709_TO_RGB_PC) ||
1452 (csc_mode == HAL_CSC_MODE_BT601_TO_RGB_TV) || (csc_mode == HAL_CSC_MODE_BT709_TO_RGB_TV)) {
1453 vo_drv_set_csc_coef_y2r(&csc_value, csc_tmp, cst_coef);
1454 } else {
1455 vo_drv_set_csc_coef_r2y(&csc_value, csc_tmp, cst_coef);
1456 }
1457 return;
1458 }
1459
vo_drv_get_hal_cscmode(vo_csc_matrix csc_matrix,hal_csc_mode * csc_mode)1460 hi_void vo_drv_get_hal_cscmode(vo_csc_matrix csc_matrix, hal_csc_mode *csc_mode)
1461 {
1462 if (csc_matrix == VO_CSC_MATRIX_RGB_TO_BT601_PC) {
1463 *csc_mode = HAL_CSC_MODE_RGB_TO_BT601_PC;
1464 } else if (csc_matrix == VO_CSC_MATRIX_RGB_TO_BT709_PC) {
1465 *csc_mode = HAL_CSC_MODE_RGB_TO_BT709_PC;
1466 } else if (csc_matrix == VO_CSC_MATRIX_RGB_TO_BT601_TV) {
1467 *csc_mode = HAL_CSC_MODE_RGB_TO_BT601_TV;
1468 } else if (csc_matrix == VO_CSC_MATRIX_RGB_TO_BT709_TV) {
1469 *csc_mode = HAL_CSC_MODE_RGB_TO_BT709_TV;
1470 } else if (csc_matrix == VO_CSC_MATRIX_BT601_TO_RGB_PC) {
1471 *csc_mode = HAL_CSC_MODE_BT601_TO_RGB_PC;
1472 } else if (csc_matrix == VO_CSC_MATRIX_BT709_TO_RGB_PC) {
1473 *csc_mode = HAL_CSC_MODE_BT709_TO_RGB_PC;
1474 } else if (csc_matrix == VO_CSC_MATRIX_IDENTITY) {
1475 *csc_mode = HAL_CSC_MODE_RGB_TO_RGB;
1476 } else {
1477 *csc_mode = HAL_CSC_MODE_RGB_TO_RGB;
1478 }
1479 }
1480
graphic_drv_set_csc_coef(hal_disp_layer gfx_layer,const vo_csc * gfx_csc,const csc_coef_param * coef_param)1481 hi_s32 graphic_drv_set_csc_coef(hal_disp_layer gfx_layer, const vo_csc *gfx_csc, const csc_coef_param *coef_param)
1482 {
1483 vo_csc_coef coef;
1484 hal_csc_mode csc_mode = HAL_CSC_MODE_RGB_TO_BT601_TV;
1485
1486 /* pre cal 8, dc pre cal 4 */
1487 const hi_u32 pre = 8;
1488 const hi_u32 dc_pre = 4;
1489
1490 vo_drv_get_hal_cscmode(gfx_csc->csc_matrix, &csc_mode);
1491
1492 vo_drv_calc_csc_matrix(gfx_csc, csc_mode, &coef);
1493
1494 coef.new_csc_clip_max = GFX_CSC_CLIP_MAX;
1495 coef.new_csc_clip_min = GFX_CSC_CLIP_MIN;
1496 coef.new_csc_scale2p = GFX_CSC_SCALE;
1497
1498 /* x1024/1000 is to adjust coef value */
1499 coef.csc_coef00 = (hi_s32)pre * coef.csc_coef00 * 1024 / 1000;
1500 coef.csc_coef01 = (hi_s32)pre * coef.csc_coef01 * 1024 / 1000;
1501 coef.csc_coef02 = (hi_s32)pre * coef.csc_coef02 * 1024 / 1000;
1502 coef.csc_coef10 = (hi_s32)pre * coef.csc_coef10 * 1024 / 1000;
1503 coef.csc_coef11 = (hi_s32)pre * coef.csc_coef11 * 1024 / 1000;
1504 coef.csc_coef12 = (hi_s32)pre * coef.csc_coef12 * 1024 / 1000;
1505 coef.csc_coef20 = (hi_s32)pre * coef.csc_coef20 * 1024 / 1000;
1506 coef.csc_coef21 = (hi_s32)pre * coef.csc_coef21 * 1024 / 1000;
1507 coef.csc_coef22 = (hi_s32)pre * coef.csc_coef22 * 1024 / 1000;
1508
1509 coef.csc_in_dc0 = (hi_s32)dc_pre * coef.csc_in_dc0;
1510 coef.csc_in_dc1 = (hi_s32)dc_pre * coef.csc_in_dc1;
1511 coef.csc_in_dc2 = (hi_s32)dc_pre * coef.csc_in_dc2;
1512
1513 coef.csc_out_dc0 = (hi_s32)dc_pre * coef.csc_out_dc0;
1514 coef.csc_out_dc1 = (hi_s32)dc_pre * coef.csc_out_dc1;
1515 coef.csc_out_dc2 = (hi_s32)dc_pre * coef.csc_out_dc2;
1516
1517 hal_layer_set_csc_coef(gfx_layer, &coef);
1518
1519 return HI_SUCCESS;
1520 }
1521
vo_drv_video_set_csc_coef(vo_hal_layer vo_layer,vo_csc_matrix csc_matrix)1522 hi_s32 vo_drv_video_set_csc_coef(vo_hal_layer vo_layer, vo_csc_matrix csc_matrix)
1523 {
1524 vo_csc_coef coef;
1525 hal_csc_mode csc_mode;
1526 const hi_u32 dc_pre = 4; /* dc pre 4 */
1527 vo_csc csc = {0};
1528
1529 /* 50 default value */
1530 csc.contrast = 50;
1531 csc.hue = 50;
1532 csc.luma = 50;
1533 csc.satuature = 50;
1534
1535 if ((vo_layer < LAYER_VHD_START) || (vo_layer > LAYER_VHD_END)) {
1536 printf("[%s][%d] vo_layer:%d not supported\n", __FUNCTION__, __LINE__, vo_layer);
1537 return HI_FAILURE;
1538 }
1539
1540 vo_drv_get_hal_cscmode(csc_matrix, &csc_mode);
1541
1542 vo_drv_calc_csc_matrix(&csc, csc_mode, &coef);
1543
1544 /* 0xfff 0x0 0xa default value from algorithm */
1545 coef.new_csc_clip_max = 0xfff;
1546 coef.new_csc_clip_min = 0x0;
1547 coef.new_csc_scale2p = 0xa;
1548
1549 /* x1024/1000 is to adjust coef value */
1550 coef.csc_coef00 = coef.csc_coef00 * 1024 / 1000;
1551 coef.csc_coef01 = coef.csc_coef01 * 1024 / 1000;
1552 coef.csc_coef02 = coef.csc_coef02 * 1024 / 1000;
1553 coef.csc_coef10 = coef.csc_coef10 * 1024 / 1000;
1554 coef.csc_coef11 = coef.csc_coef11 * 1024 / 1000;
1555 coef.csc_coef12 = coef.csc_coef12 * 1024 / 1000;
1556 coef.csc_coef20 = coef.csc_coef20 * 1024 / 1000;
1557 coef.csc_coef21 = coef.csc_coef21 * 1024 / 1000;
1558 coef.csc_coef22 = coef.csc_coef22 * 1024 / 1000;
1559
1560 coef.csc_in_dc0 = (hi_s32)dc_pre * coef.csc_in_dc0;
1561 coef.csc_in_dc1 = (hi_s32)dc_pre * coef.csc_in_dc1;
1562 coef.csc_in_dc2 = (hi_s32)dc_pre * coef.csc_in_dc2;
1563
1564 coef.csc_out_dc0 = (hi_s32)dc_pre * coef.csc_out_dc0;
1565 coef.csc_out_dc1 = (hi_s32)dc_pre * coef.csc_out_dc1;
1566 coef.csc_out_dc2 = (hi_s32)dc_pre * coef.csc_out_dc2;
1567
1568 hal_layer_set_csc_coef(vo_layer, &coef);
1569
1570 return HI_SUCCESS;
1571 }