1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your 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, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18 #include "hdmi_hal_intf.h"
19 #include "hdmi_hal_phy.h"
20 #include "hdmi_reg_crg.h"
21 #include "hdmi_product_define.h"
22 #include "drv_hdmi_intf.h"
23
24 #define TX_MAX_TMDS_CLK 600
25 #define CTRL_RESET_WAIT 20
26
27 typedef hi_void *hdmi_handle;
28
29 static hdmi_hal_cfg g_hal_cfg[HDMI_DEVICE_ID_BUTT];
30
depth_convert_to_deep_color(hdmi_video_bit_depth video_bit_depth)31 static hdmi_deep_color depth_convert_to_deep_color(hdmi_video_bit_depth video_bit_depth)
32 {
33 hdmi_deep_color ret;
34
35 switch (video_bit_depth) {
36 case HDMI_VIDEO_BITDEPTH_8:
37 ret = HDMI_DEEP_COLOR_24BIT;
38 break;
39 case HDMI_VIDEO_BITDEPTH_10:
40 ret = HDMI_DEEP_COLOR_30BIT;
41 break;
42 case HDMI_VIDEO_BITDEPTH_12:
43 ret = HDMI_DEEP_COLOR_36BIT;
44 break;
45 case HDMI_VIDEO_BITDEPTH_16:
46 ret = HDMI_DEEP_COLOR_24BIT;
47 break;
48 case HDMI_VIDEO_BITDEPTH_OFF:
49 ret = HDMI_DEEP_COLOR_OFF;
50 break;
51 default:
52 ret = HDMI_DEEP_COLOR_OFF;
53 break;
54 }
55
56 return ret;
57 }
58
intf_hal_info_ptr_get(hdmi_device_id hdmi)59 static hdmi_hal_cfg *intf_hal_info_ptr_get(hdmi_device_id hdmi)
60 {
61 if (hdmi < HDMI_DEVICE_ID_BUTT) {
62 return &g_hal_cfg[hdmi];
63 }
64 return HI_NULL;
65 }
66
67 #ifdef HDMI_DEBUG_SUPPORT
hal_hdmi_cbar_enable(hi_bool enable)68 static hi_void hal_hdmi_cbar_enable(hi_bool enable)
69 {
70 hi_u32 *reg_addr = HI_NULL;
71 hi_u32 reg_value;
72
73 reg_addr = (hi_u32 *)osal_ioremap_nocache(HDMI_COLOR_BAR_BASE, 4); /* 4: register size */
74 hdmi_if_null_return_void(reg_addr);
75 reg_value = hdmi_reg_read(reg_addr);
76
77 if (enable) {
78 reg_value |= HDMI_COLOR_BAR_MASK;
79 reg_value |= HDMI_COLOR_BAR_UPDATE_MASK;
80 } else {
81 reg_value &= ~HDMI_COLOR_BAR_MASK;
82 reg_value |= HDMI_COLOR_BAR_UPDATE_MASK;
83 }
84 hdmi_reg_write(reg_addr, reg_value);
85 osal_iounmap((void *)reg_addr, 0x4);
86 }
87 #endif
88
intf_tx_capability_init(hdmi_device_id hdmi_id)89 static hi_void intf_tx_capability_init(hdmi_device_id hdmi_id)
90 {
91 hdmi_hal_cfg *hal_cfg = intf_hal_info_ptr_get(hdmi_id);
92
93 hdmi_if_null_return_void(hal_cfg);
94
95 /* tx capability */
96 hal_cfg->tx_capability.tx_hdmi_14 = HI_TRUE;
97 hal_cfg->tx_capability.tx_hdmi_20 = HI_TRUE;
98 hal_cfg->tx_capability.tx_hdcp_14 = HI_TRUE;
99 hal_cfg->tx_capability.tx_hdcp_22 = HI_TRUE;
100 hal_cfg->tx_capability.tx_rgb444 = HI_TRUE;
101 hal_cfg->tx_capability.tx_ycbcr444 = HI_TRUE;
102 hal_cfg->tx_capability.tx_ycbcr422 = HI_TRUE;
103 hal_cfg->tx_capability.tx_ycbcr420 = HI_TRUE;
104 hal_cfg->tx_capability.tx_deep_clr10_bit = HI_TRUE;
105 hal_cfg->tx_capability.tx_deep_clr12_bit = HI_TRUE;
106 hal_cfg->tx_capability.tx_deep_clr16_bit = HI_FALSE;
107 hal_cfg->tx_capability.tx_rgb_ycbcr444 = HI_TRUE;
108 hal_cfg->tx_capability.tx_ycbcr444_422 = HI_TRUE;
109 hal_cfg->tx_capability.tx_ycbcr422_420 = HI_TRUE;
110 hal_cfg->tx_capability.tx_ycbcr420_422 = HI_TRUE;
111 hal_cfg->tx_capability.tx_ycbcr422_444 = HI_TRUE;
112 hal_cfg->tx_capability.tx_ycbcr444_rgb = HI_TRUE;
113 hal_cfg->tx_capability.tx_scdc = HI_TRUE;
114 hal_cfg->tx_capability.tx_max_tmds_clk = TX_MAX_TMDS_CLK;
115 return;
116 }
117
hal_hdmi_hardware_init(const struct hdmi_hal_ * hal)118 static hi_void hal_hdmi_hardware_init(const struct hdmi_hal_ *hal)
119 {
120 hi_unused(hal);
121 drv_hdmi_prod_crg_init();
122 return;
123 }
124
hal_hdmi_tmds_mode_set(const struct hdmi_hal_ * hal,hdmi_tmds_mode tmds_mode)125 static hi_void hal_hdmi_tmds_mode_set(const struct hdmi_hal_ *hal, hdmi_tmds_mode tmds_mode)
126 {
127 hdmi_if_null_return_void(hal);
128 hal_hdmi_ctrl_tmds_mode_set(hal->hal_ctx.hdmi_id, tmds_mode);
129 return;
130 }
131
hal_hdmi_avmute_set(const struct hdmi_hal_ * hal,hi_bool avmute)132 static hi_void hal_hdmi_avmute_set(const struct hdmi_hal_ *hal, hi_bool avmute)
133 {
134 hdmi_avmute_cfg avmute_cfg = {0};
135
136 hdmi_if_null_return_void(hal);
137
138 drv_hdmi_compat_avmute_get(hal->hal_ctx.hdmi_id, avmute, &avmute_cfg);
139 hal_hdmi_ctrl_avmute_set(hal->hal_ctx.hdmi_id, &avmute_cfg);
140
141 return;
142 }
143
hal_hdmi_emi_status_get(const struct hdmi_hal_ * hal,hdmi_emi_status * emi_status)144 static hi_void hal_hdmi_emi_status_get(const struct hdmi_hal_ *hal, hdmi_emi_status *emi_status)
145 {
146 #ifndef HDMI_FPGA_SUPPORT
147 hdmi_phy_info phy_info = {0};
148
149 hdmi_if_null_return_void(emi_status);
150
151 hal_hdmi_phy_info_get(&phy_info);
152 emi_status->sw_emi_enable = phy_info.ssc_cfg.ssc_enable;
153 emi_status->debug_enable = phy_info.ssc_cfg.ssc_debug_en;
154 hal_hdmi_phy_ssc_get(&emi_status->hw_emi_enable);
155 #endif
156 hi_unused(hal);
157 return;
158 }
159
hal_hdmi_csc_param_set(struct hdmi_hal_ * hal,hdmi_video_config * video_cfg)160 static hi_void hal_hdmi_csc_param_set(struct hdmi_hal_ *hal, hdmi_video_config *video_cfg)
161 {
162 /* colorspace in & out, quantization, CONVERSION_STD */
163 hdmi_if_null_return_void(hal);
164 hdmi_if_null_return_void(video_cfg);
165
166 hal_hdmi_ctrl_csc_set(hal->hal_ctx.hdmi_id, video_cfg);
167 hal->hal_ctx.video_cfg.in_color_space = video_cfg->in_color_space;
168 hal->hal_ctx.video_cfg.out_color_space = video_cfg->out_color_space;
169 hal->hal_ctx.video_cfg.out_csc_quantization = video_cfg->out_color_space;
170 hal->hal_ctx.video_cfg.conv_std = video_cfg->conv_std;
171
172 return;
173 }
174
hal_hdmi_infoframe_set(const struct hdmi_hal_ * hal,hdmi_infoframe_id infoframe_id,hi_u8 * in_buffer,hi_u32 buf_len)175 static hi_void hal_hdmi_infoframe_set(const struct hdmi_hal_ *hal,
176 hdmi_infoframe_id infoframe_id, hi_u8 *in_buffer, hi_u32 buf_len)
177 {
178 hdmi_if_null_return_void(hal);
179 hdmi_if_null_return_void(in_buffer);
180 hal_hdmi_ctrl_infoframe_data_set(hal->hal_ctx.hdmi_id, infoframe_id, in_buffer, buf_len);
181 return;
182 }
183
hal_hdmi_infoframe_enable_set(const struct hdmi_hal_ * hal,hdmi_infoframe_id infoframe_id,hi_bool enable)184 static hi_void hal_hdmi_infoframe_enable_set(const struct hdmi_hal_ *hal,
185 hdmi_infoframe_id infoframe_id, hi_bool enable)
186 {
187 hdmi_if_null_return_void(hal);
188 hal_hdmi_ctrl_infoframe_en_set(hal->hal_ctx.hdmi_id, infoframe_id, enable);
189 return;
190 }
191
hal_hdmi_video_path_set(const struct hdmi_hal_ * hal,hdmi_video_config * video_cfg)192 static hi_s32 hal_hdmi_video_path_set(const struct hdmi_hal_ *hal, hdmi_video_config *video_cfg)
193 {
194 hi_s32 ret;
195 hdmi_video_path video_path = {0};
196 hdmi_hal_cfg *hal_cfg = HI_NULL;
197
198 hdmi_if_null_return(hal, HI_FAILURE);
199 hdmi_if_null_return(video_cfg, HI_FAILURE);
200
201 hal_cfg = intf_hal_info_ptr_get(hal->hal_ctx.hdmi_id);
202 hdmi_if_null_return(hal_cfg, HI_FAILURE);
203 hal_cfg->tmds_clk = video_cfg->tmds_clk;
204 video_path.in_color_space = video_cfg->in_color_space;
205 video_path.out_color_space = video_cfg->out_color_space;
206 video_path.in_deep_color = depth_convert_to_deep_color(video_cfg->in_bit_depth);
207 video_path.out_deep_color = video_cfg->deep_color;
208 video_path.out_hv_sync_pol.de_inver = video_cfg->de_pol;
209 video_path.out_hv_sync_pol.h_pol_inver = video_cfg->h_sync_pol;
210 video_path.out_hv_sync_pol.v_pol_inver = video_cfg->v_sync_pol;
211
212 switch (video_cfg->conv_std) {
213 case HDMI_CONV_STD_BT_601:
214 video_path.out_colormetry = HDMI_COLORMETRY_BT601;
215 break;
216 case HDMI_CONV_STD_BT_709:
217 video_path.out_colormetry = HDMI_COLORMETRY_BT709;
218 break;
219 case HDMI_CONV_STD_BT_2020_NON_CONST_LUMINOUS:
220 video_path.out_colormetry = HDMI_COLORMETRY_BT2020;
221 break;
222 case HDMI_CONV_STD_BT_2020_CONST_LUMINOUS:
223 video_path.out_colormetry = HDMI_COLORMETRY_BT2020_CONST;
224 break;
225 default:
226 video_path.out_colormetry = HDMI_COLORMETRY_BT709;
227 break;
228 }
229 video_path.in_colormetry = video_path.out_colormetry;
230 video_path.in_quantization = video_cfg->out_csc_quantization;
231 video_path.out_quantization = video_cfg->out_csc_quantization;
232 video_path.in_pixel_clk = video_cfg->pixel_clk;
233 video_path.out_tmds_clk = video_cfg->tmds_clk;
234 video_path.timing = video_cfg->timing;
235 ret = hal_hdmi_ctrl_video_path_set(hal->hal_ctx.hdmi_id, &video_path);
236
237 return ret;
238 }
239
hal_hdmi_ctrl_reset(const struct hdmi_hal_ * hal)240 static hi_void hal_hdmi_ctrl_reset(const struct hdmi_hal_ *hal)
241 {
242 hi_u32 i;
243 hi_bool tmds_stable = HI_FALSE;
244 hi_bool output = HI_FALSE;
245
246 hdmi_if_null_return_void(hal);
247
248 hal_hdmi_phy_oe_get(&output);
249 if (output == HI_TRUE) {
250 hdmi_info("oe enable, do not reset!\n");
251 return;
252 }
253
254 hal_hdmi_ctrl_data_reset(hal->hal_ctx.hdmi_id, HI_FALSE, 0);
255
256 for (i = 0; (!tmds_stable) && (i < CTRL_RESET_WAIT); i++) {
257 osal_msleep(1);
258 hal_hdmi_ctrl_tmds_stable_get(hal->hal_ctx.hdmi_id, &tmds_stable);
259 }
260
261 hdmi_info("wait %ums, tmds_stable=%u\n", i, tmds_stable);
262
263 return;
264 }
265
hal_hdmi_phy_hw_spec_set(const struct hdmi_hal_ * hal,hi_u32 tmds_clk,const hdmi_hw_spec * hw_spec)266 static hi_s32 hal_hdmi_phy_hw_spec_set(const struct hdmi_hal_ *hal, hi_u32 tmds_clk, const hdmi_hw_spec *hw_spec)
267 {
268 hi_s32 ret = HI_SUCCESS;
269
270 #ifndef HDMI_FPGA_SUPPORT
271 hdmi_if_null_return(hw_spec, HI_ERR_NULL_PTR);
272 ret = hal_hdmi_phy_params_set(tmds_clk, hw_spec);
273 #else
274 hi_unused(tmds_clk);
275 hi_unused(hw_spec);
276 #endif
277 hi_unused(hal);
278 return ret;
279 }
280
hal_hdmi_phy_hw_spec_get(const struct hdmi_hal_ * hal,hdmi_hw_spec * hw_spec)281 static hi_s32 hal_hdmi_phy_hw_spec_get(const struct hdmi_hal_ *hal, hdmi_hw_spec *hw_spec)
282 {
283 hi_s32 ret = HI_SUCCESS;
284
285 #ifndef HDMI_FPGA_SUPPORT
286 errno_t errnumber;
287 hdmi_phy_hw_param phy_hw_param = {0};
288
289 hdmi_if_null_return(hw_spec, HI_ERR_NULL_PTR);
290 ret = hal_hdmi_phy_params_get(&phy_hw_param);
291
292 errnumber = memcpy_s(hw_spec, sizeof(*hw_spec), &phy_hw_param.hw_spec_cfg, sizeof(hdmi_hw_spec));
293 hdmi_unequal_eok_return(errnumber, HI_ERR_HDMI_INVALID_PARA);
294 #endif
295 hi_unused(hal);
296 return ret;
297 }
298
hal_hdmi_phy_output_enable_set(const struct hdmi_hal_ * hal,hi_bool enable)299 static hi_void hal_hdmi_phy_output_enable_set(const struct hdmi_hal_ *hal, hi_bool enable)
300 {
301 hdmi_if_null_return_void(hal);
302
303 #ifndef HDMI_FPGA_SUPPORT
304 hal_hdmi_phy_oe_set(enable);
305 #else
306 hi_unused(enable);
307 #endif
308 return;
309 }
310
hal_hdmi_phy_power_enable_set(const struct hdmi_hal_ * hal,hi_bool enable)311 static hi_void hal_hdmi_phy_power_enable_set(const struct hdmi_hal_ *hal, hi_bool enable)
312 {
313 #ifndef HDMI_FPGA_SUPPORT
314 hi_bool old_eable = HI_FALSE;
315
316 hal_hdmi_phy_power_get(&old_eable);
317 if (enable != old_eable) {
318 hal_hdmi_phy_power_set(enable);
319 }
320 #else
321 hi_unused(enable);
322 #endif
323 hi_unused(hal);
324 return;
325 }
326
hal_hdmi_phy_set(const struct hdmi_hal_ * hal,hdmi_phy_cfg * phy_cfg)327 static hi_void hal_hdmi_phy_set(const struct hdmi_hal_ *hal, hdmi_phy_cfg *phy_cfg)
328 {
329 #ifndef HDMI_FPGA_SUPPORT
330 hdmi_phy_tmds_cfg cfg = {0};
331
332 hdmi_if_null_return_void(phy_cfg);
333
334 cfg.deep_color = phy_cfg->deep_color;
335 cfg.emi_enable = phy_cfg->emi_enable;
336 cfg.mode_cfg = phy_cfg->mode_cfg;
337 cfg.pixel_clk = phy_cfg->pixel_clk;
338 cfg.tmds_clk = phy_cfg->tmds_clk;
339 cfg.trace_len = phy_cfg->trace_len;
340
341 hal_hdmi_phy_tmds_set(&cfg);
342 #else
343 hi_unused(phy_cfg);
344 #endif
345 hi_unused(hal);
346 return;
347 }
348
hal_hdmi_tx_capability_get(const struct hdmi_hal_ * hal,hdmi_tx_capability_data * tx_capability)349 static hi_void hal_hdmi_tx_capability_get(const struct hdmi_hal_ *hal, hdmi_tx_capability_data *tx_capability)
350 {
351 errno_t ret;
352 hdmi_hal_cfg *hal_cfg = HI_NULL;
353
354 hdmi_if_null_return_void(hal);
355 hdmi_if_null_return_void(tx_capability);
356
357 hal_cfg = intf_hal_info_ptr_get(hal->hal_ctx.hdmi_id);
358 hdmi_if_null_return_void(hal_cfg);
359 hdmi_if_false_return_void(hal_cfg->init);
360 ret = memcpy_s(tx_capability, sizeof(hdmi_tx_capability_data),
361 &hal_cfg->tx_capability, sizeof(hdmi_tx_capability_data));
362 hdmi_unequal_eok_return_void(ret);
363
364 return;
365 }
366
367 #ifdef HDMI_HDR_SUPPORT
hal_hdmi_hdr_timer_set(const struct hdmi_hal_ * hal,hdmi_timer_config * timer_cfg)368 static hi_void hal_hdmi_hdr_timer_set(const struct hdmi_hal_ *hal, hdmi_timer_config *timer_cfg)
369 {
370 hdmi_if_null_return_void(hal);
371 hdmi_if_null_return_void(timer_cfg);
372 hal_hdmi_ctrl_hdr_timer_set(hal->hal_ctx.hdmi_id, timer_cfg);
373 return;
374 }
375 #endif
376
hal_hdmi_sequencer_handler_process(const struct hdmi_hal_ * hal)377 static hi_void hal_hdmi_sequencer_handler_process(const struct hdmi_hal_ *hal)
378 {
379 hi_unused(hal);
380 hal_hdmi_mach_invoke();
381 return;
382 }
383
hal_hdmi_hw_audio_status_get(hi_u32 hdmi_id,hdmi_hardware_status * hw_status)384 static hi_void hal_hdmi_hw_audio_status_get(hi_u32 hdmi_id, hdmi_hardware_status *hw_status)
385 {
386 ctrl_audio_status audio_stat = {0};
387
388 hal_hdmi_ctrl_audio_path_get(hdmi_id, &audio_stat);
389 hw_status->audio_status.audio_mute = audio_stat.audio_mute;
390 hw_status->audio_status.audio_enable = audio_stat.enable_audio;
391 hw_status->audio_status.sample_fs = audio_stat.sample_rate;
392 hw_status->audio_status.layout = audio_stat.channel_num;
393 hw_status->audio_status.sound_intf = audio_stat.sound_intf;
394 hw_status->audio_status.sample_depth = audio_stat.sample_bit;
395 hw_status->audio_status.down_sample = HI_FALSE;
396 hw_status->audio_status.ref_cts = audio_stat.ref_cts;
397 hw_status->audio_status.reg_cts = audio_stat.reg_cts;
398 hw_status->audio_status.ref_n = audio_stat.ref_n;
399 hw_status->audio_status.reg_n = audio_stat.reg_n;
400
401 return;
402 }
403
hal_hdmi_hw_video_status_get(hi_u32 hdmi_id,hdmi_hardware_status * hw_status)404 static hi_void hal_hdmi_hw_video_status_get(hi_u32 hdmi_id, hdmi_hardware_status *hw_status)
405 {
406 ctrl_video_status video_stat = {0};
407
408 hal_hdmi_ctrl_video_path_get(hdmi_id, &video_stat);
409 hal_hdmi_ctrl_video_mute_get(hdmi_id, &hw_status->video_status.video_mute);
410 hw_status->video_status.ycbcr2rgb =
411 video_stat.csc_enable && (video_stat.out_color_space == HDMI_COLORSPACE_RGB);
412 hw_status->video_status.rgb2ycbcr =
413 video_stat.csc_enable && (video_stat.in_color_space == HDMI_COLORSPACE_RGB);
414 hw_status->video_status.ycbcr444_422 = video_stat.y422_enable;
415 hw_status->video_status.ycbcr422_420 = video_stat.y420_enable;
416 hw_status->video_status.ycbcr420_422 = HI_FALSE; // not support
417 hw_status->video_status.ycbcr422_444 = HI_FALSE; // not support
418 hw_status->video_status.in420_ydemux = video_stat.dwsm_vert_enable;
419 hw_status->video_status.out420_ydemux = HI_FALSE; // not support
420 hw_status->video_status.dither = video_stat.dither_mode;
421 hw_status->video_status.v_sync_pol = video_stat.out_hv_sync_pol.h_pol_inver;
422 hw_status->video_status.h_sync_pol = video_stat.out_hv_sync_pol.v_pol_inver;
423 hw_status->video_status.sync_pol = HI_FALSE; // not support
424 hw_status->video_status.de_pol = video_stat.out_hv_sync_pol.de_inver;
425 hw_status->video_status.swap_hs_cs = HI_FALSE; // not support
426 hw_status->video_status.in_color_space = video_stat.in_color_space;
427 hw_status->video_status.out_color_space = video_stat.out_color_space;
428 hw_status->video_status.out_bit_depth =
429 (video_stat.out_deep_color == HDMI_DEEP_COLOR_OFF) ? HDMI_VIDEO_BITDEPTH_OFF : video_stat.out_deep_color;
430 hw_status->video_status.sync_sw_enable = video_stat.timing.sync_sw_enable;
431 hw_status->video_status.vsync_polarity = video_stat.timing.vsync_polarity;
432 hw_status->video_status.hsync_polarity = video_stat.timing.hsync_polarity;
433 hw_status->video_status.progressive = video_stat.timing.progressive;
434 hw_status->video_status.hsync_total = video_stat.timing.hsync_total;
435 hw_status->video_status.hactive_cnt = video_stat.timing.hactive_cnt;
436 hw_status->video_status.vsync_total = video_stat.timing.vsync_total;
437 hw_status->video_status.vactive_cnt = video_stat.timing.vactive_cnt;
438 hw_status->video_status.out_csc_quantization = video_stat.out_quantization;
439
440 return;
441 }
442
hal_hdmi_phy_hwparam_get(hi_u32 hdmi_id,hdmi_hwspec * hwspec)443 static hi_void hal_hdmi_phy_hwparam_get(hi_u32 hdmi_id, hdmi_hwspec *hwspec)
444 {
445 errno_t ret;
446 hdmi_phy_hw_param hw_param = {0};
447
448 hi_unused(hdmi_id);
449 hal_hdmi_phy_params_get(&hw_param);
450 ret = memcpy_s(&hwspec->hwspec_user, sizeof(hwspec->hwspec_user),
451 &hw_param.hw_spec_cfg, sizeof(hdmi_hw_spec));
452 hdmi_unequal_eok_return_void(ret);
453 ret = memcpy_s(&hwspec->hwspec_def, sizeof(hwspec->hwspec_def),
454 &hw_param.hw_spec_def, sizeof(hdmi_hw_spec));
455 hdmi_unequal_eok_return_void(ret);
456 ret = memcpy_s(&hwspec->hwparam_cur, sizeof(hwspec->hwparam_cur),
457 &hw_param.hw_param_cur, sizeof(hdmi_hw_param));
458 hdmi_unequal_eok_return_void(ret);
459
460 return;
461 }
462
hal_hdmi_hardware_status_get(const struct hdmi_hal_ * hal,hdmi_hardware_status * hw_status)463 static hi_void hal_hdmi_hardware_status_get(const struct hdmi_hal_ *hal, hdmi_hardware_status *hw_status)
464 {
465 hdmi_hpd_rsen hpd_rsen = {0};
466
467 hdmi_if_null_return_void(hal);
468 hdmi_if_null_return_void(hw_status);
469
470 #ifndef HDMI_FPGA_SUPPORT
471 hal_hdmi_phy_oe_get(&hw_status->phy_status.phy_oe);
472 hal_hdmi_phy_power_get(&hw_status->phy_status.phy_power_on);
473 #endif
474 hal_hdmi_ctrl_infoframe_en_get(hal->hal_ctx.hdmi_id,
475 HDMI_INFOFRAME_TYPE_AVI, &hw_status->info_frame_status.avi_enable);
476 hal_hdmi_ctrl_infoframe_en_get(hal->hal_ctx.hdmi_id,
477 HDMI_INFOFRAME_TYPE_AUDIO, &hw_status->info_frame_status.audio_enable);
478 hal_hdmi_ctrl_infoframe_en_get(hal->hal_ctx.hdmi_id,
479 HDMI_INFOFRAME_TYPE_VENDOR, &hw_status->info_frame_status.vsif_enable);
480 hal_hdmi_ctrl_infoframe_en_get(hal->hal_ctx.hdmi_id,
481 HDMI_INFOFRAME_TYPE_GBD, &hw_status->info_frame_status.gbd_enable);
482 hal_hdmi_ctrl_infoframe_en_get(hal->hal_ctx.hdmi_id,
483 HDMI_INFOFRAME_TYPE_DRM, &hw_status->info_frame_status.drm_enable);
484 hal_hdmi_ctrl_infoframe_data_get(hal->hal_ctx.hdmi_id,
485 HDMI_INFOFRAME_TYPE_AVI, hw_status->info_frame_status.avi);
486 hal_hdmi_ctrl_infoframe_data_get(hal->hal_ctx.hdmi_id,
487 HDMI_INFOFRAME_TYPE_AUDIO, hw_status->info_frame_status.audio);
488 hal_hdmi_ctrl_infoframe_data_get(hal->hal_ctx.hdmi_id,
489 HDMI_INFOFRAME_TYPE_VENDOR, hw_status->info_frame_status.vsif);
490 hal_hdmi_ctrl_infoframe_data_get(hal->hal_ctx.hdmi_id,
491 HDMI_INFOFRAME_TYPE_GBD, hw_status->info_frame_status.gdb);
492 hal_hdmi_ctrl_infoframe_data_get(hal->hal_ctx.hdmi_id,
493 HDMI_INFOFRAME_TYPE_DRM, hw_status->info_frame_status.drm);
494
495 /* HPD, avmute, tmds_mode */
496 hal_hdmi_ctrl_hpd_rsen_get(hal->hal_ctx.hdmi_id, &hpd_rsen);
497 hw_status->common_status.hotplug = hpd_rsen.hpd_on;
498 hw_status->common_status.rsen = hpd_rsen.rsen_on;
499 hal_hdmi_ctrl_avmute_get(hal->hal_ctx.hdmi_id, &hw_status->common_status.avmute);
500 hal_hdmi_ctrl_tmds_mode_get(hal->hal_ctx.hdmi_id, &hw_status->common_status.tmds_mode);
501
502 hal_hdmi_hw_audio_status_get(hal->hal_ctx.hdmi_id, hw_status);
503 hal_hdmi_hw_video_status_get(hal->hal_ctx.hdmi_id, hw_status);
504 hal_hdmi_phy_hwparam_get(hal->hal_ctx.hdmi_id, &hw_status->phy_hwspec);
505
506 return;
507 }
508
hal_hdmi_hdp_intr_status_get(const struct hdmi_hal_ * hal,hi_bool * intr_status)509 static hi_void hal_hdmi_hdp_intr_status_get(const struct hdmi_hal_ *hal, hi_bool *intr_status)
510 {
511 hi_unused(hal);
512 *intr_status = (hdmi_reg_aon_intr_stat0_get() == 0) ? HI_FALSE : HI_TRUE;
513 return;
514 }
515
hal_hdmi_hot_plug_status_get(const struct hdmi_hal_ * hal,hi_bool * hot_plug)516 static hi_void hal_hdmi_hot_plug_status_get(const struct hdmi_hal_ *hal, hi_bool *hot_plug)
517 {
518 hdmi_hpd_rsen hpd_rsen = {0};
519
520 if (hot_plug != HI_NULL) {
521 hdmi_if_null_return_void(hal);
522 hal_hdmi_ctrl_hpd_rsen_get(hal->hal_ctx.hdmi_id, &hpd_rsen);
523 *hot_plug = hpd_rsen.hpd_on;
524 } else {
525 hdmi_err("ctrl hot_plug = null!\n");
526 }
527
528 return;
529 }
530
hal_hdmi_audio_mute_set(const struct hdmi_hal_ * hal,hi_bool audio_mute)531 static hi_void hal_hdmi_audio_mute_set(const struct hdmi_hal_ *hal, hi_bool audio_mute)
532 {
533 hdmi_if_null_return_void(hal);
534 hal_hdmi_ctrl_audio_mute_set(hal->hal_ctx.hdmi_id, audio_mute);
535 return;
536 }
537
hal_hdmi_audio_path_set(const struct hdmi_hal_ * hal,hdmi_audio_config * audio_cfg)538 static hi_s32 hal_hdmi_audio_path_set(const struct hdmi_hal_ *hal, hdmi_audio_config *audio_cfg)
539 {
540 hdmi_audio_path audio_path = {0};
541
542 hdmi_if_null_return(hal, HI_FAILURE);
543 hdmi_if_null_return(audio_cfg, HI_FAILURE);
544
545 audio_path.sound_intf = audio_cfg->sound_intf;
546 audio_path.sample_rate = audio_cfg->sample_fs;
547 audio_path.channel_num = audio_cfg->layout;
548 audio_path.sample_bit = audio_cfg->sample_depth;
549 audio_path.pixel_clk = audio_cfg->tmds_clk;
550 hal_hdmi_ctrl_audio_path_set(hal->hal_ctx.hdmi_id, &audio_path);
551
552 return HI_SUCCESS;
553 }
554
hal_hdmi_audio_path_enable_set(const struct hdmi_hal_ * hal,hi_bool enable)555 static hi_void hal_hdmi_audio_path_enable_set(const struct hdmi_hal_ *hal, hi_bool enable)
556 {
557 hdmi_if_null_return_void(hal);
558 hal_hdmi_ctrl_audio_path_enable_set(hal->hal_ctx.hdmi_id, enable);
559 return;
560 }
561
hal_hdmi_edid_raw_data_read(const struct hdmi_hal_ * hal,hi_u32 size,hi_u8 out_buffer[])562 static hi_s32 hal_hdmi_edid_raw_data_read(const struct hdmi_hal_ *hal, hi_u32 size, hi_u8 out_buffer[])
563 {
564 hi_s32 ret;
565
566 hdmi_if_null_return(hal, HI_FAILURE);
567 hdmi_if_null_return(out_buffer, HI_FAILURE);
568 ret = hal_hdmi_ddc_edid_raw_get(hal->hal_ctx.hdmi_id, size, out_buffer);
569
570 return ret;
571 }
572
hal_hdmi_phy_output_enable_get(const struct hdmi_hal_ * hal,hi_bool * enable)573 static hi_void hal_hdmi_phy_output_enable_get(const struct hdmi_hal_ *hal, hi_bool *enable)
574 {
575 #ifndef HDMI_FPGA_SUPPORT
576 hal_hdmi_phy_oe_get(enable);
577 #endif
578 hi_unused(hal);
579 return;
580 }
581
hal_hdmi_video_mute_set(const struct hdmi_hal_ * hal,hi_bool v_mute)582 static hi_void hal_hdmi_video_mute_set(const struct hdmi_hal_ *hal, hi_bool v_mute)
583 {
584 hdmi_if_null_return_void(hal);
585 hal_hdmi_ctrl_video_mute_set(hal->hal_ctx.hdmi_id, v_mute);
586 return;
587 }
588
hal_hdmi_black_data_set(const struct hdmi_hal_ * hal,hdmi_black_frame_info * black)589 static hi_void hal_hdmi_black_data_set(const struct hdmi_hal_ *hal, hdmi_black_frame_info *black)
590 {
591 hdmi_if_null_return_void(hal);
592 hdmi_if_null_return_void(black);
593 hal_hdmi_ctrl_video_mute_set(hal->hal_ctx.hdmi_id, black->black_enable);
594
595 return;
596 }
597
598 #ifdef HDMI_DEBUG_SUPPORT
hal_hdmi_debug(const struct hdmi_hal_ * hal,hdmi_debug_cmd debug_cmd,hi_void * data)599 static hi_void hal_hdmi_debug(const struct hdmi_hal_ *hal, hdmi_debug_cmd debug_cmd, hi_void *data)
600 {
601 hdmi_if_null_return_void(data);
602 hdmi_if_null_return_void(hal);
603
604 switch (debug_cmd) {
605 case HDMI_DEBUG_CMD_COLOR_BAR:
606 hal_hdmi_cbar_enable(*(hi_bool *)data);
607 break;
608 case HDMI_DEBUG_CMD_DITHER:
609 hal_hdmi_ctrl_dither_dbg_set(hal->hal_ctx.hdmi_id, *(hdmi_video_dither *)data);
610 break;
611 default:
612 hdmi_err("debug_cmd = %u\n", debug_cmd);
613 break;
614 }
615
616 return;
617 }
618 #endif
619
hal_hdmi_base_addr_get(const struct hdmi_hal_ * hal)620 static hi_u32 *hal_hdmi_base_addr_get(const struct hdmi_hal_ *hal)
621 {
622 hi_u32 *base_addr = HI_NULL;
623
624 if (hal == HI_NULL) {
625 hdmi_err("NULL ptr!\n");
626 return HI_NULL;
627 }
628
629 base_addr = (hi_u32 *)hal->hal_ctx.base_addr;
630
631 return base_addr;
632 }
633
634 #ifdef HDMI_SCDC_SUPPORT
hal_hdmi_scdc_status_set(const struct hdmi_hal_ * hal,hdmi_scdc_status * status)635 static hi_void hal_hdmi_scdc_status_set(const struct hdmi_hal_ *hal, hdmi_scdc_status *status)
636 {
637 scdc_attr attr = {0};
638
639 hdmi_if_null_return_void(hal);
640 hdmi_if_null_return_void(status);
641
642 attr.sink_read_quest = HI_FALSE;
643 attr.sink_scramble = status->sink_scramble_on;
644 attr.src_scramble = status->source_scramble_on;
645 attr.tmds_clk_ratio40x = status->tmds_bit_clk_ratio == SCDC_TMDS_BIT_CLK_RATIO_40X ? HI_TRUE : HI_FALSE;
646 attr.scramble_interval = status->scramble_interval;
647 attr.scramble_timeout = status->scramble_timeout;
648 hal_hdmi_scdc_attr_set(hal->hal_ctx.hdmi_id, &attr);
649
650 return;
651 }
652
hal_hdmi_scdc_status_get(const struct hdmi_hal_ * hal,hdmi_scdc_status * status)653 static hi_void hal_hdmi_scdc_status_get(const struct hdmi_hal_ *hal, hdmi_scdc_status *status)
654 {
655 scdc_attr attr = {0};
656
657 hdmi_if_null_return_void(hal);
658 hdmi_if_null_return_void(status);
659
660 hal_hdmi_scdc_attr_get(hal->hal_ctx.hdmi_id, &attr);
661 status->sink_read_quest = HI_FALSE;
662 status->sink_scramble_on = attr.sink_scramble;
663 status->source_scramble_on = attr.src_scramble;
664 status->tmds_bit_clk_ratio = attr.tmds_clk_ratio40x ? SCDC_TMDS_BIT_CLK_RATIO_40X : SCDC_TMDS_BIT_CLK_RATIO_10X;
665 status->scramble_interval = attr.scramble_interval;
666 status->scramble_timeout = attr.scramble_timeout;
667
668 return;
669 }
670
hal_hdmi_scdc_config(const struct hdmi_hal_ * hal,hdmi_scdc_config * scdc_config)671 static hi_void hal_hdmi_scdc_config(const struct hdmi_hal_ *hal, hdmi_scdc_config *scdc_config)
672 {
673 hi_unused(hal);
674 hi_unused(scdc_config);
675 return;
676 }
677 #endif
678
hal_pfn_init(hdmi_hal * hal)679 static hi_void hal_pfn_init(hdmi_hal *hal)
680 {
681 hal->hal_hdmi_hardware_init = hal_hdmi_hardware_init;
682 hal->hal_hdmi_avmute_set = hal_hdmi_avmute_set;
683 hal->hal_hdmi_tmds_mode_set = hal_hdmi_tmds_mode_set;
684 hal->hal_hdmi_infoframe_set = hal_hdmi_infoframe_set;
685 hal->hal_hdmi_infoframe_enable_set = hal_hdmi_infoframe_enable_set;
686 hal->hal_hdmi_video_path_set = hal_hdmi_video_path_set;
687 hal->hal_hdmi_phy_power_enable_set = hal_hdmi_phy_power_enable_set;
688 hal->hal_hdmi_phy_output_enable_set = hal_hdmi_phy_output_enable_set;
689 hal->hal_hdmi_tx_capability_get = hal_hdmi_tx_capability_get;
690 hal->hal_hdmi_emi_status_get = hal_hdmi_emi_status_get;
691 hal->hal_hdmi_csc_param_set = hal_hdmi_csc_param_set;
692 hal->hal_hdmi_phy_set = hal_hdmi_phy_set;
693 hal->hal_hdmi_ctrl_reset = hal_hdmi_ctrl_reset;
694 hal->hal_hdmi_phy_hw_spec_set = hal_hdmi_phy_hw_spec_set;
695 hal->hal_hdmi_phy_hw_spec_get = hal_hdmi_phy_hw_spec_get;
696 hal->hal_hdmi_hardware_status_get = hal_hdmi_hardware_status_get;
697 hal->hal_hdmi_sequencer_handler_process = hal_hdmi_sequencer_handler_process;
698 hal->hal_hdmi_audio_mute_set = hal_hdmi_audio_mute_set;
699 hal->hal_hdmi_audio_path_set = hal_hdmi_audio_path_set;
700 hal->hal_hdmi_audio_path_enable_set = hal_hdmi_audio_path_enable_set;
701 hal->hal_hdmi_edid_raw_data_read = hal_hdmi_edid_raw_data_read;
702 hal->hal_hdmi_phy_output_enable_get = hal_hdmi_phy_output_enable_get;
703 hal->hal_hdmi_hot_plug_status_get = hal_hdmi_hot_plug_status_get;
704 hal->hal_hdmi_video_mute_set = hal_hdmi_video_mute_set;
705 hal->hal_hdmi_hdp_intr_status_get = hal_hdmi_hdp_intr_status_get;
706 hal->hal_hdmi_black_data_set = hal_hdmi_black_data_set;
707 #ifdef HDMI_DEBUG_SUPPORT
708 hal->hal_hdmi_debug = hal_hdmi_debug;
709 #endif
710 hal->hal_hdmi_base_addr_get = hal_hdmi_base_addr_get;
711 #ifdef HDMI_HDR_SUPPORT
712 hal->hal_hdmi_hdr_timer_set = hal_hdmi_hdr_timer_set;
713 #endif
714 #ifdef HDMI_SCDC_SUPPORT
715 hal->hal_hdmi_scdc_config = hal_hdmi_scdc_config;
716 hal->hal_hdmi_scdc_status_get = hal_hdmi_scdc_status_get;
717 hal->hal_hdmi_scdc_status_set = hal_hdmi_scdc_status_set;
718 #endif
719
720 return;
721 }
722
hal_hdmi_open(hdmi_hal_init * hal_init,hdmi_hal ** hal_handle)723 hi_s32 hal_hdmi_open(hdmi_hal_init *hal_init, hdmi_hal **hal_handle)
724 {
725 hdmi_hal *hal = HI_NULL;
726 hdmi_hal_cfg *hal_cfg = HI_NULL;
727
728 if (hal_handle == HI_NULL) {
729 hdmi_err("hal_handle == NULL!\n");
730 return HI_FAILURE;
731 }
732
733 hal = (hdmi_hal *)osal_vmalloc(sizeof(hdmi_hal));
734 if (hal == HI_NULL) {
735 hdmi_err("alloc hdmi_hal struct memory fail\n");
736 return HI_FAILURE;
737 }
738 (hi_void)memset_s(hal, sizeof(hdmi_hal), 0, sizeof(hdmi_hal));
739
740 if (hal_init != HI_NULL) {
741 hal->hal_ctx.callback = hal_init->event_callback;
742 hal->hal_ctx.hdmi_dev = hal_init->event_data;
743 hal->hal_ctx.hdmi_id = hal_init->hdmi_dev_id;
744 hal->hal_ctx.base_addr = hal_init->base_addr;
745 hal->hal_ctx.phy_addr = hal_init->phy_addr;
746 } else {
747 hdmi_info("hal_init null! open in boot!\n");
748 }
749
750 hal_cfg = intf_hal_info_ptr_get(hal->hal_ctx.hdmi_id);
751 if (hal_cfg == HI_NULL) {
752 osal_vfree(hal);
753 hdmi_err("hal_cfg null, fail!\n");
754 return HI_FAILURE;
755 }
756
757 intf_tx_capability_init(hal->hal_ctx.hdmi_id);
758 #ifndef HDMI_FPGA_SUPPORT
759 hal_hdmi_phy_init(hal_init);
760 #endif
761 hal_hdmi_mach_init();
762 hal_hdmi_ctrl_init(hal->hal_ctx.hdmi_id, hal_init);
763 hal_hdmi_ddc_init(hal->hal_ctx.hdmi_id);
764 #ifdef HDMI_SCDC_SUPPORT
765 hal_hdmi_scdc_init(hal->hal_ctx.hdmi_id);
766 #endif
767 hal_pfn_init(hal);
768
769 *hal_handle = hal;
770 hal_cfg->init = HI_TRUE;
771
772 return HI_SUCCESS;
773 }
774
hal_hdmi_close(struct hdmi_hal_ * hal)775 void hal_hdmi_close(struct hdmi_hal_ *hal)
776 {
777 hdmi_hal_cfg *hal_cfg = (hdmi_hal_cfg *)HI_NULL;
778
779 hdmi_if_null_return_void(hal);
780 hal_cfg = intf_hal_info_ptr_get(hal->hal_ctx.hdmi_id);
781 hdmi_if_null_return_void(hal_cfg);
782
783 #ifdef HDMI_SCDC_SUPPORT
784 hal_hdmi_scdc_deinit(hal->hal_ctx.hdmi_id);
785 #endif
786 hal_hdmi_ddc_deinit(hal->hal_ctx.hdmi_id);
787 hal_hdmi_ctrl_deinit(hal->hal_ctx.hdmi_id);
788 hal_hdmi_mach_deinit();
789 #ifndef HDMI_FPGA_SUPPORT
790 hal_hdmi_phy_deinit();
791 #endif
792 hdmi_reg_crg_deinit();
793
794 hal->hal_ctx.base_addr = HI_NULL;
795 hal->hal_ctx.phy_addr = HI_NULL;
796 (hi_void)memset_s(hal, sizeof(hdmi_hal), 0, sizeof(hdmi_hal));
797 osal_vfree(hal);
798 hal = HI_NULL;
799
800 hal_cfg->init = HI_FALSE;
801
802 return;
803 }
804
805