• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }