• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/video/fbdev/sunxi/disp2/disp/de/lowlevel_v33x/disp_al_tcon/disp_al_tcon.c
3  *
4  * Copyright (c) 2007-2018 Allwinnertech Co., Ltd.
5  * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 #include "disp_al_tcon.h"
18 
19 
20 /*
21  * disp_al_private_data - abstract layer private data
22  * @output_type: current output type of specified device(eg. LCD/HDMI/TV)
23  * @output_mode: current output mode of specified device(eg. 720P,1080P)
24  * @output_format: current output color format of specified device
25  * @output_color_space: current output color space of specified device
26  * @tcon_id: the id of device connect to the specified de
27  * @de_id: the id of de connect to the specified tcon
28  * @disp_size: the output size of specified de
29  * @output_fps: the output fps of specified device
30  * @tcon_type: tcon type, 0: tcon0(drive panel), 1: tcon1(general drive HDMI/TV)
31  */
32 struct disp_al_private_data {
33 	u32 output_type[DEVICE_NUM];
34 	/* u32 output_mode[DEVICE_NUM]; */
35 	u32 output_format[DEVICE_NUM];
36 	/* u32 output_color_space[DEVICE_NUM]; */
37 	/* u32 output_color_range[DEVICE_NUM]; */
38 	/* u32 output_eotf[DEVICE_NUM]; */
39 	/* u32 tcon_id[DE_NUM]; */
40 	u32 de_id[DEVICE_NUM];
41 	/* struct disp_rect disp_size[DE_NUM]; */
42 	/* u32 output_fps[DEVICE_NUM]; */
43 	u32 tcon_type[DEVICE_NUM];
44 	/* u32 de_backcolor[DE_NUM]; */
45 	/* bool direct_show[DE_NUM]; */
46 	/* bool direct_show_toggle[DE_NUM]; */
47 	u32 de_use_rcq[DEVICE_NUM];
48 };
49 
50 static struct disp_al_private_data al_priv;
51 
52 /* lcd */
53 /* lcd_dclk_freq * div -> lcd_clk_freq * div2 -> pll_freq */
54 /* lcd_dclk_freq * dsi_div -> lcd_dsi_freq */
disp_al_lcd_get_clk_info(u32 screen_id,struct lcd_clk_info * info,struct disp_panel_para * panel)55 int disp_al_lcd_get_clk_info(u32 screen_id,
56 	struct lcd_clk_info *info, struct disp_panel_para *panel)
57 {
58 	int tcon_div = 6, lcd_div = 1, dsi_div = 4, dsi_rate = 0, find = 0,
59 	    i = 0;
60 	/* tcon_div >= 6 when
61 	 * lcd_dev[sel]->tcon0_dclk.bits.tcon0_dclk_en = 0xf
62 	 * */
63 
64 #if defined(CONFIG_FPGA_V7_PLATFORM) || defined(CONFIG_FPGA_V4_PLATFORM)
65 	struct lcd_clk_info clk_tbl[] = {
66 		{LCD_IF_HV, 0x12, 1, 1, 0},
67 		{LCD_IF_CPU, 12, 1, 1, 0},
68 		{LCD_IF_LVDS, 7, 1, 1, 0},
69 #if defined (DSI_VERSION_28)
70 		{LCD_IF_DSI, 4, 1, 4, 0},
71 #else
72 		{LCD_IF_DSI, 4, 1, 4, 148500000},
73 #endif /*endif DSI_VERSION_28 */
74 	};
75 #else
76 	static struct lcd_clk_info clk_tbl[] = {
77 		{LCD_IF_HV, 6, 1, 1, 0},
78 		{LCD_IF_CPU, 12, 1, 1, 0},
79 		{LCD_IF_LVDS, 7, 1, 1, 0},
80 #if defined (DSI_VERSION_28)
81 		{LCD_IF_DSI, 4, 1, 4, 0},
82 #else
83 		{LCD_IF_DSI, 4, 1, 4, 148500000},
84 #endif /*endif DSI_VERSION_28 */
85 	};
86 #endif
87 
88 
89 	if (panel == NULL) {
90 		__wrn("panel is NULL\n");
91 		return -1;
92 	}
93 
94 	memset(info, 0, sizeof(struct lcd_clk_info));
95 	for (i = 0; i < sizeof(clk_tbl) / sizeof(struct lcd_clk_info); i++) {
96 		if (clk_tbl[i].lcd_if == panel->lcd_if) {
97 			tcon_div = clk_tbl[i].tcon_div;
98 			lcd_div = clk_tbl[i].lcd_div;
99 			dsi_div = clk_tbl[i].dsi_div;
100 			dsi_rate = clk_tbl[i].dsi_rate;
101 			find = 1;
102 			break;
103 		}
104 	}
105 
106 #if !defined(DSI_VERSION_28)
107 	if (panel->lcd_if == LCD_IF_DSI) {
108 		u32 lane = panel->lcd_dsi_lane;
109 		u32 bitwidth = 0;
110 
111 		switch (panel->lcd_dsi_format) {
112 		case LCD_DSI_FORMAT_RGB888:
113 			bitwidth = 24;
114 			break;
115 		case LCD_DSI_FORMAT_RGB666:
116 			bitwidth = 24;
117 			break;
118 		case LCD_DSI_FORMAT_RGB565:
119 			bitwidth = 16;
120 			break;
121 		case LCD_DSI_FORMAT_RGB666P:
122 			bitwidth = 18;
123 			break;
124 		}
125 
126 		dsi_div = bitwidth / lane;
127 		if (panel->lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
128 			tcon_div = dsi_div;
129 		}
130 	}
131 #endif /*endif DSI_VERSION_28 */
132 
133 	if (find == 0)
134 		__wrn("cant find clk info for lcd_if %d\n", panel->lcd_if);
135 	if (panel->lcd_if == LCD_IF_HV &&
136 	    panel->lcd_hv_if == LCD_HV_IF_CCIR656_2CYC &&
137 	    panel->ccir_clk_div > 0)
138 		tcon_div = panel->ccir_clk_div;
139 	else if (panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI &&
140 		 panel->lcd_if == LCD_IF_DSI) {
141 		tcon_div = tcon_div / 2;
142 		dsi_div /= 2;
143 	}
144 
145 #if defined(DSI_VERSION_28)
146 	if (panel->lcd_if == LCD_IF_DSI &&
147 	    panel->lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
148 		tcon_div = 6;
149 		dsi_div = 6;
150 	}
151 #endif
152 
153 	info->tcon_div = tcon_div;
154 	info->lcd_div = lcd_div;
155 	info->dsi_div = dsi_div;
156 	info->dsi_rate = dsi_rate;
157 
158 	return 0;
159 }
160 
disp_al_lcd_cfg(u32 screen_id,struct disp_panel_para * panel,struct panel_extend_para * extend_panel)161 int disp_al_lcd_cfg(u32 screen_id, struct disp_panel_para *panel,
162 		    struct panel_extend_para *extend_panel)
163 {
164 	struct lcd_clk_info info;
165 
166 	memset(&info, 0, sizeof(struct lcd_clk_info));
167 
168 	tcon_init(screen_id);
169 	disp_al_lcd_get_clk_info(screen_id, &info, panel);
170 	tcon0_set_dclk_div(screen_id, info.tcon_div);
171 
172 #if !defined(TCON1_DRIVE_PANEL)
173 	al_priv.tcon_type[screen_id] = 0;
174 	if (tcon0_cfg(screen_id, panel, al_priv.de_use_rcq[screen_id]) != 0)
175 		DE_WRN("lcd cfg fail!\n");
176 	else
177 		DE_INF("lcd cfg ok!\n");
178 
179 	tcon0_cfg_ext(screen_id, extend_panel);
180 	tcon0_src_select(screen_id, LCD_SRC_DE, al_priv.de_id[screen_id]);
181 
182 	if (panel->lcd_if == LCD_IF_DSI)	{
183 #if defined(SUPPORT_DSI)
184 		if (panel->lcd_if == LCD_IF_DSI) {
185 			if (0 != dsi_cfg(screen_id, panel))
186 				DE_WRN("dsi %d cfg fail!\n", screen_id);
187 			if (panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI &&
188 			    screen_id + 1 < DEVICE_DSI_NUM) {
189 				if (0 != dsi_cfg(screen_id + 1, panel))
190 					DE_WRN("dsi %d cfg fail!\n",
191 					       screen_id + 1);
192 			}
193 		}
194 #endif
195 	}
196 #else
197 
198 	/* There is no tcon0 on this platform,
199 	 * At fpga period, we can use tcon1 to driver lcd pnael,
200 	 * so, here we need to config tcon1 here.
201 	 */
202 	al_priv.tcon_type[screen_id] = 1;
203 	if (tcon1_cfg_ex(screen_id, panel) != 0)
204 		DE_WRN("lcd cfg fail!\n");
205 	else
206 		DE_INF("lcd cfg ok!\n");
207 #endif
208 	return 0;
209 }
210 
disp_al_lcd_cfg_ext(u32 screen_id,struct panel_extend_para * extend_panel)211 int disp_al_lcd_cfg_ext(u32 screen_id, struct panel_extend_para *extend_panel)
212 {
213 	tcon0_cfg_ext(screen_id, extend_panel);
214 
215 	return 0;
216 }
217 
disp_al_lcd_enable(u32 screen_id,struct disp_panel_para * panel)218 int disp_al_lcd_enable(u32 screen_id, struct disp_panel_para *panel)
219 {
220 #if !defined(TCON1_DRIVE_PANEL)
221 
222 	tcon0_open(screen_id, panel);
223 	if (panel->lcd_if == LCD_IF_LVDS) {
224 		lvds_open(screen_id, panel);
225 	} else if (panel->lcd_if == LCD_IF_DSI) {
226 #if defined(SUPPORT_DSI)
227 		dsi_open(screen_id, panel);
228 		if (panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI &&
229 		    screen_id + 1 < DEVICE_DSI_NUM)
230 			dsi_open(screen_id + 1, panel);
231 #endif
232 	}
233 
234 #else
235 	/* There is no tcon0 on this platform,
236 	 * At fpga period, we can use tcon1 to driver lcd pnael,
237 	 * so, here we need to open tcon1 here.
238 	 */
239 	tcon1_open(screen_id);
240 #endif
241 
242 	return 0;
243 }
244 
disp_al_lcd_disable(u32 screen_id,struct disp_panel_para * panel)245 int disp_al_lcd_disable(u32 screen_id, struct disp_panel_para *panel)
246 {
247 
248 #if !defined(TCON1_DRIVE_PANEL)
249 
250 	if (panel->lcd_if == LCD_IF_LVDS) {
251 		lvds_close(screen_id);
252 	} else if (panel->lcd_if == LCD_IF_DSI) {
253 #if defined(SUPPORT_DSI)
254 		dsi_close(screen_id);
255 		if (panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI &&
256 		    screen_id + 1 < DEVICE_DSI_NUM)
257 			dsi_close(screen_id + 1);
258 #endif
259 	}
260 	tcon0_close(screen_id);
261 #else
262 	/* There is no tcon0 on platform sun50iw2,
263 	 * on fpga period, we can use tcon1 to driver lcd pnael,
264 	 * so, here we need to close tcon1.
265 	 */
266 	tcon1_close(screen_id);
267 #endif
268 	tcon_exit(screen_id);
269 
270 	return 0;
271 }
272 
273 /* query lcd irq, clear it when the irq queried exist
274  */
disp_al_lcd_query_irq(u32 screen_id,enum __lcd_irq_id_t irq_id,struct disp_panel_para * panel)275 int disp_al_lcd_query_irq(u32 screen_id, enum __lcd_irq_id_t irq_id,
276 			  struct disp_panel_para *panel)
277 {
278 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
279 	if (panel->lcd_if == LCD_IF_DSI &&
280 	    panel->lcd_dsi_if != LCD_DSI_IF_COMMAND_MODE) {
281 		enum __dsi_irq_id_t dsi_irq = (irq_id == LCD_IRQ_TCON0_VBLK)
282 						  ? DSI_IRQ_VIDEO_VBLK
283 						  : DSI_IRQ_VIDEO_LINE;
284 
285 		return dsi_irq_query(screen_id, dsi_irq);
286 	} else
287 #endif
288 	return tcon_irq_query(screen_id,
289 			      (al_priv.tcon_type[screen_id] == 0) ?
290 			      irq_id : LCD_IRQ_TCON1_VBLK);
291 }
292 
disp_al_lcd_enable_irq(u32 screen_id,enum __lcd_irq_id_t irq_id,struct disp_panel_para * panel)293 int disp_al_lcd_enable_irq(u32 screen_id, enum __lcd_irq_id_t irq_id,
294 			   struct disp_panel_para *panel)
295 {
296 	int ret = 0;
297 
298 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
299 	if (panel->lcd_if == LCD_IF_DSI) {
300 		enum __dsi_irq_id_t dsi_irq =
301 		    (irq_id == LCD_IRQ_TCON0_VBLK) ?
302 		    DSI_IRQ_VIDEO_VBLK : DSI_IRQ_VIDEO_LINE;
303 
304 		ret = dsi_irq_enable(screen_id, dsi_irq);
305 	}
306 #endif
307 	ret =
308 	    tcon_irq_enable(screen_id,
309 			    (al_priv.tcon_type[screen_id] == 0) ?
310 			    irq_id : LCD_IRQ_TCON1_VBLK);
311 
312 	return ret;
313 }
314 
disp_al_lcd_disable_irq(u32 screen_id,enum __lcd_irq_id_t irq_id,struct disp_panel_para * panel)315 int disp_al_lcd_disable_irq(u32 screen_id, enum __lcd_irq_id_t irq_id,
316 			    struct disp_panel_para *panel)
317 {
318 	int ret = 0;
319 
320 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
321 	if (panel->lcd_if == LCD_IF_DSI) {
322 		enum __dsi_irq_id_t dsi_irq =
323 		    (irq_id == LCD_IRQ_TCON0_VBLK) ?
324 		    DSI_IRQ_VIDEO_VBLK : DSI_IRQ_VIDEO_LINE;
325 
326 		ret = dsi_irq_disable(screen_id, dsi_irq);
327 	}
328 #endif
329 	ret =
330 	    tcon_irq_disable(screen_id,
331 			     (al_priv.tcon_type[screen_id] ==
332 			      0) ? irq_id : LCD_IRQ_TCON1_VBLK);
333 
334 	return ret;
335 }
336 
disp_al_lcd_tri_busy(u32 screen_id,struct disp_panel_para * panel)337 int disp_al_lcd_tri_busy(u32 screen_id, struct disp_panel_para *panel)
338 {
339 	int busy = 0;
340 	int ret = 0;
341 
342 	busy |= tcon0_tri_busy(screen_id);
343 #if defined(SUPPORT_DSI)
344 	busy |= dsi_inst_busy(screen_id);
345 #endif
346 	ret = (busy == 0) ? 0 : 1;
347 
348 	return ret;
349 }
350 
351 /* take dsi irq s32o account, todo? */
disp_al_lcd_tri_start(u32 screen_id,struct disp_panel_para * panel)352 int disp_al_lcd_tri_start(u32 screen_id, struct disp_panel_para *panel)
353 {
354 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
355 	if (panel->lcd_if == LCD_IF_DSI)
356 		dsi_tri_start(screen_id);
357 #endif
358 	return tcon0_tri_start(screen_id);
359 }
360 
disp_al_lcd_io_cfg(u32 screen_id,u32 enable,struct disp_panel_para * panel)361 int disp_al_lcd_io_cfg(u32 screen_id, u32 enable, struct disp_panel_para *panel)
362 {
363 #if defined(SUPPORT_DSI)
364 	if (panel->lcd_if == LCD_IF_DSI) {
365 		if (enable == 1) {
366 			dsi_io_open(screen_id, panel);
367 			if (panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI &&
368 			    screen_id + 1 < DEVICE_DSI_NUM)
369 				dsi_io_open(screen_id + 1, panel);
370 		} else {
371 			dsi_io_close(screen_id);
372 			if (panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI &&
373 			    screen_id + 1 < DEVICE_DSI_NUM)
374 				dsi_io_close(screen_id + 1);
375 		}
376 	}
377 #endif
378 
379 	return 0;
380 }
381 
disp_al_lcd_get_cur_line(u32 screen_id,struct disp_panel_para * panel)382 int disp_al_lcd_get_cur_line(u32 screen_id, struct disp_panel_para *panel)
383 {
384 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
385 	if (panel->lcd_if == LCD_IF_DSI)
386 		return dsi_get_cur_line(screen_id);
387 #endif
388 	return tcon_get_cur_line(screen_id,
389 				 al_priv.tcon_type[screen_id]);
390 }
391 
disp_al_lcd_get_start_delay(u32 screen_id,struct disp_panel_para * panel)392 int disp_al_lcd_get_start_delay(u32 screen_id, struct disp_panel_para *panel)
393 {
394 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
395 	u32 lcd_start_delay = 0;
396 	u32 de_clk_rate = de_get_clk_rate() / 1000000;
397 	if (panel && panel->lcd_if == LCD_IF_DSI) {
398 		lcd_start_delay =
399 		    ((tcon0_get_cpu_tri2_start_delay(screen_id) + 1) << 3) *
400 		    (panel->lcd_dclk_freq) / (panel->lcd_ht * de_clk_rate);
401 		return dsi_get_start_delay(screen_id) + lcd_start_delay;
402 	} else
403 #endif
404 	return tcon_get_start_delay(screen_id,
405 				    al_priv.tcon_type[screen_id]);
406 }
407 
408 /* hdmi */
disp_al_hdmi_pad_sel(u32 screen_id,u32 pad)409 int disp_al_hdmi_pad_sel(u32 screen_id, u32 pad)
410 {
411 	tcon_pan_sel(screen_id, pad);
412 
413 	return 0;
414 }
415 
disp_al_hdmi_enable(u32 screen_id)416 int disp_al_hdmi_enable(u32 screen_id)
417 {
418 	tcon1_hdmi_clk_enable(screen_id, 1);
419 
420 	tcon1_open(screen_id);
421 	return 0;
422 }
423 
disp_al_hdmi_disable(u32 screen_id)424 int disp_al_hdmi_disable(u32 screen_id)
425 {
426 	tcon1_close(screen_id);
427 	tcon_exit(screen_id);
428 	tcon1_hdmi_clk_enable(screen_id, 0);
429 
430 	return 0;
431 }
432 
disp_al_hdmi_set_output_format(u32 screen_id,u32 output_format)433 int disp_al_hdmi_set_output_format(
434 	u32 screen_id, u32 output_format)
435 {
436 	al_priv.output_format[screen_id] = output_format;
437 	return 0;
438 }
439 
disp_al_hdmi_cfg(u32 screen_id,struct disp_video_timings * video_info)440 int disp_al_hdmi_cfg(u32 screen_id, struct disp_video_timings *video_info)
441 {
442 	struct disp_video_timings *timings = NULL;
443 
444 	al_priv.tcon_type[screen_id] = 1;
445 	al_priv.output_format[screen_id]
446 		= bsp_disp_hdmi_get_color_format();
447 
448 	timings = kmalloc(sizeof(struct disp_video_timings),
449 			  GFP_KERNEL | __GFP_ZERO);
450 	if (timings) {
451 		memcpy(timings, video_info, sizeof(struct disp_video_timings));
452 		if (al_priv.output_format[screen_id] == DISP_CSC_TYPE_YUV420) {
453 			timings->x_res /= 2;
454 			timings->hor_total_time /= 2;
455 			timings->hor_back_porch /= 2;
456 			timings->hor_front_porch /= 2;
457 			timings->hor_sync_time /= 2;
458 		}
459 	} else {
460 		__wrn("malloc memory for timings fail! size=0x%x\n",
461 		      (unsigned int)sizeof(struct disp_video_timings));
462 	}
463 	tcon_init(screen_id);
464 
465 	if (timings)
466 		tcon1_set_timming(screen_id, timings);
467 	else
468 		tcon1_set_timming(screen_id, video_info);
469 	tcon1_src_select(screen_id, LCD_SRC_DE, al_priv.de_id[screen_id]);
470 	tcon1_black_src(screen_id, 0, al_priv.output_format[screen_id]);
471 
472 	kfree(timings);
473 
474 	return 0;
475 }
476 
disp_al_hdmi_irq_enable(u32 screen_id)477 int disp_al_hdmi_irq_enable(u32 screen_id)
478 {
479 	tcon_irq_enable(screen_id, LCD_IRQ_TCON1_VBLK);
480 	return 0;
481 }
482 
disp_al_hdmi_irq_disable(u32 screen_id)483 int disp_al_hdmi_irq_disable(u32 screen_id)
484 {
485 	tcon_irq_disable(screen_id, LCD_IRQ_TCON1_VBLK);
486 	return 0;
487 }
488 
489 /* tv */
disp_al_tv_enable(u32 screen_id)490 int disp_al_tv_enable(u32 screen_id)
491 {
492 	tcon1_tv_clk_enable(screen_id, 1);
493 	tcon1_open(screen_id);
494 
495 	return 0;
496 }
497 
disp_al_tv_disable(u32 screen_id)498 int disp_al_tv_disable(u32 screen_id)
499 {
500 	tcon1_close(screen_id);
501 	tcon_exit(screen_id);
502 	tcon1_tv_clk_enable(screen_id, 0);
503 
504 	return 0;
505 }
506 
507 #if defined(SUPPORT_EDP)
disp_al_edp_cfg(u32 screen_id,u32 fps,u32 edp_index)508 int disp_al_edp_cfg(u32 screen_id, u32 fps, u32 edp_index)
509 {
510 	al_priv.tcon_type[screen_id] = 0;
511 	edp_de_attach(edp_index, al_priv.de_id[screen_id]);
512 	return 0;
513 }
514 
disp_al_edp_disable(u32 screen_id)515 int disp_al_edp_disable(u32 screen_id)
516 {
517 	return 0;
518 }
519 #endif
520 
disp_al_tv_cfg(u32 screen_id,struct disp_video_timings * video_info)521 int disp_al_tv_cfg(u32 screen_id, struct disp_video_timings *video_info)
522 {
523 	al_priv.tcon_type[screen_id] = 1;
524 
525 	tcon_init(screen_id);
526 /*#if defined(HAVE_DEVICE_COMMON_MODULE)*/
527 	/*rgb_src_sel(screen_id);*/
528 /*#endif*/
529 	tcon1_set_timming(screen_id, video_info);
530 #if defined (CONFIG_ARCH_SUN50IW9)
531 	tcon1_yuv_range(screen_id, 0);
532 #else
533 	tcon1_yuv_range(screen_id, 1);
534 #endif
535 	tcon1_src_select(screen_id, LCD_SRC_DE, al_priv.de_id[screen_id]);
536 
537 	return 0;
538 }
539 
disp_al_tv_irq_enable(u32 screen_id)540 int disp_al_tv_irq_enable(u32 screen_id)
541 {
542 	tcon_irq_enable(screen_id, LCD_IRQ_TCON1_VBLK);
543 
544 	return 0;
545 }
546 
disp_al_tv_irq_disable(u32 screen_id)547 int disp_al_tv_irq_disable(u32 screen_id)
548 {
549 	tcon_irq_disable(screen_id, LCD_IRQ_TCON1_VBLK);
550 
551 	return 0;
552 }
553 
554 #if defined(SUPPORT_VGA)
555 /* vga interface
556  */
disp_al_vga_enable(u32 screen_id)557 int disp_al_vga_enable(u32 screen_id)
558 {
559 	tcon1_open(screen_id);
560 
561 	return 0;
562 }
563 
disp_al_vga_disable(u32 screen_id)564 int disp_al_vga_disable(u32 screen_id)
565 {
566 	tcon1_close(screen_id);
567 	tcon_exit(screen_id);
568 
569 	return 0;
570 }
571 
disp_al_vga_cfg(u32 screen_id,struct disp_video_timings * video_info)572 int disp_al_vga_cfg(u32 screen_id, struct disp_video_timings *video_info)
573 {
574 	al_priv.tcon_type[screen_id] = 1;
575 
576 	tcon_init(screen_id);
577 	tcon1_set_timming(screen_id, video_info);
578 	tcon1_src_select(screen_id, LCD_SRC_DE, al_priv.de_id[screen_id]);
579 
580 	return 0;
581 }
582 
disp_al_vga_irq_enable(u32 screen_id)583 int disp_al_vga_irq_enable(u32 screen_id)
584 {
585 	tcon_irq_enable(screen_id, LCD_IRQ_TCON1_VBLK);
586 
587 	return 0;
588 }
589 
disp_al_vga_irq_disable(u32 screen_id)590 int disp_al_vga_irq_disable(u32 screen_id)
591 {
592 	tcon_irq_disable(screen_id, LCD_IRQ_TCON1_VBLK);
593 
594 	return 0;
595 }
596 #endif
597 
disp_al_vdevice_cfg(u32 screen_id,struct disp_video_timings * video_info,struct disp_vdevice_interface_para * para,u8 config_tcon_only)598 int disp_al_vdevice_cfg(u32 screen_id, struct disp_video_timings *video_info,
599 			struct disp_vdevice_interface_para *para,
600 			u8 config_tcon_only)
601 {
602 	struct lcd_clk_info clk_info;
603 	struct disp_panel_para info;
604 
605 	al_priv.tcon_type[screen_id] = 0;
606 
607 	memset(&info, 0, sizeof(struct disp_panel_para));
608 	info.lcd_if = para->intf;
609 	info.lcd_x = video_info->x_res;
610 	info.lcd_y = video_info->y_res;
611 	info.lcd_hv_if = (enum disp_lcd_hv_if) para->sub_intf;
612 	info.lcd_dclk_freq = video_info->pixel_clk;
613 	info.lcd_ht = video_info->hor_total_time;
614 	info.lcd_hbp = video_info->hor_back_porch + video_info->hor_sync_time;
615 	info.lcd_hspw = video_info->hor_sync_time;
616 	info.lcd_vt = video_info->ver_total_time;
617 	info.lcd_vbp = video_info->ver_back_porch + video_info->ver_sync_time;
618 	info.lcd_vspw = video_info->ver_sync_time;
619 	info.lcd_interlace = video_info->b_interlace;
620 	info.lcd_hv_syuv_fdly = para->fdelay;
621 	info.lcd_hv_clk_phase = para->clk_phase;
622 	info.lcd_hv_sync_polarity = para->sync_polarity;
623 	info.ccir_clk_div = para->ccir_clk_div;
624 	info.input_csc = para->input_csc;
625 
626 	if (info.lcd_hv_if == LCD_HV_IF_CCIR656_2CYC)
627 		info.lcd_hv_syuv_seq = para->sequence;
628 	else
629 		info.lcd_hv_srgb_seq = para->sequence;
630 	tcon_init(screen_id);
631 	disp_al_lcd_get_clk_info(screen_id, &clk_info, &info);
632 	tcon0_set_dclk_div(screen_id, clk_info.tcon_div);
633 
634 	if (para->sub_intf == LCD_HV_IF_CCIR656_2CYC)
635 		tcon1_yuv_range(screen_id, 1);
636 	if (tcon0_cfg(screen_id, &info, al_priv.de_use_rcq[screen_id]) != 0)
637 		DE_WRN("lcd cfg fail!\n");
638 	else
639 		DE_INF("lcd cfg ok!\n");
640 
641 	if (!config_tcon_only)
642 		tcon0_src_select(screen_id, LCD_SRC_DE,
643 				 al_priv.de_id[screen_id]);
644 	else
645 		DE_INF("%s:config_tcon_only is %d\n", __func__,
646 		       config_tcon_only);
647 
648 	return 0;
649 }
650 
disp_al_vdevice_enable(u32 screen_id)651 int disp_al_vdevice_enable(u32 screen_id)
652 {
653 	struct disp_panel_para panel;
654 
655 	memset(&panel, 0, sizeof(struct disp_panel_para));
656 	panel.lcd_if = LCD_IF_HV;
657 	tcon0_open(screen_id, &panel);
658 
659 	return 0;
660 }
661 
disp_al_vdevice_disable(u32 screen_id)662 int disp_al_vdevice_disable(u32 screen_id)
663 {
664 	tcon0_close(screen_id);
665 	tcon_exit(screen_id);
666 
667 	return 0;
668 }
669 
670 /* screen_id: used for index of manager */
disp_al_device_get_cur_line(u32 screen_id)671 int disp_al_device_get_cur_line(u32 screen_id)
672 {
673 	u32 tcon_type = al_priv.tcon_type[screen_id];
674 
675 	return tcon_get_cur_line(screen_id, tcon_type);
676 }
677 
disp_al_device_get_start_delay(u32 screen_id)678 int disp_al_device_get_start_delay(u32 screen_id)
679 {
680 	u32 tcon_type = al_priv.tcon_type[screen_id];
681 
682 	tcon_type = (al_priv.tcon_type[screen_id] == 0) ? 0 : 1;
683 	return tcon_get_start_delay(screen_id, tcon_type);
684 }
685 
disp_al_device_query_irq(u32 screen_id)686 int disp_al_device_query_irq(u32 screen_id)
687 {
688 	int ret = 0;
689 	int irq_id = 0;
690 
691 	irq_id = (al_priv.tcon_type[screen_id] == 0) ?
692 	    LCD_IRQ_TCON0_VBLK : LCD_IRQ_TCON1_VBLK;
693 	ret = tcon_irq_query(screen_id, irq_id);
694 
695 	return ret;
696 }
697 
disp_al_device_enable_irq(u32 screen_id)698 int disp_al_device_enable_irq(u32 screen_id)
699 {
700 	int ret = 0;
701 	int irq_id = 0;
702 
703 	irq_id = (al_priv.tcon_type[screen_id] == 0) ?
704 	    LCD_IRQ_TCON0_VBLK : LCD_IRQ_TCON1_VBLK;
705 	ret = tcon_irq_enable(screen_id, irq_id);
706 
707 	return ret;
708 }
709 
disp_al_device_disable_irq(u32 screen_id)710 int disp_al_device_disable_irq(u32 screen_id)
711 {
712 	int ret = 0;
713 	int irq_id = 0;
714 
715 	irq_id = (al_priv.tcon_type[screen_id] == 0) ?
716 	    LCD_IRQ_TCON0_VBLK : LCD_IRQ_TCON1_VBLK;
717 	ret = tcon_irq_disable(screen_id, irq_id);
718 
719 	return ret;
720 }
721 
disp_al_lcd_get_status(u32 screen_id,struct disp_panel_para * panel)722 int disp_al_lcd_get_status(u32 screen_id, struct disp_panel_para *panel)
723 {
724 	int ret = 0;
725 #if defined(DSI_VERSION_40)
726 	if (panel->lcd_if == LCD_IF_DSI)
727 		ret = dsi_get_status(screen_id);
728 	else
729 #endif
730 		ret = tcon_get_status(screen_id, al_priv.tcon_type[screen_id]);
731 
732 	return ret;
733 }
734 
disp_al_device_get_status(u32 screen_id)735 int disp_al_device_get_status(u32 screen_id)
736 {
737 	int ret = 0;
738 
739 	ret = tcon_get_status(screen_id, al_priv.tcon_type[screen_id]);
740 
741 	return ret;
742 }
743 
disp_al_device_src_select(u32 screen_id,u32 src)744 int disp_al_device_src_select(u32 screen_id, u32 src)
745 {
746 	int ret = 0;
747 
748 	return ret;
749 }
750 
disp_al_device_set_de_id(u32 screen_id,u32 de_id)751 int disp_al_device_set_de_id(u32 screen_id, u32 de_id)
752 {
753 	al_priv.de_id[screen_id] = de_id;
754 	return 0;
755 }
756 
disp_al_device_set_de_use_rcq(u32 screen_id,u32 use_rcq)757 int disp_al_device_set_de_use_rcq(u32 screen_id, u32 use_rcq)
758 {
759 	al_priv.de_use_rcq[screen_id] = use_rcq;
760 	return 0;
761 }
762 
disp_al_device_set_output_type(u32 screen_id,u32 output_type)763 int disp_al_device_set_output_type(u32 screen_id, u32 output_type)
764 {
765 	al_priv.output_type[screen_id] = output_type;
766 
767 	al_priv.tcon_type[screen_id] = 0;
768 
769 #if defined(SUPPORT_HDMI)
770 	if (output_type == DISP_OUTPUT_TYPE_HDMI) {
771 		al_priv.tcon_type[screen_id] = 1;
772 	}
773 #endif
774 
775 #if defined(SUPPORT_TV)
776 	al_priv.tcon_type[screen_id] =
777 		(output_type == DISP_OUTPUT_TYPE_TV) ?
778 		1 : al_priv.tcon_type[screen_id];
779 #if defined(CONFIG_DISP2_TV_AC200)
780 	al_priv.tcon_type[screen_id] =
781 		(output_type == DISP_OUTPUT_TYPE_TV) ?
782 		0 : al_priv.tcon_type[screen_id];
783 #endif /*endif CONFIG_DISP2_TV_AC200 */
784 #endif /* defined(SUPPORT_TV) */
785 
786 	return 0;
787 }
788 
789 
790 
disp_al_init_tcon(struct disp_bsp_init_para * para)791 s32 disp_al_init_tcon(struct disp_bsp_init_para *para)
792 {
793 	u32 i;
794 
795 	for (i = 0; i < DEVICE_NUM; i++) {
796 		tcon_set_reg_base(i, para->reg_base[DISP_MOD_LCD0 + i]);
797 	}
798 #if defined(HAVE_DEVICE_COMMON_MODULE)
799 	tcon_top_set_reg_base(0, para->reg_base[DISP_MOD_DEVICE]);
800 #endif
801 
802 	return 0;
803 }
804 
disp_al_show_builtin_patten(u32 hwdev_index,u32 patten)805 void disp_al_show_builtin_patten(u32 hwdev_index, u32 patten)
806 {
807 	tcon_show_builtin_patten(hwdev_index, patten);
808 }
809