amba-clcd-versatile.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include <linux/device.h>
  2. #include <linux/dma-mapping.h>
  3. #include <linux/amba/bus.h>
  4. #include <linux/amba/clcd.h>
  5. #include <linux/platform_data/video-clcd-versatile.h>
  6. static struct clcd_panel vga = {
  7. .mode = {
  8. .name = "VGA",
  9. .refresh = 60,
  10. .xres = 640,
  11. .yres = 480,
  12. .pixclock = 39721,
  13. .left_margin = 40,
  14. .right_margin = 24,
  15. .upper_margin = 32,
  16. .lower_margin = 11,
  17. .hsync_len = 96,
  18. .vsync_len = 2,
  19. .sync = 0,
  20. .vmode = FB_VMODE_NONINTERLACED,
  21. },
  22. .width = -1,
  23. .height = -1,
  24. .tim2 = TIM2_BCD | TIM2_IPC,
  25. .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
  26. .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
  27. .bpp = 16,
  28. };
  29. static struct clcd_panel xvga = {
  30. .mode = {
  31. .name = "XVGA",
  32. .refresh = 60,
  33. .xres = 1024,
  34. .yres = 768,
  35. .pixclock = 15748,
  36. .left_margin = 152,
  37. .right_margin = 48,
  38. .upper_margin = 23,
  39. .lower_margin = 3,
  40. .hsync_len = 104,
  41. .vsync_len = 4,
  42. .sync = 0,
  43. .vmode = FB_VMODE_NONINTERLACED,
  44. },
  45. .width = -1,
  46. .height = -1,
  47. .tim2 = TIM2_BCD | TIM2_IPC,
  48. .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
  49. .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
  50. .bpp = 16,
  51. };
  52. /* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */
  53. static struct clcd_panel sanyo_tm38qv67a02a = {
  54. .mode = {
  55. .name = "Sanyo TM38QV67A02A",
  56. .refresh = 116,
  57. .xres = 320,
  58. .yres = 240,
  59. .pixclock = 100000,
  60. .left_margin = 6,
  61. .right_margin = 6,
  62. .upper_margin = 5,
  63. .lower_margin = 5,
  64. .hsync_len = 6,
  65. .vsync_len = 6,
  66. .sync = 0,
  67. .vmode = FB_VMODE_NONINTERLACED,
  68. },
  69. .width = -1,
  70. .height = -1,
  71. .tim2 = TIM2_BCD,
  72. .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
  73. .caps = CLCD_CAP_5551,
  74. .bpp = 16,
  75. };
  76. static struct clcd_panel sanyo_2_5_in = {
  77. .mode = {
  78. .name = "Sanyo QVGA Portrait",
  79. .refresh = 116,
  80. .xres = 240,
  81. .yres = 320,
  82. .pixclock = 100000,
  83. .left_margin = 20,
  84. .right_margin = 10,
  85. .upper_margin = 2,
  86. .lower_margin = 2,
  87. .hsync_len = 10,
  88. .vsync_len = 2,
  89. .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  90. .vmode = FB_VMODE_NONINTERLACED,
  91. },
  92. .width = -1,
  93. .height = -1,
  94. .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
  95. .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
  96. .caps = CLCD_CAP_5551,
  97. .bpp = 16,
  98. };
  99. /* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */
  100. static struct clcd_panel epson_l2f50113t00 = {
  101. .mode = {
  102. .name = "Epson L2F50113T00",
  103. .refresh = 390,
  104. .xres = 176,
  105. .yres = 220,
  106. .pixclock = 62500,
  107. .left_margin = 3,
  108. .right_margin = 2,
  109. .upper_margin = 1,
  110. .lower_margin = 0,
  111. .hsync_len = 3,
  112. .vsync_len = 2,
  113. .sync = 0,
  114. .vmode = FB_VMODE_NONINTERLACED,
  115. },
  116. .width = -1,
  117. .height = -1,
  118. .tim2 = TIM2_BCD | TIM2_IPC,
  119. .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
  120. .caps = CLCD_CAP_5551,
  121. .bpp = 16,
  122. };
  123. static struct clcd_panel *panels[] = {
  124. &vga,
  125. &xvga,
  126. &sanyo_tm38qv67a02a,
  127. &sanyo_2_5_in,
  128. &epson_l2f50113t00,
  129. };
  130. struct clcd_panel *versatile_clcd_get_panel(const char *name)
  131. {
  132. int i;
  133. for (i = 0; i < ARRAY_SIZE(panels); i++)
  134. if (strcmp(panels[i]->mode.name, name) == 0)
  135. break;
  136. if (i < ARRAY_SIZE(panels))
  137. return panels[i];
  138. pr_err("CLCD: couldn't get parameters for panel %s\n", name);
  139. return NULL;
  140. }
  141. int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize)
  142. {
  143. dma_addr_t dma;
  144. fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
  145. &dma, GFP_KERNEL);
  146. if (!fb->fb.screen_base) {
  147. pr_err("CLCD: unable to map framebuffer\n");
  148. return -ENOMEM;
  149. }
  150. fb->fb.fix.smem_start = dma;
  151. fb->fb.fix.smem_len = framesize;
  152. return 0;
  153. }
  154. int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
  155. {
  156. return dma_mmap_writecombine(&fb->dev->dev, vma,
  157. fb->fb.screen_base,
  158. fb->fb.fix.smem_start,
  159. fb->fb.fix.smem_len);
  160. }
  161. void versatile_clcd_remove_dma(struct clcd_fb *fb)
  162. {
  163. dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
  164. fb->fb.screen_base, fb->fb.fix.smem_start);
  165. }