lcd.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. #include <string.h>
  2. #include "FreeRTOS.h"
  3. #include "event_groups.h"
  4. #include "chip.h"
  5. #include "board.h"
  6. /* LCD timing */
  7. #define LCD_PARAM0 0x000
  8. #define LCD_PARAM1 0x004
  9. #define LCD_PARAM2 0x008
  10. #define LCD_PARAM3 0x00C
  11. #define LCD_PARAM4 0x010
  12. #define LCD_PARAM5 0x014
  13. #define LCD_PARAM6 0x018
  14. #define LCD_PARAM7 0x01C
  15. #define LCD_PARAM8 0x020
  16. #define LCD_PARAM9 0x024
  17. #define LCD_PARAM10 0x028
  18. #define LCD_PARAM11 0x02C
  19. #define LCD_PARAM12 0x030
  20. #define LCD_PARAM13 0x034
  21. #define LCD_PARAM14 0x038
  22. #define LCD_PARAM15 0x03C
  23. #define LCD_PARAM16 0x040
  24. #define LCD_PARAM17 0x044
  25. #define LCD_PARAM18 0x048
  26. #define LCD_PARAM19 0x04C
  27. #define LCD_PARAM20 0x050
  28. #define LCD_PARAM21 0x054
  29. #define LCD_PARAM22 0x058
  30. /* OSD */
  31. #define LCD_OSD0_PARAM0 0x05C
  32. #define LCD_OSD0_PARAM1 0x060
  33. #define LCD_OSD0_PARAM2 0x064
  34. #define LCD_OSD0_PARAM3 0x068
  35. #define LCD_OSD0_PARAM4 0x06C
  36. #define LCD_OSD0_PARAM5 0x070
  37. #define LCD_OSD1_PARAM0 0x074
  38. #define LCD_OSD1_PARAM1 0x078
  39. #define LCD_OSD1_PARAM2 0x07C
  40. #define LCD_OSD1_PARAM3 0x080
  41. #define LCD_OSD1_PARAM4 0x084
  42. #define LCD_OSD1_PARAM5 0x088
  43. #define LCD_OSD01_PARAM 0x08C
  44. #define LCD_OSD_COEF_SYNC 0x090
  45. #define LCD_OSD0_PARAM2_RD 0x280
  46. #define LCD_OSD0_PARAM3_RD 0x284
  47. #define LCD_OSD0_PARAM4_RD 0x288
  48. #define LCD_OSD1_PARAM2_RD 0x28C
  49. #define LCD_OSD1_PARAM3_RD 0x290
  50. #define LCD_OSD1_PARAM4_RD 0x294
  51. /* Dithering */
  52. #define LCD_DITHERING_CFG0 0x0BC
  53. #define LCD_DITHERING_CFG1 0x0C0
  54. #define LCD_DITHERING_CFG2 0x0C4
  55. #define LCD_INTR_CLR 0x0C8
  56. #define LCD_STATUS_REG 0x0CC
  57. #define LCD_R_BIT_ORDER 0x130
  58. #define LCD_G_BIT_ORDER 0x134
  59. #define LCD_B_BIT_ORDER 0x138
  60. #define LCD_GAMMA_REG 0x13c
  61. /* CPU screen & SRGB screen */
  62. #define LCD_SRGB_CFG 0x200
  63. #define LCD_CPU_SCR_SOFT_REG 0x0E0
  64. #define LCD_CPU_SCR_CTRL_REG 0x0E4
  65. #define LCD_ADR_CLR_DATA_REG0 0x0E8
  66. #define LCD_ADR_CLR_DATA_REG1 0x0EC
  67. #define LCD_ADR_CLR_DATA_REG2 0x0F0
  68. #define LCD_ADR_CLR_DATA_REG3 0x0F4
  69. #define LCD_ADR_CLR_DATA_REG4 0x0F8
  70. #define LCD_ADR_CLR_DATA_REG5 0x0FC
  71. #define LCD_ADR_CLR_DATA_REG6 0x100
  72. #define LCD_ADR_CLR_DATA_REG7 0x104
  73. #define LCD_ADR_CLR_DATA_REG8 0x108
  74. #define LCD_ADR_CLR_DATA_REG9 0x10C
  75. #define LCD_ADR_CLR_DATA_REGA 0x110
  76. #define LCD_ADR_CLR_DATA_REGB 0x114
  77. #define LCD_ADR_CLR_DATA_REGC 0x118
  78. #define LCD_ADR_CLR_DATA_REGD 0x11C
  79. #define LCD_ADR_CLR_DATA_REGE 0x120
  80. #define LCD_ADR_CLR_DATA_REGF 0x124
  81. #define LCD_CPU_SCREEN_STATUS 0x128
  82. #define LCD_OSD_CCM_REG0 0x208
  83. #define LCD_OSD_CCM_REG1 0x20C
  84. #define LCD_OSD_CCM_REG2 0x210
  85. #define LCD_OSD_CCM_REG3 0x214
  86. #define LCD_OSD_CCM_REG4 0x218
  87. #define LCD_OSD_CCM_REG5 0x21C
  88. #define LCD_CCM_EN_REG0 0x238
  89. #define LCD_CCM_EN_REG1 0x23C
  90. #define LCD_CCM_EN_REG2 0x240
  91. #define LCD_CCM_EN_REG3 0x244
  92. #define LCD_CCM_EN_REG4 0x248
  93. #define LCD_CCM_EN_REG5 0x24C
  94. #define LCD_CCM_EN_REG 0x250
  95. #define LCD_ITU_EAV_CODE_CFG 0x254
  96. #define LCD_ITU_SAV_CODE_CFG 0x258
  97. #define LCD_HLOCK_CFG_RG 0x25C
  98. #if defined(AWTK) || LCD_ROTATE_ANGLE != LCD_ROTATE_ANGLE_0
  99. #define FB_COUNT 3
  100. #else
  101. #define FB_COUNT 2
  102. #endif
  103. static void *fb_buf = NULL;
  104. static uint32_t fb_addr = 0;
  105. struct ark_lcd_timing
  106. {
  107. uint32_t vs_start;
  108. uint32_t hs_start;
  109. uint32_t hd; //width
  110. uint32_t vd; //height
  111. uint32_t vbp;
  112. uint32_t vfp;
  113. uint32_t vsw;
  114. uint32_t hbp;
  115. uint32_t hfp;
  116. uint32_t hsw;
  117. };
  118. #if configUSE_16_BIT_TICKS == 1
  119. #define MAX_VSYNC_WAIT_TASKS 8
  120. #else
  121. #define MAX_VSYNC_WAIT_TASKS 24
  122. #endif
  123. struct ark_lcd_data
  124. {
  125. struct ark_lcd_timing timing;
  126. EventGroupHandle_t vsync_waitq;
  127. void *waitq_tasks[MAX_VSYNC_WAIT_TASKS];
  128. uint32_t waitbits;
  129. };
  130. struct ark_lcd_data *g_lcd = NULL;
  131. static int g_osdConfig[LCD_OSD_NUMS] = {0};
  132. #ifdef AWTK
  133. #include "rtos.h"
  134. #include "fb_queue.h"
  135. #include "xm_base.h"
  136. static queue_s lcd_fb_ready; // 已准备好的LCD帧
  137. static queue_s lcd_fb_free; // 空闲
  138. static fb_queue_s fb_queue_unit[FB_COUNT];
  139. #define ENABLE_FB_DIRTY_RECTS_COPY
  140. #ifdef ENABLE_FB_DIRTY_RECTS_COPY
  141. int vg_set_surface(unsigned int *surface_addr, int surface_size,
  142. unsigned int surface_width,
  143. unsigned int surface_height,
  144. unsigned int surface_bpp, unsigned int surface_stride);
  145. #endif
  146. void fb_queue_init (void)
  147. {
  148. queue_initialize (&lcd_fb_ready);
  149. queue_initialize (&lcd_fb_free);
  150. memset (fb_queue_unit, 0, sizeof(fb_queue_unit));
  151. for (int i = 0; i < FB_COUNT; i ++)
  152. {
  153. fb_queue_unit[i].fb_base = i * FB_SIZE + (unsigned int)fb_buf;
  154. queue_insert ((queue_s *)(fb_queue_unit + i), &lcd_fb_free);
  155. }
  156. #ifdef ENABLE_FB_DIRTY_RECTS_COPY
  157. {
  158. unsigned int fb_addr[FB_COUNT];
  159. for (int i = 0; i < FB_COUNT; i ++)
  160. {
  161. fb_addr[i] = i * FB_SIZE + (unsigned int)fb_buf;
  162. }
  163. vg_set_surface (fb_addr, FB_COUNT, OSD_WIDTH, OSD_HEIGHT, LCD_BPP, OSD_WIDTH * LCD_BPP/8);
  164. }
  165. #endif
  166. }
  167. void fb_queue_exit (void)
  168. {
  169. }
  170. fb_queue_s *fb_queue_get_free_unit(void)
  171. {
  172. fb_queue_s *unit = NULL;
  173. XM_lock();
  174. if(!queue_empty (&lcd_fb_free))
  175. {
  176. unit = (fb_queue_s *)queue_delete_next (&lcd_fb_free);
  177. }
  178. XM_unlock();
  179. return unit;
  180. }
  181. void fb_queue_set_free (fb_queue_s *unit)
  182. {
  183. XM_lock();
  184. queue_insert ((queue_s *)unit, &lcd_fb_free);
  185. XM_unlock();
  186. }
  187. void fb_queue_set_free_isr (fb_queue_s *unit)
  188. {
  189. queue_insert ((queue_s *)unit, &lcd_fb_free);
  190. }
  191. void fb_queue_set_ready (fb_queue_s *unit)
  192. {
  193. XM_lock();
  194. queue_insert ((queue_s *)unit, &lcd_fb_ready);
  195. XM_unlock();
  196. }
  197. fb_queue_s *fb_queue_get_ready_unit_isr(void)
  198. {
  199. fb_queue_s *unit = NULL;
  200. if(!queue_empty (&lcd_fb_ready))
  201. {
  202. unit = (fb_queue_s *)queue_delete_next (&lcd_fb_ready);
  203. }
  204. return unit;
  205. }
  206. fb_queue_s *fb_queue_get_ready_unit(void)
  207. {
  208. fb_queue_s *unit = NULL;
  209. XM_lock();
  210. if(!queue_empty (&lcd_fb_ready))
  211. {
  212. unit = (fb_queue_s *)queue_delete_next (&lcd_fb_ready);
  213. }
  214. XM_unlock();
  215. return unit;
  216. }
  217. fb_queue_s *fb_queue_get_unit_from_base(unsigned int base)
  218. {
  219. for (int i = 0; i < FB_COUNT; i ++)
  220. {
  221. if(fb_queue_unit[i].fb_base == base)
  222. return fb_queue_unit + i;
  223. }
  224. return NULL;
  225. }
  226. #endif
  227. static void ark_lcd_writel(uint32_t reg, uint32_t mask, uint8_t offset, uint32_t val)
  228. {
  229. uint32_t tmp = readl(REGS_LCD_BASE+reg);
  230. tmp &= (~(mask << offset));
  231. tmp |= (val << offset);
  232. writel(tmp, REGS_LCD_BASE+reg);
  233. }
  234. int ark_lcd_set_osd_sync(LCD_OSD_LAYER osd)
  235. {
  236. if(osd >= LCD_OSD_NUMS) {
  237. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  238. return -1;
  239. }
  240. if(osd == LCD_OSD0)
  241. writel(readl(REGS_LCD_BASE+LCD_OSD_COEF_SYNC)|(1<<0), REGS_LCD_BASE+LCD_OSD_COEF_SYNC);
  242. else if(osd == LCD_OSD1)
  243. writel(readl(REGS_LCD_BASE+LCD_OSD_COEF_SYNC)|(1<<1), REGS_LCD_BASE+LCD_OSD_COEF_SYNC);
  244. else if(osd == LCD_OSD_NUMS)
  245. writel(readl(REGS_LCD_BASE+LCD_OSD_COEF_SYNC)|(3<<0), REGS_LCD_BASE+LCD_OSD_COEF_SYNC);
  246. return 0;
  247. }
  248. static int ark_lcd_set_osd_stride(LCD_OSD_LAYER osd, uint32_t width)
  249. {
  250. uint32_t reg = LCD_OSD0_PARAM5 + osd*0x18;
  251. if(osd >= LCD_OSD_NUMS) {
  252. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  253. return -1;
  254. }
  255. if(width > 0xFFF) {
  256. printf("ERR: %s, Invalid width:0x%x\n", __func__, width);
  257. return -1;
  258. }
  259. ark_lcd_writel(reg, 0xFFF, 0, width);
  260. return 0;
  261. }
  262. int ark_lcd_get_osd_size(LCD_OSD_LAYER osd, uint32_t *width, uint32_t *height)
  263. {
  264. uint32_t reg = LCD_OSD0_PARAM0 + osd*0x18;
  265. uint32_t val;
  266. if(osd>= LCD_OSD_NUMS) {
  267. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  268. return -1;
  269. }
  270. val = readl(REGS_LCD_BASE+reg);
  271. *width = (val >> 6) & 0xFFF;
  272. *height = (val >> 18) & 0xFFF;
  273. return 0;
  274. }
  275. int ark_lcd_set_osd_size(LCD_OSD_LAYER osd, uint32_t width, uint32_t height)
  276. {
  277. uint32_t reg = LCD_OSD0_PARAM0 + osd*0x18;
  278. if(osd>= LCD_OSD_NUMS) {
  279. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  280. return -1;
  281. }
  282. width &= 0xFFF;
  283. height &= 0xFFF;
  284. ark_lcd_writel(reg, 0xFFFFFF, 6, (height<<12)|width);
  285. ark_lcd_set_osd_stride(osd, width);
  286. return 0;
  287. }
  288. int ark_lcd_get_osd_format(LCD_OSD_LAYER osd, LCD_OSD_FORMAT *format)
  289. {
  290. uint32_t reg = LCD_OSD0_PARAM0 + osd*0x18;
  291. uint32_t val;
  292. if(osd >= LCD_OSD_NUMS) {
  293. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  294. return -1;
  295. }
  296. val = readl(REGS_LCD_BASE+reg);
  297. *format = (val>>3)&0x07;
  298. if(*format >= LCD_OSD_FORAMT_NUMS) {
  299. printf("ERR: %s, Invalid osd%d format:%d\n", __func__, osd, *format);
  300. return -1;
  301. }
  302. return 0;
  303. }
  304. int ark_lcd_set_osd_format(LCD_OSD_LAYER osd, LCD_OSD_FORMAT format)
  305. {
  306. uint32_t reg = LCD_OSD0_PARAM0 + osd*0x18;
  307. if(osd >= LCD_OSD_NUMS) {
  308. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  309. return -1;
  310. }
  311. if(format >= LCD_OSD_FORAMT_NUMS) {
  312. printf("ERR: %s, Invalid osd%d format:%d\n", __func__, osd, format);
  313. return -1;
  314. }
  315. ark_lcd_writel(reg, 0x7, 3, format);
  316. return 0;
  317. }
  318. int ark_lcd_osd_enable(LCD_OSD_LAYER osd, uint8_t enable)
  319. {
  320. uint32_t reg = LCD_OSD0_PARAM0 + osd*0x18;
  321. if(osd >= LCD_OSD_NUMS) {
  322. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  323. return -1;
  324. }
  325. ark_lcd_writel(reg, 0x1, 1, (enable?1:0));
  326. return 0;
  327. }
  328. int ark_lcd_get_osd_enable(LCD_OSD_LAYER osd)
  329. {
  330. uint32_t reg = LCD_OSD0_PARAM0 + osd*0x18;
  331. uint32_t val;
  332. if(osd >= LCD_OSD_NUMS) {
  333. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  334. return -1;
  335. }
  336. val = readl(REGS_LCD_BASE + reg);
  337. return (val >> 1) & 1;
  338. }
  339. int ark_lcd_osd_coeff_enable(LCD_OSD_LAYER osd, uint8_t enable)
  340. {
  341. uint32_t reg = LCD_OSD0_PARAM0 + osd*0x18;
  342. if(osd >= LCD_OSD_NUMS) {
  343. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  344. return -1;
  345. }
  346. ark_lcd_writel(reg, 0x0, 1, (enable?1:0));
  347. return 0;
  348. }
  349. int ark_lcd_osd_set_coeff(LCD_OSD_LAYER osd, uint32_t value)
  350. {
  351. uint32_t reg = LCD_OSD0_PARAM1 + osd*0x18;
  352. if(osd >= LCD_OSD_NUMS) {
  353. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  354. return -1;
  355. }
  356. ark_lcd_writel(reg, 0xFF, 24, value);
  357. return 0;
  358. }
  359. int ark_lcd_set_osd_possition(LCD_OSD_LAYER osd, uint32_t h, uint32_t v)
  360. {
  361. uint32_t reg = LCD_OSD0_PARAM1 + osd*0x18;
  362. if(osd >= LCD_OSD_NUMS) {
  363. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  364. return -1;
  365. }
  366. if((v > 0xFFF) || (h > 0xFFF)) {
  367. printf("ERR: %s, Invalid v:0x%x or h:0x%x\n", __func__, v, h);
  368. return -1;
  369. }
  370. ark_lcd_writel(reg, 0xFFFFFF, 0, ((v<<12)|h));
  371. return 0;
  372. }
  373. int ark_lcd_get_osd_yaddr(LCD_OSD_LAYER osd, uint32_t *yaddr)
  374. {
  375. uint32_t reg = LCD_OSD0_PARAM2 + osd*0x18;
  376. if(osd >= LCD_OSD_NUMS) {
  377. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  378. return -1;
  379. }
  380. *yaddr = readl(REGS_LCD_BASE+reg);
  381. return 0;
  382. }
  383. int ark_lcd_set_osd_yaddr(LCD_OSD_LAYER osd, uint32_t yaddr)
  384. {
  385. uint32_t reg = LCD_OSD0_PARAM2 + osd*0x18;
  386. if(osd >= LCD_OSD_NUMS) {
  387. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  388. return -1;
  389. }
  390. #if LCD_V_FLIP
  391. LCD_OSD_FORMAT format;
  392. uint32_t width, height;
  393. ark_lcd_get_osd_format(osd, &format);
  394. ark_lcd_get_osd_size(osd, &width, &height);
  395. if (format == LCD_OSD_FORAMT_YUV420)
  396. yaddr += width * (height - 1);
  397. else if (format == LCD_OSD_FORAMT_ARGB888)
  398. yaddr += width * (height - 1) * 4;
  399. else if (format == LCD_OSD_FORAMT_RGB565)
  400. yaddr += width * (height - 1) * 2;
  401. #endif
  402. writel(yaddr, REGS_LCD_BASE+reg);
  403. return 0;
  404. }
  405. int ark_lcd_set_osd_uaddr(LCD_OSD_LAYER osd, uint32_t uaddr)
  406. {
  407. uint32_t reg = LCD_OSD0_PARAM3 + osd*0x18;
  408. if(osd >= LCD_OSD_NUMS) {
  409. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  410. return -1;
  411. }
  412. #if LCD_V_FLIP
  413. LCD_OSD_FORMAT format;
  414. uint32_t width, height;
  415. LCD_OSD_YUV420_MODE yuv420_mode;
  416. ark_lcd_get_osd_format(osd, &format);
  417. ark_lcd_get_osd_size(osd, &width, &height);
  418. ark_lcd_get_osd_yuv420_mode(osd, &yuv420_mode);
  419. if (format == LCD_OSD_FORAMT_YUV420) {
  420. if (yuv420_mode == LCD_OSD_Y_U_V420)
  421. uaddr += width * (height - 2) / 4;
  422. else
  423. uaddr += width * (height - 2) / 2;
  424. }
  425. #endif
  426. writel(uaddr, REGS_LCD_BASE+reg);
  427. return 0;
  428. }
  429. int ark_lcd_set_osd_vaddr(LCD_OSD_LAYER osd, uint32_t vaddr)
  430. {
  431. uint32_t reg = LCD_OSD0_PARAM4 + osd*0x18;
  432. if(osd >= LCD_OSD_NUMS) {
  433. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  434. return -1;
  435. }
  436. #if LCD_V_FLIP
  437. LCD_OSD_FORMAT format;
  438. uint32_t width, height;
  439. LCD_OSD_YUV420_MODE yuv420_mode;
  440. ark_lcd_get_osd_format(osd, &format);
  441. ark_lcd_get_osd_size(osd, &width, &height);
  442. ark_lcd_get_osd_yuv420_mode(osd, &yuv420_mode);
  443. if (format == LCD_OSD_FORAMT_YUV420 && yuv420_mode == LCD_OSD_Y_U_V420)
  444. vaddr += width * (height - 2) / 4;
  445. #endif
  446. writel(vaddr, REGS_LCD_BASE+reg);
  447. return 0;
  448. }
  449. int ark_lcd_set_osd_mult_coef(LCD_OSD_LAYER osd, uint32_t value)
  450. {
  451. uint32_t reg = LCD_OSD0_PARAM5 + osd*0x18;
  452. if(osd >= LCD_OSD_NUMS) {
  453. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  454. return -1;
  455. }
  456. if(value > 0x7F) {
  457. printf("ERR: %s, Invalid value:0x%x\n", __func__, value);
  458. return -1;
  459. }
  460. ark_lcd_writel(reg, 0x7F, 24, value);
  461. return 0;
  462. }
  463. int ark_lcd_set_osd_h_offset(LCD_OSD_LAYER osd, uint32_t offset)
  464. {
  465. uint32_t reg = LCD_OSD0_PARAM5 + osd*0x18;
  466. if(osd >= LCD_OSD_NUMS) {
  467. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  468. return -1;
  469. }
  470. if(offset > 0xFFF) {
  471. printf("ERR: %s, Invalid offset:0x%x\n", __func__, offset);
  472. return -1;
  473. }
  474. ark_lcd_writel(reg, 0xFFF, 12, offset);
  475. return 0;
  476. }
  477. int ark_lcd_set_osd_yuv420_mode(LCD_OSD_LAYER osd, LCD_OSD_YUV420_MODE mode)
  478. {
  479. uint32_t reg = LCD_OSD01_PARAM;
  480. if(osd >= LCD_OSD_NUMS) {
  481. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  482. return -1;
  483. }
  484. if(mode > LCD_OSD_Y_UV420) {
  485. printf("ERR: %s, Invalid osd%d mode:%d\n", __func__, osd, mode);
  486. return -1;
  487. }
  488. if (osd == LCD_OSD0)
  489. ark_lcd_writel(reg, 0x1, 12, mode);
  490. else
  491. ark_lcd_writel(reg, 0x1, 14, mode);
  492. return 0;
  493. }
  494. int ark_lcd_get_osd_yuv420_mode(LCD_OSD_LAYER osd, LCD_OSD_YUV420_MODE *mode)
  495. {
  496. uint32_t reg = LCD_OSD01_PARAM;
  497. if(osd >= LCD_OSD_NUMS) {
  498. printf("ERR: %s, Invalid osd%d\n", __func__, osd);
  499. return -1;
  500. }
  501. if (osd == LCD_OSD0)
  502. *mode = (readl(REGS_LCD_BASE + reg) >> 12) & 1;
  503. else
  504. *mode = (readl(REGS_LCD_BASE + reg) >> 14) & 1;
  505. return 0;
  506. }
  507. int ark_lcd_enable(uint8_t enable)
  508. {
  509. ark_lcd_writel(LCD_PARAM0, 0x01, 0, (enable?1:0));
  510. return 0;
  511. }
  512. int ark_lcd_wait_for_vsync(void)
  513. {
  514. struct ark_lcd_data *lcd = g_lcd;
  515. int i;
  516. if(!lcd) {
  517. printf("ERR: %s, Invalid lcd(NULL)\n", __func__);
  518. return -EINVAL;
  519. }
  520. #if LCD_INTERFACE_TYPE != LCD_INTERFACE_CPU
  521. portENTER_CRITICAL();
  522. for (i = 0; i < MAX_VSYNC_WAIT_TASKS; i++) {
  523. if (lcd->waitq_tasks[i] == xTaskGetCurrentTaskHandle()) {
  524. lcd->waitbits |= 1 << i;
  525. break;
  526. } else if (lcd->waitq_tasks[i] == NULL) {
  527. lcd->waitq_tasks[i] = xTaskGetCurrentTaskHandle();
  528. lcd->waitbits |= 1 << i;
  529. break;
  530. }
  531. }
  532. portEXIT_CRITICAL();
  533. if (i == MAX_VSYNC_WAIT_TASKS) {
  534. printf("ERR: %s, waitq_tasks full\n", __func__);
  535. return -1;
  536. }
  537. xEventGroupClearBits(lcd->vsync_waitq, 1 << i);
  538. xEventGroupWaitBits(lcd->vsync_waitq, 1 << i, pdFALSE, pdFALSE, pdMS_TO_TICKS(50));
  539. portENTER_CRITICAL();
  540. lcd->waitbits &= ~(1 << i);
  541. portEXIT_CRITICAL();
  542. #endif
  543. return 0;
  544. }
  545. int ark_lcd_set_osd_info_atomic(LCD_OSD_LAYER osd, LcdOsdInfo *info)
  546. {
  547. portENTER_CRITICAL();
  548. ark_lcd_set_osd_possition(osd, info->x, info->y);
  549. ark_lcd_set_osd_size(osd, info->width, info->height);
  550. ark_lcd_set_osd_format(osd, info->format);
  551. ark_lcd_set_osd_yaddr(osd, info->yaddr);
  552. ark_lcd_set_osd_uaddr(osd, info->uaddr);
  553. ark_lcd_set_osd_vaddr(osd, info->vaddr);
  554. ark_lcd_set_osd_sync(osd);
  555. g_osdConfig[osd - LCD_OSD0] = 1;
  556. portEXIT_CRITICAL();
  557. return 0;
  558. }
  559. int ark_lcd_get_osd_info_atomic_isactive(LCD_OSD_LAYER osd)
  560. {
  561. int active;
  562. portENTER_CRITICAL();
  563. active = !g_osdConfig[osd - LCD_OSD0];
  564. portEXIT_CRITICAL();
  565. return active;
  566. }
  567. uint32_t ark_lcd_get_virt_addr(void)
  568. {
  569. return (uint32_t)fb_buf;
  570. }
  571. static int ark_lcd_timing_init(struct ark_lcd_data *lcd)
  572. {
  573. struct ark_lcd_timing timing;
  574. uint32_t VS_START, HS_START, HD, VD;
  575. uint32_t VBP, VFP, VSW, TV;
  576. uint32_t HBP, HFP, HSW, TH;
  577. uint32_t lcd_param0, lcd_param1, lcd_param2, lcd_param3 ;
  578. uint32_t lcd_param4, lcd_param5, lcd_param6, lcd_param7 ;
  579. uint32_t lcd_param8, lcd_param9, lcd_param10, lcd_param11 ;
  580. uint32_t lcd_param12, lcd_param13, lcd_param14, lcd_param15 ;
  581. uint32_t lcd_param16, lcd_param17;
  582. uint8_t stop_lcd = 0 ;
  583. if(!lcd) {
  584. printf("ERR: %s, lcd == NULL\n", __func__);
  585. return -1;
  586. }
  587. timing = lcd->timing;
  588. VS_START = timing.vs_start;
  589. HS_START = timing.hs_start;
  590. HD = timing.hd;
  591. VD = timing.vd;
  592. VBP = timing.vbp;
  593. VFP = timing.vfp;
  594. VSW = timing.vsw;
  595. TV =(VS_START+VSW+VBP+VD+VFP);
  596. HBP = timing.hbp;
  597. HFP = timing.hfp;
  598. HSW = timing.hsw;
  599. TH = (HS_START+HSW+HBP+HD+HFP);
  600. #define lcd_enable 0 // 1
  601. #define screen_width HD
  602. #define rgb_pad_mode LCD_WIRING_MODE
  603. #define direct_enable 0
  604. #define mem_lcd_enable 0
  605. #define range_coeff_y 0
  606. #define range_coeff_uv 0
  607. #define lcd_done_intr_enable 1
  608. #define dac_for_video 0
  609. #define dac_for_cvbs 0
  610. #define lcd_interlace_flag 0
  611. #define screen_type 1 //pRGB_i 0 pRGB_p 1 sRGB_p 2 ITU656 3
  612. #define VSW1_enable 0
  613. #define LcdVComp 0
  614. #define itu_pal_ntsc 0
  615. #define hsync_ivs 1
  616. #define vsync_ivs 1
  617. #define lcd_ac_ivs 0
  618. #define test_on_flag 0
  619. #define back_color (0x00<<16)|(0x00<<8)|(0x00)
  620. #define DEN_h_rise (HFP+HSW+HBP)
  621. #define DEN_h_fall (HFP+HSW+HBP+HD)//(20+800*1)
  622. #define DEN0_v_rise (VFP+VSW+VBP)
  623. #define DEN0_v_fall (VFP+VSW+VBP+VD)
  624. #define DEN1_v_rise (VFP+VSW+VBP)
  625. #define DEN1_v_fall (VFP+VSW+VBP+VD)
  626. // ֡Ƶ = LCDʱÖÓ/(CPL * LPS)
  627. // ÿÐÐʱÖÓÖÜÆÚ¸öÊý
  628. #define CPL (TH) // clock cycles per line max 4096 ; from register timing2 16
  629. #define LPS (TV) // Lines per screen value ; from register timing1 0
  630. #define HSW_rise (HFP)
  631. #define HSW_fall (HFP+HSW)
  632. #define VSW0_v_rise (VFP) // Vertical sync width value ; from register timing1 10
  633. #define VSW0_v_fall (VFP+VFP) // Vertical sync width value ; from register timing1 10
  634. #define VSW0_h_rise (HFP)
  635. #define VSW0_h_fall (HFP+HSW)
  636. #define VSW1_v_rise (VFP) // Vertical sync width value ; from register timing1 10
  637. #define VSW1_v_fall (VFP+VSW) // Vertical sync width value ; from register timing1 10
  638. #define VSW1_h_rise (HFP)
  639. #define VSW1_h_fall (HFP+HSW)
  640. writel(0, REGS_LCD_BASE+LCD_PARAM0);
  641. lcd_param0 =
  642. lcd_enable |
  643. (screen_width<<1) |
  644. (rgb_pad_mode<<13) |
  645. (direct_enable<<16) |
  646. (mem_lcd_enable<<17)|
  647. (range_coeff_y<<18) |
  648. (range_coeff_uv<<22)|
  649. (lcd_done_intr_enable<<26)|
  650. (dac_for_video<<27) |
  651. (dac_for_cvbs<<28) |
  652. (1<<30) |
  653. (stop_lcd<<31);
  654. lcd_param1 =
  655. (lcd_interlace_flag<<0) |
  656. (screen_type<<1) |
  657. (VSW1_enable<<13) |
  658. (LcdVComp<<14) |
  659. (itu_pal_ntsc<<15) |
  660. (hsync_ivs<<17) |
  661. (vsync_ivs<<18) |
  662. (lcd_ac_ivs<<19) |
  663. (1<<21) |
  664. (1<<23) |
  665. (test_on_flag<<31);
  666. lcd_param2 =
  667. (back_color<<0) |
  668. (1<<24) |
  669. (1<<25);
  670. lcd_param3 =
  671. (DEN_h_rise<<0) |
  672. (DEN_h_fall<<12) ;
  673. lcd_param4 =
  674. (DEN0_v_rise<<0) |
  675. (DEN0_v_fall<<12) ;
  676. lcd_param5 =
  677. (DEN1_v_rise<<0) |
  678. (DEN1_v_fall<<12 ) ;
  679. lcd_param6 =
  680. (CPL<<0) | // clock cycles per line max 4096 ; from register timing2 16
  681. (LPS<<12) ; // Lines per screen value ; from register timing1 0
  682. lcd_param7 =
  683. (HSW_rise<<0)|
  684. (HSW_fall<<12) ;
  685. lcd_param8 =
  686. (VSW0_v_rise<<0)| // Vertical sync width value ; from register timing1 10
  687. (VSW0_v_fall<<12) ; // Vertical sync width value ; from register timing1 10
  688. lcd_param9 =
  689. (VSW0_h_rise <<0 )|
  690. (VSW0_h_fall <<12 ) ;
  691. lcd_param10 =
  692. (VSW1_v_rise<<0)|
  693. (VSW1_v_fall<<12) ;
  694. lcd_param11 =
  695. (VSW1_h_rise<<0)|
  696. (VSW1_h_fall<<12) ;
  697. lcd_param12 = 66 | (129<<9) | (25<<18);
  698. lcd_param13 = 38 | (74<<9) | (112<<18);
  699. lcd_param14 = 112 | (94<<9) | (18<<18);
  700. lcd_param15 = 256 | (0<<9) | (351<<18);
  701. lcd_param16 = 256 | (86<<9) | (179<<18);
  702. lcd_param17 = 256 | (443<<9) | (0<<19);
  703. writel(lcd_param1, REGS_LCD_BASE+LCD_PARAM1);
  704. writel(lcd_param2, REGS_LCD_BASE+LCD_PARAM2);
  705. writel(lcd_param3, REGS_LCD_BASE+LCD_PARAM3);
  706. writel(lcd_param4, REGS_LCD_BASE+LCD_PARAM4);
  707. writel(lcd_param5, REGS_LCD_BASE+LCD_PARAM5);
  708. writel(lcd_param6, REGS_LCD_BASE+LCD_PARAM6);
  709. writel(lcd_param7, REGS_LCD_BASE+LCD_PARAM7);
  710. writel(lcd_param8, REGS_LCD_BASE+LCD_PARAM8);
  711. writel(lcd_param9, REGS_LCD_BASE+LCD_PARAM9);
  712. writel(lcd_param10, REGS_LCD_BASE+LCD_PARAM10);
  713. writel(lcd_param11, REGS_LCD_BASE+LCD_PARAM11);
  714. writel(lcd_param12, REGS_LCD_BASE+LCD_PARAM12);
  715. writel(lcd_param13, REGS_LCD_BASE+LCD_PARAM13);
  716. writel(lcd_param14, REGS_LCD_BASE+LCD_PARAM14);
  717. writel(lcd_param15, REGS_LCD_BASE+LCD_PARAM15);
  718. writel(lcd_param16, REGS_LCD_BASE+LCD_PARAM16);
  719. writel(lcd_param17, REGS_LCD_BASE+LCD_PARAM17);
  720. writel(lcd_param0, REGS_LCD_BASE+LCD_PARAM0);
  721. #if LCD_WIRING_BIT_ORDER == LCD_WIRING_BIT_ORDER_LSB
  722. writel((0<<21|1<<18|2<<15|3<<12|4<<9|5<<6|6<<3|7<<0), REGS_LCD_BASE+LCD_R_BIT_ORDER);
  723. writel((0<<21|1<<18|2<<15|3<<12|4<<9|5<<6|6<<3|7<<0), REGS_LCD_BASE+LCD_G_BIT_ORDER);
  724. writel((0<<21|1<<18|2<<15|3<<12|4<<9|5<<6|6<<3|7<<0), REGS_LCD_BASE+LCD_B_BIT_ORDER);
  725. #elif LCD_WIRING_BIT_ORDER == LCD_WIRING_BIT_ORDER_MSB
  726. writel((7<<21|6<<18|5<<15|4<<12|3<<9|2<<6|1<<3|0<<0), REGS_LCD_BASE+LCD_R_BIT_ORDER);
  727. writel((7<<21|6<<18|5<<15|4<<12|3<<9|2<<6|1<<3|0<<0), REGS_LCD_BASE+LCD_G_BIT_ORDER);
  728. writel((7<<21|6<<18|5<<15|4<<12|3<<9|2<<6|1<<3|0<<0), REGS_LCD_BASE+LCD_B_BIT_ORDER);
  729. #endif
  730. return 0;
  731. }
  732. static int ark_lcd_hw_init()
  733. {
  734. uint32_t HD, VD;
  735. #ifdef AWTK
  736. HD = OSD_WIDTH;
  737. VD = OSD_HEIGHT;
  738. #else
  739. HD = LCD_WIDTH;
  740. VD = LCD_HEIGHT;
  741. #endif
  742. #if LCD_H_FLIP
  743. uint8_t osd_0_hflip = 1;
  744. uint8_t osd_1_hflip = 1;
  745. #else
  746. uint8_t osd_0_hflip = 0;
  747. uint8_t osd_1_hflip = 0;
  748. #endif
  749. #if LCD_V_FLIP
  750. uint8_t osd_0_vflip = 1;
  751. uint8_t osd_1_vflip = 1;
  752. #else
  753. uint8_t osd_0_vflip = 0;
  754. uint8_t osd_1_vflip = 0;
  755. #endif
  756. uint8_t osd_0_uvfirst = 0;
  757. uint8_t osd_0_yuv420mode = 1;
  758. //uint8_t osd_0_yuv422mode = 0;
  759. uint32_t osd_01_param =
  760. //osd_0_yuv422mode<<20|
  761. osd_0_hflip<<16|
  762. osd_0_vflip<<17|
  763. osd_1_hflip<<18|
  764. osd_1_vflip<<19|
  765. osd_0_yuv420mode<<12|
  766. osd_0_uvfirst<<13;
  767. writel(osd_01_param, REGS_LCD_BASE+LCD_OSD01_PARAM);
  768. //osd0 init
  769. ark_lcd_set_osd_size(LCD_OSD0, HD, VD);
  770. #if LCD_BPP == 32
  771. ark_lcd_set_osd_format(LCD_OSD0, LCD_OSD_FORAMT_ARGB888);
  772. #elif LCD_BPP == 16
  773. ark_lcd_set_osd_format(LCD_OSD0, LCD_OSD_FORAMT_RGB565);
  774. #endif
  775. ark_lcd_set_osd_possition(LCD_OSD0, 0, 0);
  776. ark_lcd_set_osd_yaddr(LCD_OSD0, fb_addr);
  777. ark_lcd_set_osd_h_offset(LCD_OSD0, 0);
  778. ark_lcd_set_osd_mult_coef(LCD_OSD0, 64);
  779. //ark_lcd_osd_enable(LCD_OSD0, 1);
  780. ark_lcd_set_osd_sync(LCD_OSD0);
  781. //osd1 init
  782. ark_lcd_set_osd_size(LCD_OSD1, HD, VD);
  783. #if LCD_BPP == 32
  784. ark_lcd_set_osd_format(LCD_OSD1, LCD_OSD_FORAMT_ARGB888);
  785. ark_lcd_osd_coeff_enable(LCD_OSD1, 0);
  786. #elif LCD_BPP == 16
  787. ark_lcd_set_osd_format(LCD_OSD1, LCD_OSD_FORAMT_RGB565);
  788. ark_lcd_osd_coeff_enable(LCD_OSD1, 1);
  789. ark_lcd_osd_set_coeff(LCD_OSD1, 255);
  790. #endif
  791. ark_lcd_set_osd_possition(LCD_OSD1, 0, 0);
  792. ark_lcd_set_osd_h_offset(LCD_OSD1, 0);
  793. ark_lcd_set_osd_mult_coef(LCD_OSD1, 64);
  794. ark_lcd_set_osd_yaddr(LCD_OSD1, fb_addr);
  795. ark_lcd_osd_enable(LCD_OSD1, 1);
  796. ark_lcd_set_osd_sync(LCD_OSD1);
  797. memset(fb_buf, 0, FB_SIZE);
  798. CP15_clean_dcache_for_dma(fb_addr, fb_addr + FB_SIZE);
  799. return 0;
  800. }
  801. static unsigned int ark_lcd_set_clk_below16(uint32_t freq)
  802. {
  803. int div;
  804. uint32_t parent_rate;
  805. if (freq < 14000000) {
  806. vSysctlConfigure(SYS_VOU_CLK_CFG, 0, 3, 2);
  807. parent_rate = ulClkGetRate(CLK_XTAL24M);
  808. div = DIV_ROUND_UP(parent_rate, freq);
  809. vSysctlConfigure(SYS_VOU_CLK_CFG, 3, 0x1f, div - 1);
  810. return parent_rate / div;
  811. } else { //14-16MH配置为16MHZ
  812. vClkSetRate(CLK_LCD, 16000000);
  813. return ulClkGetRate(CLK_LCD);
  814. }
  815. }
  816. static int ark_lcd_clk_init(uint32_t freq)
  817. {
  818. if (freq >= 16000000) {
  819. vClkSetRate(CLK_LCD, freq);
  820. printf("%s, set clk:%d\n", __func__, ulClkGetRate(CLK_LCD));
  821. } else {
  822. uint32_t real_freq = ark_lcd_set_clk_below16(freq);
  823. printf("%s, set clk:%d\n", __func__, real_freq);
  824. }
  825. return 0;
  826. }
  827. #ifdef AWTK
  828. #include <assert.h>
  829. static volatile fb_queue_s *last_fb = NULL;
  830. #endif
  831. static void ark_lcd_interrupt(void *param)
  832. {
  833. struct ark_lcd_data *lcd = (struct ark_lcd_data *)param;
  834. uint32_t status = readl(REGS_LCD_BASE+LCD_STATUS_REG);
  835. writel(0x07, REGS_LCD_BASE+LCD_INTR_CLR);
  836. //frame vsync
  837. #ifdef AWTK
  838. //frame vsync
  839. if( status & (0x01 << 0) ) // Lcd_done_intr LCD场结束中断状态位
  840. {
  841. // 进入消隐区, 切换framebuffer
  842. //unsigned int fb_curr_address = (*(volatile unsigned *)(REGS_LCD_BASE + 0x28c)); // layer 1 当前显示的基址
  843. //fb_queue_s *next_ready_unit = fb_queue_get_ready_unit ();
  844. fb_queue_s *next_ready_unit = fb_queue_get_ready_unit_isr ();
  845. if(next_ready_unit)
  846. {
  847. fb_queue_s *fb_temp;
  848. //(*(volatile unsigned *)(REGS_LCD_BASE + 31 * 4)) = next_ready_unit->fb_base;
  849. //*(volatile unsigned int *)(REGS_LCD_BASE + 0x90) |= 0x02;
  850. fb_temp = (fb_queue_s *)last_fb;
  851. last_fb = next_ready_unit;
  852. ark_lcd_set_osd_yaddr(LCD_UI_LAYER, (unsigned int)next_ready_unit->fb_base);
  853. ark_lcd_set_osd_sync(LCD_UI_LAYER);
  854. // 释放老的
  855. fb_queue_s *old_fb = fb_temp;//fb_queue_get_unit_from_base (fb_curr_address);
  856. if(old_fb)
  857. {
  858. //fb_queue_set_free (old_fb);
  859. fb_queue_set_free_isr (old_fb);
  860. }
  861. else
  862. {
  863. static int fb_error_count = 0;
  864. fb_error_count ++;
  865. if(fb_error_count > 10)
  866. assert (0);
  867. }
  868. //XM_printf ("o %x, n %x\n", fb_curr_address, next_ready_unit->fb_base);
  869. }
  870. }
  871. #endif
  872. if (status & (1<<0)) {
  873. int i;
  874. for (i = 0; i < LCD_OSD_NUMS; i++)
  875. g_osdConfig[i] = 0;
  876. if (lcd->waitbits)
  877. xEventGroupSetBitsFromISR(lcd->vsync_waitq, lcd->waitbits, NULL);
  878. }
  879. }
  880. #if LCD_INTERFACE_TYPE == LCD_INTERFACE_LVDS
  881. static void lvds_screen_reset(void)
  882. {
  883. gpio_direction_output(LVDS_SCREEN_RST_GPIO, 0);
  884. udelay(100);
  885. gpio_direction_output(LVDS_SCREEN_RST_GPIO, 1);
  886. mdelay(20);
  887. }
  888. #endif
  889. int lcd_init(void)
  890. {
  891. int ret = ENOERR;
  892. struct ark_lcd_data *lcd = (struct ark_lcd_data *)pvPortMalloc(sizeof(struct ark_lcd_data));
  893. if(!lcd) {
  894. printf("ERR: %s, malloc failed\n", __func__);
  895. return -ENOMEM;
  896. }
  897. memset(lcd, 0, sizeof(struct ark_lcd_data));
  898. fb_buf = pvPortMalloc(FB_SIZE * FB_COUNT);
  899. if (!fb_buf) {
  900. printf("ERR: malloc framebuffer fail.\n");
  901. vPortFree(lcd);
  902. return -ENOMEM;
  903. }
  904. fb_addr = (uint32_t)fb_buf;
  905. sys_soft_reset(softreset_lcd);
  906. /* lcd timing init */
  907. lcd->timing.vs_start = 0;
  908. lcd->timing.hs_start = 0;
  909. lcd->timing.hd = LCD_WIDTH;
  910. lcd->timing.vd = LCD_HEIGHT;
  911. lcd->timing.vbp = LCD_TIMING_VBP;
  912. lcd->timing.vfp = LCD_TIMING_VFP;
  913. lcd->timing.vsw = LCD_TIMING_VSW;
  914. lcd->timing.hbp = LCD_TIMING_HBP;
  915. lcd->timing.hfp = LCD_TIMING_HFP;
  916. lcd->timing.hsw = LCD_TIMING_HSW;
  917. ark_lcd_clk_init(LCD_CLK_FREQ);
  918. #if LCD_INTERFACE_TYPE == LCD_INTERFACE_LVDS
  919. uint32_t lvds_cfg = 0xe0ec;
  920. #if LVDS_PANEL_FORMAT == LVDS_PANEL_FORMAT_TI
  921. lvds_cfg |= (1 << 16);
  922. #endif
  923. #if LVDS_PANEL_DATA == LVDS_PANEL_DATA_8BIT
  924. lvds_cfg &= ~(1 << 15);
  925. lvds_cfg |= (1 << 4) | 1;
  926. #endif
  927. writel(lvds_cfg, REGS_SYSCTL_BASE + SYS_ANA3_CFG);
  928. lvds_screen_reset();
  929. #endif
  930. ark_lcd_timing_init(lcd);
  931. lcd->vsync_waitq = xEventGroupCreate();
  932. ark_lcd_hw_init();
  933. #ifdef AWTK
  934. fb_queue_init ();
  935. #endif
  936. request_irq(LCD_IRQn, 0, ark_lcd_interrupt, lcd);
  937. g_lcd = lcd;
  938. return ret;
  939. }
  940. void lcd_uninit(void)
  941. {
  942. if(g_lcd) {
  943. vPortFree(g_lcd);
  944. g_lcd = NULL;
  945. }
  946. }