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