w100fb.c 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873
  1. /*
  2. * linux/drivers/video/w100fb.c
  3. *
  4. * Frame Buffer Device for ATI Imageon w100 (Wallaby)
  5. *
  6. * Copyright (C) 2002, ATI Corp.
  7. * Copyright (C) 2004-2005 Richard Purdie
  8. *
  9. * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. *
  15. */
  16. #include <linux/delay.h>
  17. #include <linux/fb.h>
  18. #include <linux/init.h>
  19. #include <linux/kernel.h>
  20. #include <linux/mm.h>
  21. #include <linux/device.h>
  22. #include <linux/string.h>
  23. #include <linux/proc_fs.h>
  24. #include <asm/io.h>
  25. #include <asm/uaccess.h>
  26. #include <video/w100fb.h>
  27. #include "w100fb.h"
  28. /*
  29. * Prototypes
  30. */
  31. static void w100fb_save_buffer(void);
  32. static void w100fb_clear_buffer(void);
  33. static void w100fb_restore_buffer(void);
  34. static void w100fb_clear_screen(u32 mode, long int offset);
  35. static void w100_resume(void);
  36. static void w100_suspend(u32 mode);
  37. static void w100_init_qvga_rotation(u16 deg);
  38. static void w100_init_vga_rotation(u16 deg);
  39. static void w100_vsync(void);
  40. static void w100_init_sharp_lcd(u32 mode);
  41. static void w100_pwm_setup(void);
  42. static void w100_InitExtMem(u32 mode);
  43. static void w100_hw_init(void);
  44. static u16 w100_set_fastsysclk(u16 Freq);
  45. static void lcdtg_hw_init(u32 mode);
  46. static void lcdtg_lcd_change(u32 mode);
  47. static void lcdtg_resume(void);
  48. static void lcdtg_suspend(void);
  49. /* Register offsets & lengths */
  50. #define REMAPPED_FB_LEN 0x15ffff
  51. #define BITS_PER_PIXEL 16
  52. /* Pseudo palette size */
  53. #define MAX_PALETTES 16
  54. /* for resolution change */
  55. #define LCD_MODE_INIT (-1)
  56. #define LCD_MODE_480 0
  57. #define LCD_MODE_320 1
  58. #define LCD_MODE_240 2
  59. #define LCD_MODE_640 3
  60. #define LCD_SHARP_QVGA 0
  61. #define LCD_SHARP_VGA 1
  62. #define LCD_MODE_PORTRAIT 0
  63. #define LCD_MODE_LANDSCAPE 1
  64. #define W100_SUSPEND_EXTMEM 0
  65. #define W100_SUSPEND_ALL 1
  66. /* General frame buffer data structures */
  67. struct w100fb_par {
  68. u32 xres;
  69. u32 yres;
  70. int fastsysclk_mode;
  71. int lcdMode;
  72. int rotation_flag;
  73. int blanking_flag;
  74. int comadj;
  75. int phadadj;
  76. };
  77. static struct w100fb_par *current_par;
  78. /* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */
  79. static void *remapped_base;
  80. static void *remapped_regs;
  81. static void *remapped_fbuf;
  82. /* External Function */
  83. static void(*w100fb_ssp_send)(u8 adrs, u8 data);
  84. /*
  85. * Sysfs functions
  86. */
  87. static ssize_t rotation_show(struct device *dev, struct device_attribute *attr, char *buf)
  88. {
  89. struct fb_info *info = dev_get_drvdata(dev);
  90. struct w100fb_par *par=info->par;
  91. return sprintf(buf, "%d\n",par->rotation_flag);
  92. }
  93. static ssize_t rotation_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  94. {
  95. unsigned int rotate;
  96. struct fb_info *info = dev_get_drvdata(dev);
  97. struct w100fb_par *par=info->par;
  98. rotate = simple_strtoul(buf, NULL, 10);
  99. if (rotate > 0) par->rotation_flag = 1;
  100. else par->rotation_flag = 0;
  101. if (par->lcdMode == LCD_MODE_320)
  102. w100_init_qvga_rotation(par->rotation_flag ? 270 : 90);
  103. else if (par->lcdMode == LCD_MODE_240)
  104. w100_init_qvga_rotation(par->rotation_flag ? 180 : 0);
  105. else if (par->lcdMode == LCD_MODE_640)
  106. w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
  107. else if (par->lcdMode == LCD_MODE_480)
  108. w100_init_vga_rotation(par->rotation_flag ? 180 : 0);
  109. return count;
  110. }
  111. static DEVICE_ATTR(rotation, 0644, rotation_show, rotation_store);
  112. static ssize_t w100fb_reg_read(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  113. {
  114. unsigned long param;
  115. unsigned long regs;
  116. regs = simple_strtoul(buf, NULL, 16);
  117. param = readl(remapped_regs + regs);
  118. printk("Read Register 0x%08lX: 0x%08lX\n", regs, param);
  119. return count;
  120. }
  121. static DEVICE_ATTR(reg_read, 0200, NULL, w100fb_reg_read);
  122. static ssize_t w100fb_reg_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  123. {
  124. unsigned long regs;
  125. unsigned long param;
  126. sscanf(buf, "%lx %lx", &regs, &param);
  127. if (regs <= 0x2000) {
  128. printk("Write Register 0x%08lX: 0x%08lX\n", regs, param);
  129. writel(param, remapped_regs + regs);
  130. }
  131. return count;
  132. }
  133. static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write);
  134. static ssize_t fastsysclk_show(struct device *dev, struct device_attribute *attr, char *buf)
  135. {
  136. struct fb_info *info = dev_get_drvdata(dev);
  137. struct w100fb_par *par=info->par;
  138. return sprintf(buf, "%d\n",par->fastsysclk_mode);
  139. }
  140. static ssize_t fastsysclk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  141. {
  142. int param;
  143. struct fb_info *info = dev_get_drvdata(dev);
  144. struct w100fb_par *par=info->par;
  145. param = simple_strtoul(buf, NULL, 10);
  146. if (param == 75) {
  147. printk("Set fastsysclk %d\n", param);
  148. par->fastsysclk_mode = param;
  149. w100_set_fastsysclk(par->fastsysclk_mode);
  150. } else if (param == 100) {
  151. printk("Set fastsysclk %d\n", param);
  152. par->fastsysclk_mode = param;
  153. w100_set_fastsysclk(par->fastsysclk_mode);
  154. }
  155. return count;
  156. }
  157. static DEVICE_ATTR(fastsysclk, 0644, fastsysclk_show, fastsysclk_store);
  158. /*
  159. * The touchscreen on this device needs certain information
  160. * from the video driver to function correctly. We export it here.
  161. */
  162. int w100fb_get_xres(void) {
  163. return current_par->xres;
  164. }
  165. int w100fb_get_blanking(void) {
  166. return current_par->blanking_flag;
  167. }
  168. int w100fb_get_fastsysclk(void) {
  169. return current_par->fastsysclk_mode;
  170. }
  171. EXPORT_SYMBOL(w100fb_get_xres);
  172. EXPORT_SYMBOL(w100fb_get_blanking);
  173. EXPORT_SYMBOL(w100fb_get_fastsysclk);
  174. /*
  175. * Set a palette value from rgb components
  176. */
  177. static int w100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  178. u_int trans, struct fb_info *info)
  179. {
  180. unsigned int val;
  181. int ret = 1;
  182. /*
  183. * If greyscale is true, then we convert the RGB value
  184. * to greyscale no matter what visual we are using.
  185. */
  186. if (info->var.grayscale)
  187. red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16;
  188. /*
  189. * 16-bit True Colour. We encode the RGB value
  190. * according to the RGB bitfield information.
  191. */
  192. if (regno < MAX_PALETTES) {
  193. u32 *pal = info->pseudo_palette;
  194. val = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
  195. pal[regno] = val;
  196. ret = 0;
  197. }
  198. return ret;
  199. }
  200. /*
  201. * Blank the display based on value in blank_mode
  202. */
  203. static int w100fb_blank(int blank_mode, struct fb_info *info)
  204. {
  205. struct w100fb_par *par;
  206. par=info->par;
  207. switch(blank_mode) {
  208. case FB_BLANK_NORMAL: /* Normal blanking */
  209. case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
  210. case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
  211. case FB_BLANK_POWERDOWN: /* Poweroff */
  212. if (par->blanking_flag == 0) {
  213. w100fb_save_buffer();
  214. lcdtg_suspend();
  215. par->blanking_flag = 1;
  216. }
  217. break;
  218. case FB_BLANK_UNBLANK: /* Unblanking */
  219. if (par->blanking_flag != 0) {
  220. w100fb_restore_buffer();
  221. lcdtg_resume();
  222. par->blanking_flag = 0;
  223. }
  224. break;
  225. }
  226. return 0;
  227. }
  228. /*
  229. * Change the resolution by calling the appropriate hardware functions
  230. */
  231. static void w100fb_changeres(int rotate_mode, u32 mode)
  232. {
  233. u16 rotation=0;
  234. switch(rotate_mode) {
  235. case LCD_MODE_LANDSCAPE:
  236. rotation=(current_par->rotation_flag ? 270 : 90);
  237. break;
  238. case LCD_MODE_PORTRAIT:
  239. rotation=(current_par->rotation_flag ? 180 : 0);
  240. break;
  241. }
  242. w100_pwm_setup();
  243. switch(mode) {
  244. case LCD_SHARP_QVGA:
  245. w100_vsync();
  246. w100_suspend(W100_SUSPEND_EXTMEM);
  247. w100_init_sharp_lcd(LCD_SHARP_QVGA);
  248. w100_init_qvga_rotation(rotation);
  249. w100_InitExtMem(LCD_SHARP_QVGA);
  250. w100fb_clear_screen(LCD_SHARP_QVGA, 0);
  251. lcdtg_lcd_change(LCD_SHARP_QVGA);
  252. break;
  253. case LCD_SHARP_VGA:
  254. w100fb_clear_screen(LCD_SHARP_QVGA, 0);
  255. writel(0xBFFFA000, remapped_regs + mmMC_EXT_MEM_LOCATION);
  256. w100_InitExtMem(LCD_SHARP_VGA);
  257. w100fb_clear_screen(LCD_SHARP_VGA, 0x200000);
  258. w100_vsync();
  259. w100_init_sharp_lcd(LCD_SHARP_VGA);
  260. if (rotation != 0)
  261. w100_init_vga_rotation(rotation);
  262. lcdtg_lcd_change(LCD_SHARP_VGA);
  263. break;
  264. }
  265. }
  266. /*
  267. * Set up the display for the fb subsystem
  268. */
  269. static void w100fb_activate_var(struct fb_info *info)
  270. {
  271. u32 temp32;
  272. struct w100fb_par *par=info->par;
  273. struct fb_var_screeninfo *var = &info->var;
  274. /* Set the hardware to 565 */
  275. temp32 = readl(remapped_regs + mmDISP_DEBUG2);
  276. temp32 &= 0xff7fffff;
  277. temp32 |= 0x00800000;
  278. writel(temp32, remapped_regs + mmDISP_DEBUG2);
  279. if (par->lcdMode == LCD_MODE_INIT) {
  280. w100_init_sharp_lcd(LCD_SHARP_VGA);
  281. w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
  282. par->lcdMode = LCD_MODE_640;
  283. lcdtg_hw_init(LCD_SHARP_VGA);
  284. } else if (var->xres == 320 && var->yres == 240) {
  285. if (par->lcdMode != LCD_MODE_320) {
  286. w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_QVGA);
  287. par->lcdMode = LCD_MODE_320;
  288. }
  289. } else if (var->xres == 240 && var->yres == 320) {
  290. if (par->lcdMode != LCD_MODE_240) {
  291. w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_QVGA);
  292. par->lcdMode = LCD_MODE_240;
  293. }
  294. } else if (var->xres == 640 && var->yres == 480) {
  295. if (par->lcdMode != LCD_MODE_640) {
  296. w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_VGA);
  297. par->lcdMode = LCD_MODE_640;
  298. }
  299. } else if (var->xres == 480 && var->yres == 640) {
  300. if (par->lcdMode != LCD_MODE_480) {
  301. w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_VGA);
  302. par->lcdMode = LCD_MODE_480;
  303. }
  304. } else printk(KERN_ERR "W100FB: Resolution error!\n");
  305. }
  306. /*
  307. * w100fb_check_var():
  308. * Get the video params out of 'var'. If a value doesn't fit, round it up,
  309. * if it's too big, return -EINVAL.
  310. *
  311. */
  312. static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  313. {
  314. if (var->xres < var->yres) { /* Portrait mode */
  315. if ((var->xres > 480) || (var->yres > 640)) {
  316. return -EINVAL;
  317. } else if ((var->xres > 240) || (var->yres > 320)) {
  318. var->xres = 480;
  319. var->yres = 640;
  320. } else {
  321. var->xres = 240;
  322. var->yres = 320;
  323. }
  324. } else { /* Landscape mode */
  325. if ((var->xres > 640) || (var->yres > 480)) {
  326. return -EINVAL;
  327. } else if ((var->xres > 320) || (var->yres > 240)) {
  328. var->xres = 640;
  329. var->yres = 480;
  330. } else {
  331. var->xres = 320;
  332. var->yres = 240;
  333. }
  334. }
  335. var->xres_virtual = max(var->xres_virtual, var->xres);
  336. var->yres_virtual = max(var->yres_virtual, var->yres);
  337. if (var->bits_per_pixel > BITS_PER_PIXEL)
  338. return -EINVAL;
  339. else
  340. var->bits_per_pixel = BITS_PER_PIXEL;
  341. var->red.offset = 11;
  342. var->red.length = 5;
  343. var->green.offset = 5;
  344. var->green.length = 6;
  345. var->blue.offset = 0;
  346. var->blue.length = 5;
  347. var->transp.offset = var->transp.length = 0;
  348. var->nonstd = 0;
  349. var->height = -1;
  350. var->width = -1;
  351. var->vmode = FB_VMODE_NONINTERLACED;
  352. var->sync = 0;
  353. var->pixclock = 0x04; /* 171521; */
  354. return 0;
  355. }
  356. /*
  357. * w100fb_set_par():
  358. * Set the user defined part of the display for the specified console
  359. * by looking at the values in info.var
  360. */
  361. static int w100fb_set_par(struct fb_info *info)
  362. {
  363. struct w100fb_par *par=info->par;
  364. par->xres = info->var.xres;
  365. par->yres = info->var.yres;
  366. info->fix.visual = FB_VISUAL_TRUECOLOR;
  367. info->fix.ypanstep = 0;
  368. info->fix.ywrapstep = 0;
  369. if (par->blanking_flag)
  370. w100fb_clear_buffer();
  371. w100fb_activate_var(info);
  372. if (par->lcdMode == LCD_MODE_480) {
  373. info->fix.line_length = (480 * BITS_PER_PIXEL) / 8;
  374. info->fix.smem_len = 0x200000;
  375. } else if (par->lcdMode == LCD_MODE_320) {
  376. info->fix.line_length = (320 * BITS_PER_PIXEL) / 8;
  377. info->fix.smem_len = 0x60000;
  378. } else if (par->lcdMode == LCD_MODE_240) {
  379. info->fix.line_length = (240 * BITS_PER_PIXEL) / 8;
  380. info->fix.smem_len = 0x60000;
  381. } else if (par->lcdMode == LCD_MODE_INIT || par->lcdMode == LCD_MODE_640) {
  382. info->fix.line_length = (640 * BITS_PER_PIXEL) / 8;
  383. info->fix.smem_len = 0x200000;
  384. }
  385. return 0;
  386. }
  387. /*
  388. * Frame buffer operations
  389. */
  390. static struct fb_ops w100fb_ops = {
  391. .owner = THIS_MODULE,
  392. .fb_check_var = w100fb_check_var,
  393. .fb_set_par = w100fb_set_par,
  394. .fb_setcolreg = w100fb_setcolreg,
  395. .fb_blank = w100fb_blank,
  396. .fb_fillrect = cfb_fillrect,
  397. .fb_copyarea = cfb_copyarea,
  398. .fb_imageblit = cfb_imageblit,
  399. .fb_cursor = soft_cursor,
  400. };
  401. static void w100fb_clear_screen(u32 mode, long int offset)
  402. {
  403. int i, numPix = 0;
  404. if (mode == LCD_SHARP_VGA)
  405. numPix = 640 * 480;
  406. else if (mode == LCD_SHARP_QVGA)
  407. numPix = 320 * 240;
  408. for (i = 0; i < numPix; i++)
  409. writew(0xffff, remapped_fbuf + offset + (2*i));
  410. }
  411. /* Need to split up the buffers to stay within the limits of kmalloc */
  412. #define W100_BUF_NUM 6
  413. static uint32_t *gSaveImagePtr[W100_BUF_NUM] = { NULL };
  414. static void w100fb_save_buffer(void)
  415. {
  416. int i, j, bufsize;
  417. bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
  418. for (i = 0; i < W100_BUF_NUM; i++) {
  419. if (gSaveImagePtr[i] == NULL)
  420. gSaveImagePtr[i] = kmalloc(bufsize, GFP_KERNEL);
  421. if (gSaveImagePtr[i] == NULL) {
  422. w100fb_clear_buffer();
  423. printk(KERN_WARNING "can't alloc pre-off image buffer %d\n", i);
  424. break;
  425. }
  426. for (j = 0; j < bufsize/4; j++)
  427. *(gSaveImagePtr[i] + j) = readl(remapped_fbuf + (bufsize*i) + j*4);
  428. }
  429. }
  430. static void w100fb_restore_buffer(void)
  431. {
  432. int i, j, bufsize;
  433. bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
  434. for (i = 0; i < W100_BUF_NUM; i++) {
  435. if (gSaveImagePtr[i] == NULL) {
  436. printk(KERN_WARNING "can't find pre-off image buffer %d\n", i);
  437. w100fb_clear_buffer();
  438. break;
  439. }
  440. for (j = 0; j < (bufsize/4); j++)
  441. writel(*(gSaveImagePtr[i] + j),remapped_fbuf + (bufsize*i) + (j*4));
  442. kfree(gSaveImagePtr[i]);
  443. gSaveImagePtr[i] = NULL;
  444. }
  445. }
  446. static void w100fb_clear_buffer(void)
  447. {
  448. int i;
  449. for (i = 0; i < W100_BUF_NUM; i++) {
  450. kfree(gSaveImagePtr[i]);
  451. gSaveImagePtr[i] = NULL;
  452. }
  453. }
  454. #ifdef CONFIG_PM
  455. static int w100fb_suspend(struct device *dev, pm_message_t state, u32 level)
  456. {
  457. if (level == SUSPEND_POWER_DOWN) {
  458. struct fb_info *info = dev_get_drvdata(dev);
  459. struct w100fb_par *par=info->par;
  460. w100fb_save_buffer();
  461. lcdtg_suspend();
  462. w100_suspend(W100_SUSPEND_ALL);
  463. par->blanking_flag = 1;
  464. }
  465. return 0;
  466. }
  467. static int w100fb_resume(struct device *dev, u32 level)
  468. {
  469. if (level == RESUME_POWER_ON) {
  470. struct fb_info *info = dev_get_drvdata(dev);
  471. struct w100fb_par *par=info->par;
  472. w100_resume();
  473. w100fb_restore_buffer();
  474. lcdtg_resume();
  475. par->blanking_flag = 0;
  476. }
  477. return 0;
  478. }
  479. #else
  480. #define w100fb_suspend NULL
  481. #define w100fb_resume NULL
  482. #endif
  483. int __init w100fb_probe(struct device *dev)
  484. {
  485. struct w100fb_mach_info *inf;
  486. struct fb_info *info;
  487. struct w100fb_par *par;
  488. struct platform_device *pdev = to_platform_device(dev);
  489. struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  490. if (!mem)
  491. return -EINVAL;
  492. /* remap the areas we're going to use */
  493. remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN);
  494. if (remapped_base == NULL)
  495. return -EIO;
  496. remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN);
  497. if (remapped_regs == NULL) {
  498. iounmap(remapped_base);
  499. return -EIO;
  500. }
  501. remapped_fbuf = ioremap_nocache(mem->start+MEM_EXT_BASE_VALUE, REMAPPED_FB_LEN);
  502. if (remapped_fbuf == NULL) {
  503. iounmap(remapped_base);
  504. iounmap(remapped_regs);
  505. return -EIO;
  506. }
  507. info=framebuffer_alloc(sizeof(struct w100fb_par), dev);
  508. if (!info) {
  509. iounmap(remapped_base);
  510. iounmap(remapped_regs);
  511. iounmap(remapped_fbuf);
  512. return -ENOMEM;
  513. }
  514. info->device=dev;
  515. par = info->par;
  516. current_par=info->par;
  517. dev_set_drvdata(dev, info);
  518. inf = dev->platform_data;
  519. par->phadadj = inf->phadadj;
  520. par->comadj = inf->comadj;
  521. par->fastsysclk_mode = 75;
  522. par->lcdMode = LCD_MODE_INIT;
  523. par->rotation_flag=0;
  524. par->blanking_flag=0;
  525. w100fb_ssp_send = inf->w100fb_ssp_send;
  526. w100_hw_init();
  527. w100_pwm_setup();
  528. info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL);
  529. if (!info->pseudo_palette) {
  530. iounmap(remapped_base);
  531. iounmap(remapped_regs);
  532. iounmap(remapped_fbuf);
  533. return -ENOMEM;
  534. }
  535. info->fbops = &w100fb_ops;
  536. info->flags = FBINFO_DEFAULT;
  537. info->node = -1;
  538. info->screen_base = remapped_fbuf;
  539. info->screen_size = REMAPPED_FB_LEN;
  540. info->var.xres = 640;
  541. info->var.xres_virtual = info->var.xres;
  542. info->var.yres = 480;
  543. info->var.yres_virtual = info->var.yres;
  544. info->var.pixclock = 0x04; /* 171521; */
  545. info->var.sync = 0;
  546. info->var.grayscale = 0;
  547. info->var.xoffset = info->var.yoffset = 0;
  548. info->var.accel_flags = 0;
  549. info->var.activate = FB_ACTIVATE_NOW;
  550. strcpy(info->fix.id, "w100fb");
  551. info->fix.type = FB_TYPE_PACKED_PIXELS;
  552. info->fix.type_aux = 0;
  553. info->fix.accel = FB_ACCEL_NONE;
  554. info->fix.smem_start = mem->start+MEM_EXT_BASE_VALUE;
  555. info->fix.mmio_start = mem->start+W100_REG_BASE;
  556. info->fix.mmio_len = W100_REG_LEN;
  557. w100fb_check_var(&info->var, info);
  558. w100fb_set_par(info);
  559. if (register_framebuffer(info) < 0) {
  560. kfree(info->pseudo_palette);
  561. iounmap(remapped_base);
  562. iounmap(remapped_regs);
  563. iounmap(remapped_fbuf);
  564. return -EINVAL;
  565. }
  566. device_create_file(dev, &dev_attr_fastsysclk);
  567. device_create_file(dev, &dev_attr_reg_read);
  568. device_create_file(dev, &dev_attr_reg_write);
  569. device_create_file(dev, &dev_attr_rotation);
  570. printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
  571. return 0;
  572. }
  573. static int w100fb_remove(struct device *dev)
  574. {
  575. struct fb_info *info = dev_get_drvdata(dev);
  576. device_remove_file(dev, &dev_attr_fastsysclk);
  577. device_remove_file(dev, &dev_attr_reg_read);
  578. device_remove_file(dev, &dev_attr_reg_write);
  579. device_remove_file(dev, &dev_attr_rotation);
  580. unregister_framebuffer(info);
  581. w100fb_clear_buffer();
  582. kfree(info->pseudo_palette);
  583. iounmap(remapped_base);
  584. iounmap(remapped_regs);
  585. iounmap(remapped_fbuf);
  586. framebuffer_release(info);
  587. return 0;
  588. }
  589. /* ------------------- chipset specific functions -------------------------- */
  590. static void w100_soft_reset(void)
  591. {
  592. u16 val = readw((u16 *) remapped_base + cfgSTATUS);
  593. writew(val | 0x08, (u16 *) remapped_base + cfgSTATUS);
  594. udelay(100);
  595. writew(0x00, (u16 *) remapped_base + cfgSTATUS);
  596. udelay(100);
  597. }
  598. /*
  599. * Initialization of critical w100 hardware
  600. */
  601. static void w100_hw_init(void)
  602. {
  603. u32 temp32;
  604. union cif_cntl_u cif_cntl;
  605. union intf_cntl_u intf_cntl;
  606. union cfgreg_base_u cfgreg_base;
  607. union wrap_top_dir_u wrap_top_dir;
  608. union cif_read_dbg_u cif_read_dbg;
  609. union cpu_defaults_u cpu_default;
  610. union cif_write_dbg_u cif_write_dbg;
  611. union wrap_start_dir_u wrap_start_dir;
  612. union mc_ext_mem_location_u mc_ext_mem_loc;
  613. union cif_io_u cif_io;
  614. w100_soft_reset();
  615. /* This is what the fpga_init code does on reset. May be wrong
  616. but there is little info available */
  617. writel(0x31, remapped_regs + mmSCRATCH_UMSK);
  618. for (temp32 = 0; temp32 < 10000; temp32++)
  619. readl(remapped_regs + mmSCRATCH_UMSK);
  620. writel(0x30, remapped_regs + mmSCRATCH_UMSK);
  621. /* Set up CIF */
  622. cif_io.val = defCIF_IO;
  623. writel((u32)(cif_io.val), remapped_regs + mmCIF_IO);
  624. cif_write_dbg.val = readl(remapped_regs + mmCIF_WRITE_DBG);
  625. cif_write_dbg.f.dis_packer_ful_during_rbbm_timeout = 0;
  626. cif_write_dbg.f.en_dword_split_to_rbbm = 1;
  627. cif_write_dbg.f.dis_timeout_during_rbbm = 1;
  628. writel((u32) (cif_write_dbg.val), remapped_regs + mmCIF_WRITE_DBG);
  629. cif_read_dbg.val = readl(remapped_regs + mmCIF_READ_DBG);
  630. cif_read_dbg.f.dis_rd_same_byte_to_trig_fetch = 1;
  631. writel((u32) (cif_read_dbg.val), remapped_regs + mmCIF_READ_DBG);
  632. cif_cntl.val = readl(remapped_regs + mmCIF_CNTL);
  633. cif_cntl.f.dis_system_bits = 1;
  634. cif_cntl.f.dis_mr = 1;
  635. cif_cntl.f.en_wait_to_compensate_dq_prop_dly = 0;
  636. cif_cntl.f.intb_oe = 1;
  637. cif_cntl.f.interrupt_active_high = 1;
  638. writel((u32) (cif_cntl.val), remapped_regs + mmCIF_CNTL);
  639. /* Setup cfgINTF_CNTL and cfgCPU defaults */
  640. intf_cntl.val = defINTF_CNTL;
  641. intf_cntl.f.ad_inc_a = 1;
  642. intf_cntl.f.ad_inc_b = 1;
  643. intf_cntl.f.rd_data_rdy_a = 0;
  644. intf_cntl.f.rd_data_rdy_b = 0;
  645. writeb((u8) (intf_cntl.val), remapped_base + cfgINTF_CNTL);
  646. cpu_default.val = defCPU_DEFAULTS;
  647. cpu_default.f.access_ind_addr_a = 1;
  648. cpu_default.f.access_ind_addr_b = 1;
  649. cpu_default.f.access_scratch_reg = 1;
  650. cpu_default.f.transition_size = 0;
  651. writeb((u8) (cpu_default.val), remapped_base + cfgCPU_DEFAULTS);
  652. /* set up the apertures */
  653. writeb((u8) (W100_REG_BASE >> 16), remapped_base + cfgREG_BASE);
  654. cfgreg_base.val = defCFGREG_BASE;
  655. cfgreg_base.f.cfgreg_base = W100_CFG_BASE;
  656. writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE);
  657. /* This location is relative to internal w100 addresses */
  658. writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
  659. mc_ext_mem_loc.val = defMC_EXT_MEM_LOCATION;
  660. mc_ext_mem_loc.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8;
  661. mc_ext_mem_loc.f.mc_ext_mem_top = MEM_EXT_TOP_VALUE >> 8;
  662. writel((u32) (mc_ext_mem_loc.val), remapped_regs + mmMC_EXT_MEM_LOCATION);
  663. if ((current_par->lcdMode == LCD_MODE_240) || (current_par->lcdMode == LCD_MODE_320))
  664. w100_InitExtMem(LCD_SHARP_QVGA);
  665. else
  666. w100_InitExtMem(LCD_SHARP_VGA);
  667. wrap_start_dir.val = defWRAP_START_DIR;
  668. wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1;
  669. writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR);
  670. wrap_top_dir.val = defWRAP_TOP_DIR;
  671. wrap_top_dir.f.top_addr = WRAP_BUF_TOP_VALUE >> 1;
  672. writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR);
  673. writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL);
  674. }
  675. /*
  676. * Types
  677. */
  678. struct pll_parm {
  679. u16 freq; /* desired Fout for PLL */
  680. u8 M;
  681. u8 N_int;
  682. u8 N_fac;
  683. u8 tfgoal;
  684. u8 lock_time;
  685. };
  686. struct power_state {
  687. union clk_pin_cntl_u clk_pin_cntl;
  688. union pll_ref_fb_div_u pll_ref_fb_div;
  689. union pll_cntl_u pll_cntl;
  690. union sclk_cntl_u sclk_cntl;
  691. union pclk_cntl_u pclk_cntl;
  692. union clk_test_cntl_u clk_test_cntl;
  693. union pwrmgt_cntl_u pwrmgt_cntl;
  694. u32 freq; /* Fout for PLL calibration */
  695. u8 tf100; /* for pll calibration */
  696. u8 tf80; /* for pll calibration */
  697. u8 tf20; /* for pll calibration */
  698. u8 M; /* for pll calibration */
  699. u8 N_int; /* for pll calibration */
  700. u8 N_fac; /* for pll calibration */
  701. u8 lock_time; /* for pll calibration */
  702. u8 tfgoal; /* for pll calibration */
  703. u8 auto_mode; /* hardware auto switch? */
  704. u8 pwm_mode; /* 0 fast, 1 normal/slow */
  705. u16 fast_sclk; /* fast clk freq */
  706. u16 norm_sclk; /* slow clk freq */
  707. };
  708. /*
  709. * Global state variables
  710. */
  711. static struct power_state w100_pwr_state;
  712. /* This table is specific for 12.5MHz ref crystal. */
  713. static struct pll_parm gPLLTable[] = {
  714. /*freq M N_int N_fac tfgoal lock_time */
  715. { 50, 0, 1, 0, 0xE0, 56}, /* 50.00 MHz */
  716. { 75, 0, 5, 0, 0xDE, 37}, /* 75.00 MHz */
  717. {100, 0, 7, 0, 0xE0, 28}, /* 100.00 MHz */
  718. {125, 0, 9, 0, 0xE0, 22}, /* 125.00 MHz */
  719. {150, 0, 11, 0, 0xE0, 17}, /* 150.00 MHz */
  720. { 0, 0, 0, 0, 0, 0} /* Terminator */
  721. };
  722. static u8 w100_pll_get_testcount(u8 testclk_sel)
  723. {
  724. udelay(5);
  725. w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
  726. w100_pwr_state.clk_test_cntl.f.testclk_sel = testclk_sel;
  727. w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x1; /*reset test count */
  728. writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
  729. w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
  730. writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
  731. w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x1;
  732. writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
  733. udelay(20);
  734. w100_pwr_state.clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL);
  735. w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
  736. writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
  737. return w100_pwr_state.clk_test_cntl.f.test_count;
  738. }
  739. static u8 w100_pll_adjust(void)
  740. {
  741. do {
  742. /* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V
  743. * therefore, commented out the following lines
  744. * tf80 meant tf100
  745. * set VCO input = 0.8 * VDD
  746. */
  747. w100_pwr_state.pll_cntl.f.pll_dactal = 0xd;
  748. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  749. w100_pwr_state.tf80 = w100_pll_get_testcount(0x1); /* PLLCLK */
  750. if (w100_pwr_state.tf80 >= (w100_pwr_state.tfgoal)) {
  751. /* set VCO input = 0.2 * VDD */
  752. w100_pwr_state.pll_cntl.f.pll_dactal = 0x7;
  753. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  754. w100_pwr_state.tf20 = w100_pll_get_testcount(0x1); /* PLLCLK */
  755. if (w100_pwr_state.tf20 <= (w100_pwr_state.tfgoal))
  756. return 1; // Success
  757. if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) &&
  758. ((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) ||
  759. (w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) {
  760. /* slow VCO config */
  761. w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1;
  762. w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
  763. w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
  764. writel((u32) (w100_pwr_state.pll_cntl.val),
  765. remapped_regs + mmPLL_CNTL);
  766. continue;
  767. }
  768. }
  769. if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) {
  770. w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1;
  771. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  772. continue;
  773. }
  774. if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) {
  775. w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
  776. w100_pwr_state.pll_cntl.f.pll_pvg += 0x1;
  777. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  778. continue;
  779. }
  780. return 0; // error
  781. } while(1);
  782. }
  783. /*
  784. * w100_pll_calibration
  785. * freq = target frequency of the PLL
  786. * (note: crystal = 14.3MHz)
  787. */
  788. static u8 w100_pll_calibration(u32 freq)
  789. {
  790. u8 status;
  791. /* initial setting */
  792. w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0; /* power down */
  793. w100_pwr_state.pll_cntl.f.pll_reset = 0x0; /* not reset */
  794. w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1; /* Hi-Z */
  795. w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; /* VCO gain = 0 */
  796. w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0; /* VCO frequency range control = off */
  797. w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; /* current offset inside VCO = 0 */
  798. w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
  799. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  800. /* check for (tf80 >= tfgoal) && (tf20 =< tfgoal) */
  801. if ((w100_pwr_state.tf80 < w100_pwr_state.tfgoal) || (w100_pwr_state.tf20 > w100_pwr_state.tfgoal)) {
  802. status=w100_pll_adjust();
  803. }
  804. /* PLL Reset And Lock */
  805. /* set VCO input = 0.5 * VDD */
  806. w100_pwr_state.pll_cntl.f.pll_dactal = 0xa;
  807. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  808. /* reset time */
  809. udelay(1);
  810. /* enable charge pump */
  811. w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; /* normal */
  812. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  813. /* set VCO input = Hi-Z */
  814. /* disable DAC */
  815. w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;
  816. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  817. /* lock time */
  818. udelay(400); /* delay 400 us */
  819. /* PLL locked */
  820. w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x1; /* PLL clock */
  821. writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
  822. w100_pwr_state.tf100 = w100_pll_get_testcount(0x1); /* PLLCLK */
  823. return status;
  824. }
  825. static u8 w100_pll_set_clk(void)
  826. {
  827. u8 status;
  828. if (w100_pwr_state.auto_mode == 1) /* auto mode */
  829. {
  830. w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; /* disable fast to normal */
  831. w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; /* disable normal to fast */
  832. writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
  833. }
  834. w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* crystal clock */
  835. writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
  836. w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = w100_pwr_state.M;
  837. w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = w100_pwr_state.N_int;
  838. w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = w100_pwr_state.N_fac;
  839. w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = w100_pwr_state.lock_time;
  840. writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
  841. w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0;
  842. writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
  843. status = w100_pll_calibration (w100_pwr_state.freq);
  844. if (w100_pwr_state.auto_mode == 1) /* auto mode */
  845. {
  846. w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1; /* reenable fast to normal */
  847. w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1; /* reenable normal to fast */
  848. writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
  849. }
  850. return status;
  851. }
  852. /* assume reference crystal clk is 12.5MHz,
  853. * and that doubling is not enabled.
  854. *
  855. * Freq = 12 == 12.5MHz.
  856. */
  857. static u16 w100_set_slowsysclk(u16 freq)
  858. {
  859. if (w100_pwr_state.norm_sclk == freq)
  860. return freq;
  861. if (w100_pwr_state.auto_mode == 1) /* auto mode */
  862. return 0;
  863. if (freq == 12) {
  864. w100_pwr_state.norm_sclk = freq;
  865. w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */
  866. w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* crystal src */
  867. writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
  868. w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x1;
  869. writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
  870. w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x1;
  871. w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1;
  872. writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
  873. w100_pwr_state.pwm_mode = 1; /* normal mode */
  874. return freq;
  875. } else
  876. return 0;
  877. }
  878. static u16 w100_set_fastsysclk(u16 freq)
  879. {
  880. u16 pll_freq;
  881. int i;
  882. while(1) {
  883. pll_freq = (u16) (freq * (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast + 1));
  884. i = 0;
  885. do {
  886. if (pll_freq == gPLLTable[i].freq) {
  887. w100_pwr_state.freq = gPLLTable[i].freq * 1000000;
  888. w100_pwr_state.M = gPLLTable[i].M;
  889. w100_pwr_state.N_int = gPLLTable[i].N_int;
  890. w100_pwr_state.N_fac = gPLLTable[i].N_fac;
  891. w100_pwr_state.tfgoal = gPLLTable[i].tfgoal;
  892. w100_pwr_state.lock_time = gPLLTable[i].lock_time;
  893. w100_pwr_state.tf20 = 0xff; /* set highest */
  894. w100_pwr_state.tf80 = 0x00; /* set lowest */
  895. w100_pll_set_clk();
  896. w100_pwr_state.pwm_mode = 0; /* fast mode */
  897. w100_pwr_state.fast_sclk = freq;
  898. return freq;
  899. }
  900. i++;
  901. } while(gPLLTable[i].freq);
  902. if (w100_pwr_state.auto_mode == 1)
  903. break;
  904. if (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast == 0)
  905. break;
  906. w100_pwr_state.sclk_cntl.f.sclk_post_div_fast -= 1;
  907. writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
  908. }
  909. return 0;
  910. }
  911. /* Set up an initial state. Some values/fields set
  912. here will be overwritten. */
  913. static void w100_pwm_setup(void)
  914. {
  915. w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1;
  916. w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f;
  917. w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0;
  918. w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0;
  919. w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = 0x0; /* no freq doubling */
  920. w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0;
  921. writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
  922. w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* Crystal Clk */
  923. w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0; /* Pfast = 1 */
  924. w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3;
  925. w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */
  926. w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0;
  927. w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0; /* Dynamic */
  928. w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0; /* Dynamic */
  929. w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0; /* Dynamic */
  930. w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0; /* Dynamic */
  931. w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0; /* Dynamic */
  932. w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0; /* Dynamic */
  933. w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0; /* Dynamic */
  934. w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0; /* Dynamic */
  935. w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0; /* Dynamic */
  936. w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0;
  937. w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0;
  938. w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0;
  939. w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0;
  940. writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
  941. w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x0; /* Crystal Clk */
  942. w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1; /* P = 2 */
  943. w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0; /* Dynamic */
  944. writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
  945. w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0; /* M = 1 */
  946. w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0; /* N = 1.0 */
  947. w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0;
  948. w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5;
  949. w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff;
  950. writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
  951. w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1;
  952. w100_pwr_state.pll_cntl.f.pll_reset = 0x1;
  953. w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0;
  954. w100_pwr_state.pll_cntl.f.pll_mode = 0x0; /* uses VCO clock */
  955. w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0;
  956. w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0;
  957. w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;
  958. w100_pwr_state.pll_cntl.f.pll_pcp = 0x4;
  959. w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
  960. w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;
  961. w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
  962. w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0;
  963. w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0;
  964. w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; /* Hi-Z */
  965. w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3;
  966. w100_pwr_state.pll_cntl.f.pll_conf = 0x2;
  967. w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2;
  968. w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
  969. writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
  970. w100_pwr_state.clk_test_cntl.f.testclk_sel = 0x1; /* PLLCLK (for testing) */
  971. w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
  972. w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
  973. writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
  974. w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0;
  975. w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1; /* normal mode (0, 1, 3) */
  976. w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0;
  977. w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;
  978. w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;
  979. w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1; /* PM4,ENG */
  980. w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1; /* PM4,ENG */
  981. w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF;
  982. w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF;
  983. writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
  984. w100_pwr_state.auto_mode = 0; /* manual mode */
  985. w100_pwr_state.pwm_mode = 1; /* normal mode (0, 1, 2) */
  986. w100_pwr_state.freq = 50000000; /* 50 MHz */
  987. w100_pwr_state.M = 3; /* M = 4 */
  988. w100_pwr_state.N_int = 6; /* N = 7.0 */
  989. w100_pwr_state.N_fac = 0;
  990. w100_pwr_state.tfgoal = 0xE0;
  991. w100_pwr_state.lock_time = 56;
  992. w100_pwr_state.tf20 = 0xff; /* set highest */
  993. w100_pwr_state.tf80 = 0x00; /* set lowest */
  994. w100_pwr_state.tf100 = 0x00; /* set lowest */
  995. w100_pwr_state.fast_sclk = 50; /* 50.0 MHz */
  996. w100_pwr_state.norm_sclk = 12; /* 12.5 MHz */
  997. }
  998. static void w100_init_sharp_lcd(u32 mode)
  999. {
  1000. u32 temp32;
  1001. union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl;
  1002. /* Prevent display updates */
  1003. disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
  1004. disp_db_buf_wr_cntl.f.update_db_buf = 0;
  1005. disp_db_buf_wr_cntl.f.en_db_buf = 0;
  1006. writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
  1007. switch(mode) {
  1008. case LCD_SHARP_QVGA:
  1009. w100_set_slowsysclk(12); /* use crystal -- 12.5MHz */
  1010. /* not use PLL */
  1011. writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
  1012. writel(0x85FF8000, remapped_regs + mmMC_FB_LOCATION);
  1013. writel(0x00000003, remapped_regs + mmLCD_FORMAT);
  1014. writel(0x00CF1C06, remapped_regs + mmGRAPHIC_CTRL);
  1015. writel(0x01410145, remapped_regs + mmCRTC_TOTAL);
  1016. writel(0x01170027, remapped_regs + mmACTIVE_H_DISP);
  1017. writel(0x01410001, remapped_regs + mmACTIVE_V_DISP);
  1018. writel(0x01170027, remapped_regs + mmGRAPHIC_H_DISP);
  1019. writel(0x01410001, remapped_regs + mmGRAPHIC_V_DISP);
  1020. writel(0x81170027, remapped_regs + mmCRTC_SS);
  1021. writel(0xA0140000, remapped_regs + mmCRTC_LS);
  1022. writel(0x00400008, remapped_regs + mmCRTC_REV);
  1023. writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
  1024. writel(0xC0140014, remapped_regs + mmCRTC_GS);
  1025. writel(0x00010141, remapped_regs + mmCRTC_VPOS_GS);
  1026. writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
  1027. writel(0x80100110, remapped_regs + mmCRTC_GOE);
  1028. writel(0x00000000, remapped_regs + mmCRTC_FRAME);
  1029. writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
  1030. writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
  1031. writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
  1032. writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
  1033. writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
  1034. writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
  1035. writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
  1036. writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
  1037. writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
  1038. writel(0x000001e0, remapped_regs + mmGRAPHIC_PITCH);
  1039. writel(0x000000bf, remapped_regs + mmGPIO_DATA);
  1040. writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
  1041. writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
  1042. writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
  1043. break;
  1044. case LCD_SHARP_VGA:
  1045. w100_set_slowsysclk(12); /* use crystal -- 12.5MHz */
  1046. w100_set_fastsysclk(current_par->fastsysclk_mode); /* use PLL -- 75.0MHz */
  1047. w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
  1048. w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x2;
  1049. writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
  1050. writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
  1051. writel(0x9FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
  1052. writel(0x00000003, remapped_regs + mmLCD_FORMAT);
  1053. writel(0x00DE1D66, remapped_regs + mmGRAPHIC_CTRL);
  1054. writel(0x0283028B, remapped_regs + mmCRTC_TOTAL);
  1055. writel(0x02360056, remapped_regs + mmACTIVE_H_DISP);
  1056. writel(0x02830003, remapped_regs + mmACTIVE_V_DISP);
  1057. writel(0x02360056, remapped_regs + mmGRAPHIC_H_DISP);
  1058. writel(0x02830003, remapped_regs + mmGRAPHIC_V_DISP);
  1059. writel(0x82360056, remapped_regs + mmCRTC_SS);
  1060. writel(0xA0280000, remapped_regs + mmCRTC_LS);
  1061. writel(0x00400008, remapped_regs + mmCRTC_REV);
  1062. writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
  1063. writel(0x80280028, remapped_regs + mmCRTC_GS);
  1064. writel(0x02830002, remapped_regs + mmCRTC_VPOS_GS);
  1065. writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
  1066. writel(0x80100110, remapped_regs + mmCRTC_GOE);
  1067. writel(0x00000000, remapped_regs + mmCRTC_FRAME);
  1068. writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
  1069. writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
  1070. writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
  1071. writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
  1072. writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
  1073. writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
  1074. writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
  1075. writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
  1076. writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
  1077. writel(0x000003C0, remapped_regs + mmGRAPHIC_PITCH);
  1078. writel(0x000000bf, remapped_regs + mmGPIO_DATA);
  1079. writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
  1080. writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
  1081. writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
  1082. break;
  1083. default:
  1084. break;
  1085. }
  1086. /* Hack for overlay in ext memory */
  1087. temp32 = readl(remapped_regs + mmDISP_DEBUG2);
  1088. temp32 |= 0xc0000000;
  1089. writel(temp32, remapped_regs + mmDISP_DEBUG2);
  1090. /* Re-enable display updates */
  1091. disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
  1092. disp_db_buf_wr_cntl.f.update_db_buf = 1;
  1093. disp_db_buf_wr_cntl.f.en_db_buf = 1;
  1094. writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
  1095. }
  1096. static void w100_set_vga_rotation_regs(u16 divider, unsigned long ctrl, unsigned long offset, unsigned long pitch)
  1097. {
  1098. w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
  1099. w100_pwr_state.pclk_cntl.f.pclk_post_div = divider;
  1100. writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
  1101. writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
  1102. writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
  1103. writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
  1104. /* Re-enable display updates */
  1105. writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
  1106. }
  1107. static void w100_init_vga_rotation(u16 deg)
  1108. {
  1109. switch(deg) {
  1110. case 0:
  1111. w100_set_vga_rotation_regs(0x02, 0x00DE1D66, 0x00800000, 0x000003c0);
  1112. break;
  1113. case 90:
  1114. w100_set_vga_rotation_regs(0x06, 0x00DE1D0e, 0x00895b00, 0x00000500);
  1115. break;
  1116. case 180:
  1117. w100_set_vga_rotation_regs(0x02, 0x00DE1D7e, 0x00895ffc, 0x000003c0);
  1118. break;
  1119. case 270:
  1120. w100_set_vga_rotation_regs(0x06, 0x00DE1D16, 0x008004fc, 0x00000500);
  1121. break;
  1122. default:
  1123. /* not-support */
  1124. break;
  1125. }
  1126. }
  1127. static void w100_set_qvga_rotation_regs(unsigned long ctrl, unsigned long offset, unsigned long pitch)
  1128. {
  1129. writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
  1130. writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
  1131. writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
  1132. /* Re-enable display updates */
  1133. writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
  1134. }
  1135. static void w100_init_qvga_rotation(u16 deg)
  1136. {
  1137. switch(deg) {
  1138. case 0:
  1139. w100_set_qvga_rotation_regs(0x00d41c06, 0x00800000, 0x000001e0);
  1140. break;
  1141. case 90:
  1142. w100_set_qvga_rotation_regs(0x00d41c0E, 0x00825580, 0x00000280);
  1143. break;
  1144. case 180:
  1145. w100_set_qvga_rotation_regs(0x00d41c1e, 0x008257fc, 0x000001e0);
  1146. break;
  1147. case 270:
  1148. w100_set_qvga_rotation_regs(0x00d41c16, 0x0080027c, 0x00000280);
  1149. break;
  1150. default:
  1151. /* not-support */
  1152. break;
  1153. }
  1154. }
  1155. static void w100_suspend(u32 mode)
  1156. {
  1157. u32 val;
  1158. writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
  1159. writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL);
  1160. val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL);
  1161. val &= ~(0x00100000); /* bit20=0 */
  1162. val |= 0xFF000000; /* bit31:24=0xff */
  1163. writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL);
  1164. val = readl(remapped_regs + mmMEM_EXT_CNTL);
  1165. val &= ~(0x00040000); /* bit18=0 */
  1166. val |= 0x00080000; /* bit19=1 */
  1167. writel(val, remapped_regs + mmMEM_EXT_CNTL);
  1168. udelay(1); /* wait 1us */
  1169. if (mode == W100_SUSPEND_EXTMEM) {
  1170. /* CKE: Tri-State */
  1171. val = readl(remapped_regs + mmMEM_EXT_CNTL);
  1172. val |= 0x40000000; /* bit30=1 */
  1173. writel(val, remapped_regs + mmMEM_EXT_CNTL);
  1174. /* CLK: Stop */
  1175. val = readl(remapped_regs + mmMEM_EXT_CNTL);
  1176. val &= ~(0x00000001); /* bit0=0 */
  1177. writel(val, remapped_regs + mmMEM_EXT_CNTL);
  1178. } else {
  1179. writel(0x00000000, remapped_regs + mmSCLK_CNTL);
  1180. writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL);
  1181. writel(0x00000015, remapped_regs + mmPWRMGT_CNTL);
  1182. udelay(5);
  1183. val = readl(remapped_regs + mmPLL_CNTL);
  1184. val |= 0x00000004; /* bit2=1 */
  1185. writel(val, remapped_regs + mmPLL_CNTL);
  1186. writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL);
  1187. }
  1188. }
  1189. static void w100_resume(void)
  1190. {
  1191. u32 temp32;
  1192. w100_hw_init();
  1193. w100_pwm_setup();
  1194. temp32 = readl(remapped_regs + mmDISP_DEBUG2);
  1195. temp32 &= 0xff7fffff;
  1196. temp32 |= 0x00800000;
  1197. writel(temp32, remapped_regs + mmDISP_DEBUG2);
  1198. if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
  1199. w100_init_sharp_lcd(LCD_SHARP_VGA);
  1200. if (current_par->lcdMode == LCD_MODE_640) {
  1201. w100_init_vga_rotation(current_par->rotation_flag ? 270 : 90);
  1202. }
  1203. } else {
  1204. w100_init_sharp_lcd(LCD_SHARP_QVGA);
  1205. if (current_par->lcdMode == LCD_MODE_320) {
  1206. w100_init_qvga_rotation(current_par->rotation_flag ? 270 : 90);
  1207. }
  1208. }
  1209. }
  1210. static void w100_vsync(void)
  1211. {
  1212. u32 tmp;
  1213. int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */
  1214. tmp = readl(remapped_regs + mmACTIVE_V_DISP);
  1215. /* set vline pos */
  1216. writel((tmp >> 16) & 0x3ff, remapped_regs + mmDISP_INT_CNTL);
  1217. /* disable vline irq */
  1218. tmp = readl(remapped_regs + mmGEN_INT_CNTL);
  1219. tmp &= ~0x00000002;
  1220. writel(tmp, remapped_regs + mmGEN_INT_CNTL);
  1221. /* clear vline irq status */
  1222. writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
  1223. /* enable vline irq */
  1224. writel((tmp | 0x00000002), remapped_regs + mmGEN_INT_CNTL);
  1225. /* clear vline irq status */
  1226. writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
  1227. while(timeout > 0) {
  1228. if (readl(remapped_regs + mmGEN_INT_STATUS) & 0x00000002)
  1229. break;
  1230. udelay(1);
  1231. timeout--;
  1232. }
  1233. /* disable vline irq */
  1234. writel(tmp, remapped_regs + mmGEN_INT_CNTL);
  1235. /* clear vline irq status */
  1236. writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
  1237. }
  1238. static void w100_InitExtMem(u32 mode)
  1239. {
  1240. switch(mode) {
  1241. case LCD_SHARP_QVGA:
  1242. /* QVGA doesn't use external memory
  1243. nothing to do, really. */
  1244. break;
  1245. case LCD_SHARP_VGA:
  1246. writel(0x00007800, remapped_regs + mmMC_BIST_CTRL);
  1247. writel(0x00040003, remapped_regs + mmMEM_EXT_CNTL);
  1248. writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
  1249. udelay(100);
  1250. writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
  1251. udelay(100);
  1252. writel(0x00650021, remapped_regs + mmMEM_SDRAM_MODE_REG);
  1253. udelay(100);
  1254. writel(0x10002a4a, remapped_regs + mmMEM_EXT_TIMING_CNTL);
  1255. writel(0x7ff87012, remapped_regs + mmMEM_IO_CNTL);
  1256. break;
  1257. default:
  1258. break;
  1259. }
  1260. }
  1261. #define RESCTL_ADRS 0x00
  1262. #define PHACTRL_ADRS 0x01
  1263. #define DUTYCTRL_ADRS 0x02
  1264. #define POWERREG0_ADRS 0x03
  1265. #define POWERREG1_ADRS 0x04
  1266. #define GPOR3_ADRS 0x05
  1267. #define PICTRL_ADRS 0x06
  1268. #define POLCTRL_ADRS 0x07
  1269. #define RESCTL_QVGA 0x01
  1270. #define RESCTL_VGA 0x00
  1271. #define POWER1_VW_ON 0x01 /* VW Supply FET ON */
  1272. #define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */
  1273. #define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */
  1274. #define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */
  1275. #define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */
  1276. #define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */
  1277. #define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */
  1278. #define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */
  1279. #define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */
  1280. #define POWER0_COM_ON 0x08 /* COM Powewr Supply ON */
  1281. #define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */
  1282. #define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */
  1283. #define POWER0_COM_OFF 0x00 /* COM Powewr Supply OFF */
  1284. #define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */
  1285. #define PICTRL_INIT_STATE 0x01
  1286. #define PICTRL_INIOFF 0x02
  1287. #define PICTRL_POWER_DOWN 0x04
  1288. #define PICTRL_COM_SIGNAL_OFF 0x08
  1289. #define PICTRL_DAC_SIGNAL_OFF 0x10
  1290. #define PICTRL_POWER_ACTIVE (0)
  1291. #define POLCTRL_SYNC_POL_FALL 0x01
  1292. #define POLCTRL_EN_POL_FALL 0x02
  1293. #define POLCTRL_DATA_POL_FALL 0x04
  1294. #define POLCTRL_SYNC_ACT_H 0x08
  1295. #define POLCTRL_EN_ACT_L 0x10
  1296. #define POLCTRL_SYNC_POL_RISE 0x00
  1297. #define POLCTRL_EN_POL_RISE 0x00
  1298. #define POLCTRL_DATA_POL_RISE 0x00
  1299. #define POLCTRL_SYNC_ACT_L 0x00
  1300. #define POLCTRL_EN_ACT_H 0x00
  1301. #define PHACTRL_PHASE_MANUAL 0x01
  1302. #define PHAD_QVGA_DEFAULT_VAL (9)
  1303. #define COMADJ_DEFAULT (125)
  1304. static void lcdtg_ssp_send(u8 adrs, u8 data)
  1305. {
  1306. w100fb_ssp_send(adrs,data);
  1307. }
  1308. /*
  1309. * This is only a psuedo I2C interface. We can't use the standard kernel
  1310. * routines as the interface is write only. We just assume the data is acked...
  1311. */
  1312. static void lcdtg_ssp_i2c_send(u8 data)
  1313. {
  1314. lcdtg_ssp_send(POWERREG0_ADRS, data);
  1315. udelay(10);
  1316. }
  1317. static void lcdtg_i2c_send_bit(u8 data)
  1318. {
  1319. lcdtg_ssp_i2c_send(data);
  1320. lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
  1321. lcdtg_ssp_i2c_send(data);
  1322. }
  1323. static void lcdtg_i2c_send_start(u8 base)
  1324. {
  1325. lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
  1326. lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
  1327. lcdtg_ssp_i2c_send(base);
  1328. }
  1329. static void lcdtg_i2c_send_stop(u8 base)
  1330. {
  1331. lcdtg_ssp_i2c_send(base);
  1332. lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
  1333. lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
  1334. }
  1335. static void lcdtg_i2c_send_byte(u8 base, u8 data)
  1336. {
  1337. int i;
  1338. for (i = 0; i < 8; i++) {
  1339. if (data & 0x80)
  1340. lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
  1341. else
  1342. lcdtg_i2c_send_bit(base);
  1343. data <<= 1;
  1344. }
  1345. }
  1346. static void lcdtg_i2c_wait_ack(u8 base)
  1347. {
  1348. lcdtg_i2c_send_bit(base);
  1349. }
  1350. static void lcdtg_set_common_voltage(u8 base_data, u8 data)
  1351. {
  1352. /* Set Common Voltage to M62332FP via I2C */
  1353. lcdtg_i2c_send_start(base_data);
  1354. lcdtg_i2c_send_byte(base_data, 0x9c);
  1355. lcdtg_i2c_wait_ack(base_data);
  1356. lcdtg_i2c_send_byte(base_data, 0x00);
  1357. lcdtg_i2c_wait_ack(base_data);
  1358. lcdtg_i2c_send_byte(base_data, data);
  1359. lcdtg_i2c_wait_ack(base_data);
  1360. lcdtg_i2c_send_stop(base_data);
  1361. }
  1362. static struct lcdtg_register_setting {
  1363. u8 adrs;
  1364. u8 data;
  1365. u32 wait;
  1366. } lcdtg_power_on_table[] = {
  1367. /* Initialize Internal Logic & Port */
  1368. { PICTRL_ADRS,
  1369. PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE |
  1370. PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF,
  1371. 0 },
  1372. { POWERREG0_ADRS,
  1373. POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF | POWER0_COM_OFF |
  1374. POWER0_VCC5_OFF,
  1375. 0 },
  1376. { POWERREG1_ADRS,
  1377. POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF,
  1378. 0 },
  1379. /* VDD(+8V),SVSS(-4V) ON */
  1380. { POWERREG1_ADRS,
  1381. POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON /* VDD ON */,
  1382. 3000 },
  1383. /* DAC ON */
  1384. { POWERREG0_ADRS,
  1385. POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
  1386. POWER0_COM_OFF | POWER0_VCC5_OFF,
  1387. 0 },
  1388. /* INIB = H, INI = L */
  1389. { PICTRL_ADRS,
  1390. /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
  1391. PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF,
  1392. 0 },
  1393. /* Set Common Voltage */
  1394. { 0xfe, 0, 0 },
  1395. /* VCC5 ON */
  1396. { POWERREG0_ADRS,
  1397. POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
  1398. POWER0_COM_OFF | POWER0_VCC5_ON /* VCC5 ON */,
  1399. 0 },
  1400. /* GVSS(-8V) ON */
  1401. { POWERREG1_ADRS,
  1402. POWER1_VW_OFF | POWER1_GVSS_ON /* GVSS ON */ |
  1403. POWER1_VDD_ON /* VDD ON */,
  1404. 2000 },
  1405. /* COM SIGNAL ON (PICTL[3] = L) */
  1406. { PICTRL_ADRS,
  1407. PICTRL_INIT_STATE,
  1408. 0 },
  1409. /* COM ON */
  1410. { POWERREG0_ADRS,
  1411. POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
  1412. POWER0_COM_ON /* COM ON */ | POWER0_VCC5_ON /* VCC5_ON */,
  1413. 0 },
  1414. /* VW ON */
  1415. { POWERREG1_ADRS,
  1416. POWER1_VW_ON /* VW ON */ | POWER1_GVSS_ON /* GVSS ON */ |
  1417. POWER1_VDD_ON /* VDD ON */,
  1418. 0 /* Wait 100ms */ },
  1419. /* Signals output enable */
  1420. { PICTRL_ADRS,
  1421. 0 /* Signals output enable */,
  1422. 0 },
  1423. { PHACTRL_ADRS,
  1424. PHACTRL_PHASE_MANUAL,
  1425. 0 },
  1426. /* Initialize for Input Signals from ATI */
  1427. { POLCTRL_ADRS,
  1428. POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE | POLCTRL_DATA_POL_RISE |
  1429. POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H,
  1430. 1000 /*100000*/ /* Wait 100ms */ },
  1431. /* end mark */
  1432. { 0xff, 0, 0 }
  1433. };
  1434. static void lcdtg_resume(void)
  1435. {
  1436. if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
  1437. lcdtg_hw_init(LCD_SHARP_VGA);
  1438. } else {
  1439. lcdtg_hw_init(LCD_SHARP_QVGA);
  1440. }
  1441. }
  1442. static void lcdtg_suspend(void)
  1443. {
  1444. int i;
  1445. for (i = 0; i < (current_par->xres * current_par->yres); i++) {
  1446. writew(0xffff, remapped_fbuf + (2*i));
  1447. }
  1448. /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
  1449. mdelay(34);
  1450. /* (1)VW OFF */
  1451. lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
  1452. /* (2)COM OFF */
  1453. lcdtg_ssp_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
  1454. lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
  1455. /* (3)Set Common Voltage Bias 0V */
  1456. lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
  1457. /* (4)GVSS OFF */
  1458. lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
  1459. /* (5)VCC5 OFF */
  1460. lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
  1461. /* (6)Set PDWN, INIOFF, DACOFF */
  1462. lcdtg_ssp_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
  1463. PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
  1464. /* (7)DAC OFF */
  1465. lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
  1466. /* (8)VDD OFF */
  1467. lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
  1468. }
  1469. static void lcdtg_set_phadadj(u32 mode)
  1470. {
  1471. int adj;
  1472. if (mode == LCD_SHARP_VGA) {
  1473. /* Setting for VGA */
  1474. adj = current_par->phadadj;
  1475. if (adj < 0) {
  1476. adj = PHACTRL_PHASE_MANUAL;
  1477. } else {
  1478. adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
  1479. }
  1480. } else {
  1481. /* Setting for QVGA */
  1482. adj = (PHAD_QVGA_DEFAULT_VAL << 1) | PHACTRL_PHASE_MANUAL;
  1483. }
  1484. lcdtg_ssp_send(PHACTRL_ADRS, adj);
  1485. }
  1486. static void lcdtg_hw_init(u32 mode)
  1487. {
  1488. int i;
  1489. int comadj;
  1490. i = 0;
  1491. while(lcdtg_power_on_table[i].adrs != 0xff) {
  1492. if (lcdtg_power_on_table[i].adrs == 0xfe) {
  1493. /* Set Common Voltage */
  1494. comadj = current_par->comadj;
  1495. if (comadj < 0) {
  1496. comadj = COMADJ_DEFAULT;
  1497. }
  1498. lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
  1499. } else if (lcdtg_power_on_table[i].adrs == PHACTRL_ADRS) {
  1500. /* Set Phase Adjuct */
  1501. lcdtg_set_phadadj(mode);
  1502. } else {
  1503. /* Other */
  1504. lcdtg_ssp_send(lcdtg_power_on_table[i].adrs, lcdtg_power_on_table[i].data);
  1505. }
  1506. if (lcdtg_power_on_table[i].wait != 0)
  1507. udelay(lcdtg_power_on_table[i].wait);
  1508. i++;
  1509. }
  1510. switch(mode) {
  1511. case LCD_SHARP_QVGA:
  1512. /* Set Lcd Resolution (QVGA) */
  1513. lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
  1514. break;
  1515. case LCD_SHARP_VGA:
  1516. /* Set Lcd Resolution (VGA) */
  1517. lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
  1518. break;
  1519. default:
  1520. break;
  1521. }
  1522. }
  1523. static void lcdtg_lcd_change(u32 mode)
  1524. {
  1525. /* Set Phase Adjuct */
  1526. lcdtg_set_phadadj(mode);
  1527. if (mode == LCD_SHARP_VGA)
  1528. /* Set Lcd Resolution (VGA) */
  1529. lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
  1530. else if (mode == LCD_SHARP_QVGA)
  1531. /* Set Lcd Resolution (QVGA) */
  1532. lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
  1533. }
  1534. static struct device_driver w100fb_driver = {
  1535. .name = "w100fb",
  1536. .bus = &platform_bus_type,
  1537. .probe = w100fb_probe,
  1538. .remove = w100fb_remove,
  1539. .suspend = w100fb_suspend,
  1540. .resume = w100fb_resume,
  1541. };
  1542. int __devinit w100fb_init(void)
  1543. {
  1544. return driver_register(&w100fb_driver);
  1545. }
  1546. void __exit w100fb_cleanup(void)
  1547. {
  1548. driver_unregister(&w100fb_driver);
  1549. }
  1550. module_init(w100fb_init);
  1551. module_exit(w100fb_cleanup);
  1552. MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver");
  1553. MODULE_LICENSE("GPLv2");