pxafb.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. /*
  2. * PXA LCD Controller
  3. *
  4. * (C) Copyright 2001-2002
  5. * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. */
  25. /************************************************************************/
  26. /* ** HEADER FILES */
  27. /************************************************************************/
  28. #include <config.h>
  29. #include <common.h>
  30. #include <version.h>
  31. #include <stdarg.h>
  32. #include <linux/types.h>
  33. #include <stdio_dev.h>
  34. #include <lcd.h>
  35. #include <asm/arch/pxa-regs.h>
  36. #include <asm/io.h>
  37. /* #define DEBUG */
  38. #ifdef CONFIG_LCD
  39. /*----------------------------------------------------------------------*/
  40. /*
  41. * Define panel bpp, LCCR0, LCCR3 and panel_info video struct for
  42. * your display.
  43. */
  44. #ifdef CONFIG_PXA_VGA
  45. /* LCD outputs connected to a video DAC */
  46. # define LCD_BPP LCD_COLOR8
  47. /* you have to set lccr0 and lccr3 (including pcd) */
  48. # define REG_LCCR0 0x003008f8
  49. # define REG_LCCR3 0x0300FF01
  50. /* 640x480x16 @ 61 Hz */
  51. vidinfo_t panel_info = {
  52. .vl_col = 640,
  53. .vl_row = 480,
  54. .vl_width = 640,
  55. .vl_height = 480,
  56. .vl_clkp = CONFIG_SYS_HIGH,
  57. .vl_oep = CONFIG_SYS_HIGH,
  58. .vl_hsp = CONFIG_SYS_HIGH,
  59. .vl_vsp = CONFIG_SYS_HIGH,
  60. .vl_dp = CONFIG_SYS_HIGH,
  61. .vl_bpix = LCD_BPP,
  62. .vl_lbw = 0,
  63. .vl_splt = 0,
  64. .vl_clor = 0,
  65. .vl_tft = 1,
  66. .vl_hpw = 40,
  67. .vl_blw = 56,
  68. .vl_elw = 56,
  69. .vl_vpw = 20,
  70. .vl_bfw = 8,
  71. .vl_efw = 8,
  72. };
  73. #endif /* CONFIG_PXA_VIDEO */
  74. /*----------------------------------------------------------------------*/
  75. #ifdef CONFIG_SHARP_LM8V31
  76. # define LCD_BPP LCD_COLOR8
  77. # define LCD_INVERT_COLORS /* Needed for colors to be correct, but why? */
  78. /* you have to set lccr0 and lccr3 (including pcd) */
  79. # define REG_LCCR0 0x0030087C
  80. # define REG_LCCR3 0x0340FF08
  81. vidinfo_t panel_info = {
  82. .vl_col = 640,
  83. .vl_row = 480,
  84. .vl_width = 157,
  85. .vl_height = 118,
  86. .vl_clkp = CONFIG_SYS_HIGH,
  87. .vl_oep = CONFIG_SYS_HIGH,
  88. .vl_hsp = CONFIG_SYS_HIGH,
  89. .vl_vsp = CONFIG_SYS_HIGH,
  90. .vl_dp = CONFIG_SYS_HIGH,
  91. .vl_bpix = LCD_BPP,
  92. .vl_lbw = 0,
  93. .vl_splt = 1,
  94. .vl_clor = 1,
  95. .vl_tft = 0,
  96. .vl_hpw = 1,
  97. .vl_blw = 3,
  98. .vl_elw = 3,
  99. .vl_vpw = 1,
  100. .vl_bfw = 0,
  101. .vl_efw = 0,
  102. };
  103. #endif /* CONFIG_SHARP_LM8V31 */
  104. /*----------------------------------------------------------------------*/
  105. #ifdef CONFIG_VOIPAC_LCD
  106. # define LCD_BPP LCD_COLOR8
  107. # define LCD_INVERT_COLORS
  108. /* you have to set lccr0 and lccr3 (including pcd) */
  109. # define REG_LCCR0 0x043008f8
  110. # define REG_LCCR3 0x0340FF08
  111. vidinfo_t panel_info = {
  112. .vl_col = 640,
  113. .vl_row = 480,
  114. .vl_width = 157,
  115. .vl_height = 118,
  116. .vl_clkp = CONFIG_SYS_HIGH,
  117. .vl_oep = CONFIG_SYS_HIGH,
  118. .vl_hsp = CONFIG_SYS_HIGH,
  119. .vl_vsp = CONFIG_SYS_HIGH,
  120. .vl_dp = CONFIG_SYS_HIGH,
  121. .vl_bpix = LCD_BPP,
  122. .vl_lbw = 0,
  123. .vl_splt = 1,
  124. .vl_clor = 1,
  125. .vl_tft = 1,
  126. .vl_hpw = 32,
  127. .vl_blw = 144,
  128. .vl_elw = 32,
  129. .vl_vpw = 2,
  130. .vl_bfw = 13,
  131. .vl_efw = 30,
  132. };
  133. #endif /* CONFIG_VOIPAC_LCD */
  134. /*----------------------------------------------------------------------*/
  135. #ifdef CONFIG_HITACHI_SX14
  136. /* Hitachi SX14Q004-ZZA color STN LCD */
  137. #define LCD_BPP LCD_COLOR8
  138. /* you have to set lccr0 and lccr3 (including pcd) */
  139. #define REG_LCCR0 0x00301079
  140. #define REG_LCCR3 0x0340FF20
  141. vidinfo_t panel_info = {
  142. .vl_col = 320,
  143. .vl_row = 240,
  144. .vl_width = 167,
  145. .vl_height = 109,
  146. .vl_clkp = CONFIG_SYS_HIGH,
  147. .vl_oep = CONFIG_SYS_HIGH,
  148. .vl_hsp = CONFIG_SYS_HIGH,
  149. .vl_vsp = CONFIG_SYS_HIGH,
  150. .vl_dp = CONFIG_SYS_HIGH,
  151. .vl_bpix = LCD_BPP,
  152. .vl_lbw = 1,
  153. .vl_splt = 0,
  154. .vl_clor = 1,
  155. .vl_tft = 0,
  156. .vl_hpw = 1,
  157. .vl_blw = 1,
  158. .vl_elw = 1,
  159. .vl_vpw = 7,
  160. .vl_bfw = 0,
  161. .vl_efw = 0,
  162. };
  163. #endif /* CONFIG_HITACHI_SX14 */
  164. /*----------------------------------------------------------------------*/
  165. #ifdef CONFIG_LMS283GF05
  166. # define LCD_BPP LCD_COLOR8
  167. /*# define LCD_INVERT_COLORS*/
  168. /* you have to set lccr0 and lccr3 (including pcd) */
  169. # define REG_LCCR0 0x043008f8
  170. # define REG_LCCR3 0x03b00009
  171. vidinfo_t panel_info = {
  172. .vl_col = 240,
  173. .vl_row = 320,
  174. .vl_width = 240,
  175. .vl_height = 320,
  176. .vl_clkp = CONFIG_SYS_HIGH,
  177. .vl_oep = CONFIG_SYS_LOW,
  178. .vl_hsp = CONFIG_SYS_LOW,
  179. .vl_vsp = CONFIG_SYS_LOW,
  180. .vl_dp = CONFIG_SYS_HIGH,
  181. .vl_bpix = LCD_BPP,
  182. .vl_lbw = 0,
  183. .vl_splt = 1,
  184. .vl_clor = 1,
  185. .vl_tft = 1,
  186. .vl_hpw = 4,
  187. .vl_blw = 4,
  188. .vl_elw = 8,
  189. .vl_vpw = 4,
  190. .vl_bfw = 4,
  191. .vl_efw = 8,
  192. };
  193. #endif /* CONFIG_LMS283GF05 */
  194. /*----------------------------------------------------------------------*/
  195. #ifdef CONFIG_ACX517AKN
  196. # define LCD_BPP LCD_COLOR8
  197. /* you have to set lccr0 and lccr3 (including pcd) */
  198. # define REG_LCCR0 0x003008f9
  199. # define REG_LCCR3 0x03700006
  200. vidinfo_t panel_info = {
  201. .vl_col = 320,
  202. .vl_row = 320,
  203. .vl_width = 320,
  204. .vl_height = 320,
  205. .vl_clkp = CONFIG_SYS_HIGH,
  206. .vl_oep = CONFIG_SYS_LOW,
  207. .vl_hsp = CONFIG_SYS_LOW,
  208. .vl_vsp = CONFIG_SYS_LOW,
  209. .vl_dp = CONFIG_SYS_HIGH,
  210. .vl_bpix = LCD_BPP,
  211. .vl_lbw = 0,
  212. .vl_splt = 1,
  213. .vl_clor = 1,
  214. .vl_tft = 1,
  215. .vl_hpw = 0x04,
  216. .vl_blw = 0x1c,
  217. .vl_elw = 0x08,
  218. .vl_vpw = 0x01,
  219. .vl_bfw = 0x07,
  220. .vl_efw = 0x08,
  221. };
  222. #endif /* CONFIG_ACX517AKN */
  223. /*----------------------------------------------------------------------*/
  224. #ifdef CONFIG_LQ038J7DH53
  225. # define LCD_BPP LCD_COLOR8
  226. /* you have to set lccr0 and lccr3 (including pcd) */
  227. # define REG_LCCR0 0x003008f9
  228. # define REG_LCCR3 0x03700004
  229. vidinfo_t panel_info = {
  230. .vl_col = 320,
  231. .vl_row = 480,
  232. .vl_width = 320,
  233. .vl_height = 480,
  234. .vl_clkp = CONFIG_SYS_HIGH,
  235. .vl_oep = CONFIG_SYS_LOW,
  236. .vl_hsp = CONFIG_SYS_LOW,
  237. .vl_vsp = CONFIG_SYS_LOW,
  238. .vl_dp = CONFIG_SYS_HIGH,
  239. .vl_bpix = LCD_BPP,
  240. .vl_lbw = 0,
  241. .vl_splt = 1,
  242. .vl_clor = 1,
  243. .vl_tft = 1,
  244. .vl_hpw = 0x04,
  245. .vl_blw = 0x20,
  246. .vl_elw = 0x01,
  247. .vl_vpw = 0x01,
  248. .vl_bfw = 0x04,
  249. .vl_efw = 0x01,
  250. };
  251. #endif /* CONFIG_ACX517AKN */
  252. /*----------------------------------------------------------------------*/
  253. #ifdef CONFIG_LITTLETON_LCD
  254. # define LCD_BPP LCD_COLOR8
  255. /* you have to set lccr0 and lccr3 (including pcd) */
  256. # define REG_LCCR0 0x003008f8
  257. # define REG_LCCR3 0x0300FF04
  258. vidinfo_t panel_info = {
  259. .vl_col = 480,
  260. .vl_row = 640,
  261. .vl_width = 480,
  262. .vl_height = 640,
  263. .vl_clkp = CONFIG_SYS_HIGH,
  264. .vl_oep = CONFIG_SYS_HIGH,
  265. .vl_hsp = CONFIG_SYS_HIGH,
  266. .vl_vsp = CONFIG_SYS_HIGH,
  267. .vl_dp = CONFIG_SYS_HIGH,
  268. .vl_bpix = LCD_BPP,
  269. .vl_lbw = 0,
  270. .vl_splt = 0,
  271. .vl_clor = 0,
  272. .vl_tft = 1,
  273. .vl_hpw = 9,
  274. .vl_blw = 8,
  275. .vl_elw = 24,
  276. .vl_vpw = 2,
  277. .vl_bfw = 2,
  278. .vl_efw = 4,
  279. };
  280. #endif /* CONFIG_LITTLETON_LCD */
  281. /*----------------------------------------------------------------------*/
  282. #if LCD_BPP == LCD_COLOR8
  283. void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue);
  284. #endif
  285. #if LCD_BPP == LCD_MONOCHROME
  286. void lcd_initcolregs (void);
  287. #endif
  288. #ifdef NOT_USED_SO_FAR
  289. void lcd_disable (void);
  290. void lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue);
  291. #endif /* NOT_USED_SO_FAR */
  292. void lcd_ctrl_init (void *lcdbase);
  293. void lcd_enable (void);
  294. int lcd_line_length;
  295. int lcd_color_fg;
  296. int lcd_color_bg;
  297. void *lcd_base; /* Start of framebuffer memory */
  298. void *lcd_console_address; /* Start of console buffer */
  299. short console_col;
  300. short console_row;
  301. static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid);
  302. static void pxafb_setup_gpio (vidinfo_t *vid);
  303. static void pxafb_enable_controller (vidinfo_t *vid);
  304. static int pxafb_init (vidinfo_t *vid);
  305. /************************************************************************/
  306. /************************************************************************/
  307. /* --------------- PXA chipset specific functions ------------------- */
  308. /************************************************************************/
  309. void lcd_ctrl_init (void *lcdbase)
  310. {
  311. pxafb_init_mem(lcdbase, &panel_info);
  312. pxafb_init(&panel_info);
  313. pxafb_setup_gpio(&panel_info);
  314. pxafb_enable_controller(&panel_info);
  315. }
  316. /*----------------------------------------------------------------------*/
  317. #ifdef NOT_USED_SO_FAR
  318. void
  319. lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue)
  320. {
  321. }
  322. #endif /* NOT_USED_SO_FAR */
  323. /*----------------------------------------------------------------------*/
  324. #if LCD_BPP == LCD_COLOR8
  325. void
  326. lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
  327. {
  328. struct pxafb_info *fbi = &panel_info.pxa;
  329. unsigned short *palette = (unsigned short *)fbi->palette;
  330. u_int val;
  331. if (regno < fbi->palette_size) {
  332. val = ((red << 8) & 0xf800);
  333. val |= ((green << 4) & 0x07e0);
  334. val |= (blue & 0x001f);
  335. #ifdef LCD_INVERT_COLORS
  336. palette[regno] = ~val;
  337. #else
  338. palette[regno] = val;
  339. #endif
  340. }
  341. debug ("setcolreg: reg %2d @ %p: R=%02X G=%02X B=%02X => %04X\n",
  342. regno, &palette[regno],
  343. red, green, blue,
  344. palette[regno]);
  345. }
  346. #endif /* LCD_COLOR8 */
  347. /*----------------------------------------------------------------------*/
  348. #if LCD_BPP == LCD_MONOCHROME
  349. void lcd_initcolregs (void)
  350. {
  351. struct pxafb_info *fbi = &panel_info.pxa;
  352. cmap = (ushort *)fbi->palette;
  353. ushort regno;
  354. for (regno = 0; regno < 16; regno++) {
  355. cmap[regno * 2] = 0;
  356. cmap[(regno * 2) + 1] = regno & 0x0f;
  357. }
  358. }
  359. #endif /* LCD_MONOCHROME */
  360. /*----------------------------------------------------------------------*/
  361. void lcd_enable (void)
  362. {
  363. }
  364. /*----------------------------------------------------------------------*/
  365. #ifdef NOT_USED_SO_FAR
  366. static void lcd_disable (void)
  367. {
  368. }
  369. #endif /* NOT_USED_SO_FAR */
  370. /*----------------------------------------------------------------------*/
  371. /************************************************************************/
  372. /* ** PXA255 specific routines */
  373. /************************************************************************/
  374. /*
  375. * Calculate fb size for VIDEOLFB_ATAG. Size returned contains fb,
  376. * descriptors and palette areas.
  377. */
  378. ulong calc_fbsize (void)
  379. {
  380. ulong size;
  381. int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
  382. size = line_length * panel_info.vl_row;
  383. size += PAGE_SIZE;
  384. return size;
  385. }
  386. static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid)
  387. {
  388. u_long palette_mem_size;
  389. struct pxafb_info *fbi = &vid->pxa;
  390. int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
  391. fbi->screen = (u_long)lcdbase;
  392. fbi->palette_size = NBITS(vid->vl_bpix) == 8 ? 256 : 16;
  393. palette_mem_size = fbi->palette_size * sizeof(u16);
  394. debug("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
  395. /* locate palette and descs at end of page following fb */
  396. fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
  397. return 0;
  398. }
  399. #ifdef CONFIG_CPU_MONAHANS
  400. static inline void pxafb_setup_gpio (vidinfo_t *vid) {}
  401. #else
  402. static void pxafb_setup_gpio (vidinfo_t *vid)
  403. {
  404. u_long lccr0;
  405. /*
  406. * setup is based on type of panel supported
  407. */
  408. lccr0 = vid->pxa.reg_lccr0;
  409. /* 4 bit interface */
  410. if ((lccr0 & LCCR0_CMS) && (lccr0 & LCCR0_SDS) && !(lccr0 & LCCR0_DPD))
  411. {
  412. debug("Setting GPIO for 4 bit data\n");
  413. /* bits 58-61 */
  414. writel(readl(GPDR1) | (0xf << 26), GPDR1);
  415. writel((readl(GAFR1_U) & ~(0xff << 20)) | (0xaa << 20),
  416. GAFR1_U);
  417. /* bits 74-77 */
  418. writel(readl(GPDR2) | (0xf << 10), GPDR2);
  419. writel((readl(GAFR2_L) & ~(0xff << 20)) | (0xaa << 20),
  420. GAFR2_L);
  421. }
  422. /* 8 bit interface */
  423. else if (((lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_DPD))) ||
  424. (!(lccr0 & LCCR0_CMS) && !(lccr0 & LCCR0_PAS) && !(lccr0 & LCCR0_SDS)))
  425. {
  426. debug("Setting GPIO for 8 bit data\n");
  427. /* bits 58-65 */
  428. writel(readl(GPDR1) | (0x3f << 26), GPDR1);
  429. writel(readl(GPDR2) | (0x3), GPDR2);
  430. writel((readl(GAFR1_U) & ~(0xfff << 20)) | (0xaaa << 20),
  431. GAFR1_U);
  432. writel((readl(GAFR2_L) & ~0xf) | (0xa), GAFR2_L);
  433. /* bits 74-77 */
  434. writel(readl(GPDR2) | (0xf << 10), GPDR2);
  435. writel((readl(GAFR2_L) & ~(0xff << 20)) | (0xaa << 20),
  436. GAFR2_L);
  437. }
  438. /* 16 bit interface */
  439. else if (!(lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_PAS)))
  440. {
  441. debug("Setting GPIO for 16 bit data\n");
  442. /* bits 58-77 */
  443. writel(readl(GPDR1) | (0x3f << 26), GPDR1);
  444. writel(readl(GPDR2) | 0x00003fff, GPDR2);
  445. writel((readl(GAFR1_U) & ~(0xfff << 20)) | (0xaaa << 20),
  446. GAFR1_U);
  447. writel((readl(GAFR2_L) & 0xf0000000) | 0x0aaaaaaa, GAFR2_L);
  448. }
  449. else
  450. {
  451. printf("pxafb_setup_gpio: unable to determine bits per pixel\n");
  452. }
  453. }
  454. #endif
  455. static void pxafb_enable_controller (vidinfo_t *vid)
  456. {
  457. debug("Enabling LCD controller\n");
  458. /* Sequence from 11.7.10 */
  459. writel(vid->pxa.reg_lccr3, LCCR3);
  460. writel(vid->pxa.reg_lccr2, LCCR2);
  461. writel(vid->pxa.reg_lccr1, LCCR1);
  462. writel(vid->pxa.reg_lccr0 & ~LCCR0_ENB, LCCR0);
  463. writel(vid->pxa.fdadr0, FDADR0);
  464. writel(vid->pxa.fdadr1, FDADR1);
  465. writel(readl(LCCR0) | LCCR0_ENB, LCCR0);
  466. #ifdef CONFIG_CPU_MONAHANS
  467. writel(readl(CKENA) | CKENA_1_LCD, CKENA);
  468. #else
  469. writel(readl(CKEN) | CKEN16_LCD, CKEN);
  470. #endif
  471. debug("FDADR0 = 0x%08x\n", readl(FDADR0));
  472. debug("FDADR1 = 0x%08x\n", readl(FDADR1));
  473. debug("LCCR0 = 0x%08x\n", readl(LCCR0));
  474. debug("LCCR1 = 0x%08x\n", readl(LCCR1));
  475. debug("LCCR2 = 0x%08x\n", readl(LCCR2));
  476. debug("LCCR3 = 0x%08x\n", readl(LCCR3));
  477. }
  478. static int pxafb_init (vidinfo_t *vid)
  479. {
  480. struct pxafb_info *fbi = &vid->pxa;
  481. debug("Configuring PXA LCD\n");
  482. fbi->reg_lccr0 = REG_LCCR0;
  483. fbi->reg_lccr3 = REG_LCCR3;
  484. debug("vid: vl_col=%d hslen=%d lm=%d rm=%d\n",
  485. vid->vl_col, vid->vl_hpw,
  486. vid->vl_blw, vid->vl_elw);
  487. debug("vid: vl_row=%d vslen=%d um=%d bm=%d\n",
  488. vid->vl_row, vid->vl_vpw,
  489. vid->vl_bfw, vid->vl_efw);
  490. fbi->reg_lccr1 =
  491. LCCR1_DisWdth(vid->vl_col) +
  492. LCCR1_HorSnchWdth(vid->vl_hpw) +
  493. LCCR1_BegLnDel(vid->vl_blw) +
  494. LCCR1_EndLnDel(vid->vl_elw);
  495. fbi->reg_lccr2 =
  496. LCCR2_DisHght(vid->vl_row) +
  497. LCCR2_VrtSnchWdth(vid->vl_vpw) +
  498. LCCR2_BegFrmDel(vid->vl_bfw) +
  499. LCCR2_EndFrmDel(vid->vl_efw);
  500. fbi->reg_lccr3 = REG_LCCR3 & ~(LCCR3_HSP | LCCR3_VSP);
  501. fbi->reg_lccr3 |= (vid->vl_hsp ? LCCR3_HorSnchL : LCCR3_HorSnchH)
  502. | (vid->vl_vsp ? LCCR3_VrtSnchL : LCCR3_VrtSnchH);
  503. /* setup dma descriptors */
  504. fbi->dmadesc_fblow = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
  505. fbi->dmadesc_fbhigh = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
  506. fbi->dmadesc_palette = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
  507. #define BYTES_PER_PANEL ((fbi->reg_lccr0 & LCCR0_SDS) ? \
  508. (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8 / 2) : \
  509. (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8))
  510. /* populate descriptors */
  511. fbi->dmadesc_fblow->fdadr = (u_long)fbi->dmadesc_fblow;
  512. fbi->dmadesc_fblow->fsadr = fbi->screen + BYTES_PER_PANEL;
  513. fbi->dmadesc_fblow->fidr = 0;
  514. fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL;
  515. fbi->fdadr1 = (u_long)fbi->dmadesc_fblow; /* only used in dual-panel mode */
  516. fbi->dmadesc_fbhigh->fsadr = fbi->screen;
  517. fbi->dmadesc_fbhigh->fidr = 0;
  518. fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL;
  519. fbi->dmadesc_palette->fsadr = fbi->palette;
  520. fbi->dmadesc_palette->fidr = 0;
  521. fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
  522. if( NBITS(vid->vl_bpix) < 12)
  523. {
  524. /* assume any mode with <12 bpp is palette driven */
  525. fbi->dmadesc_palette->fdadr = (u_long)fbi->dmadesc_fbhigh;
  526. fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_palette;
  527. /* flips back and forth between pal and fbhigh */
  528. fbi->fdadr0 = (u_long)fbi->dmadesc_palette;
  529. }
  530. else
  531. {
  532. /* palette shouldn't be loaded in true-color mode */
  533. fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_fbhigh;
  534. fbi->fdadr0 = (u_long)fbi->dmadesc_fbhigh; /* no pal just fbhigh */
  535. }
  536. debug("fbi->dmadesc_fblow = 0x%lx\n", (u_long)fbi->dmadesc_fblow);
  537. debug("fbi->dmadesc_fbhigh = 0x%lx\n", (u_long)fbi->dmadesc_fbhigh);
  538. debug("fbi->dmadesc_palette = 0x%lx\n", (u_long)fbi->dmadesc_palette);
  539. debug("fbi->dmadesc_fblow->fdadr = 0x%lx\n", fbi->dmadesc_fblow->fdadr);
  540. debug("fbi->dmadesc_fbhigh->fdadr = 0x%lx\n", fbi->dmadesc_fbhigh->fdadr);
  541. debug("fbi->dmadesc_palette->fdadr = 0x%lx\n", fbi->dmadesc_palette->fdadr);
  542. debug("fbi->dmadesc_fblow->fsadr = 0x%lx\n", fbi->dmadesc_fblow->fsadr);
  543. debug("fbi->dmadesc_fbhigh->fsadr = 0x%lx\n", fbi->dmadesc_fbhigh->fsadr);
  544. debug("fbi->dmadesc_palette->fsadr = 0x%lx\n", fbi->dmadesc_palette->fsadr);
  545. debug("fbi->dmadesc_fblow->ldcmd = 0x%lx\n", fbi->dmadesc_fblow->ldcmd);
  546. debug("fbi->dmadesc_fbhigh->ldcmd = 0x%lx\n", fbi->dmadesc_fbhigh->ldcmd);
  547. debug("fbi->dmadesc_palette->ldcmd = 0x%lx\n", fbi->dmadesc_palette->ldcmd);
  548. return 0;
  549. }
  550. /************************************************************************/
  551. /************************************************************************/
  552. #endif /* CONFIG_LCD */