2 * linux/drivers/video/w100fb.c
4 * Frame Buffer Device for ATI Imageon w100 (Wallaby)
6 * Copyright (C) 2002, ATI Corp.
7 * Copyright (C) 2004-2005 Richard Purdie
9 * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net>
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.
17 #include <linux/delay.h>
19 #include <linux/init.h>
20 #include <linux/kernel.h>
22 #include <linux/device.h>
23 #include <linux/string.h>
24 #include <linux/proc_fs.h>
25 #include <linux/vmalloc.h>
27 #include <asm/uaccess.h>
28 #include <video/w100fb.h>
34 static void w100fb_save_buffer(void);
35 static void w100fb_clear_buffer(void);
36 static void w100fb_restore_buffer(void);
37 static void w100fb_clear_screen(u32 mode, long int offset);
38 static void w100_resume(void);
39 static void w100_suspend(u32 mode);
40 static void w100_init_qvga_rotation(u16 deg);
41 static void w100_init_vga_rotation(u16 deg);
42 static void w100_vsync(void);
43 static void w100_init_sharp_lcd(u32 mode);
44 static void w100_pwm_setup(void);
45 static void w100_InitExtMem(u32 mode);
46 static void w100_hw_init(void);
47 static u16 w100_set_fastsysclk(u16 Freq);
49 static void lcdtg_hw_init(u32 mode);
50 static void lcdtg_lcd_change(u32 mode);
51 static void lcdtg_resume(void);
52 static void lcdtg_suspend(void);
55 /* Register offsets & lengths */
56 #define REMAPPED_FB_LEN 0x15ffff
58 #define BITS_PER_PIXEL 16
60 /* Pseudo palette size */
61 #define MAX_PALETTES 16
63 /* for resolution change */
64 #define LCD_MODE_INIT (-1)
65 #define LCD_MODE_480 0
66 #define LCD_MODE_320 1
67 #define LCD_MODE_240 2
68 #define LCD_MODE_640 3
70 #define LCD_SHARP_QVGA 0
71 #define LCD_SHARP_VGA 1
73 #define LCD_MODE_PORTRAIT 0
74 #define LCD_MODE_LANDSCAPE 1
76 #define W100_SUSPEND_EXTMEM 0
77 #define W100_SUSPEND_ALL 1
79 /* General frame buffer data structures */
91 static struct w100fb_par *current_par;
93 static u16 *gSaveImagePtr = NULL;
95 /* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */
96 static void *remapped_base;
97 static void *remapped_regs;
98 static void *remapped_fbuf;
100 /* External Function */
101 static void(*w100fb_ssp_send)(u8 adrs, u8 data);
107 static ssize_t rotation_show(struct device *dev, char *buf)
109 struct fb_info *info = dev_get_drvdata(dev);
110 struct w100fb_par *par=info->par;
112 return sprintf(buf, "%d\n",par->rotation_flag);
115 static ssize_t rotation_store(struct device *dev, const char *buf, size_t count)
118 struct fb_info *info = dev_get_drvdata(dev);
119 struct w100fb_par *par=info->par;
121 rotate = simple_strtoul(buf, NULL, 10);
123 if (rotate > 0) par->rotation_flag = 1;
124 else par->rotation_flag = 0;
126 if (par->lcdMode == LCD_MODE_320)
127 w100_init_qvga_rotation(par->rotation_flag ? 270 : 90);
128 else if (par->lcdMode == LCD_MODE_240)
129 w100_init_qvga_rotation(par->rotation_flag ? 180 : 0);
130 else if (par->lcdMode == LCD_MODE_640)
131 w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
132 else if (par->lcdMode == LCD_MODE_480)
133 w100_init_vga_rotation(par->rotation_flag ? 180 : 0);
138 static DEVICE_ATTR(rotation, 0644, rotation_show, rotation_store);
140 static ssize_t w100fb_reg_read(struct device *dev, const char *buf, size_t count)
144 regs = simple_strtoul(buf, NULL, 16);
145 param = readl(remapped_regs + regs);
146 printk("Read Register 0x%08lX: 0x%08lX\n", regs, param);
150 static DEVICE_ATTR(reg_read, 0200, NULL, w100fb_reg_read);
152 static ssize_t w100fb_reg_write(struct device *dev, const char *buf, size_t count)
156 sscanf(buf, "%lx %lx", ®s, ¶m);
158 if (regs <= 0x2000) {
159 printk("Write Register 0x%08lX: 0x%08lX\n", regs, param);
160 writel(param, remapped_regs + regs);
166 static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write);
169 static ssize_t fastsysclk_show(struct device *dev, char *buf)
171 struct fb_info *info = dev_get_drvdata(dev);
172 struct w100fb_par *par=info->par;
174 return sprintf(buf, "%d\n",par->fastsysclk_mode);
177 static ssize_t fastsysclk_store(struct device *dev, const char *buf, size_t count)
180 struct fb_info *info = dev_get_drvdata(dev);
181 struct w100fb_par *par=info->par;
183 param = simple_strtoul(buf, NULL, 10);
186 printk("Set fastsysclk %d\n", param);
187 par->fastsysclk_mode = param;
188 w100_set_fastsysclk(par->fastsysclk_mode);
189 } else if (param == 100) {
190 printk("Set fastsysclk %d\n", param);
191 par->fastsysclk_mode = param;
192 w100_set_fastsysclk(par->fastsysclk_mode);
197 static DEVICE_ATTR(fastsysclk, 0644, fastsysclk_show, fastsysclk_store);
200 * The touchscreen on this device needs certain information
201 * from the video driver to function correctly. We export it here.
203 int w100fb_get_xres(void) {
204 return current_par->xres;
207 int w100fb_get_blanking(void) {
208 return current_par->blanking_flag;
211 int w100fb_get_fastsysclk(void) {
212 return current_par->fastsysclk_mode;
214 EXPORT_SYMBOL(w100fb_get_xres);
215 EXPORT_SYMBOL(w100fb_get_blanking);
216 EXPORT_SYMBOL(w100fb_get_fastsysclk);
220 * Set a palette value from rgb components
222 static int w100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
223 u_int trans, struct fb_info *info)
229 * If greyscale is true, then we convert the RGB value
230 * to greyscale no matter what visual we are using.
232 if (info->var.grayscale)
233 red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16;
236 * 16-bit True Colour. We encode the RGB value
237 * according to the RGB bitfield information.
239 if (regno < MAX_PALETTES) {
241 u32 *pal = info->pseudo_palette;
243 val = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
252 * Blank the display based on value in blank_mode
254 static int w100fb_blank(int blank_mode, struct fb_info *info)
256 struct w100fb_par *par;
261 case FB_BLANK_NORMAL: /* Normal blanking */
262 case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
263 case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
264 case FB_BLANK_POWERDOWN: /* Poweroff */
265 if (par->blanking_flag == 0) {
266 w100fb_save_buffer();
268 par->blanking_flag = 1;
272 case FB_BLANK_UNBLANK: /* Unblanking */
273 if (par->blanking_flag != 0) {
274 w100fb_restore_buffer();
276 par->blanking_flag = 0;
284 * Change the resolution by calling the appropriate hardware functions
286 static void w100fb_changeres(int rotate_mode, u32 mode)
290 switch(rotate_mode) {
291 case LCD_MODE_LANDSCAPE:
292 rotation=(current_par->rotation_flag ? 270 : 90);
294 case LCD_MODE_PORTRAIT:
295 rotation=(current_par->rotation_flag ? 180 : 0);
303 w100_suspend(W100_SUSPEND_EXTMEM);
304 w100_init_sharp_lcd(LCD_SHARP_QVGA);
305 w100_init_qvga_rotation(rotation);
306 w100_InitExtMem(LCD_SHARP_QVGA);
307 w100fb_clear_screen(LCD_SHARP_QVGA, 0);
308 lcdtg_lcd_change(LCD_SHARP_QVGA);
311 w100fb_clear_screen(LCD_SHARP_QVGA, 0);
312 writel(0xBFFFA000, remapped_regs + mmMC_EXT_MEM_LOCATION);
313 w100_InitExtMem(LCD_SHARP_VGA);
314 w100fb_clear_screen(LCD_SHARP_VGA, 0x200000);
316 w100_init_sharp_lcd(LCD_SHARP_VGA);
318 w100_init_vga_rotation(rotation);
319 lcdtg_lcd_change(LCD_SHARP_VGA);
325 * Set up the display for the fb subsystem
327 static void w100fb_activate_var(struct fb_info *info)
330 struct w100fb_par *par=info->par;
331 struct fb_var_screeninfo *var = &info->var;
333 /* Set the hardware to 565 */
334 temp32 = readl(remapped_regs + mmDISP_DEBUG2);
335 temp32 &= 0xff7fffff;
336 temp32 |= 0x00800000;
337 writel(temp32, remapped_regs + mmDISP_DEBUG2);
339 if (par->lcdMode == LCD_MODE_INIT) {
340 w100_init_sharp_lcd(LCD_SHARP_VGA);
341 w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
342 par->lcdMode = LCD_MODE_640;
343 lcdtg_hw_init(LCD_SHARP_VGA);
344 } else if (var->xres == 320 && var->yres == 240) {
345 if (par->lcdMode != LCD_MODE_320) {
346 w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_QVGA);
347 par->lcdMode = LCD_MODE_320;
349 } else if (var->xres == 240 && var->yres == 320) {
350 if (par->lcdMode != LCD_MODE_240) {
351 w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_QVGA);
352 par->lcdMode = LCD_MODE_240;
354 } else if (var->xres == 640 && var->yres == 480) {
355 if (par->lcdMode != LCD_MODE_640) {
356 w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_VGA);
357 par->lcdMode = LCD_MODE_640;
359 } else if (var->xres == 480 && var->yres == 640) {
360 if (par->lcdMode != LCD_MODE_480) {
361 w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_VGA);
362 par->lcdMode = LCD_MODE_480;
364 } else printk(KERN_ERR "W100FB: Resolution error!\n");
369 * w100fb_check_var():
370 * Get the video params out of 'var'. If a value doesn't fit, round it up,
371 * if it's too big, return -EINVAL.
374 static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
376 if (var->xres < var->yres) { /* Portrait mode */
377 if ((var->xres > 480) || (var->yres > 640)) {
379 } else if ((var->xres > 240) || (var->yres > 320)) {
386 } else { /* Landscape mode */
387 if ((var->xres > 640) || (var->yres > 480)) {
389 } else if ((var->xres > 320) || (var->yres > 240)) {
398 var->xres_virtual = max(var->xres_virtual, var->xres);
399 var->yres_virtual = max(var->yres_virtual, var->yres);
401 if (var->bits_per_pixel > BITS_PER_PIXEL)
404 var->bits_per_pixel = BITS_PER_PIXEL;
406 var->red.offset = 11;
408 var->green.offset = 5;
409 var->green.length = 6;
410 var->blue.offset = 0;
411 var->blue.length = 5;
412 var->transp.offset = var->transp.length = 0;
418 var->vmode = FB_VMODE_NONINTERLACED;
421 var->pixclock = 0x04; /* 171521; */
429 * Set the user defined part of the display for the specified console
430 * by looking at the values in info.var
432 static int w100fb_set_par(struct fb_info *info)
434 struct w100fb_par *par=info->par;
436 par->xres = info->var.xres;
437 par->yres = info->var.yres;
439 info->fix.visual = FB_VISUAL_TRUECOLOR;
441 info->fix.ypanstep = 0;
442 info->fix.ywrapstep = 0;
444 if (par->blanking_flag)
445 w100fb_clear_buffer();
447 w100fb_activate_var(info);
449 if (par->lcdMode == LCD_MODE_480) {
450 info->fix.line_length = (480 * BITS_PER_PIXEL) / 8;
451 info->fix.smem_len = 0x200000;
452 } else if (par->lcdMode == LCD_MODE_320) {
453 info->fix.line_length = (320 * BITS_PER_PIXEL) / 8;
454 info->fix.smem_len = 0x60000;
455 } else if (par->lcdMode == LCD_MODE_240) {
456 info->fix.line_length = (240 * BITS_PER_PIXEL) / 8;
457 info->fix.smem_len = 0x60000;
458 } else if (par->lcdMode == LCD_MODE_INIT || par->lcdMode == LCD_MODE_640) {
459 info->fix.line_length = (640 * BITS_PER_PIXEL) / 8;
460 info->fix.smem_len = 0x200000;
468 * Frame buffer operations
470 static struct fb_ops w100fb_ops = {
471 .owner = THIS_MODULE,
472 .fb_check_var = w100fb_check_var,
473 .fb_set_par = w100fb_set_par,
474 .fb_setcolreg = w100fb_setcolreg,
475 .fb_blank = w100fb_blank,
476 .fb_fillrect = cfb_fillrect,
477 .fb_copyarea = cfb_copyarea,
478 .fb_imageblit = cfb_imageblit,
479 .fb_cursor = soft_cursor,
483 static void w100fb_clear_screen(u32 mode, long int offset)
487 if (mode == LCD_SHARP_VGA)
489 else if (mode == LCD_SHARP_QVGA)
492 for (i = 0; i < numPix; i++)
493 writew(0xffff, remapped_fbuf + offset + (2*i));
497 static void w100fb_save_buffer(void)
501 if (gSaveImagePtr != NULL) {
502 vfree(gSaveImagePtr);
503 gSaveImagePtr = NULL;
505 gSaveImagePtr = vmalloc(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8);
506 if (gSaveImagePtr != NULL) {
507 for (i = 0; i < (current_par->xres * current_par->yres); i++)
508 *(gSaveImagePtr + i) = readw(remapped_fbuf + (2*i));
510 printk(KERN_WARNING "can't alloc pre-off image buffer\n");
515 static void w100fb_restore_buffer(void)
519 if (gSaveImagePtr != NULL) {
520 for (i = 0; i < (current_par->xres * current_par->yres); i++) {
521 writew(*(gSaveImagePtr + i),remapped_fbuf + (2*i));
523 vfree(gSaveImagePtr);
524 gSaveImagePtr = NULL;
528 static void w100fb_clear_buffer(void)
530 if (gSaveImagePtr != NULL) {
531 vfree(gSaveImagePtr);
532 gSaveImagePtr = NULL;
538 static int w100fb_suspend(struct device *dev, u32 state, u32 level)
540 if (level == SUSPEND_POWER_DOWN) {
541 struct fb_info *info = dev_get_drvdata(dev);
542 struct w100fb_par *par=info->par;
544 w100fb_save_buffer();
546 w100_suspend(W100_SUSPEND_ALL);
547 par->blanking_flag = 1;
552 static int w100fb_resume(struct device *dev, u32 level)
554 if (level == RESUME_POWER_ON) {
555 struct fb_info *info = dev_get_drvdata(dev);
556 struct w100fb_par *par=info->par;
559 w100fb_restore_buffer();
561 par->blanking_flag = 0;
566 #define w100fb_suspend NULL
567 #define w100fb_resume NULL
571 int __init w100fb_probe(struct device *dev)
573 struct w100fb_mach_info *inf;
574 struct fb_info *info;
575 struct w100fb_par *par;
576 struct platform_device *pdev = to_platform_device(dev);
577 struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
582 /* remap the areas we're going to use */
583 remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN);
584 if (remapped_base == NULL)
587 remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN);
588 if (remapped_regs == NULL) {
589 iounmap(remapped_base);
593 remapped_fbuf = ioremap_nocache(mem->start+MEM_EXT_BASE_VALUE, REMAPPED_FB_LEN);
594 if (remapped_fbuf == NULL) {
595 iounmap(remapped_base);
596 iounmap(remapped_regs);
600 info=framebuffer_alloc(sizeof(struct w100fb_par), dev);
602 iounmap(remapped_base);
603 iounmap(remapped_regs);
604 iounmap(remapped_fbuf);
610 current_par=info->par;
611 dev_set_drvdata(dev, info);
613 inf = dev->platform_data;
614 par->phadadj = inf->phadadj;
615 par->comadj = inf->comadj;
616 par->fastsysclk_mode = 75;
617 par->lcdMode = LCD_MODE_INIT;
618 par->rotation_flag=0;
619 par->blanking_flag=0;
620 w100fb_ssp_send = inf->w100fb_ssp_send;
625 info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL);
626 if (!info->pseudo_palette) {
627 iounmap(remapped_base);
628 iounmap(remapped_regs);
629 iounmap(remapped_fbuf);
633 info->fbops = &w100fb_ops;
634 info->flags = FBINFO_DEFAULT;
636 info->screen_base = remapped_fbuf;
637 info->screen_size = REMAPPED_FB_LEN;
639 info->var.xres = 640;
640 info->var.xres_virtual = info->var.xres;
641 info->var.yres = 480;
642 info->var.yres_virtual = info->var.yres;
643 info->var.pixclock = 0x04; /* 171521; */
645 info->var.grayscale = 0;
646 info->var.xoffset = info->var.yoffset = 0;
647 info->var.accel_flags = 0;
648 info->var.activate = FB_ACTIVATE_NOW;
650 strcpy(info->fix.id, "w100fb");
651 info->fix.type = FB_TYPE_PACKED_PIXELS;
652 info->fix.type_aux = 0;
653 info->fix.accel = FB_ACCEL_NONE;
654 info->fix.smem_start = mem->start+MEM_EXT_BASE_VALUE;
655 info->fix.mmio_start = mem->start+W100_REG_BASE;
656 info->fix.mmio_len = W100_REG_LEN;
658 w100fb_check_var(&info->var, info);
659 w100fb_set_par(info);
661 if (register_framebuffer(info) < 0) {
662 kfree(info->pseudo_palette);
663 iounmap(remapped_base);
664 iounmap(remapped_regs);
665 iounmap(remapped_fbuf);
669 device_create_file(dev, &dev_attr_fastsysclk);
670 device_create_file(dev, &dev_attr_reg_read);
671 device_create_file(dev, &dev_attr_reg_write);
672 device_create_file(dev, &dev_attr_rotation);
674 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
679 static int w100fb_remove(struct device *dev)
681 struct fb_info *info = dev_get_drvdata(dev);
683 device_remove_file(dev, &dev_attr_fastsysclk);
684 device_remove_file(dev, &dev_attr_reg_read);
685 device_remove_file(dev, &dev_attr_reg_write);
686 device_remove_file(dev, &dev_attr_rotation);
688 unregister_framebuffer(info);
690 w100fb_clear_buffer();
691 kfree(info->pseudo_palette);
693 iounmap(remapped_base);
694 iounmap(remapped_regs);
695 iounmap(remapped_fbuf);
697 framebuffer_release(info);
703 /* ------------------- chipset specific functions -------------------------- */
706 static void w100_soft_reset(void)
708 u16 val = readw((u16 *) remapped_base + cfgSTATUS);
709 writew(val | 0x08, (u16 *) remapped_base + cfgSTATUS);
711 writew(0x00, (u16 *) remapped_base + cfgSTATUS);
716 * Initialization of critical w100 hardware
718 static void w100_hw_init(void)
721 union cif_cntl_u cif_cntl;
722 union intf_cntl_u intf_cntl;
723 union cfgreg_base_u cfgreg_base;
724 union wrap_top_dir_u wrap_top_dir;
725 union cif_read_dbg_u cif_read_dbg;
726 union cpu_defaults_u cpu_default;
727 union cif_write_dbg_u cif_write_dbg;
728 union wrap_start_dir_u wrap_start_dir;
729 union mc_ext_mem_location_u mc_ext_mem_loc;
730 union cif_io_u cif_io;
734 /* This is what the fpga_init code does on reset. May be wrong
735 but there is little info available */
736 writel(0x31, remapped_regs + mmSCRATCH_UMSK);
737 for (temp32 = 0; temp32 < 10000; temp32++)
738 readl(remapped_regs + mmSCRATCH_UMSK);
739 writel(0x30, remapped_regs + mmSCRATCH_UMSK);
742 cif_io.val = defCIF_IO;
743 writel((u32)(cif_io.val), remapped_regs + mmCIF_IO);
745 cif_write_dbg.val = readl(remapped_regs + mmCIF_WRITE_DBG);
746 cif_write_dbg.f.dis_packer_ful_during_rbbm_timeout = 0;
747 cif_write_dbg.f.en_dword_split_to_rbbm = 1;
748 cif_write_dbg.f.dis_timeout_during_rbbm = 1;
749 writel((u32) (cif_write_dbg.val), remapped_regs + mmCIF_WRITE_DBG);
751 cif_read_dbg.val = readl(remapped_regs + mmCIF_READ_DBG);
752 cif_read_dbg.f.dis_rd_same_byte_to_trig_fetch = 1;
753 writel((u32) (cif_read_dbg.val), remapped_regs + mmCIF_READ_DBG);
755 cif_cntl.val = readl(remapped_regs + mmCIF_CNTL);
756 cif_cntl.f.dis_system_bits = 1;
757 cif_cntl.f.dis_mr = 1;
758 cif_cntl.f.en_wait_to_compensate_dq_prop_dly = 0;
759 cif_cntl.f.intb_oe = 1;
760 cif_cntl.f.interrupt_active_high = 1;
761 writel((u32) (cif_cntl.val), remapped_regs + mmCIF_CNTL);
763 /* Setup cfgINTF_CNTL and cfgCPU defaults */
764 intf_cntl.val = defINTF_CNTL;
765 intf_cntl.f.ad_inc_a = 1;
766 intf_cntl.f.ad_inc_b = 1;
767 intf_cntl.f.rd_data_rdy_a = 0;
768 intf_cntl.f.rd_data_rdy_b = 0;
769 writeb((u8) (intf_cntl.val), remapped_base + cfgINTF_CNTL);
771 cpu_default.val = defCPU_DEFAULTS;
772 cpu_default.f.access_ind_addr_a = 1;
773 cpu_default.f.access_ind_addr_b = 1;
774 cpu_default.f.access_scratch_reg = 1;
775 cpu_default.f.transition_size = 0;
776 writeb((u8) (cpu_default.val), remapped_base + cfgCPU_DEFAULTS);
778 /* set up the apertures */
779 writeb((u8) (W100_REG_BASE >> 16), remapped_base + cfgREG_BASE);
781 cfgreg_base.val = defCFGREG_BASE;
782 cfgreg_base.f.cfgreg_base = W100_CFG_BASE;
783 writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE);
785 /* This location is relative to internal w100 addresses */
786 writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
788 mc_ext_mem_loc.val = defMC_EXT_MEM_LOCATION;
789 mc_ext_mem_loc.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8;
790 mc_ext_mem_loc.f.mc_ext_mem_top = MEM_EXT_TOP_VALUE >> 8;
791 writel((u32) (mc_ext_mem_loc.val), remapped_regs + mmMC_EXT_MEM_LOCATION);
793 if ((current_par->lcdMode == LCD_MODE_240) || (current_par->lcdMode == LCD_MODE_320))
794 w100_InitExtMem(LCD_SHARP_QVGA);
796 w100_InitExtMem(LCD_SHARP_VGA);
798 wrap_start_dir.val = defWRAP_START_DIR;
799 wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1;
800 writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR);
802 wrap_top_dir.val = defWRAP_TOP_DIR;
803 wrap_top_dir.f.top_addr = WRAP_BUF_TOP_VALUE >> 1;
804 writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR);
806 writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL);
815 u16 freq; /* desired Fout for PLL */
824 union clk_pin_cntl_u clk_pin_cntl;
825 union pll_ref_fb_div_u pll_ref_fb_div;
826 union pll_cntl_u pll_cntl;
827 union sclk_cntl_u sclk_cntl;
828 union pclk_cntl_u pclk_cntl;
829 union clk_test_cntl_u clk_test_cntl;
830 union pwrmgt_cntl_u pwrmgt_cntl;
831 u32 freq; /* Fout for PLL calibration */
832 u8 tf100; /* for pll calibration */
833 u8 tf80; /* for pll calibration */
834 u8 tf20; /* for pll calibration */
835 u8 M; /* for pll calibration */
836 u8 N_int; /* for pll calibration */
837 u8 N_fac; /* for pll calibration */
838 u8 lock_time; /* for pll calibration */
839 u8 tfgoal; /* for pll calibration */
840 u8 auto_mode; /* hardware auto switch? */
841 u8 pwm_mode; /* 0 fast, 1 normal/slow */
842 u16 fast_sclk; /* fast clk freq */
843 u16 norm_sclk; /* slow clk freq */
848 * Global state variables
851 static struct power_state w100_pwr_state;
853 /* This table is specific for 12.5MHz ref crystal. */
854 static struct pll_parm gPLLTable[] = {
855 /*freq M N_int N_fac tfgoal lock_time */
856 { 50, 0, 1, 0, 0xE0, 56}, /* 50.00 MHz */
857 { 75, 0, 5, 0, 0xDE, 37}, /* 75.00 MHz */
858 {100, 0, 7, 0, 0xE0, 28}, /* 100.00 MHz */
859 {125, 0, 9, 0, 0xE0, 22}, /* 125.00 MHz */
860 {150, 0, 11, 0, 0xE0, 17}, /* 150.00 MHz */
861 { 0, 0, 0, 0, 0, 0} /* Terminator */
865 static u8 w100_pll_get_testcount(u8 testclk_sel)
869 w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
870 w100_pwr_state.clk_test_cntl.f.testclk_sel = testclk_sel;
871 w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x1; /*reset test count */
872 writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
873 w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
874 writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
876 w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x1;
877 writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
881 w100_pwr_state.clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL);
882 w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
883 writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
885 return w100_pwr_state.clk_test_cntl.f.test_count;
889 static u8 w100_pll_adjust(void)
892 /* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V
893 * therefore, commented out the following lines
895 * set VCO input = 0.8 * VDD
897 w100_pwr_state.pll_cntl.f.pll_dactal = 0xd;
898 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
900 w100_pwr_state.tf80 = w100_pll_get_testcount(0x1); /* PLLCLK */
901 if (w100_pwr_state.tf80 >= (w100_pwr_state.tfgoal)) {
902 /* set VCO input = 0.2 * VDD */
903 w100_pwr_state.pll_cntl.f.pll_dactal = 0x7;
904 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
906 w100_pwr_state.tf20 = w100_pll_get_testcount(0x1); /* PLLCLK */
907 if (w100_pwr_state.tf20 <= (w100_pwr_state.tfgoal))
910 if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) &&
911 ((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) ||
912 (w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) {
913 /* slow VCO config */
914 w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1;
915 w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
916 w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
917 writel((u32) (w100_pwr_state.pll_cntl.val),
918 remapped_regs + mmPLL_CNTL);
922 if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) {
923 w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1;
924 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
927 if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) {
928 w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
929 w100_pwr_state.pll_cntl.f.pll_pvg += 0x1;
930 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
939 * w100_pll_calibration
940 * freq = target frequency of the PLL
941 * (note: crystal = 14.3MHz)
943 static u8 w100_pll_calibration(u32 freq)
947 /* initial setting */
948 w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0; /* power down */
949 w100_pwr_state.pll_cntl.f.pll_reset = 0x0; /* not reset */
950 w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1; /* Hi-Z */
951 w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; /* VCO gain = 0 */
952 w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0; /* VCO frequency range control = off */
953 w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; /* current offset inside VCO = 0 */
954 w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
955 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
957 /* check for (tf80 >= tfgoal) && (tf20 =< tfgoal) */
958 if ((w100_pwr_state.tf80 < w100_pwr_state.tfgoal) || (w100_pwr_state.tf20 > w100_pwr_state.tfgoal)) {
959 status=w100_pll_adjust();
961 /* PLL Reset And Lock */
963 /* set VCO input = 0.5 * VDD */
964 w100_pwr_state.pll_cntl.f.pll_dactal = 0xa;
965 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
970 /* enable charge pump */
971 w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; /* normal */
972 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
974 /* set VCO input = Hi-Z */
976 w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;
977 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
980 udelay(400); /* delay 400 us */
984 w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x1; /* PLL clock */
985 writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
987 w100_pwr_state.tf100 = w100_pll_get_testcount(0x1); /* PLLCLK */
993 static u8 w100_pll_set_clk(void)
997 if (w100_pwr_state.auto_mode == 1) /* auto mode */
999 w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; /* disable fast to normal */
1000 w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; /* disable normal to fast */
1001 writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
1004 w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* crystal clock */
1005 writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
1007 w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = w100_pwr_state.M;
1008 w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = w100_pwr_state.N_int;
1009 w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = w100_pwr_state.N_fac;
1010 w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = w100_pwr_state.lock_time;
1011 writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
1013 w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0;
1014 writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
1016 status = w100_pll_calibration (w100_pwr_state.freq);
1018 if (w100_pwr_state.auto_mode == 1) /* auto mode */
1020 w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1; /* reenable fast to normal */
1021 w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1; /* reenable normal to fast */
1022 writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
1028 /* assume reference crystal clk is 12.5MHz,
1029 * and that doubling is not enabled.
1031 * Freq = 12 == 12.5MHz.
1033 static u16 w100_set_slowsysclk(u16 freq)
1035 if (w100_pwr_state.norm_sclk == freq)
1038 if (w100_pwr_state.auto_mode == 1) /* auto mode */
1042 w100_pwr_state.norm_sclk = freq;
1043 w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */
1044 w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* crystal src */
1046 writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
1048 w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x1;
1049 writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
1051 w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x1;
1052 w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1;
1053 writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
1054 w100_pwr_state.pwm_mode = 1; /* normal mode */
1061 static u16 w100_set_fastsysclk(u16 freq)
1067 pll_freq = (u16) (freq * (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast + 1));
1070 if (pll_freq == gPLLTable[i].freq) {
1071 w100_pwr_state.freq = gPLLTable[i].freq * 1000000;
1072 w100_pwr_state.M = gPLLTable[i].M;
1073 w100_pwr_state.N_int = gPLLTable[i].N_int;
1074 w100_pwr_state.N_fac = gPLLTable[i].N_fac;
1075 w100_pwr_state.tfgoal = gPLLTable[i].tfgoal;
1076 w100_pwr_state.lock_time = gPLLTable[i].lock_time;
1077 w100_pwr_state.tf20 = 0xff; /* set highest */
1078 w100_pwr_state.tf80 = 0x00; /* set lowest */
1081 w100_pwr_state.pwm_mode = 0; /* fast mode */
1082 w100_pwr_state.fast_sclk = freq;
1086 } while(gPLLTable[i].freq);
1088 if (w100_pwr_state.auto_mode == 1)
1091 if (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast == 0)
1094 w100_pwr_state.sclk_cntl.f.sclk_post_div_fast -= 1;
1095 writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
1101 /* Set up an initial state. Some values/fields set
1102 here will be overwritten. */
1103 static void w100_pwm_setup(void)
1105 w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1;
1106 w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f;
1107 w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0;
1108 w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0;
1109 w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = 0x0; /* no freq doubling */
1110 w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0;
1111 writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
1113 w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* Crystal Clk */
1114 w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0; /* Pfast = 1 */
1115 w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3;
1116 w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */
1117 w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0;
1118 w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0; /* Dynamic */
1119 w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0; /* Dynamic */
1120 w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0; /* Dynamic */
1121 w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0; /* Dynamic */
1122 w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0; /* Dynamic */
1123 w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0; /* Dynamic */
1124 w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0; /* Dynamic */
1125 w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0; /* Dynamic */
1126 w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0; /* Dynamic */
1127 w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0;
1128 w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0;
1129 w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0;
1130 w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0;
1131 writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
1133 w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x0; /* Crystal Clk */
1134 w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1; /* P = 2 */
1135 w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0; /* Dynamic */
1136 writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
1138 w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0; /* M = 1 */
1139 w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0; /* N = 1.0 */
1140 w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0;
1141 w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5;
1142 w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff;
1143 writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
1145 w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1;
1146 w100_pwr_state.pll_cntl.f.pll_reset = 0x1;
1147 w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0;
1148 w100_pwr_state.pll_cntl.f.pll_mode = 0x0; /* uses VCO clock */
1149 w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0;
1150 w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0;
1151 w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;
1152 w100_pwr_state.pll_cntl.f.pll_pcp = 0x4;
1153 w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
1154 w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;
1155 w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
1156 w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0;
1157 w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0;
1158 w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; /* Hi-Z */
1159 w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3;
1160 w100_pwr_state.pll_cntl.f.pll_conf = 0x2;
1161 w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2;
1162 w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
1163 writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
1165 w100_pwr_state.clk_test_cntl.f.testclk_sel = 0x1; /* PLLCLK (for testing) */
1166 w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
1167 w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
1168 writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
1170 w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0;
1171 w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1; /* normal mode (0, 1, 3) */
1172 w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0;
1173 w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;
1174 w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;
1175 w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1; /* PM4,ENG */
1176 w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1; /* PM4,ENG */
1177 w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF;
1178 w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF;
1179 writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
1181 w100_pwr_state.auto_mode = 0; /* manual mode */
1182 w100_pwr_state.pwm_mode = 1; /* normal mode (0, 1, 2) */
1183 w100_pwr_state.freq = 50000000; /* 50 MHz */
1184 w100_pwr_state.M = 3; /* M = 4 */
1185 w100_pwr_state.N_int = 6; /* N = 7.0 */
1186 w100_pwr_state.N_fac = 0;
1187 w100_pwr_state.tfgoal = 0xE0;
1188 w100_pwr_state.lock_time = 56;
1189 w100_pwr_state.tf20 = 0xff; /* set highest */
1190 w100_pwr_state.tf80 = 0x00; /* set lowest */
1191 w100_pwr_state.tf100 = 0x00; /* set lowest */
1192 w100_pwr_state.fast_sclk = 50; /* 50.0 MHz */
1193 w100_pwr_state.norm_sclk = 12; /* 12.5 MHz */
1197 static void w100_init_sharp_lcd(u32 mode)
1200 union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl;
1202 /* Prevent display updates */
1203 disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
1204 disp_db_buf_wr_cntl.f.update_db_buf = 0;
1205 disp_db_buf_wr_cntl.f.en_db_buf = 0;
1206 writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
1209 case LCD_SHARP_QVGA:
1210 w100_set_slowsysclk(12); /* use crystal -- 12.5MHz */
1213 writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
1214 writel(0x85FF8000, remapped_regs + mmMC_FB_LOCATION);
1215 writel(0x00000003, remapped_regs + mmLCD_FORMAT);
1216 writel(0x00CF1C06, remapped_regs + mmGRAPHIC_CTRL);
1217 writel(0x01410145, remapped_regs + mmCRTC_TOTAL);
1218 writel(0x01170027, remapped_regs + mmACTIVE_H_DISP);
1219 writel(0x01410001, remapped_regs + mmACTIVE_V_DISP);
1220 writel(0x01170027, remapped_regs + mmGRAPHIC_H_DISP);
1221 writel(0x01410001, remapped_regs + mmGRAPHIC_V_DISP);
1222 writel(0x81170027, remapped_regs + mmCRTC_SS);
1223 writel(0xA0140000, remapped_regs + mmCRTC_LS);
1224 writel(0x00400008, remapped_regs + mmCRTC_REV);
1225 writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
1226 writel(0xC0140014, remapped_regs + mmCRTC_GS);
1227 writel(0x00010141, remapped_regs + mmCRTC_VPOS_GS);
1228 writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
1229 writel(0x80100110, remapped_regs + mmCRTC_GOE);
1230 writel(0x00000000, remapped_regs + mmCRTC_FRAME);
1231 writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
1232 writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
1233 writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
1234 writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
1235 writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
1236 writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
1237 writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
1238 writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
1239 writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
1240 writel(0x000001e0, remapped_regs + mmGRAPHIC_PITCH);
1241 writel(0x000000bf, remapped_regs + mmGPIO_DATA);
1242 writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
1243 writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
1244 writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
1247 w100_set_slowsysclk(12); /* use crystal -- 12.5MHz */
1248 w100_set_fastsysclk(current_par->fastsysclk_mode); /* use PLL -- 75.0MHz */
1249 w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
1250 w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x2;
1251 writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
1252 writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
1253 writel(0x9FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
1254 writel(0x00000003, remapped_regs + mmLCD_FORMAT);
1255 writel(0x00DE1D66, remapped_regs + mmGRAPHIC_CTRL);
1257 writel(0x0283028B, remapped_regs + mmCRTC_TOTAL);
1258 writel(0x02360056, remapped_regs + mmACTIVE_H_DISP);
1259 writel(0x02830003, remapped_regs + mmACTIVE_V_DISP);
1260 writel(0x02360056, remapped_regs + mmGRAPHIC_H_DISP);
1261 writel(0x02830003, remapped_regs + mmGRAPHIC_V_DISP);
1262 writel(0x82360056, remapped_regs + mmCRTC_SS);
1263 writel(0xA0280000, remapped_regs + mmCRTC_LS);
1264 writel(0x00400008, remapped_regs + mmCRTC_REV);
1265 writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
1266 writel(0x80280028, remapped_regs + mmCRTC_GS);
1267 writel(0x02830002, remapped_regs + mmCRTC_VPOS_GS);
1268 writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
1269 writel(0x80100110, remapped_regs + mmCRTC_GOE);
1270 writel(0x00000000, remapped_regs + mmCRTC_FRAME);
1271 writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
1272 writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
1273 writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
1274 writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
1275 writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
1276 writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
1277 writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
1278 writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
1279 writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
1280 writel(0x000003C0, remapped_regs + mmGRAPHIC_PITCH);
1281 writel(0x000000bf, remapped_regs + mmGPIO_DATA);
1282 writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
1283 writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
1284 writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
1290 /* Hack for overlay in ext memory */
1291 temp32 = readl(remapped_regs + mmDISP_DEBUG2);
1292 temp32 |= 0xc0000000;
1293 writel(temp32, remapped_regs + mmDISP_DEBUG2);
1295 /* Re-enable display updates */
1296 disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
1297 disp_db_buf_wr_cntl.f.update_db_buf = 1;
1298 disp_db_buf_wr_cntl.f.en_db_buf = 1;
1299 writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
1303 static void w100_set_vga_rotation_regs(u16 divider, unsigned long ctrl, unsigned long offset, unsigned long pitch)
1305 w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
1306 w100_pwr_state.pclk_cntl.f.pclk_post_div = divider;
1307 writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
1309 writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
1310 writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
1311 writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
1313 /* Re-enable display updates */
1314 writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
1318 static void w100_init_vga_rotation(u16 deg)
1322 w100_set_vga_rotation_regs(0x02, 0x00DE1D66, 0x00800000, 0x000003c0);
1325 w100_set_vga_rotation_regs(0x06, 0x00DE1D0e, 0x00895b00, 0x00000500);
1328 w100_set_vga_rotation_regs(0x02, 0x00DE1D7e, 0x00895ffc, 0x000003c0);
1331 w100_set_vga_rotation_regs(0x06, 0x00DE1D16, 0x008004fc, 0x00000500);
1340 static void w100_set_qvga_rotation_regs(unsigned long ctrl, unsigned long offset, unsigned long pitch)
1342 writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
1343 writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
1344 writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
1346 /* Re-enable display updates */
1347 writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
1351 static void w100_init_qvga_rotation(u16 deg)
1355 w100_set_qvga_rotation_regs(0x00d41c06, 0x00800000, 0x000001e0);
1358 w100_set_qvga_rotation_regs(0x00d41c0E, 0x00825580, 0x00000280);
1361 w100_set_qvga_rotation_regs(0x00d41c1e, 0x008257fc, 0x000001e0);
1364 w100_set_qvga_rotation_regs(0x00d41c16, 0x0080027c, 0x00000280);
1373 static void w100_suspend(u32 mode)
1377 writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
1378 writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL);
1380 val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL);
1381 val &= ~(0x00100000); /* bit20=0 */
1382 val |= 0xFF000000; /* bit31:24=0xff */
1383 writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL);
1385 val = readl(remapped_regs + mmMEM_EXT_CNTL);
1386 val &= ~(0x00040000); /* bit18=0 */
1387 val |= 0x00080000; /* bit19=1 */
1388 writel(val, remapped_regs + mmMEM_EXT_CNTL);
1390 udelay(1); /* wait 1us */
1392 if (mode == W100_SUSPEND_EXTMEM) {
1394 /* CKE: Tri-State */
1395 val = readl(remapped_regs + mmMEM_EXT_CNTL);
1396 val |= 0x40000000; /* bit30=1 */
1397 writel(val, remapped_regs + mmMEM_EXT_CNTL);
1400 val = readl(remapped_regs + mmMEM_EXT_CNTL);
1401 val &= ~(0x00000001); /* bit0=0 */
1402 writel(val, remapped_regs + mmMEM_EXT_CNTL);
1405 writel(0x00000000, remapped_regs + mmSCLK_CNTL);
1406 writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL);
1407 writel(0x00000015, remapped_regs + mmPWRMGT_CNTL);
1411 val = readl(remapped_regs + mmPLL_CNTL);
1412 val |= 0x00000004; /* bit2=1 */
1413 writel(val, remapped_regs + mmPLL_CNTL);
1414 writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL);
1419 static void w100_resume(void)
1426 temp32 = readl(remapped_regs + mmDISP_DEBUG2);
1427 temp32 &= 0xff7fffff;
1428 temp32 |= 0x00800000;
1429 writel(temp32, remapped_regs + mmDISP_DEBUG2);
1431 if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
1432 w100_init_sharp_lcd(LCD_SHARP_VGA);
1433 if (current_par->lcdMode == LCD_MODE_640) {
1434 w100_init_vga_rotation(current_par->rotation_flag ? 270 : 90);
1437 w100_init_sharp_lcd(LCD_SHARP_QVGA);
1438 if (current_par->lcdMode == LCD_MODE_320) {
1439 w100_init_qvga_rotation(current_par->rotation_flag ? 270 : 90);
1445 static void w100_vsync(void)
1448 int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */
1450 tmp = readl(remapped_regs + mmACTIVE_V_DISP);
1453 writel((tmp >> 16) & 0x3ff, remapped_regs + mmDISP_INT_CNTL);
1455 /* disable vline irq */
1456 tmp = readl(remapped_regs + mmGEN_INT_CNTL);
1459 writel(tmp, remapped_regs + mmGEN_INT_CNTL);
1461 /* clear vline irq status */
1462 writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
1464 /* enable vline irq */
1465 writel((tmp | 0x00000002), remapped_regs + mmGEN_INT_CNTL);
1467 /* clear vline irq status */
1468 writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
1470 while(timeout > 0) {
1471 if (readl(remapped_regs + mmGEN_INT_STATUS) & 0x00000002)
1477 /* disable vline irq */
1478 writel(tmp, remapped_regs + mmGEN_INT_CNTL);
1480 /* clear vline irq status */
1481 writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
1485 static void w100_InitExtMem(u32 mode)
1488 case LCD_SHARP_QVGA:
1489 /* QVGA doesn't use external memory
1490 nothing to do, really. */
1493 writel(0x00007800, remapped_regs + mmMC_BIST_CTRL);
1494 writel(0x00040003, remapped_regs + mmMEM_EXT_CNTL);
1495 writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
1497 writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
1499 writel(0x00650021, remapped_regs + mmMEM_SDRAM_MODE_REG);
1501 writel(0x10002a4a, remapped_regs + mmMEM_EXT_TIMING_CNTL);
1502 writel(0x7ff87012, remapped_regs + mmMEM_IO_CNTL);
1510 #define RESCTL_ADRS 0x00
1511 #define PHACTRL_ADRS 0x01
1512 #define DUTYCTRL_ADRS 0x02
1513 #define POWERREG0_ADRS 0x03
1514 #define POWERREG1_ADRS 0x04
1515 #define GPOR3_ADRS 0x05
1516 #define PICTRL_ADRS 0x06
1517 #define POLCTRL_ADRS 0x07
1519 #define RESCTL_QVGA 0x01
1520 #define RESCTL_VGA 0x00
1522 #define POWER1_VW_ON 0x01 /* VW Supply FET ON */
1523 #define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */
1524 #define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */
1526 #define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */
1527 #define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */
1528 #define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */
1530 #define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */
1531 #define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */
1532 #define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */
1533 #define POWER0_COM_ON 0x08 /* COM Powewr Supply ON */
1534 #define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */
1536 #define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */
1537 #define POWER0_COM_OFF 0x00 /* COM Powewr Supply OFF */
1538 #define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */
1540 #define PICTRL_INIT_STATE 0x01
1541 #define PICTRL_INIOFF 0x02
1542 #define PICTRL_POWER_DOWN 0x04
1543 #define PICTRL_COM_SIGNAL_OFF 0x08
1544 #define PICTRL_DAC_SIGNAL_OFF 0x10
1546 #define PICTRL_POWER_ACTIVE (0)
1548 #define POLCTRL_SYNC_POL_FALL 0x01
1549 #define POLCTRL_EN_POL_FALL 0x02
1550 #define POLCTRL_DATA_POL_FALL 0x04
1551 #define POLCTRL_SYNC_ACT_H 0x08
1552 #define POLCTRL_EN_ACT_L 0x10
1554 #define POLCTRL_SYNC_POL_RISE 0x00
1555 #define POLCTRL_EN_POL_RISE 0x00
1556 #define POLCTRL_DATA_POL_RISE 0x00
1557 #define POLCTRL_SYNC_ACT_L 0x00
1558 #define POLCTRL_EN_ACT_H 0x00
1560 #define PHACTRL_PHASE_MANUAL 0x01
1562 #define PHAD_QVGA_DEFAULT_VAL (9)
1563 #define COMADJ_DEFAULT (125)
1565 static void lcdtg_ssp_send(u8 adrs, u8 data)
1567 w100fb_ssp_send(adrs,data);
1571 * This is only a psuedo I2C interface. We can't use the standard kernel
1572 * routines as the interface is write only. We just assume the data is acked...
1574 static void lcdtg_ssp_i2c_send(u8 data)
1576 lcdtg_ssp_send(POWERREG0_ADRS, data);
1580 static void lcdtg_i2c_send_bit(u8 data)
1582 lcdtg_ssp_i2c_send(data);
1583 lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
1584 lcdtg_ssp_i2c_send(data);
1587 static void lcdtg_i2c_send_start(u8 base)
1589 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
1590 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
1591 lcdtg_ssp_i2c_send(base);
1594 static void lcdtg_i2c_send_stop(u8 base)
1596 lcdtg_ssp_i2c_send(base);
1597 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
1598 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
1601 static void lcdtg_i2c_send_byte(u8 base, u8 data)
1604 for (i = 0; i < 8; i++) {
1606 lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
1608 lcdtg_i2c_send_bit(base);
1613 static void lcdtg_i2c_wait_ack(u8 base)
1615 lcdtg_i2c_send_bit(base);
1618 static void lcdtg_set_common_voltage(u8 base_data, u8 data)
1620 /* Set Common Voltage to M62332FP via I2C */
1621 lcdtg_i2c_send_start(base_data);
1622 lcdtg_i2c_send_byte(base_data, 0x9c);
1623 lcdtg_i2c_wait_ack(base_data);
1624 lcdtg_i2c_send_byte(base_data, 0x00);
1625 lcdtg_i2c_wait_ack(base_data);
1626 lcdtg_i2c_send_byte(base_data, data);
1627 lcdtg_i2c_wait_ack(base_data);
1628 lcdtg_i2c_send_stop(base_data);
1631 static struct lcdtg_register_setting {
1635 } lcdtg_power_on_table[] = {
1637 /* Initialize Internal Logic & Port */
1639 PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE |
1640 PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF,
1644 POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF | POWER0_COM_OFF |
1649 POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF,
1652 /* VDD(+8V),SVSS(-4V) ON */
1654 POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON /* VDD ON */,
1659 POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
1660 POWER0_COM_OFF | POWER0_VCC5_OFF,
1663 /* INIB = H, INI = L */
1665 /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
1666 PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF,
1669 /* Set Common Voltage */
1674 POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
1675 POWER0_COM_OFF | POWER0_VCC5_ON /* VCC5 ON */,
1680 POWER1_VW_OFF | POWER1_GVSS_ON /* GVSS ON */ |
1681 POWER1_VDD_ON /* VDD ON */,
1684 /* COM SIGNAL ON (PICTL[3] = L) */
1691 POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
1692 POWER0_COM_ON /* COM ON */ | POWER0_VCC5_ON /* VCC5_ON */,
1697 POWER1_VW_ON /* VW ON */ | POWER1_GVSS_ON /* GVSS ON */ |
1698 POWER1_VDD_ON /* VDD ON */,
1699 0 /* Wait 100ms */ },
1701 /* Signals output enable */
1703 0 /* Signals output enable */,
1707 PHACTRL_PHASE_MANUAL,
1710 /* Initialize for Input Signals from ATI */
1712 POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE | POLCTRL_DATA_POL_RISE |
1713 POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H,
1714 1000 /*100000*/ /* Wait 100ms */ },
1720 static void lcdtg_resume(void)
1722 if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
1723 lcdtg_hw_init(LCD_SHARP_VGA);
1725 lcdtg_hw_init(LCD_SHARP_QVGA);
1729 static void lcdtg_suspend(void)
1733 for (i = 0; i < (current_par->xres * current_par->yres); i++) {
1734 writew(0xffff, remapped_fbuf + (2*i));
1737 /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
1741 lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
1744 lcdtg_ssp_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
1745 lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
1747 /* (3)Set Common Voltage Bias 0V */
1748 lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
1751 lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
1754 lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
1756 /* (6)Set PDWN, INIOFF, DACOFF */
1757 lcdtg_ssp_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
1758 PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
1761 lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
1764 lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
1768 static void lcdtg_set_phadadj(u32 mode)
1772 if (mode == LCD_SHARP_VGA) {
1773 /* Setting for VGA */
1774 adj = current_par->phadadj;
1776 adj = PHACTRL_PHASE_MANUAL;
1778 adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
1781 /* Setting for QVGA */
1782 adj = (PHAD_QVGA_DEFAULT_VAL << 1) | PHACTRL_PHASE_MANUAL;
1784 lcdtg_ssp_send(PHACTRL_ADRS, adj);
1787 static void lcdtg_hw_init(u32 mode)
1793 while(lcdtg_power_on_table[i].adrs != 0xff) {
1794 if (lcdtg_power_on_table[i].adrs == 0xfe) {
1795 /* Set Common Voltage */
1796 comadj = current_par->comadj;
1798 comadj = COMADJ_DEFAULT;
1800 lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
1801 } else if (lcdtg_power_on_table[i].adrs == PHACTRL_ADRS) {
1802 /* Set Phase Adjuct */
1803 lcdtg_set_phadadj(mode);
1806 lcdtg_ssp_send(lcdtg_power_on_table[i].adrs, lcdtg_power_on_table[i].data);
1808 if (lcdtg_power_on_table[i].wait != 0)
1809 udelay(lcdtg_power_on_table[i].wait);
1814 case LCD_SHARP_QVGA:
1815 /* Set Lcd Resolution (QVGA) */
1816 lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
1819 /* Set Lcd Resolution (VGA) */
1820 lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
1827 static void lcdtg_lcd_change(u32 mode)
1829 /* Set Phase Adjuct */
1830 lcdtg_set_phadadj(mode);
1832 if (mode == LCD_SHARP_VGA)
1833 /* Set Lcd Resolution (VGA) */
1834 lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
1835 else if (mode == LCD_SHARP_QVGA)
1836 /* Set Lcd Resolution (QVGA) */
1837 lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
1841 static struct device_driver w100fb_driver = {
1843 .bus = &platform_bus_type,
1844 .probe = w100fb_probe,
1845 .remove = w100fb_remove,
1846 .suspend = w100fb_suspend,
1847 .resume = w100fb_resume,
1850 int __devinit w100fb_init(void)
1852 return driver_register(&w100fb_driver);
1855 void __exit w100fb_cleanup(void)
1857 driver_unregister(&w100fb_driver);
1860 module_init(w100fb_init);
1861 module_exit(w100fb_cleanup);
1863 MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver");
1864 MODULE_LICENSE("GPLv2");