s3c2410fb_6448.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:21k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #include <linux/config.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/sched.h>
  5. #include <linux/errno.h>
  6. #include <linux/string.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/slab.h>
  9. #include <linux/fb.h>
  10. #include <linux/delay.h>
  11. #include <linux/pm.h>
  12. #include <linux/init.h>
  13. #include <asm/hardware.h>
  14. #include <asm/io.h>
  15. #include <asm/irq.h>
  16. #include <asm/mach-types.h>
  17. #include <asm/uaccess.h>
  18. #include <video/fbcon.h>
  19. #include <video/fbcon-mfb.h>
  20. #include <video/fbcon-cfb4.h>
  21. #include <video/fbcon-cfb8.h>
  22. #include <video/fbcon-cfb16.h>
  23. #include "s3c2410fb.h"
  24. void (*s3c2410fb_blank_helper)(int blank);
  25. EXPORT_SYMBOL(s3c2410fb_blank_helper);
  26. /*
  27.  * CONFIG_FB_S3C2410_EMUL
  28.  *
  29.  * 伙己 炮饭皋平胶 ? : 96*320 俊鼓饭捞记.
  30.  *
  31.  *  var.xres = 96 栏肺 窍绊,
  32.  *  fix.line_length = 240*2 肺 茄促.
  33.  *  app 啊 linux FB spec. 阑 霖荐茄促搁 巩力啊 绝阑 巴捞促.
  34.  *
  35.  *  var.xres_virtual 阑 炼沥窍绰 规过档 积阿秦 杭 荐 乐瘤父, spec. 苞绰 喊档肺
  36.  *  app. 啊 决没 度度秦具 且 挥父 酒聪扼, panning/wrapping 苞 部老 堪妨啊
  37.  *  乐栏骨肺 硅力茄促.
  38.  */
  39. static struct s3c2410fb_rgb rgb_8 = {
  40. red: {offset: 0, length: 4, },
  41. green: {offset: 0, length: 4, },
  42. blue: {offset: 0, length: 4, },
  43. transp: {offset: 0, length: 0, },
  44. };
  45. static struct s3c2410fb_rgb def_rgb_16 = {
  46.      red: {offset: 11, length: 5, },
  47. green: {offset: 5,  length: 6, },
  48. blue: {offset: 0,  length: 5, },
  49. transp: {offset: 0,  length: 0, },
  50. };
  51. #if 0
  52. static struct s3c2410fb_rgb xxx_tft_rgb_16 = {
  53.      red: {offset: 11, length: 5, },
  54. green: {offset: 6, length: 5, },
  55. blue: {offset: 1, length: 5, },
  56. transp: {offset: 0, length: 1, },
  57. };
  58. #else
  59. static struct s3c2410fb_rgb xxx_tft_rgb_16 = {
  60.      red: {offset: 11, length: 5, },
  61. green: {offset: 5, length: 6, },
  62. blue: {offset: 0, length: 5, },
  63. transp: {offset: 0, length: 0, },
  64. };
  65. #endif
  66. #if 0
  67. #ifdef CONFIG_S3C2410_SMDK
  68. static struct s3c2410fb_mach_info xxx_stn_info __initdata = {
  69.      pixclock: 174757, bpp: 16,
  70. #ifdef CONFIG_FB_S3C2410_EMUL
  71. xres: 96,
  72. #else
  73. xres: 240,
  74. #endif
  75. yres: 320,
  76. hsync_len   :  5,    vsync_len    :  1,
  77. left_margin :  7,    upper_margin :  1,
  78. right_margin:  3,    lower_margin :  3,
  79. sync: 0, cmap_static: 1,
  80. reg : {
  81. lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1) ,
  82. lcdcon2 : LCD2_VBPD(1) | LCD2_VFPD(2) | LCD2_VSPW(1),
  83. lcdcon3 : LCD3_HBPD(6) | LCD3_HFPD(2),
  84. lcdcon4 : LCD4_HSPW(4) | LCD4_MVAL(13),
  85. lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN,
  86. },
  87. };
  88. #endif
  89. #else
  90. #ifdef CONFIG_S3C2410_SMDK
  91. static struct s3c2410fb_mach_info xxx_stn_info __initdata = {
  92.      pixclock: 39721, bpp: 16,
  93. #ifdef CONFIG_FB_S3C2410_EMUL
  94. xres: 96,
  95. #else
  96. xres: 640,
  97. #endif
  98. yres: 480,
  99. hsync_len   :  96,    vsync_len    :  2,
  100. left_margin :  40,    upper_margin :  24,
  101. right_margin:  32,    lower_margin :  11,
  102. sync: 0, cmap_static: 1,
  103. reg : {
  104. lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1) ,
  105. lcdcon2 : LCD2_VBPD(32) | LCD2_VFPD(9) | LCD2_VSPW(1),
  106. lcdcon3 : LCD3_HBPD(47) | LCD3_HFPD(15),
  107. lcdcon4 : LCD4_HSPW(95) | LCD4_MVAL(13),
  108. // lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN,
  109. //LCD5_PWREN:enable power, LDC5_HWSWP:enable half word swap,I am not sure,so I delete it.
  110. lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN,
  111. },
  112. };
  113. #endif
  114. #endif
  115. static inline u_int
  116. chan_to_field(u_int chan, struct fb_bitfield *bf)
  117. {
  118.     chan &= 0xffff;
  119.     chan >>= 16 - bf->length;
  120.     return chan << bf->offset;
  121. }
  122. /*
  123.  * Convert bits-per-pixel to a hardware palette PBS value.
  124.  */
  125. static inline u_int
  126. palette_pbs(struct fb_var_screeninfo *var)
  127. {
  128.    int ret = 0;
  129.    switch (var->bits_per_pixel) {
  130. #ifdef FBCON_HAS_CFB4
  131.       case 4:  ret = 0 << 12; break;
  132. #endif
  133. #ifdef FBCON_HAS_CFB8
  134.       case 8:  ret = 1 << 12; break;
  135. #endif
  136. #ifdef FBCON_HAS_CFB16
  137.       case 16: ret = 2 << 12; break;
  138. #endif
  139.    }
  140.    return ret;
  141. }
  142. static struct s3c2410fb_mach_info * __init
  143. s3c2410fb_get_machine_info(struct s3c2410fb_info *fbi)
  144. {
  145.     struct s3c2410fb_mach_info *inf = NULL;
  146.     inf = &xxx_stn_info;
  147. fbi->reg = inf->reg;
  148.     fbi->rgb[RGB_16] = &xxx_tft_rgb_16;
  149.     return inf;
  150. }
  151. static inline struct fb_var_screeninfo *get_con_var(struct fb_info *info, int con)
  152. {
  153.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  154.     return (con == fbi->currcon || con == -1) ? &fbi->fb.var : &fb_display[con].var;
  155. }
  156. static inline struct fb_cmap *get_con_cmap(struct fb_info *info, int con)
  157. {
  158.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  159.     return (con == fbi->currcon || con == -1) ? &fbi->fb.cmap : &fb_display[con].cmap;
  160. }
  161. static inline struct display *get_con_display(struct fb_info *info, int con)
  162. {
  163.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  164.     return (con < 0) ? (fbi->fb.disp) : &(fb_display[con]);
  165. }
  166. static int
  167. s3c2410fb_validate_var(struct fb_var_screeninfo *var,
  168.       struct s3c2410fb_info *fbi)
  169. {
  170.     int ret = -EINVAL;
  171.     if (var->xres < MIN_XRES)
  172. var->xres = MIN_XRES;
  173.     if (var->yres < MIN_YRES)
  174. var->yres = MIN_YRES;
  175.     if (var->xres > fbi->max_xres)
  176. var->xres = fbi->max_xres;
  177.     if (var->yres > fbi->max_yres)
  178. var->yres = fbi->max_yres;
  179.     var->xres_virtual =
  180. var->xres_virtual < var->xres ? var->xres : var->xres_virtual;
  181.     var->yres_virtual =
  182. var->yres_virtual < var->yres ? var->yres : var->yres_virtual;
  183.     switch(var->bits_per_pixel) {
  184. #ifdef FBCON_HAS_CFB4
  185. case 4: ret = 0; break;
  186. #endif
  187. #ifdef FBCON_HAS_CFB8
  188. case 8: ret = 0; break;
  189. #endif
  190. #ifdef FBCON_HAS_CFB16
  191. case 16: ret = 0; break;
  192. #endif
  193. default:
  194. break;
  195.     }
  196.     return ret;
  197. }
  198. static int
  199. s3c2410fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
  200. u_int trans, struct fb_info *info)
  201. {
  202.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  203.     u_int val, ret = 1;
  204.     if (regno < fbi->palette_size) {
  205. #ifndef CONFIG_S3C2400_GAMEPARK
  206. val = ((red >> 4) & 0xf00);
  207. val |= ((green >> 8) & 0x0f0);
  208. val |= ((blue >> 12) & 0x00f);
  209. #else
  210. val = ((blue >> 16) & 0x001f);
  211.     val |= ((green >> 11) & 0x07e0);
  212.     val |= ((red >> 5) & 0x0f800);
  213. val |= 1; /* intensity bit */
  214. #endif
  215. if (regno == 0)
  216.     val |= palette_pbs(&fbi->fb.var);
  217. fbi->palette_cpu[regno] = val;
  218. ret = 0;
  219.     }
  220.     return ret;
  221. }
  222. static int
  223. s3c2410fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  224.     u_int trans, struct fb_info *info)
  225. {
  226.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  227.     struct display *disp = get_con_display(info, fbi->currcon);
  228.     u_int var;
  229.     int ret = 1;
  230.     if (disp->inverse) {
  231. red  = 0xffff - red;
  232. green  = 0xffff - green;
  233. blue = 0xffff - blue;
  234.     }
  235.     if (fbi->fb.var.grayscale)
  236. red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16;
  237.     switch (fbi->fb.disp->visual) {
  238. case FB_VISUAL_TRUECOLOR:
  239.     if (regno < 16) {
  240. u16 *pal = fbi->fb.pseudo_palette;
  241. var = chan_to_field(red, &fbi->fb.var.red);
  242. var |= chan_to_field(green, &fbi->fb.var.green);
  243. var |= chan_to_field(blue, &fbi->fb.var.blue);
  244. pal[regno] = var;
  245. ret = 0;
  246.     }
  247.     break;
  248. case FB_VISUAL_STATIC_PSEUDOCOLOR:
  249. case FB_VISUAL_PSEUDOCOLOR:
  250.     ret = s3c2410fb_setpalettereg(regno, red, green, blue, trans, info);
  251.     break;
  252.     }
  253.     return ret;
  254. }
  255. static int s3c2410fb_activate_var(struct fb_var_screeninfo *var, struct s3c2410fb_info *fbi)
  256. {
  257.     struct s3c2410fb_lcd_reg new_regs;
  258.     u_int half_screen_size, yres;
  259.     u_long flags;
  260.     /*new_reg 啊 绢录绊 历录绊 */
  261.     unsigned long VideoPhysicalTemp = fbi->screen_dma;
  262.     save_flags_cli(flags);
  263.     new_regs.lcdcon1 = fbi->reg.lcdcon1 & ~LCD1_ENVID;
  264.     new_regs.lcdcon2 = (fbi->reg.lcdcon2 & ~LCD2_LINEVAL_MSK)
  265. | LCD2_LINEVAL(var->yres - 1);
  266. /* TFT LCD only ! */
  267.     new_regs.lcdcon3 = (fbi->reg.lcdcon3 & ~LCD3_HOZVAL_MSK)
  268. | LCD3_HOZVAL(var->xres - 1);
  269.      new_regs.lcdcon4 = fbi->reg.lcdcon4;
  270.     new_regs.lcdcon5 = fbi->reg.lcdcon5;
  271.     new_regs.lcdsaddr1 =
  272. LCDADDR_BANK(((unsigned long)VideoPhysicalTemp >> 22))
  273. | LCDADDR_BASEU(((unsigned long)VideoPhysicalTemp >> 1));
  274. /* 16bpp */
  275.     new_regs.lcdsaddr2 = LCDADDR_BASEL(
  276. ((unsigned long)VideoPhysicalTemp + (var->xres * 2 * (var->yres/*-1*/)))
  277. >> 1);
  278.     new_regs.lcdsaddr3 = LCDADDR_OFFSET(0) | (LCDADDR_PAGE(var->xres) /*>> 1*/);
  279.     yres = var->yres;
  280.     /* if ( dual 捞搁) */
  281.     //yres /= 2;
  282.     half_screen_size = var->bits_per_pixel;
  283.     half_screen_size = half_screen_size * var->xres * var->yres / 16;
  284. fbi->reg.lcdcon1 = new_regs.lcdcon1;
  285. fbi->reg.lcdcon2 = new_regs.lcdcon2;
  286. fbi->reg.lcdcon3 = new_regs.lcdcon3;
  287. fbi->reg.lcdcon4 = new_regs.lcdcon4;
  288. fbi->reg.lcdcon5 = new_regs.lcdcon5;
  289. fbi->reg.lcdsaddr1 = new_regs.lcdsaddr1;
  290. fbi->reg.lcdsaddr2 = new_regs.lcdsaddr2;
  291. fbi->reg.lcdsaddr3 = new_regs.lcdsaddr3;
  292.     LCDCON1 = fbi->reg.lcdcon1;
  293.     LCDCON2 = fbi->reg.lcdcon2;
  294.     LCDCON3 = fbi->reg.lcdcon3;
  295.     LCDCON4 = fbi->reg.lcdcon4;
  296.     LCDCON5 = fbi->reg.lcdcon5;
  297.     LCDADDR1 = fbi->reg.lcdsaddr1;
  298.     LCDADDR2 = fbi->reg.lcdsaddr2;
  299.     LCDADDR3 = fbi->reg.lcdsaddr3;
  300. //softmcu
  301. //#if defined(CONFIG_S3C2410_SMDK) && !defined(CONFIG_SMDK_AIJI)
  302. //    LCDLPCSEL = 0x2;
  303. //#elif defined(CONFIG_S3C2410_SMDK) && defined(CONFIG_SMDK_AIJI)
  304. //    LCDLPCSEL = 0x7;
  305. //#endif
  306. //LCDINTMSK |=(3);
  307. LCDLPCSEL &= (~7);
  308.     TPAL = 0;
  309.     LCDCON1 |= LCD1_ENVID;
  310. printk("testing the lcd by softmcun");
  311. #if 0
  312. {
  313. printk("con1 = 0x%08lxn", LCDCON1);
  314. printk("con2 = 0x%08lxn", LCDCON2);
  315. printk("con3 = 0x%08lxn", LCDCON3);
  316. printk("con4 = 0x%08lxn", LCDCON4);
  317. printk("con5 = 0x%08lxn", LCDCON5);
  318. printk("addr1 = 0x%08lxn", LCDADDR1);
  319. printk("addr2 = 0x%08lxn", LCDADDR2);
  320. printk("addr3 = 0x%08lxn", LCDADDR3);
  321. }
  322. #endif
  323.     restore_flags(flags);
  324.     return 0;
  325. }
  326. static inline void s3c2410fb_set_truecolor(u_int is_true_color)
  327. {
  328.     if (is_true_color) {
  329.     }
  330.     else {
  331.     }
  332. }
  333. static void
  334. s3c2410fb_hw_set_var(struct fb_var_screeninfo *var, struct s3c2410fb_info *fbi)
  335. {
  336.     u_long palette_mem_size;
  337.     fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
  338.     palette_mem_size = fbi->palette_size * sizeof(u16);
  339.     fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
  340.     fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
  341.     fb_set_cmap(&fbi->fb.cmap, 1, s3c2410fb_setcolreg, &fbi->fb);
  342.     s3c2410fb_set_truecolor(var->bits_per_pixel >= 16);
  343.     s3c2410fb_activate_var(var, fbi);
  344.     fbi->palette_cpu[0] = (fbi->palette_cpu[0] &
  345. 0xcfff) | palette_pbs(var);
  346. }
  347. static int
  348. s3c2410fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
  349. {
  350.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  351.     struct fb_var_screeninfo *dvar = get_con_var(&fbi->fb, con);
  352.     struct display *display = get_con_display(&fbi->fb, con);
  353.     int err, chgvar = 0, rgbidx;
  354.     err = s3c2410fb_validate_var(var, fbi);
  355.     if (err)
  356. return err;
  357.     if (var->activate & FB_ACTIVATE_TEST)
  358. return 0;
  359.     if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
  360. return -EINVAL;
  361.     if (dvar->xres != var->xres)
  362. chgvar = 1;
  363.     if (dvar->yres != var->yres)
  364. chgvar = 1;
  365.     if (dvar->xres_virtual != var->xres_virtual)
  366. chgvar = 1;
  367.     if (dvar->yres_virtual != var->yres_virtual)
  368. chgvar = 1;
  369.     if (dvar->bits_per_pixel != var->bits_per_pixel)
  370. chgvar = 1;
  371.     if (con < 0)
  372. chgvar = 0;
  373.     switch (var->bits_per_pixel) {
  374. #ifdef FBCON_HAS_CFB4
  375. case 4:
  376.      if (fbi->cmap_static)
  377.     display->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
  378. else
  379.     display->visual = FB_VISUAL_PSEUDOCOLOR;
  380. display->line_length  = var->xres / 2;
  381. display->dispsw = &fbcon_cfb4;
  382. rgbidx = RGB_8;
  383. break;
  384. #endif
  385. #ifdef FBCON_HAS_CFB8
  386. case 8:
  387. if (fbi->cmap_static)
  388.     display->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
  389. else
  390.     display->visual = FB_VISUAL_PSEUDOCOLOR;
  391. display->line_length  = var->xres;
  392.      display->dispsw = &fbcon_cfb8;
  393. rgbidx = RGB_8;
  394. break;
  395. #endif
  396. #ifdef FBCON_HAS_CFB16
  397. case 16:
  398. display->visual = FB_VISUAL_TRUECOLOR;
  399. #ifdef CONFIG_FB_S3C2410_EMUL
  400. display->line_length    = 240*2;
  401. #else
  402. display->line_length = var->xres * 2;
  403. #endif
  404. display->dispsw = &fbcon_cfb16;
  405. display->dispsw_data = fbi->fb.pseudo_palette;
  406. rgbidx = RGB_16;
  407. break;
  408. #endif
  409. default:
  410. rgbidx = 0;
  411. display->dispsw = &fbcon_dummy;
  412. break;
  413.     }
  414.     display->screen_base  = fbi->screen_cpu;
  415.     display->next_line = display->line_length;
  416.     display->type = fbi->fb.fix.type;
  417.     display->type_aux = fbi->fb.fix.type_aux;
  418.     display->ypanstep = fbi->fb.fix.ypanstep;
  419.     display->ywrapstep = fbi->fb.fix.ywrapstep;
  420.     display->can_soft_blank = 0;
  421.     display->inverse = fbi->cmap_inverse;
  422.     *dvar = *var;
  423.     dvar->activate &= ~FB_ACTIVATE_ALL;
  424.     dvar->red = fbi->rgb[rgbidx]->red;
  425.     dvar->green = fbi->rgb[rgbidx]->green;
  426.     dvar->blue = fbi->rgb[rgbidx]->blue;
  427.     dvar->transp = fbi->rgb[rgbidx]->transp;
  428.     display->var = *dvar;
  429.     if (var->activate & FB_ACTIVATE_ALL)
  430. fbi->fb.disp->var = *dvar;
  431.     if (chgvar && info && fbi->fb.changevar)
  432. fbi->fb.changevar(con);
  433.     if (con != fbi->currcon)
  434. return 0;
  435.     s3c2410fb_hw_set_var(dvar, fbi);
  436.     return 0;
  437. }
  438. static int
  439. __do_set_cmap(struct fb_cmap *cmap, int kspc, int con,
  440.       struct fb_info *info)
  441. {
  442.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  443.     struct fb_cmap *dcmap = get_con_cmap(info, con);
  444.     int err = 0;
  445.     if (con == -1)
  446. con = fbi->currcon;
  447.     if (con >= 0)
  448. err = fb_alloc_cmap(&fb_display[con].cmap, fbi->palette_size, 0);
  449.     if (!err && con == fbi->currcon)
  450. err = fb_set_cmap(cmap, kspc, s3c2410fb_setcolreg, info);
  451.     if (!err)
  452. fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
  453.     return err;
  454. }
  455. static int
  456. s3c2410fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
  457.    struct fb_info *info)
  458. {
  459.     struct display *disp = get_con_display(info, con);
  460.     if (disp->visual == FB_VISUAL_TRUECOLOR ||
  461.         disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
  462. return -EINVAL;
  463.     return __do_set_cmap(cmap, kspc, con, info);
  464. }
  465. static int
  466. s3c2410fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
  467. {
  468.     struct display *display = get_con_display(info, con);
  469.     *fix = info->fix;
  470.     fix->line_length = display->line_length;
  471.     fix->visual      = display->visual;
  472.     return 0;
  473. }
  474. static int
  475. s3c2410fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
  476. {
  477.     *var = *get_con_var(info, con);
  478.     return 0;
  479. }
  480. static int
  481. s3c2410fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
  482. {
  483.     struct fb_cmap *dcmap = get_con_cmap(info, con);
  484.     fb_copy_cmap(dcmap, cmap, kspc ? 0 : 2);
  485.     return 0;
  486. }
  487. #ifdef CONFIG_PM
  488. static int
  489. s3c2410fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  490.                unsigned long arg, int con, struct fb_info *info) {
  491. #ifdef CONFIG_MIZI
  492.     if (mz_pm_ops.fb_ioctl == NULL)
  493.       return -EINVAL;
  494.     return (*(mz_pm_ops.fb_ioctl))(inode, file, cmd, arg, PROC_CONSOLE(info), info);
  495. #endif /* CONFIG_MIZI */
  496. }
  497. #endif /* CONFIG_PM */
  498. static struct fb_ops s3c2410fb_ops = {
  499. owner: THIS_MODULE,
  500. fb_get_fix: s3c2410fb_get_fix,
  501. fb_get_var: s3c2410fb_get_var,
  502. fb_set_var: s3c2410fb_set_var,
  503. fb_get_cmap: s3c2410fb_get_cmap,
  504. fb_set_cmap: s3c2410fb_set_cmap,
  505. #ifdef CONFIG_PM
  506.     fb_ioctl:   s3c2410fb_ioctl,
  507. #endif /* CONFIG_PM */
  508. };
  509. static int s3c2410fb_switch(int con, struct fb_info *info)
  510. {
  511.     struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
  512.     struct display *disp;
  513.     struct fb_cmap *cmap;
  514.     if (con == fbi->currcon)
  515. return 0;
  516.     if (fbi->currcon >= 0) {
  517. disp = fb_display + fbi->currcon;
  518. disp->var = fbi->fb.var;
  519. if (disp->cmap.len)
  520.     fb_copy_cmap(&fbi->fb.cmap, &disp->cmap, 0);
  521.     }
  522.     fbi->currcon = con;
  523.     disp = fb_display + con;
  524.     fb_alloc_cmap(&fbi->fb.cmap, 256, 0);
  525.     if (disp->cmap.len)
  526. cmap = &disp->cmap;
  527.     else
  528. cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
  529.     fb_copy_cmap(cmap, &fbi->fb.cmap, 0);
  530.     fbi->fb.var = disp->var;
  531.     fbi->fb.var.activate = FB_ACTIVATE_NOW;
  532.     s3c2410fb_set_var(&fbi->fb.var, con, info);
  533.     return 0;
  534. }
  535. #ifdef CONFIG_PM
  536. /*
  537.  * Power management hook. Note that we won't be called from IRQ context,
  538.  * unlike the blank functions above, so we may sleep
  539.  */
  540. static int s3c2410_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
  541. {
  542. struct s3c2410fb_info *fbi = pm_dev->data;
  543. u_long flags;
  544. //printk("pm_callback: %dn", req);
  545. if (req == PM_SUSPEND) {
  546. /* disable LCD controller */
  547. LCDCON1 &= ~(1 << 0);
  548. } else if (req == PM_RESUME) {
  549. /* reinitialize LCD controllers and GPIOs */
  550. save_flags_cli(flags);
  551. LCDCON1 = fbi->reg.lcdcon1;
  552. LCDCON2 = fbi->reg.lcdcon2;
  553. LCDCON3 = fbi->reg.lcdcon3;
  554. LCDCON4 = fbi->reg.lcdcon4;
  555. LCDCON5 = fbi->reg.lcdcon5;
  556. LCDADDR1 = fbi->reg.lcdsaddr1;
  557. LCDADDR2 = fbi->reg.lcdsaddr2;
  558. LCDADDR3 = fbi->reg.lcdsaddr3;
  559. //#if defined(CONFIG_S3C2410_SMDK) && !defined(CONFIG_SMDK_AIJI)
  560. LCDLPCSEL = 0x2;
  561. //#elif defined(CONFIG_S3C2410_SMDK) && defined(CONFIG_SMDK_AIJI)
  562. LCDLPCSEL = 0x7;
  563. //#endif
  564. LCDLPCSEL &= (~7);
  565. TPAL = 0;
  566. LCDCON1 |= LCD1_ENVID;
  567. restore_flags(flags);
  568. }
  569. //printk("donen");
  570. return 0;
  571. }
  572. #endif
  573. static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi)
  574. {
  575.     fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
  576.     fbi->map_cpu = consistent_alloc(GFP_KERNEL, fbi->map_size,
  577.          &fbi->map_dma);
  578.     if (fbi->map_cpu) {
  579. fbi->screen_cpu = fbi->map_cpu + PAGE_SIZE;
  580. fbi->screen_dma = fbi->map_dma + PAGE_SIZE;
  581. fbi->fb.fix.smem_start = fbi->screen_dma;
  582.     }
  583.     return fbi->map_cpu ? 0 : -ENOMEM;
  584. }
  585. static int s3c2410fb_updatevar(int con, struct fb_info *info)
  586. {
  587.     return 0;
  588. }
  589. static void s3c2410fb_blank(int blank, struct fb_info *info)
  590. {
  591. }
  592. static struct fb_monspecs monspecs __initdata = {
  593.     30000, 70000, 50, 65, 0
  594. };
  595. static struct s3c2410fb_info * __init s3c2410fb_init_fbinfo(void)
  596. {
  597.     struct s3c2410fb_mach_info *inf;
  598.     struct s3c2410fb_info *fbi;
  599.     fbi = kmalloc(sizeof(struct s3c2410fb_info) + sizeof(struct display) +
  600.        sizeof(u16)*16, GFP_KERNEL);
  601.     if (!fbi)
  602. return NULL;
  603.     memset(fbi, 0, sizeof(struct s3c2410fb_info) + sizeof(struct display));
  604.     fbi->currcon = -1;
  605.     strcpy(fbi->fb.fix.id, S3C2410_NAME);
  606.     fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
  607.     fbi->fb.fix.type_aux = 0;
  608.     fbi->fb.fix.xpanstep = 0;
  609.     fbi->fb.fix.ypanstep = 0;
  610.     fbi->fb.fix.ywrapstep = 0;
  611.     fbi->fb.fix.accel = FB_ACCEL_NONE;
  612.     fbi->fb.var.nonstd = 0;
  613.     fbi->fb.var.activate = FB_ACTIVATE_NOW;
  614.     fbi->fb.var.height = -1;
  615.     fbi->fb.var.width = -1;
  616.     fbi->fb.var.accel_flags = 0;
  617.     fbi->fb.var.vmode = FB_VMODE_NONINTERLACED;
  618.     strcpy(fbi->fb.modename, S3C2410_NAME);
  619.     strcpy(fbi->fb.fontname, "Acorn8x8");
  620.     fbi->fb.fbops = &s3c2410fb_ops;
  621.     fbi->fb.changevar = NULL;
  622.     fbi->fb.switch_con = s3c2410fb_switch;
  623.     fbi->fb.updatevar = s3c2410fb_updatevar;
  624.     fbi->fb.blank = s3c2410fb_blank;
  625.     fbi->fb.flags = FBINFO_FLAG_DEFAULT;
  626.     fbi->fb.node = -1;
  627.     fbi->fb.monspecs = monspecs;
  628.     fbi->fb.disp = (struct display *)(fbi + 1);
  629.     fbi->fb.pseudo_palette = (void *)(fbi->fb.disp + 1);
  630.     fbi->rgb[RGB_8] = &rgb_8;
  631.     fbi->rgb[RGB_16] = &def_rgb_16;
  632.     inf = s3c2410fb_get_machine_info(fbi);
  633. #ifdef CONFIG_FB_S3C2410_EMUL
  634. fbi->max_xres  = 240;
  635. #else
  636.     fbi->max_xres = inf->xres;
  637. #endif
  638.     fbi->fb.var.xres = inf->xres;
  639.     fbi->fb.var.xres_virtual = inf->xres;
  640.     fbi->max_yres = inf->yres;
  641.     fbi->fb.var.yres = inf->yres;
  642.     fbi->fb.var.yres_virtual = inf->yres;
  643.     fbi->max_bpp = inf->bpp;
  644.     fbi->fb.var.bits_per_pixel  = inf->bpp;
  645.     fbi->fb.var.pixclock = inf->pixclock;
  646.     fbi->fb.var.hsync_len = inf->hsync_len;
  647.     fbi->fb.var.left_margin = inf->left_margin;
  648.     fbi->fb.var.right_margin = inf->right_margin;
  649.     fbi->fb.var.vsync_len = inf->vsync_len;
  650.     fbi->fb.var.upper_margin = inf->upper_margin;
  651.     fbi->fb.var.lower_margin = inf->lower_margin;
  652.     fbi->fb.var.sync = inf->sync;
  653.     fbi->fb.var.grayscale = inf->cmap_grayscale;
  654.     fbi->cmap_inverse = inf->cmap_inverse;
  655.     fbi->cmap_static = inf->cmap_static;
  656.     fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres *
  657.   fbi->max_bpp / 8;
  658.     return fbi;
  659. }
  660. void s3c2410_lcd_init(void)
  661. {
  662. //softmcu
  663. GPCUP = 0xffffffff;
  664. GPDUP = 0xffffffff;
  665.     GPDCON = 0xaaaaaaaa;
  666. #ifdef CONFIG_S3C2410_SMDK
  667.     GPCCON = 0xaaaaaaaa;
  668. //softmcu
  669. //set_gpio_ctrl(GPIO_G4 | GPIO_PULLUP_EN | GPIO_MODE_LCD_PWRDN);
  670. set_gpio_ctrl(GPIO_G4 | GPIO_PULLUP_DIS | GPIO_MODE_LCD_PWRDN);
  671. #endif
  672. #if defined(CONFIG_MIZI) && defined(CONFIG_PM)
  673.     if (mz_pm_ops.blank_helper != NULL)
  674.         (*(mz_pm_ops.blank_helper))(MZ_BLANK_ON);
  675. #endif
  676. }
  677. int __init s3c2410fb_init(void)
  678. {
  679.     struct s3c2410fb_info *fbi;
  680.     int ret;
  681. //softmcu
  682. printk("test lcd start 0719n");
  683.     fbi = s3c2410fb_init_fbinfo();
  684.     ret = -ENOMEM;
  685.     if (!fbi)
  686. goto failed;
  687.     ret = s3c2410fb_map_video_memory(fbi);
  688.     if (ret)
  689. goto failed;
  690.     s3c2410_lcd_init();
  691.     s3c2410fb_set_var(&fbi->fb.var, -1, &fbi->fb);
  692.     ret = register_framebuffer(&fbi->fb);
  693.    if (ret < 0)
  694.       goto failed;
  695. #ifdef CONFIG_PM
  696. /*
  697.  * Note that console registers this as well, but we want to
  698.  * power donw the display prior to sleeping
  699.  */
  700. fbi->pm = pm_register(PM_DEBUG_DEV, PM_SYS_VGA, s3c2410_pm_callback);
  701. if (fbi->pm)
  702. fbi->pm->data = fbi;
  703. #endif
  704.    /* enable the LCD controller) */
  705. printk("Installed S3C2410 frame buffern");
  706.     MOD_INC_USE_COUNT ;
  707.     return 0;
  708. failed:
  709.     if (fbi)
  710. kfree(fbi);
  711.     return ret;
  712. }
  713. int __init s3c2410fb_setup(char *options)
  714. {
  715.     return 0;
  716. }
  717. #ifdef MODULE
  718. module_init(s3c2410fb_init);
  719. #endif