Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.12-rc6 1873 lines 54 kB view raw
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, pm_message_t 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");