clcd.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * arch/arm/mach-lh7a40x/clcd.c
  3. *
  4. * Copyright (C) 2004 Marc Singer
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * version 2 as published by the Free Software Foundation.
  9. *
  10. */
  11. #include <linux/init.h>
  12. #include <linux/device.h>
  13. #include <linux/dma-mapping.h>
  14. #include <linux/sysdev.h>
  15. #include <linux/interrupt.h>
  16. //#include <linux/module.h>
  17. //#include <linux/time.h>
  18. //#include <asm/mach/time.h>
  19. #include <asm/irq.h>
  20. #include <asm/mach/irq.h>
  21. #include <asm/system.h>
  22. #include <mach/hardware.h>
  23. #include <linux/amba/bus.h>
  24. #include <linux/amba/clcd.h>
  25. #define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
  26. #define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
  27. #define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
  28. #define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
  29. #define ALI_SETUP __REG(ALI_PHYS + 0x00)
  30. #define ALI_CONTROL __REG(ALI_PHYS + 0x04)
  31. #define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
  32. #define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
  33. #include "lcd-panel.h"
  34. static void lh7a40x_clcd_disable (struct clcd_fb *fb)
  35. {
  36. #if defined (CONFIG_MACH_LPD7A400)
  37. CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */
  38. #endif
  39. #if defined (CONFIG_MACH_LPD7A404)
  40. GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */
  41. #endif
  42. #if defined (CONFIG_ARCH_LH7A400)
  43. HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */
  44. #endif
  45. #if defined (CONFIG_ARCH_LH7A404)
  46. ALI_SETUP &= ~(1<<13); /* Disable ALI */
  47. #endif
  48. }
  49. static void lh7a40x_clcd_enable (struct clcd_fb *fb)
  50. {
  51. struct clcd_panel_extra* extra
  52. = (struct clcd_panel_extra*) fb->board_data;
  53. #if defined (CONFIG_MACH_LPD7A400)
  54. CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */
  55. #endif
  56. #if defined (CONFIG_MACH_LPD7A404)
  57. GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */
  58. GPIO_PCD |= (1<<3);
  59. #endif
  60. #if defined (CONFIG_ARCH_LH7A400)
  61. if (extra) {
  62. HRTFTC_HRSETUP
  63. = (1 << 13)
  64. | ((fb->fb.var.xres - 1) << 4)
  65. | 0xc
  66. | (extra->hrmode ? 1 : 0);
  67. HRTFTC_HRCON
  68. = ((extra->clsen ? 1 : 0) << 1)
  69. | ((extra->spsen ? 1 : 0) << 0);
  70. HRTFTC_HRTIMING1
  71. = (extra->pcdel << 8)
  72. | (extra->revdel << 4)
  73. | (extra->lpdel << 0);
  74. HRTFTC_HRTIMING2
  75. = (extra->spldel << 9)
  76. | (extra->pc2del << 0);
  77. }
  78. else
  79. HRTFTC_HRSETUP
  80. = (1 << 13)
  81. | 0xc;
  82. #endif
  83. #if defined (CONFIG_ARCH_LH7A404)
  84. if (extra) {
  85. ALI_SETUP
  86. = (1 << 13)
  87. | ((fb->fb.var.xres - 1) << 4)
  88. | 0xc
  89. | (extra->hrmode ? 1 : 0);
  90. ALI_CONTROL
  91. = ((extra->clsen ? 1 : 0) << 1)
  92. | ((extra->spsen ? 1 : 0) << 0);
  93. ALI_TIMING1
  94. = (extra->pcdel << 8)
  95. | (extra->revdel << 4)
  96. | (extra->lpdel << 0);
  97. ALI_TIMING2
  98. = (extra->spldel << 9)
  99. | (extra->pc2del << 0);
  100. }
  101. else
  102. ALI_SETUP
  103. = (1 << 13)
  104. | 0xc;
  105. #endif
  106. }
  107. #define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
  108. static int lh7a40x_clcd_setup (struct clcd_fb *fb)
  109. {
  110. dma_addr_t dma;
  111. u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
  112. *(lcd_panel.bpp/8));
  113. fb->panel = &lcd_panel;
  114. /* Enforce the sync polarity defaults */
  115. if (!(fb->panel->tim2 & TIM2_IHS))
  116. fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
  117. if (!(fb->panel->tim2 & TIM2_IVS))
  118. fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
  119. #if defined (HAS_LCD_PANEL_EXTRA)
  120. fb->board_data = &lcd_panel_extra;
  121. #endif
  122. fb->fb.screen_base
  123. = dma_alloc_writecombine (&fb->dev->dev, len,
  124. &dma, GFP_KERNEL);
  125. printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
  126. fb->fb.screen_base, (void*) dma, len,
  127. (void*) io_p2v (CLCDC_PHYS));
  128. printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
  129. if (!fb->fb.screen_base) {
  130. printk(KERN_ERR "CLCD: unable to map framebuffer\n");
  131. return -ENOMEM;
  132. }
  133. #if defined (USE_RGB555)
  134. fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
  135. #endif
  136. fb->fb.fix.smem_start = dma;
  137. fb->fb.fix.smem_len = len;
  138. /* Drive PE4 high to prevent CPLD crash */
  139. GPIO_PEDD |= (1<<4);
  140. GPIO_PED |= (1<<4);
  141. GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
  142. // fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
  143. // fb->fb.fbops->fb_set_par (&fb->fb);
  144. return 0;
  145. }
  146. static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
  147. {
  148. return dma_mmap_writecombine(&fb->dev->dev, vma,
  149. fb->fb.screen_base,
  150. fb->fb.fix.smem_start,
  151. fb->fb.fix.smem_len);
  152. }
  153. static void lh7a40x_clcd_remove (struct clcd_fb *fb)
  154. {
  155. dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
  156. fb->fb.screen_base, fb->fb.fix.smem_start);
  157. }
  158. static struct clcd_board clcd_platform_data = {
  159. .name = "lh7a40x FB",
  160. .check = clcdfb_check,
  161. .decode = clcdfb_decode,
  162. .enable = lh7a40x_clcd_enable,
  163. .setup = lh7a40x_clcd_setup,
  164. .mmap = lh7a40x_clcd_mmap,
  165. .remove = lh7a40x_clcd_remove,
  166. .disable = lh7a40x_clcd_disable,
  167. };
  168. #define IRQ_CLCDC (IRQ_LCDINTR)
  169. #define AMBA_DEVICE(name,busid,base,plat,pid) \
  170. static struct amba_device name##_device = { \
  171. .dev = { \
  172. .coherent_dma_mask = ~0, \
  173. .init_name = busid, \
  174. .platform_data = plat, \
  175. }, \
  176. .res = { \
  177. .start = base##_PHYS, \
  178. .end = (base##_PHYS) + (4*1024) - 1, \
  179. .flags = IORESOURCE_MEM, \
  180. }, \
  181. .dma_mask = ~0, \
  182. .irq = { IRQ_##base, }, \
  183. /* .dma = base##_DMA,*/ \
  184. .periphid = pid, \
  185. }
  186. AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110);
  187. static struct amba_device *amba_devs[] __initdata = {
  188. &clcd_device,
  189. };
  190. void __init lh7a40x_clcd_init (void)
  191. {
  192. int i;
  193. int result;
  194. printk ("CLCD: registering amba devices\n");
  195. for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
  196. struct amba_device *d = amba_devs[i];
  197. result = amba_device_register(d, &iomem_resource);
  198. printk (" %d -> %d\n", i ,result);
  199. }
  200. }