lcd.c 29 KB

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