• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdlib.h>
16 #include <common/bk_include.h>
17 #include <os/mem.h>
18 #include "arch_interrupt.h"
19 #include "lcd_disp_hal.h"
20 #include <driver/lcd.h>
21 #include "gpio_map.h"
22 #include "gpio_driver.h"
23 #include <driver/gpio.h>
24 #include "gpio_map.h"
25 #include <driver/int.h>
26 #include "sys_driver.h"
27 #include <modules/pm.h>
28 #include <driver/hal/hal_gpio_types.h>
29 #include <driver/hal/hal_lcd_types.h>
30 #include "lcd_disp_ll_macro_def_mp2.h"
31 #include <driver/dma2d.h>
32 #include <./lcd/lcd_devices.h>
33 
34 #if CONFIG_PWM
35 #include <driver/pwm.h>
36 #endif
37 
38 #include "lcd_devices.h"
39 
40 #define TAG "lcd_drv"
41 
42 #define IO_FUNCTION_ENABLE(pin, func) 	\
43 	do {							  	\
44 		gpio_dev_unmap(pin); 			\
45 		gpio_dev_map(pin, func);		\
46 	} while (0)
47 
48 
49 #define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
50 #define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
51 #define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
52 #define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
53 
54 typedef struct
55 {
56 #if (USE_LCD_REGISTER_CALLBACKS == 1)  //register callback
57 	lcd_isr_t lcd_8080_frame_start_handler;
58 	lcd_isr_t lcd_8080_frame_end_handler;
59 	lcd_isr_t lcd_rgb_frame_end_handler;
60 	lcd_isr_t lcd_rgb_frame_start_handler;
61 #endif
62 #if CONFIG_PWM
63 	pwm_id_t pwm_id;
64 #endif
65 	lcd_config_t config;
66 } lcd_driver_t;
67 
68 
69 extern bk_err_t bk_lcd_set_yuv_mode(lcd_data_format_t input_data_format);
70 
71 const lcd_device_t *lcd_devices[] =
72 {
73 	&lcd_device_st7282,
74 	&lcd_device_hx8282,
75 	&lcd_device_st7796s,
76 	&lcd_device_gc9503v,
77 };
78 
79 static lcd_driver_t s_lcd = {0};
80 
get_lcd_device_by_id(lcd_device_id_t id)81 const lcd_device_t *get_lcd_device_by_id(lcd_device_id_t id)
82 {
83 	uint32_t i, size = sizeof(lcd_devices) / sizeof(lcd_device_t *);
84 
85 	for (i = 0; i < size; i++)
86 	{
87 		if (lcd_devices[i]->id == id)
88 		{
89 			return lcd_devices[i];
90 		}
91 	}
92 
93 	return NULL;
94 }
95 
lcd_mcu_gpio_init(void)96 bk_err_t lcd_mcu_gpio_init(void)
97 {
98 	LOGI("%s\n", __func__);
99 
100 	IO_FUNCTION_ENABLE(LCD_MCU_D0_PIN, LCD_MCU_D0_FUNC);
101 	IO_FUNCTION_ENABLE(LCD_MCU_D1_PIN, LCD_MCU_D1_FUNC);
102 	IO_FUNCTION_ENABLE(LCD_MCU_D2_PIN, LCD_MCU_D2_FUNC);
103 	IO_FUNCTION_ENABLE(LCD_MCU_D3_PIN, LCD_MCU_D3_FUNC);
104 	IO_FUNCTION_ENABLE(LCD_MCU_D4_PIN, LCD_MCU_D4_FUNC);
105 	IO_FUNCTION_ENABLE(LCD_MCU_D5_PIN, LCD_MCU_D5_FUNC);
106 	IO_FUNCTION_ENABLE(LCD_MCU_D6_PIN, LCD_MCU_D6_FUNC);
107 	IO_FUNCTION_ENABLE(LCD_MCU_D7_PIN, LCD_MCU_D7_FUNC);
108 
109 	IO_FUNCTION_ENABLE(LCD_MCU_RDX_PIN, LCD_MCU_RDX_FUNC);
110 	IO_FUNCTION_ENABLE(LCD_MCU_WRX_PIN, LCD_MCU_WRX_FUNC);
111 	IO_FUNCTION_ENABLE(LCD_MCU_RSX_PIN, LCD_MCU_RSX_FUNC);
112 	IO_FUNCTION_ENABLE(LCD_MCU_RESET_PIN, LCD_MCU_RESET_FUNC);
113 	IO_FUNCTION_ENABLE(LCD_MCU_CSX_PIN, LCD_MCU_CSX_FUNC);
114 
115 	return BK_OK;
116 }
117 
lcd_rgb_gpio_init(void)118 static bk_err_t lcd_rgb_gpio_init(void)
119 {
120 	LOGI("%s\n", __func__);
121 
122 	IO_FUNCTION_ENABLE(LCD_RGB_R0_PIN, LCD_RGB_R0_FUNC);
123 	IO_FUNCTION_ENABLE(LCD_RGB_R1_PIN, LCD_RGB_R1_FUNC);
124 	IO_FUNCTION_ENABLE(LCD_RGB_R2_PIN, LCD_RGB_R2_FUNC);
125 	IO_FUNCTION_ENABLE(LCD_RGB_R3_PIN, LCD_RGB_R3_FUNC);
126 	IO_FUNCTION_ENABLE(LCD_RGB_R4_PIN, LCD_RGB_R4_FUNC);
127 	IO_FUNCTION_ENABLE(LCD_RGB_G0_PIN, LCD_RGB_G0_FUNC);
128 	IO_FUNCTION_ENABLE(LCD_RGB_G1_PIN, LCD_RGB_G1_FUNC);
129 	IO_FUNCTION_ENABLE(LCD_RGB_G2_PIN, LCD_RGB_G2_FUNC);
130 	IO_FUNCTION_ENABLE(LCD_RGB_G3_PIN, LCD_RGB_G3_FUNC);
131 	IO_FUNCTION_ENABLE(LCD_RGB_G4_PIN, LCD_RGB_G4_FUNC);
132 	IO_FUNCTION_ENABLE(LCD_RGB_G5_PIN, LCD_RGB_G5_FUNC);
133 	IO_FUNCTION_ENABLE(LCD_RGB_B0_PIN, LCD_RGB_B0_FUNC);
134 	IO_FUNCTION_ENABLE(LCD_RGB_B1_PIN, LCD_RGB_B1_FUNC);
135 	IO_FUNCTION_ENABLE(LCD_RGB_B2_PIN, LCD_RGB_B2_FUNC);
136 	IO_FUNCTION_ENABLE(LCD_RGB_B3_PIN, LCD_RGB_B3_FUNC);
137 	IO_FUNCTION_ENABLE(LCD_RGB_B4_PIN, LCD_RGB_B4_FUNC);
138 
139 	IO_FUNCTION_ENABLE(LCD_RGB_CLK_PIN, LCD_RGB_CLK_FUNC);
140 	IO_FUNCTION_ENABLE(LCD_RGB_DISP_PIN, LCD_RGB_DISP_FUNC);
141 	IO_FUNCTION_ENABLE(LCD_RGB_HSYNC_PIN, LCD_RGB_HSYNC_FUNC);
142 	IO_FUNCTION_ENABLE(LCD_RGB_VSYNC_PIN, LCD_RGB_VSYNC_FUNC);
143 	IO_FUNCTION_ENABLE(LCD_RGB_DE_PIN, LCD_RGB_DE_FUNC);
144 
145 	return BK_OK;
146 }
147 
148 
149 #if (USE_LCD_REGISTER_CALLBACKS == 1)
150 static void lcd_isr(void);
151 
bk_lcd_isr_register(lcd_int_type_t int_type,lcd_isr_t isr)152 bk_err_t  bk_lcd_isr_register(lcd_int_type_t int_type, lcd_isr_t isr)
153 {
154 	if(int_type == I8080_OUTPUT_SOF) {
155 		s_lcd.lcd_8080_frame_start_handler = isr;
156 	}
157 	if(int_type == I8080_OUTPUT_EOF) {
158 		s_lcd.lcd_8080_frame_end_handler = isr;
159 	}
160 	if(int_type == RGB_OUTPUT_SOF) {
161 		s_lcd.lcd_rgb_frame_start_handler= isr;
162 	}
163 	if(int_type == RGB_OUTPUT_EOF) {
164 		s_lcd.lcd_rgb_frame_end_handler= isr;
165 	}
166 	return BK_OK;
167 }
168 
lcd_isr(void)169 static void lcd_isr(void)
170 {
171 	uint32_t int_status = lcd_hal_int_status_get();
172 
173 	if (int_status & RGB_OUTPUT_SOF)
174 	{
175 		if (s_lcd.lcd_rgb_frame_start_handler)
176 		{
177 			s_lcd.lcd_rgb_frame_start_handler();
178 		}
179 		lcd_hal_rgb_sof_int_status_clear();
180 	}
181 	if (int_status & RGB_OUTPUT_EOF)
182 	{
183 		if (s_lcd.lcd_rgb_frame_end_handler)
184 		{
185 			s_lcd.lcd_rgb_frame_end_handler();
186 		}
187 		lcd_hal_rgb_eof_int_status_clear();
188 	}
189 	if (int_status & I8080_OUTPUT_SOF)
190 	{
191 		if (s_lcd.lcd_8080_frame_start_handler)
192 		{
193 			s_lcd.lcd_8080_frame_start_handler();
194 		}
195 		lcd_hal_eof_int_status_clear();
196 	}
197 
198 	if (int_status & I8080_OUTPUT_EOF)
199 	{
200 		if (s_lcd.lcd_8080_frame_end_handler)
201 		{
202 			s_lcd.lcd_8080_frame_end_handler();
203 		}
204 		lcd_hal_eof_int_status_clear();
205 	}
206 }
207 #else
bk_lcd_isr_register(lcd_isr_t lcd_isr)208 bk_err_t bk_lcd_isr_register(lcd_isr_t lcd_isr)
209 {
210 	bk_int_isr_register(INT_SRC_LCD, lcd_isr, NULL);
211 	return BK_OK;
212 }
213 
214 
bk_lcd_int_status_get(void)215 uint32_t bk_lcd_int_status_get(void)
216 {
217 	return reg_DISP_INT_CONFIG;
218 }
219 
220 
bk_lcd_int_status_clear(lcd_int_type_t int_type)221 bk_err_t bk_lcd_int_status_clear(lcd_int_type_t int_type)
222 {
223 	switch (int_type)
224 	{
225 		case RGB_OUTPUT_SOF:
226 			lcd_hal_rgb_sof_int_status_clear();
227 			break;
228 		case RGB_OUTPUT_EOF:
229 			lcd_hal_rgb_eof_int_status_clear();
230 			break;
231 		case I8080_OUTPUT_SOF:
232 			lcd_hal_eof_int_status_clear();
233 			break;
234 		case I8080_OUTPUT_EOF:
235 			lcd_hal_eof_int_status_clear();
236 			break;
237 		default:
238 			reg_DISP_INT_CONFIG = 0;
239 			break;
240 	}
241 	return BK_OK;
242 }
243 #endif
244 
bk_lcd_8080_int_enable(bool is_sof_en,bool is_eof_en)245 bk_err_t bk_lcd_8080_int_enable(bool is_sof_en, bool is_eof_en)
246 {
247 	lcd_hal_8080_int_enable(is_sof_en, is_eof_en);
248 	return BK_OK;
249 }
250 
bk_lcd_rgb_int_enable(bool is_sof_en,bool is_eof_en)251 bk_err_t  bk_lcd_rgb_int_enable(bool is_sof_en, bool is_eof_en)
252 {
253 	lcd_hal_rgb_int_enable(is_sof_en, is_eof_en);
254 	return BK_OK;
255 }
256 
257 
bk_lcd_driver_init(lcd_clk_t clk)258 bk_err_t bk_lcd_driver_init(lcd_clk_t clk)
259 {
260 	bk_err_t ret = BK_OK;
261 	bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_LCD, PM_POWER_MODULE_STATE_ON);
262 	bk_pm_clock_ctrl(PM_CLK_ID_DISP, CLK_PWR_CTRL_PWR_UP);
263 	switch (clk)
264 	{
265 		case LCD_320M:
266 			ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_0, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
267 			break;
268 		case LCD_160M:
269 			ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_0, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
270 			break;
271 		case LCD_120M:
272 			ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_0, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
273 			break;
274 		case LCD_40M:
275 			ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_1, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
276 			//ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_3, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
277 			break;
278 		case LCD_20M:
279 			ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_7, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
280 			//ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_2, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
281 			break;
282 		case LCD_60M:
283 			ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_0, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
284 			break;
285 		case LCD_80M:
286 			ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_1, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
287 			break;
288 		case LCD_54M:
289 			ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_2, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
290 			break;
291 		case LCD_32M:
292 			ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_4, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
293 			break;
294 		case LCD_12M:
295 			ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_4, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
296 			break;
297 		case LCD_10M:
298 			ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_5, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
299 			break;
300 		case LCD_26M:
301 			ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_5, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
302 			break;
303 		case LCD_8M:
304 			ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_7, DISP_INT_EN, DSIP_DISCLK_ALWAYS_ON);
305 			break;
306 		default:
307 			break;
308 	}
309 
310 #if	(USE_LCD_REGISTER_CALLBACKS == 1)
311 		bk_int_isr_register(INT_SRC_LCD, lcd_isr, NULL);
312 #endif
313 
314 	return ret;
315 }
316 /**
317  * @brief This API config lcd display x size and y size
318 
319  * @param
320  *     - width lcd display width
321  *     - height lcd display height
322  *
323  * attention 1. int the next version, the width and height deside the transfer number of lcd display.
324  *              will config with another two register x offset and y offset
325  *
326  * attention 2. in this sdk version width/height only set once in 8080_init,if you want set twice,should
327                 set bk_lcd_8080_display_enable(0)
328  */
bk_lcd_pixel_config(uint16_t x_pixel,uint16_t y_pixel)329 bk_err_t bk_lcd_pixel_config(uint16_t x_pixel, uint16_t y_pixel)
330 {
331 	lcd_hal_pixel_config(x_pixel, y_pixel);
332 	return BK_OK;
333 }
334 
335 
bk_lcd_8080_send_cmd(uint8_t param_count,uint32_t command,uint32_t * param)336 bk_err_t bk_lcd_8080_send_cmd(uint8_t param_count, uint32_t command, uint32_t *param)
337 {
338 	lcd_hal_8080_cmd_send(param_count, command, param);
339 	return BK_OK;
340 }
341 
342 
bk_lcd_8080_ram_write(uint32_t command)343 bk_err_t bk_lcd_8080_ram_write(uint32_t command)
344 {
345 	lcd_hal_8080_cmd_param_count(1);
346 	lcd_hal_8080_write_cmd(command);
347 	return BK_OK;
348 }
349 
bk_lcd_set_yuv_mode(lcd_data_format_t input_data_format)350 bk_err_t bk_lcd_set_yuv_mode(lcd_data_format_t input_data_format)
351 {
352 	switch (input_data_format)
353 	{
354 		case LCD_FMT_RGB565:
355 			lcd_hal_display_yuv_sel(0);
356 		break;
357 		case LCD_FMT_ORGINAL_YUYV:
358 			lcd_hal_display_yuv_sel(1);
359 			break;
360 		case LCD_FMT_UYVY:
361 			lcd_hal_display_yuv_sel(2);
362 			break;
363 		case LCD_FMT_YYUV:
364 			lcd_hal_display_yuv_sel(3);
365 			break;
366 		case LCD_FMT_UVYY:
367 			lcd_hal_display_yuv_sel(4);
368 			break;
369 		case LCD_FMT_VUYY:
370 			lcd_hal_display_yuv_sel(5);
371 			break;
372 		case LCD_FMT_YVYU:
373 			lcd_hal_display_yuv_sel(1);
374 			lcd_hal_set_pixel_reverse(1);
375 			break;
376 		case LCD_FMT_VYUY:
377 			lcd_hal_display_yuv_sel(2);
378 			lcd_hal_set_pixel_reverse(1);
379 			break;
380 		case LCD_FMT_YYVU:
381 			lcd_hal_display_yuv_sel(5);
382 			lcd_hal_set_pixel_reverse(1);
383 			break;
384 		default:
385 			break;
386 	}
387 	return BK_OK;
388 }
389 
bk_lcd_rgb_init(lcd_device_id_t id,uint16_t x_pixel,uint16_t y_pixel,lcd_data_format_t input_data_format)390 bk_err_t bk_lcd_rgb_init(lcd_device_id_t id, uint16_t x_pixel, uint16_t y_pixel, lcd_data_format_t input_data_format)
391 {
392 	lcd_rgb_gpio_init();
393 	lcd_hal_rgb_int_enable(0, 1);
394 	lcd_hal_rgb_display_sel(1);  //RGB display enable, and select rgb module
395 	lcd_hal_set_sync_low(HSYNC_BACK_LOW, VSYNC_BACK_LOW);
396 	switch (id)
397 	{
398 		case LCD_DEVICE_ST7282:
399 			lcd_hal_rgb_sync_config(RGB_HSYNC_BACK_PORCH, RGB_HSYNC_FRONT_PORCH, RGB_VSYNC_BACK_PORCH, RGB_VSYNC_FRONT_PORCH);
400 			lcd_hal_set_rgb_clk_rev_edge(POSEDGE_OUTPUT);
401 			break;
402 		case LCD_DEVICE_HX8282:
403 			lcd_hal_rgb_sync_config(RGB_720P_HSYNC_BACK_PORCH, RGB_720P_HSYNC_FRONT_PORCH,RGB_720P_VSYNC_BACK_PORCH, RGB_720P_VSYNC_FRONT_PORCH);
404 			lcd_hal_set_rgb_clk_rev_edge(POSEDGE_OUTPUT);
405 			break;
406 		case LCD_DEVICE_GC9503V:
407 			lcd_hal_rgb_sync_config(RGB_HSYNC_BACK_PORCH, RGB_HSYNC_FRONT_PORCH, RGB_VSYNC_BACK_PORCH, RGB_VSYNC_FRONT_PORCH);
408 			lcd_hal_set_rgb_clk_rev_edge(NEGEDGE_OUTPUT);  //output data is in clk doen edge or up adge
409 			break;
410 		default:
411 			lcd_hal_rgb_sync_config(RGB_HSYNC_BACK_PORCH, RGB_HSYNC_FRONT_PORCH, RGB_VSYNC_BACK_PORCH, RGB_VSYNC_FRONT_PORCH);
412 			lcd_hal_set_rgb_clk_rev_edge(POSEDGE_OUTPUT);
413 			break;
414 	}
415 
416 	lcd_hal_disconti_mode(DISCONTINUE_MODE);
417 	bk_lcd_pixel_config(x_pixel, y_pixel);
418 	bk_lcd_set_yuv_mode(input_data_format);
419 	lcd_hal_set_data_fifo_thrd(DATA_FIFO_WR_THRD, DATA_FIFO_RD_THRD);
420 	return BK_OK;
421 }
422 
423 
424 
bk_lcd_8080_init(uint16_t x_pixel,uint16_t y_pixel,lcd_data_format_t input_data_format)425 bk_err_t bk_lcd_8080_init(uint16_t x_pixel, uint16_t y_pixel,lcd_data_format_t input_data_format)
426 {
427 	lcd_mcu_gpio_init();
428 	lcd_hal_rgb_display_sel(0); //25bit - rgb_on = 0 select 8080 mode
429 	lcd_hal_disconti_mode(DISCONTINUE_MODE);
430 	lcd_hal_8080_verify_1ms_count(VERIFY_1MS_COUNT);
431 	lcd_hal_8080_set_tik(TIK_CNT);
432 	lcd_hal_set_data_fifo_thrd(DATA_FIFO_WR_THRD, DATA_FIFO_RD_THRD);
433 	lcd_hal_8080_set_fifo_data_thrd(CMD_FIFO_WR_THRD,CMD_FIFO_RD_THRD);
434 	bk_lcd_pixel_config(x_pixel, y_pixel);
435 	lcd_hal_8080_display_enable(1);
436 	lcd_hal_8080_int_enable(0, 1); //set eof int enable
437 	bk_lcd_set_yuv_mode(input_data_format);
438 	lcd_hal_8080_sleep_in(1);
439 	//delay(7017857); //reset need 131ms.
440 	return BK_OK;
441 }
442 
443 
bk_lcd_8080_deinit(void)444 bk_err_t bk_lcd_8080_deinit(void)
445 {
446 
447 	bk_int_isr_unregister(INT_SRC_LCD);
448 	lcd_hal_8080_sleep_in(1);
449 	lcd_hal_8080_int_enable(0, 0);
450 	lcd_hal_8080_display_enable(0);
451 	lcd_hal_8080_start_transfer(0);
452 	bk_pm_clock_ctrl(PM_CLK_ID_DISP, CLK_PWR_CTRL_PWR_DOWN);
453 	bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_LCD, PM_POWER_MODULE_STATE_OFF);
454 	if (sys_drv_lcd_close() != 0)
455 	{
456 		os_printf("lcd system deinit 8080 config error \r\n");
457 		return BK_FAIL;
458 	}
459 
460 	lcd_hal_soft_reset(1);
461 	rtos_delay_milliseconds(1);
462 
463 	return BK_OK;
464 }
465 
466 
bk_lcd_rgb_display_en(bool en)467 bk_err_t bk_lcd_rgb_display_en(bool en)
468 {
469 	lcd_hal_rgb_display_en(en);
470 	return BK_OK;
471 }
472 
bk_lcd_rgb_deinit(void)473 bk_err_t bk_lcd_rgb_deinit(void)
474 {
475 	lcd_hal_rgb_int_enable(0, 0);
476 	lcd_hal_rgb_display_en(0);
477 	lcd_hal_rgb_display_sel(0);
478 	bk_int_isr_unregister(INT_SRC_LCD);
479 	bk_pm_clock_ctrl(PM_CLK_ID_DISP, CLK_PWR_CTRL_PWR_DOWN);
480 	bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_LCD, PM_POWER_MODULE_STATE_OFF);
481 	if(sys_drv_lcd_close() != 0) {
482 		os_printf("lcd system deinit reg config error \r\n");
483 		return BK_FAIL;
484 	}
485 	lcd_hal_soft_reset(1);
486 	rtos_delay_milliseconds(1);
487 	return BK_OK;
488 }
489 
bk_lcd_8080_start_transfer(bool start)490 bk_err_t bk_lcd_8080_start_transfer(bool start)
491 {
492 	lcd_hal_8080_start_transfer(start);
493 	return BK_OK;
494 }
495 
lcd_driver_rgb_init(const lcd_config_t * config)496 bk_err_t lcd_driver_rgb_init(const lcd_config_t *config)
497 {
498 	const lcd_rgb_t *rgb = config->device->rgb;
499 	uint16_t x = ppi_to_pixel_x(config->device->ppi);  //lcd size x
500 	uint16_t y = ppi_to_pixel_y(config->device->ppi);  //lcd size y
501 
502 	LOGI("%s\n", __func__);
503 
504 	lcd_hal_set_rgb_clk_rev_edge(0);  //output data is in clk doen edge or up adge
505 	lcd_hal_rgb_display_sel(1);  //RGB display enable, and select rgb module
506 	lcd_hal_set_sync_low(HSYNC_BACK_LOW, VSYNC_BACK_LOW);
507 
508 	lcd_hal_rgb_sync_config(rgb->hsync_back_porch,
509 	                        rgb->hsync_front_porch,
510 	                        rgb->vsync_back_porch,
511 	                        rgb->vsync_front_porch);
512 
513 	lcd_hal_set_rgb_clk_rev_edge(rgb->data_out_clk_edge);
514 
515 	lcd_hal_disconti_mode(DISCONTINUE_MODE);
516 
517 	bk_lcd_pixel_config(config->pixel_x, config->pixel_y); //image xpixel ypixel
518 
519 	bk_lcd_set_yuv_mode(config->fmt);
520 	lcd_hal_set_data_fifo_thrd(DATA_FIFO_WR_THRD, DATA_FIFO_RD_THRD);
521 
522 	if (x < config->pixel_x || y < config->pixel_y)
523 	{
524 		uint16_t start_x, end_x, start_y, end_y;
525 
526 		start_x = (config->pixel_x - x) / 2 + 1;
527 		end_x = start_x + x - 1;
528 
529 		start_y = (config->pixel_y - y) / 2 + 1;
530 		end_y = start_y + y - 1;
531 
532 		LOGI("%s, offset %d, %d, %d, %d\n", __func__, start_x, end_x, start_y, end_y);
533 
534 		bk_lcd_set_partical_display(1, start_x, end_x, start_y, end_y);
535 	}
536 
537 	return BK_OK;
538 }
539 
bk_lcd_set_partical_display(bool en,uint16_t partial_clum_l,uint16_t partial_clum_r,uint16_t partial_line_l,uint16_t partial_line_r)540 bk_err_t bk_lcd_set_partical_display(bool en, uint16_t partial_clum_l, uint16_t partial_clum_r, uint16_t partial_line_l, uint16_t partial_line_r)
541 {
542 	lcd_hal_set_partical_display(en, partial_clum_l, partial_clum_r, partial_line_l, partial_line_r);
543 	return BK_OK;
544 }
545 
546 
lcd_driver_mcu_init(const lcd_config_t * config)547 bk_err_t lcd_driver_mcu_init(const lcd_config_t *config)
548 {
549 	uint16_t x = ppi_to_pixel_x(config->device->ppi);
550 	uint16_t y = ppi_to_pixel_y(config->device->ppi);
551 
552 	LOGI("%s\n", __func__);
553 
554 	lcd_hal_rgb_display_sel(0); //25bit - rgb_on = 0 select 8080 mode
555 	lcd_hal_disconti_mode(DISCONTINUE_MODE);
556 	lcd_hal_8080_verify_1ms_count(VERIFY_1MS_COUNT);
557 	lcd_hal_8080_set_tik(TIK_CNT);
558 	lcd_hal_set_data_fifo_thrd(DATA_FIFO_WR_THRD, DATA_FIFO_RD_THRD);
559 	lcd_hal_8080_set_fifo_data_thrd(CMD_FIFO_WR_THRD, CMD_FIFO_RD_THRD);
560 	lcd_hal_pixel_config(config->pixel_x, config->pixel_y);
561 	lcd_hal_8080_display_enable(1);
562 	lcd_hal_8080_int_enable(0, 1); //set eof int enable
563 	bk_lcd_set_yuv_mode(config->fmt);
564 	lcd_hal_8080_sleep_in(1);
565 
566 	if (x < config->pixel_x || y < config->pixel_y)
567 	{
568 		uint16_t start_x, end_x, start_y, end_y;
569 
570 		start_x = (config->pixel_x - x) / 2 + 1;
571 		end_x = start_x + x - 1;
572 
573 		start_y = (config->pixel_y - y) / 2 + 1;
574 		end_y = start_y + y - 1;
575 
576 		LOGI("%s, offset %d, %d, %d, %d\n", __func__, start_x, end_x, start_y, end_y);
577 
578 		bk_lcd_set_partical_display(1,start_x, end_x, start_y, end_y);
579 	}
580 
581 	return BK_OK;
582 }
583 
584 #if CONFIG_PWM
lcd_driver_backlight_init(uint8_t pwm_id,uint8_t percent)585 bk_err_t lcd_driver_backlight_init(uint8_t pwm_id, uint8_t percent)
586 {
587 	pwm_init_config_t config = {0};
588 	BK_LOG_ON_ERR(bk_pwm_driver_init());
589 
590 	if (percent > 100)
591 	{
592 		percent  = 100;
593 	}
594 
595 	config.period_cycle = 100;
596 	config.duty_cycle = percent;
597 	BK_LOG_ON_ERR(bk_pwm_init(pwm_id, &config));
598 	BK_LOG_ON_ERR(bk_pwm_start(pwm_id));
599 
600 	return BK_OK;
601 }
602 
lcd_driver_backlight_deinit(uint8_t pwm_id)603 bk_err_t lcd_driver_backlight_deinit(uint8_t pwm_id)
604 {
605 	BK_LOG_ON_ERR(bk_pwm_stop(pwm_id));
606 	BK_LOG_ON_ERR(bk_pwm_deinit(pwm_id));
607 	return BK_OK;
608 }
609 
lcd_driver_set_backlight(uint8_t percent)610 bk_err_t lcd_driver_set_backlight(uint8_t percent)
611 {
612 	pwm_period_duty_config_t config = {0};
613 
614 	if (percent > 100)
615 	{
616 		percent  = 100;
617 	}
618 
619 	config.period_cycle = 100;
620 	config.duty_cycle = percent;
621 
622 	bk_pwm_set_period_duty(s_lcd.pwm_id, &config);
623 
624 	return BK_OK;
625 }
626 #endif
627 
lcd_driver_display_enable(void)628 bk_err_t lcd_driver_display_enable(void)
629 {
630 	lcd_type_t type;
631 
632 	type = s_lcd.config.device->type;
633 
634 	if (type == LCD_TYPE_RGB565)
635 	{
636 		lcd_hal_rgb_display_en(1);
637 	}
638 	else if (type == LCD_TYPE_MCU8080)
639 	{
640 		lcd_hal_8080_start_transfer(1);
641 		lcd_hal_8080_cmd_param_count(1);
642 		lcd_hal_8080_write_cmd(0x2c);
643 	}
644 
645 	return BK_OK;
646 }
lcd_driver_display_continue(void)647 bk_err_t lcd_driver_display_continue(void)
648 {
649 	lcd_type_t type;
650 	type = s_lcd.config.device->type;
651 	if (type == LCD_TYPE_RGB565)
652 	{
653 //		lcd_hal_rgb_eof_int_status_clear();
654 	}
655 
656 	if (type == LCD_TYPE_MCU8080)
657 	{
658 		lcd_hal_8080_write_cmd(0x3c);
659 //		lcd_hal_eof_int_status_clear();
660 	}
661 	return BK_OK;
662 }
663 
lcd_driver_set_display_base_addr(uint32_t disp_base_addr)664 bk_err_t lcd_driver_set_display_base_addr(uint32_t disp_base_addr)
665 {
666 	lcd_hal_set_display_read_base_addr(disp_base_addr);
667 
668 	return BK_OK;
669 }
bk_lcd_get_display_base_addr(void)670 uint32_t bk_lcd_get_display_base_addr(void)
671 {
672 	return lcd_disp_ll_get_mater_rd_base_addr();
673 }
674 
675 
lcd_driver_init(const lcd_config_t * config)676 bk_err_t lcd_driver_init(const lcd_config_t *config)
677 {
678 	int ret = BK_FAIL;
679 	lcd_clk_t clk = 0;
680 	const lcd_device_t *device = config->device;
681 
682 	if (device == NULL)
683 	{
684 		LOGE("%s, device need to be set\n", __func__);
685 		goto error;
686 	}
687 
688 	os_memset(&s_lcd, 0, sizeof(s_lcd));
689 	os_memcpy(&s_lcd.config, config, sizeof(lcd_config_t));
690 
691 
692 	if (device->type == LCD_TYPE_RGB565)
693 	{
694 		clk = device->rgb->clk;
695 #if CONFIG_PWM
696 		s_lcd.pwm_id = LCD_PWM_BACKLIGHT;
697 #endif
698 	}
699 	else if (device->type == LCD_TYPE_MCU8080)
700 	{
701 		clk = device->mcu->clk;
702 #if CONFIG_PWM
703 		s_lcd.pwm_id = LCD_PWM_BACKLIGHT;
704 #endif
705 	}
706 
707 #if CONFIG_PWM
708 	lcd_driver_backlight_init(s_lcd.pwm_id, 90);
709 #endif
710 	LOGI("%s, LCD clk set: %d\n", __func__, clk);
711 
712 	ret = bk_lcd_driver_init(clk);
713 
714 	if (ret != BK_OK)
715 	{
716 		LOGE("%s, device clk set error\n", __func__);
717 		goto error;
718 	}
719 
720 	if (device->type == LCD_TYPE_RGB565)
721 	{
722 
723 #if	(USE_LCD_REGISTER_CALLBACKS == 1)
724 		lcd_hal_rgb_int_enable(0, 1);
725 		if (config->complete_callback)
726 		{
727 			LOGI("%s, rgb eof register\n", __func__);
728 			s_lcd.lcd_rgb_frame_end_handler = config->complete_callback;
729 		}
730 #endif
731 
732 		lcd_rgb_gpio_init();
733 		lcd_driver_rgb_init(config);
734 	}
735 	else if (device->type == LCD_TYPE_MCU8080)
736 	{
737 
738 #if	(USE_LCD_REGISTER_CALLBACKS == 1)
739 		lcd_hal_8080_int_enable(0, 1);
740 		if (config->complete_callback)
741 		{
742 			LOGI("%s, mcu eof register\n", __func__);
743 			s_lcd.lcd_8080_frame_end_handler = config->complete_callback;
744 		}
745 #endif
746 
747 		lcd_mcu_gpio_init();
748 		lcd_driver_mcu_init(config);
749 	}
750 
751 	if (device->init)
752 	{
753 		device->init();
754 	}
755 
756 	return ret;
757 
758 error:
759 
760 	return ret;
761 }
762 
lcd_driver_deinit(void)763 bk_err_t lcd_driver_deinit(void)
764 {
765 	lcd_type_t type;
766 
767 	type = s_lcd.config.device->type;
768 
769 	if (type == LCD_TYPE_RGB565)
770 	{
771 		lcd_hal_rgb_int_enable(0, 0);
772 		lcd_hal_rgb_display_en(0);
773 		lcd_hal_rgb_display_sel(0);
774 		bk_int_isr_unregister(INT_SRC_LCD);
775 		bk_pm_clock_ctrl(PM_CLK_ID_DISP, CLK_PWR_CTRL_PWR_DOWN);
776 		bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_LCD, PM_POWER_MODULE_STATE_OFF);
777 		if (sys_drv_lcd_close() != 0)
778 		{
779 			LOGE("lcd system deinit reg config error \r\n");
780 			return BK_FAIL;
781 		}
782 	}
783 	else if (type == LCD_TYPE_MCU8080)
784 	{
785 		bk_int_isr_unregister(INT_SRC_LCD);
786 		lcd_hal_8080_sleep_in(1);
787 		lcd_hal_8080_int_enable(0, 0);
788 		lcd_hal_8080_display_enable(0);
789 		lcd_hal_8080_start_transfer(0);
790 		bk_pm_clock_ctrl(PM_CLK_ID_DISP, CLK_PWR_CTRL_PWR_DOWN);
791 		bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_LCD, PM_POWER_MODULE_STATE_OFF);
792 		if (sys_drv_lcd_close() != 0)
793 		{
794 			LOGE("lcd system deinit reg config error \r\n");
795 			return BK_FAIL;
796 		}
797 	}
798 
799 	lcd_hal_soft_reset(1);
800 	rtos_delay_milliseconds(1);
801 
802 #if CONFIG_PWM
803 	lcd_driver_backlight_deinit(s_lcd.pwm_id);
804 #endif
805 
806 	return BK_OK;
807 }
808 
dma2d_lcd_fill(uint32_t frameaddr,uint16_t width,uint16_t height,uint32_t color)809 static void dma2d_lcd_fill(uint32_t frameaddr, uint16_t width, uint16_t height, uint32_t color)
810 {
811 	uint32_t color_temp = (color << 16) | color;
812 //	os_printf("displat color :%x\r\n", color_temp);
813 	dma2d_config_t dma2d_config = {0};
814 
815 	dma2d_config.init.mode   = DMA2D_R2M;                      /**< Mode Register to Memory */
816 	dma2d_config.init.color_mode	   = DMA2D_OUTPUT_ARGB8888;  /**< DMA2D Output color mode is ARGB4444 (16 bpp) */
817 	dma2d_config.init.output_offset  = 0;                      /**< offset in output */
818 	dma2d_config.init.red_blue_swap   = DMA2D_RB_REGULAR;       /**< No R&B swap for the output image */
819 	dma2d_config.init.alpha_inverted = DMA2D_REGULAR_ALPHA;     /**< No alpha inversion for the output image */
820 	bk_dma2d_driver_init(&dma2d_config);
821 
822 	if (width == 0 && height == 0)
823 	{
824 	}
825 	else if (width == 0)
826 	{
827 		height = height/2;
828 	}
829 	else if(height == 0)
830 	{
831 		width = width/2;
832 	}
833 	else
834 	{
835 		width = width/2;
836 	}
837 	bk_dma2d_start_transfer(&dma2d_config, color_temp, (uint32_t)frameaddr, width, height);
838 	while (bk_dma2d_is_transfer_busy()) {
839 	}
840 }
841 
bk_lcd_fill_color(lcd_device_id_t id,lcd_disp_framebuf_t * lcd_disp,uint32_t color)842 bk_err_t bk_lcd_fill_color(lcd_device_id_t id, lcd_disp_framebuf_t *lcd_disp, uint32_t color)
843 {
844 	if((lcd_disp->rect.x > PIXEL_320-1) || (lcd_disp->rect.x + lcd_disp->rect.width > PIXEL_320-1)) return 0;
845 	if((lcd_disp->rect.y > PIXEL_480-1) || (lcd_disp->rect.y + lcd_disp->rect.height >  PIXEL_480-1)) return 0;
846 
847 	dma2d_lcd_fill((uint32_t)lcd_disp->buffer, lcd_disp->rect.width, lcd_disp->rect.height, color);
848 	lcd_hal_pixel_config(lcd_disp->rect.width, lcd_disp->rect.height);
849 	//os_printf("displat partical (%d, %d)\r\n", lcd_disp->rect.width, lcd_disp->rect.height);
850 	lcd_hal_8080_start_transfer(1);
851 	switch (id)
852 	{
853 		case LCD_DEVICE_ST7796S:
854 			lcd_st7796s_set_display_mem_area(lcd_disp->rect.x, lcd_disp->rect.x + lcd_disp->rect.width, lcd_disp->rect.y, lcd_disp->rect.y + lcd_disp->rect.height);
855 //			os_printf("lcd partical  (xs, xe ,ys, ye) = (%d, %d,%d, %d)\r\n", lcd_disp->rect.x, lcd_disp->rect.x + lcd_disp->rect.width, lcd_disp->rect.y, lcd_disp->rect.y + lcd_disp->rect.height);
856 			break;
857 		default:
858 			break;
859 	}
860 	lcd_driver_set_display_base_addr((uint32_t)lcd_disp->buffer);
861 	return BK_OK;
862 }
863 
bk_lcd_fill_data(lcd_device_id_t id,lcd_disp_framebuf_t * lcd_disp)864 bk_err_t bk_lcd_fill_data(lcd_device_id_t id, lcd_disp_framebuf_t *lcd_disp)
865 {
866 	lcd_hal_pixel_config(lcd_disp->rect.width, lcd_disp->rect.height);
867 	lcd_hal_8080_start_transfer(1);
868 	switch (id)
869 	{
870 		case LCD_DEVICE_ST7796S:
871 			lcd_st7796s_set_display_mem_area(lcd_disp->rect.x, lcd_disp->rect.x + lcd_disp->rect.width, lcd_disp->rect.y, lcd_disp->rect.y + lcd_disp->rect.height);
872 			break;
873 		default:
874 			break;
875 	}
876 	lcd_driver_set_display_base_addr((uint32_t)lcd_disp->buffer);
877 	return BK_OK;
878 }
879 
bk_lcd_draw_point(lcd_device_id_t id,uint16_t x,uint16_t y,uint16_t pixel)880 bk_err_t bk_lcd_draw_point(lcd_device_id_t id, uint16_t x, uint16_t y, uint16_t pixel)
881 {
882 	uint16 pixel_l, pixel_h;
883 
884 	pixel_l = pixel >> 8;
885 	pixel_h = pixel & 0xff;
886 	uint32_t param_clumn[2] = {pixel_l, pixel_h};
887 
888 	switch (id)
889 	{
890 		case LCD_DEVICE_ST7796S:
891 			if(x>=320||y>=480)return 0;
892 			lcd_st7796s_set_display_mem_area(x, x+1, y, y+1);
893 			break;
894 		default:
895 			break;
896 	}
897 	lcd_hal_8080_cmd_send(2, 0x2c, param_clumn);
898 	return BK_OK;
899 }
900 
901 
902