aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2011-04-26 04:22:15 -0400
committerJiri Kosina <jkosina@suse.cz>2011-04-26 04:22:59 -0400
commit07f9479a40cc778bc1462ada11f95b01360ae4ff (patch)
tree0676cf38df3844004bb3ebfd99dfa67a4a8998f5 /drivers/video
parent9d5e6bdb3013acfb311ab407eeca0b6a6a3dedbf (diff)
parentcd2e49e90f1cae7726c9a2c54488d881d7f1cd1c (diff)
Merge branch 'master' into for-next
Fast-forwarded to current state of Linus' tree as there are patches to be applied for files that didn't exist on the old branch.
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/amba-clcd.c103
-rw-r--r--drivers/video/arkfb.c160
-rw-r--r--drivers/video/atmel_lcdfb.c34
-rw-r--r--drivers/video/aty/aty128fb.c1
-rw-r--r--drivers/video/aty/atyfb_base.c5
-rw-r--r--drivers/video/aty/mach64_cursor.c2
-rw-r--r--drivers/video/aty/radeon_backlight.c1
-rw-r--r--drivers/video/aty/radeon_base.c2
-rw-r--r--drivers/video/aty/radeon_i2c.c3
-rw-r--r--drivers/video/au1200fb.c2
-rw-r--r--drivers/video/backlight/88pm860x_bl.c35
-rw-r--r--drivers/video/backlight/Kconfig18
-rw-r--r--drivers/video/backlight/Makefile3
-rw-r--r--drivers/video/backlight/adp5520_bl.c1
-rw-r--r--drivers/video/backlight/adp8860_bl.c1
-rw-r--r--drivers/video/backlight/adx_bl.c1
-rw-r--r--drivers/video/backlight/apple_bl.c241
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c1
-rw-r--r--drivers/video/backlight/backlight.c24
-rw-r--r--drivers/video/backlight/corgi_lcd.c3
-rw-r--r--drivers/video/backlight/cr_bllcd.c1
-rw-r--r--drivers/video/backlight/da903x_bl.c1
-rw-r--r--drivers/video/backlight/ep93xx_bl.c1
-rw-r--r--drivers/video/backlight/generic_bl.c1
-rw-r--r--drivers/video/backlight/hp680_bl.c1
-rw-r--r--drivers/video/backlight/jornada720_bl.c5
-rw-r--r--drivers/video/backlight/jornada720_lcd.c4
-rw-r--r--drivers/video/backlight/kb3886_bl.c1
-rw-r--r--drivers/video/backlight/ld9040.c819
-rw-r--r--drivers/video/backlight/ld9040_gamma.h200
-rw-r--r--drivers/video/backlight/locomolcd.c3
-rw-r--r--drivers/video/backlight/max8925_bl.c1
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c400
-rw-r--r--drivers/video/backlight/omap1_bl.c1
-rw-r--r--drivers/video/backlight/pcf50633-backlight.c1
-rw-r--r--drivers/video/backlight/progear_bl.c1
-rw-r--r--drivers/video/backlight/pwm_bl.c12
-rw-r--r--drivers/video/backlight/s6e63m0.c1
-rw-r--r--drivers/video/backlight/tosa_bl.c1
-rw-r--r--drivers/video/backlight/wm831x_bl.c1
-rw-r--r--drivers/video/bf54x-lq043fb.c1
-rw-r--r--drivers/video/bfin-lq035q1-fb.c4
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c1
-rw-r--r--drivers/video/bfin_adv7393fb.h24
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/cg6.c1
-rw-r--r--drivers/video/console/fbcon.c6
-rw-r--r--drivers/video/console/font_mini_4x6.c2
-rw-r--r--drivers/video/console/tileblit.c2
-rw-r--r--drivers/video/da8xx-fb.c2
-rw-r--r--drivers/video/display/display-sysfs.c2
-rw-r--r--drivers/video/edid.h4
-rw-r--r--drivers/video/efifb.c154
-rw-r--r--drivers/video/ep93xx-fb.c2
-rw-r--r--drivers/video/fb-puv3.c28
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/ffb.c2
-rw-r--r--drivers/video/fm2fb.c2
-rw-r--r--drivers/video/fsl-diu-fb.c2
-rw-r--r--drivers/video/gbefb.c2
-rw-r--r--drivers/video/geode/lxfb.h2
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/hpfb.c6
-rw-r--r--drivers/video/i810/i810_accel.c2
-rw-r--r--drivers/video/imxfb.c1
-rw-r--r--drivers/video/intelfb/Makefile5
-rw-r--r--drivers/video/kyro/STG4000OverlayDevice.c2
-rw-r--r--drivers/video/kyro/STG4000Reg.h2
-rw-r--r--drivers/video/matrox/matroxfb_DAC1064.h2
-rw-r--r--drivers/video/matrox/matroxfb_Ti3026.c4
-rw-r--r--drivers/video/matrox/matroxfb_base.c14
-rw-r--r--drivers/video/matrox/matroxfb_base.h2
-rw-r--r--drivers/video/metronomefb.c2
-rw-r--r--drivers/video/nuc900fb.h2
-rw-r--r--drivers/video/nvidia/nv_backlight.c1
-rw-r--r--drivers/video/omap/Kconfig9
-rw-r--r--drivers/video/omap/blizzard.c3
-rw-r--r--drivers/video/omap/hwa742.c3
-rw-r--r--drivers/video/omap2/displays/Kconfig6
-rw-r--r--drivers/video/omap2/displays/Makefile1
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c1
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c25
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c279
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c1
-rw-r--r--drivers/video/omap2/displays/panel-taal.c125
-rw-r--r--drivers/video/omap2/dss/Kconfig14
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/core.c480
-rw-r--r--drivers/video/omap2/dss/dispc.c335
-rw-r--r--drivers/video/omap2/dss/display.c35
-rw-r--r--drivers/video/omap2/dss/dpi.c45
-rw-r--r--drivers/video/omap2/dss/dsi.c967
-rw-r--r--drivers/video/omap2/dss/dss.c763
-rw-r--r--drivers/video/omap2/dss/dss.h153
-rw-r--r--drivers/video/omap2/dss/dss_features.c163
-rw-r--r--drivers/video/omap2/dss/dss_features.h27
-rw-r--r--drivers/video/omap2/dss/hdmi.c1332
-rw-r--r--drivers/video/omap2/dss/hdmi.h415
-rw-r--r--drivers/video/omap2/dss/hdmi_omap4_panel.c222
-rw-r--r--drivers/video/omap2/dss/manager.c13
-rw-r--r--drivers/video/omap2/dss/overlay.c10
-rw-r--r--drivers/video/omap2/dss/rfbi.c128
-rw-r--r--drivers/video/omap2/dss/sdi.c62
-rw-r--r--drivers/video/omap2/dss/venc.c128
-rw-r--r--drivers/video/omap2/omapfb/Kconfig6
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c23
-rw-r--r--drivers/video/pxa3xx-gcu.c2
-rw-r--r--drivers/video/pxafb.c138
-rw-r--r--drivers/video/pxafb.h3
-rw-r--r--drivers/video/riva/fbdev.c1
-rw-r--r--drivers/video/s3c-fb.c9
-rw-r--r--drivers/video/s3fb.c385
-rw-r--r--drivers/video/savage/savagefb-i2c.c14
-rw-r--r--drivers/video/savage/savagefb.h2
-rw-r--r--drivers/video/savage/savagefb_driver.c4
-rw-r--r--drivers/video/sh7760fb.c4
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c57
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h1
-rw-r--r--drivers/video/sis/sis.h1
-rw-r--r--drivers/video/sis/sis_main.c315
-rw-r--r--drivers/video/sis/vgatypes.h1
-rw-r--r--drivers/video/sm501fb.c279
-rw-r--r--drivers/video/sstfb.c8
-rw-r--r--drivers/video/sticore.h2
-rw-r--r--drivers/video/svgalib.c175
-rw-r--r--drivers/video/tcx.c1
-rw-r--r--drivers/video/tdfxfb.c18
-rw-r--r--drivers/video/tmiofb.c30
-rw-r--r--drivers/video/udlfb.c2
-rw-r--r--drivers/video/uvesafb.c49
-rw-r--r--drivers/video/vermilion/vermilion.c3
-rw-r--r--drivers/video/vesafb.c44
-rw-r--r--drivers/video/vga16fb.c2
-rw-r--r--drivers/video/via/chip.h1
-rw-r--r--drivers/video/via/hw.c17
-rw-r--r--drivers/video/via/hw.h3
-rw-r--r--drivers/video/via/via_utility.c2
-rw-r--r--drivers/video/via/via_utility.h2
-rw-r--r--drivers/video/via/viafbdev.c76
-rw-r--r--drivers/video/via/viafbdev.h3
-rw-r--r--drivers/video/vt8623fb.c157
-rw-r--r--drivers/video/w100fb.c2
143 files changed, 7412 insertions, 2569 deletions
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 013c8ce57205..5fc983c5b92c 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -120,8 +120,23 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
120static int 120static int
121clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) 121clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
122{ 122{
123 u32 caps;
123 int ret = 0; 124 int ret = 0;
124 125
126 if (fb->panel->caps && fb->board->caps)
127 caps = fb->panel->caps & fb->board->caps;
128 else {
129 /* Old way of specifying what can be used */
130 caps = fb->panel->cntl & CNTL_BGR ?
131 CLCD_CAP_BGR : CLCD_CAP_RGB;
132 /* But mask out 444 modes as they weren't supported */
133 caps &= ~CLCD_CAP_444;
134 }
135
136 /* Only TFT panels can do RGB888/BGR888 */
137 if (!(fb->panel->cntl & CNTL_LCDTFT))
138 caps &= ~CLCD_CAP_888;
139
125 memset(&var->transp, 0, sizeof(var->transp)); 140 memset(&var->transp, 0, sizeof(var->transp));
126 141
127 var->red.msb_right = 0; 142 var->red.msb_right = 0;
@@ -133,6 +148,13 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
133 case 2: 148 case 2:
134 case 4: 149 case 4:
135 case 8: 150 case 8:
151 /* If we can't do 5551, reject */
152 caps &= CLCD_CAP_5551;
153 if (!caps) {
154 ret = -EINVAL;
155 break;
156 }
157
136 var->red.length = var->bits_per_pixel; 158 var->red.length = var->bits_per_pixel;
137 var->red.offset = 0; 159 var->red.offset = 0;
138 var->green.length = var->bits_per_pixel; 160 var->green.length = var->bits_per_pixel;
@@ -140,23 +162,61 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
140 var->blue.length = var->bits_per_pixel; 162 var->blue.length = var->bits_per_pixel;
141 var->blue.offset = 0; 163 var->blue.offset = 0;
142 break; 164 break;
165
143 case 16: 166 case 16:
144 var->red.length = 5; 167 /* If we can't do 444, 5551 or 565, reject */
145 var->blue.length = 5; 168 if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) {
169 ret = -EINVAL;
170 break;
171 }
172
146 /* 173 /*
147 * Green length can be 5 or 6 depending whether 174 * Green length can be 4, 5 or 6 depending whether
148 * we're operating in RGB555 or RGB565 mode. 175 * we're operating in 444, 5551 or 565 mode.
149 */ 176 */
150 if (var->green.length != 5 && var->green.length != 6) 177 if (var->green.length == 4 && caps & CLCD_CAP_444)
151 var->green.length = 6; 178 caps &= CLCD_CAP_444;
179 if (var->green.length == 5 && caps & CLCD_CAP_5551)
180 caps &= CLCD_CAP_5551;
181 else if (var->green.length == 6 && caps & CLCD_CAP_565)
182 caps &= CLCD_CAP_565;
183 else {
184 /*
185 * PL110 officially only supports RGB555,
186 * but may be wired up to allow RGB565.
187 */
188 if (caps & CLCD_CAP_565) {
189 var->green.length = 6;
190 caps &= CLCD_CAP_565;
191 } else if (caps & CLCD_CAP_5551) {
192 var->green.length = 5;
193 caps &= CLCD_CAP_5551;
194 } else {
195 var->green.length = 4;
196 caps &= CLCD_CAP_444;
197 }
198 }
199
200 if (var->green.length >= 5) {
201 var->red.length = 5;
202 var->blue.length = 5;
203 } else {
204 var->red.length = 4;
205 var->blue.length = 4;
206 }
152 break; 207 break;
153 case 32: 208 case 32:
154 if (fb->panel->cntl & CNTL_LCDTFT) { 209 /* If we can't do 888, reject */
155 var->red.length = 8; 210 caps &= CLCD_CAP_888;
156 var->green.length = 8; 211 if (!caps) {
157 var->blue.length = 8; 212 ret = -EINVAL;
158 break; 213 break;
159 } 214 }
215
216 var->red.length = 8;
217 var->green.length = 8;
218 var->blue.length = 8;
219 break;
160 default: 220 default:
161 ret = -EINVAL; 221 ret = -EINVAL;
162 break; 222 break;
@@ -168,7 +228,20 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
168 * the bitfield length defined above. 228 * the bitfield length defined above.
169 */ 229 */
170 if (ret == 0 && var->bits_per_pixel >= 16) { 230 if (ret == 0 && var->bits_per_pixel >= 16) {
171 if (fb->panel->cntl & CNTL_BGR) { 231 bool bgr, rgb;
232
233 bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
234 rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
235
236 if (!bgr && !rgb)
237 /*
238 * The requested format was not possible, try just
239 * our capabilities. One of BGR or RGB must be
240 * supported.
241 */
242 bgr = caps & CLCD_CAP_BGR;
243
244 if (bgr) {
172 var->blue.offset = 0; 245 var->blue.offset = 0;
173 var->green.offset = var->blue.offset + var->blue.length; 246 var->green.offset = var->blue.offset + var->blue.length;
174 var->red.offset = var->green.offset + var->green.length; 247 var->red.offset = var->green.offset + var->green.length;
@@ -443,8 +516,8 @@ static int clcdfb_register(struct clcd_fb *fb)
443 516
444 fb_set_var(&fb->fb, &fb->fb.var); 517 fb_set_var(&fb->fb, &fb->fb.var);
445 518
446 printk(KERN_INFO "CLCD: %s hardware, %s display\n", 519 dev_info(&fb->dev->dev, "%s hardware, %s display\n",
447 fb->board->name, fb->panel->mode.name); 520 fb->board->name, fb->panel->mode.name);
448 521
449 ret = register_framebuffer(&fb->fb); 522 ret = register_framebuffer(&fb->fb);
450 if (ret == 0) 523 if (ret == 0)
@@ -486,6 +559,10 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
486 fb->dev = dev; 559 fb->dev = dev;
487 fb->board = board; 560 fb->board = board;
488 561
562 dev_info(&fb->dev->dev, "PL%03x rev%u at 0x%08llx\n",
563 amba_part(dev), amba_rev(dev),
564 (unsigned long long)dev->res.start);
565
489 ret = fb->board->setup(fb); 566 ret = fb->board->setup(fb);
490 if (ret) 567 if (ret)
491 goto free_fb; 568 goto free_fb;
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 391ac939f011..8686429cbdf0 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -158,12 +158,19 @@ static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)
158 } 158 }
159} 159}
160 160
161static void arkfb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
162{
163 struct arkfb_info *par = info->par;
164
165 svga_tilecursor(par->state.vgabase, info, cursor);
166}
167
161static struct fb_tile_ops arkfb_tile_ops = { 168static struct fb_tile_ops arkfb_tile_ops = {
162 .fb_settile = arkfb_settile, 169 .fb_settile = arkfb_settile,
163 .fb_tilecopy = svga_tilecopy, 170 .fb_tilecopy = svga_tilecopy,
164 .fb_tilefill = svga_tilefill, 171 .fb_tilefill = svga_tilefill,
165 .fb_tileblit = svga_tileblit, 172 .fb_tileblit = svga_tileblit,
166 .fb_tilecursor = svga_tilecursor, 173 .fb_tilecursor = arkfb_tilecursor,
167 .fb_get_tilemax = svga_get_tilemax, 174 .fb_get_tilemax = svga_get_tilemax,
168}; 175};
169 176
@@ -466,32 +473,40 @@ static unsigned short dac_regs[4] = {0x3c8, 0x3c9, 0x3c6, 0x3c7};
466 473
467static void ark_dac_read_regs(void *data, u8 *code, int count) 474static void ark_dac_read_regs(void *data, u8 *code, int count)
468{ 475{
469 u8 regval = vga_rseq(NULL, 0x1C); 476 struct fb_info *info = data;
477 struct arkfb_info *par;
478 u8 regval;
470 479
480 par = info->par;
481 regval = vga_rseq(par->state.vgabase, 0x1C);
471 while (count != 0) 482 while (count != 0)
472 { 483 {
473 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 484 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
474 code[1] = vga_r(NULL, dac_regs[code[0] & 3]); 485 code[1] = vga_r(par->state.vgabase, dac_regs[code[0] & 3]);
475 count--; 486 count--;
476 code += 2; 487 code += 2;
477 } 488 }
478 489
479 vga_wseq(NULL, 0x1C, regval); 490 vga_wseq(par->state.vgabase, 0x1C, regval);
480} 491}
481 492
482static void ark_dac_write_regs(void *data, u8 *code, int count) 493static void ark_dac_write_regs(void *data, u8 *code, int count)
483{ 494{
484 u8 regval = vga_rseq(NULL, 0x1C); 495 struct fb_info *info = data;
496 struct arkfb_info *par;
497 u8 regval;
485 498
499 par = info->par;
500 regval = vga_rseq(par->state.vgabase, 0x1C);
486 while (count != 0) 501 while (count != 0)
487 { 502 {
488 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 503 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
489 vga_w(NULL, dac_regs[code[0] & 3], code[1]); 504 vga_w(par->state.vgabase, dac_regs[code[0] & 3], code[1]);
490 count--; 505 count--;
491 code += 2; 506 code += 2;
492 } 507 }
493 508
494 vga_wseq(NULL, 0x1C, regval); 509 vga_wseq(par->state.vgabase, 0x1C, regval);
495} 510}
496 511
497 512
@@ -507,8 +522,8 @@ static void ark_set_pixclock(struct fb_info *info, u32 pixclock)
507 } 522 }
508 523
509 /* Set VGA misc register */ 524 /* Set VGA misc register */
510 regval = vga_r(NULL, VGA_MIS_R); 525 regval = vga_r(par->state.vgabase, VGA_MIS_R);
511 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 526 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
512} 527}
513 528
514 529
@@ -520,7 +535,10 @@ static int arkfb_open(struct fb_info *info, int user)
520 535
521 mutex_lock(&(par->open_lock)); 536 mutex_lock(&(par->open_lock));
522 if (par->ref_count == 0) { 537 if (par->ref_count == 0) {
538 void __iomem *vgabase = par->state.vgabase;
539
523 memset(&(par->state), 0, sizeof(struct vgastate)); 540 memset(&(par->state), 0, sizeof(struct vgastate));
541 par->state.vgabase = vgabase;
524 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 542 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
525 par->state.num_crtc = 0x60; 543 par->state.num_crtc = 0x60;
526 par->state.num_seq = 0x30; 544 par->state.num_seq = 0x30;
@@ -646,50 +664,50 @@ static int arkfb_set_par(struct fb_info *info)
646 info->var.activate = FB_ACTIVATE_NOW; 664 info->var.activate = FB_ACTIVATE_NOW;
647 665
648 /* Unlock registers */ 666 /* Unlock registers */
649 svga_wcrt_mask(0x11, 0x00, 0x80); 667 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
650 668
651 /* Blank screen and turn off sync */ 669 /* Blank screen and turn off sync */
652 svga_wseq_mask(0x01, 0x20, 0x20); 670 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
653 svga_wcrt_mask(0x17, 0x00, 0x80); 671 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
654 672
655 /* Set default values */ 673 /* Set default values */
656 svga_set_default_gfx_regs(); 674 svga_set_default_gfx_regs(par->state.vgabase);
657 svga_set_default_atc_regs(); 675 svga_set_default_atc_regs(par->state.vgabase);
658 svga_set_default_seq_regs(); 676 svga_set_default_seq_regs(par->state.vgabase);
659 svga_set_default_crt_regs(); 677 svga_set_default_crt_regs(par->state.vgabase);
660 svga_wcrt_multi(ark_line_compare_regs, 0xFFFFFFFF); 678 svga_wcrt_multi(par->state.vgabase, ark_line_compare_regs, 0xFFFFFFFF);
661 svga_wcrt_multi(ark_start_address_regs, 0); 679 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, 0);
662 680
663 /* ARK specific initialization */ 681 /* ARK specific initialization */
664 svga_wseq_mask(0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */ 682 svga_wseq_mask(par->state.vgabase, 0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */
665 svga_wseq_mask(0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */ 683 svga_wseq_mask(par->state.vgabase, 0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */
666 684
667 vga_wseq(NULL, 0x13, info->fix.smem_start >> 16); 685 vga_wseq(par->state.vgabase, 0x13, info->fix.smem_start >> 16);
668 vga_wseq(NULL, 0x14, info->fix.smem_start >> 24); 686 vga_wseq(par->state.vgabase, 0x14, info->fix.smem_start >> 24);
669 vga_wseq(NULL, 0x15, 0); 687 vga_wseq(par->state.vgabase, 0x15, 0);
670 vga_wseq(NULL, 0x16, 0); 688 vga_wseq(par->state.vgabase, 0x16, 0);
671 689
672 /* Set the FIFO threshold register */ 690 /* Set the FIFO threshold register */
673 /* It is fascinating way to store 5-bit value in 8-bit register */ 691 /* It is fascinating way to store 5-bit value in 8-bit register */
674 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1; 692 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1;
675 vga_wseq(NULL, 0x18, regval); 693 vga_wseq(par->state.vgabase, 0x18, regval);
676 694
677 /* Set the offset register */ 695 /* Set the offset register */
678 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 696 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
679 svga_wcrt_multi(ark_offset_regs, offset_value); 697 svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);
680 698
681 /* fix for hi-res textmode */ 699 /* fix for hi-res textmode */
682 svga_wcrt_mask(0x40, 0x08, 0x08); 700 svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08);
683 701
684 if (info->var.vmode & FB_VMODE_DOUBLE) 702 if (info->var.vmode & FB_VMODE_DOUBLE)
685 svga_wcrt_mask(0x09, 0x80, 0x80); 703 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
686 else 704 else
687 svga_wcrt_mask(0x09, 0x00, 0x80); 705 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
688 706
689 if (info->var.vmode & FB_VMODE_INTERLACED) 707 if (info->var.vmode & FB_VMODE_INTERLACED)
690 svga_wcrt_mask(0x44, 0x04, 0x04); 708 svga_wcrt_mask(par->state.vgabase, 0x44, 0x04, 0x04);
691 else 709 else
692 svga_wcrt_mask(0x44, 0x00, 0x04); 710 svga_wcrt_mask(par->state.vgabase, 0x44, 0x00, 0x04);
693 711
694 hmul = 1; 712 hmul = 1;
695 hdiv = 1; 713 hdiv = 1;
@@ -699,40 +717,40 @@ static int arkfb_set_par(struct fb_info *info)
699 switch (mode) { 717 switch (mode) {
700 case 0: 718 case 0:
701 pr_debug("fb%d: text mode\n", info->node); 719 pr_debug("fb%d: text mode\n", info->node);
702 svga_set_textmode_vga_regs(); 720 svga_set_textmode_vga_regs(par->state.vgabase);
703 721
704 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 722 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
705 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 723 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
706 dac_set_mode(par->dac, DAC_PSEUDO8_8); 724 dac_set_mode(par->dac, DAC_PSEUDO8_8);
707 725
708 break; 726 break;
709 case 1: 727 case 1:
710 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 728 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
711 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 729 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
712 730
713 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 731 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
714 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 732 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
715 dac_set_mode(par->dac, DAC_PSEUDO8_8); 733 dac_set_mode(par->dac, DAC_PSEUDO8_8);
716 break; 734 break;
717 case 2: 735 case 2:
718 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 736 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
719 737
720 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 738 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
721 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 739 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
722 dac_set_mode(par->dac, DAC_PSEUDO8_8); 740 dac_set_mode(par->dac, DAC_PSEUDO8_8);
723 break; 741 break;
724 case 3: 742 case 3:
725 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 743 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
726 744
727 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode */ 745 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode */
728 746
729 if (info->var.pixclock > 20000) { 747 if (info->var.pixclock > 20000) {
730 pr_debug("fb%d: not using multiplex\n", info->node); 748 pr_debug("fb%d: not using multiplex\n", info->node);
731 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 749 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
732 dac_set_mode(par->dac, DAC_PSEUDO8_8); 750 dac_set_mode(par->dac, DAC_PSEUDO8_8);
733 } else { 751 } else {
734 pr_debug("fb%d: using multiplex\n", info->node); 752 pr_debug("fb%d: using multiplex\n", info->node);
735 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 753 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
736 dac_set_mode(par->dac, DAC_PSEUDO8_16); 754 dac_set_mode(par->dac, DAC_PSEUDO8_16);
737 hdiv = 2; 755 hdiv = 2;
738 } 756 }
@@ -740,22 +758,22 @@ static int arkfb_set_par(struct fb_info *info)
740 case 4: 758 case 4:
741 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 759 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
742 760
743 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 761 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
744 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 762 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
745 dac_set_mode(par->dac, DAC_RGB1555_16); 763 dac_set_mode(par->dac, DAC_RGB1555_16);
746 break; 764 break;
747 case 5: 765 case 5:
748 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 766 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
749 767
750 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 768 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
751 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 769 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
752 dac_set_mode(par->dac, DAC_RGB0565_16); 770 dac_set_mode(par->dac, DAC_RGB0565_16);
753 break; 771 break;
754 case 6: 772 case 6:
755 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 773 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
756 774
757 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode ??? */ 775 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode ??? */
758 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 776 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
759 dac_set_mode(par->dac, DAC_RGB0888_16); 777 dac_set_mode(par->dac, DAC_RGB0888_16);
760 hmul = 3; 778 hmul = 3;
761 hdiv = 2; 779 hdiv = 2;
@@ -763,8 +781,8 @@ static int arkfb_set_par(struct fb_info *info)
763 case 7: 781 case 7:
764 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 782 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
765 783
766 vga_wseq(NULL, 0x11, 0x1E); /* 32bpp accel mode */ 784 vga_wseq(par->state.vgabase, 0x11, 0x1E); /* 32bpp accel mode */
767 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 785 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
768 dac_set_mode(par->dac, DAC_RGB8888_16); 786 dac_set_mode(par->dac, DAC_RGB8888_16);
769 hmul = 2; 787 hmul = 2;
770 break; 788 break;
@@ -774,7 +792,7 @@ static int arkfb_set_par(struct fb_info *info)
774 } 792 }
775 793
776 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul); 794 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
777 svga_set_timings(&ark_timing_regs, &(info->var), hmul, hdiv, 795 svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
778 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 796 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
779 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 797 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
780 hmul, info->node); 798 hmul, info->node);
@@ -782,12 +800,12 @@ static int arkfb_set_par(struct fb_info *info)
782 /* Set interlaced mode start/end register */ 800 /* Set interlaced mode start/end register */
783 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 801 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
784 value = ((value * hmul / hdiv) / 8) - 5; 802 value = ((value * hmul / hdiv) / 8) - 5;
785 vga_wcrt(NULL, 0x42, (value + 1) / 2); 803 vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
786 804
787 memset_io(info->screen_base, 0x00, screen_size); 805 memset_io(info->screen_base, 0x00, screen_size);
788 /* Device and screen back on */ 806 /* Device and screen back on */
789 svga_wcrt_mask(0x17, 0x80, 0x80); 807 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
790 svga_wseq_mask(0x01, 0x00, 0x20); 808 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
791 809
792 return 0; 810 return 0;
793} 811}
@@ -857,23 +875,25 @@ static int arkfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
857 875
858static int arkfb_blank(int blank_mode, struct fb_info *info) 876static int arkfb_blank(int blank_mode, struct fb_info *info)
859{ 877{
878 struct arkfb_info *par = info->par;
879
860 switch (blank_mode) { 880 switch (blank_mode) {
861 case FB_BLANK_UNBLANK: 881 case FB_BLANK_UNBLANK:
862 pr_debug("fb%d: unblank\n", info->node); 882 pr_debug("fb%d: unblank\n", info->node);
863 svga_wseq_mask(0x01, 0x00, 0x20); 883 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
864 svga_wcrt_mask(0x17, 0x80, 0x80); 884 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
865 break; 885 break;
866 case FB_BLANK_NORMAL: 886 case FB_BLANK_NORMAL:
867 pr_debug("fb%d: blank\n", info->node); 887 pr_debug("fb%d: blank\n", info->node);
868 svga_wseq_mask(0x01, 0x20, 0x20); 888 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
869 svga_wcrt_mask(0x17, 0x80, 0x80); 889 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
870 break; 890 break;
871 case FB_BLANK_POWERDOWN: 891 case FB_BLANK_POWERDOWN:
872 case FB_BLANK_HSYNC_SUSPEND: 892 case FB_BLANK_HSYNC_SUSPEND:
873 case FB_BLANK_VSYNC_SUSPEND: 893 case FB_BLANK_VSYNC_SUSPEND:
874 pr_debug("fb%d: sync down\n", info->node); 894 pr_debug("fb%d: sync down\n", info->node);
875 svga_wseq_mask(0x01, 0x20, 0x20); 895 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
876 svga_wcrt_mask(0x17, 0x00, 0x80); 896 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
877 break; 897 break;
878 } 898 }
879 return 0; 899 return 0;
@@ -884,6 +904,7 @@ static int arkfb_blank(int blank_mode, struct fb_info *info)
884 904
885static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 905static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
886{ 906{
907 struct arkfb_info *par = info->par;
887 unsigned int offset; 908 unsigned int offset;
888 909
889 /* Calculate the offset */ 910 /* Calculate the offset */
@@ -897,7 +918,7 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
897 } 918 }
898 919
899 /* Set the offset */ 920 /* Set the offset */
900 svga_wcrt_multi(ark_start_address_regs, offset); 921 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, offset);
901 922
902 return 0; 923 return 0;
903} 924}
@@ -930,6 +951,8 @@ static struct fb_ops arkfb_ops = {
930/* PCI probe */ 951/* PCI probe */
931static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 952static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
932{ 953{
954 struct pci_bus_region bus_reg;
955 struct resource vga_res;
933 struct fb_info *info; 956 struct fb_info *info;
934 struct arkfb_info *par; 957 struct arkfb_info *par;
935 int rc; 958 int rc;
@@ -985,8 +1008,17 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_
985 goto err_iomap; 1008 goto err_iomap;
986 } 1009 }
987 1010
1011 bus_reg.start = 0;
1012 bus_reg.end = 64 * 1024;
1013
1014 vga_res.flags = IORESOURCE_IO;
1015
1016 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1017
1018 par->state.vgabase = (void __iomem *) vga_res.start;
1019
988 /* FIXME get memsize */ 1020 /* FIXME get memsize */
989 regval = vga_rseq(NULL, 0x10); 1021 regval = vga_rseq(par->state.vgabase, 0x10);
990 info->screen_size = (1 << (regval >> 6)) << 20; 1022 info->screen_size = (1 << (regval >> 6)) << 20;
991 info->fix.smem_len = info->screen_size; 1023 info->fix.smem_len = info->screen_size;
992 1024
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index bac163450216..4484c721f0f9 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -68,7 +68,7 @@ static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
68} 68}
69#endif 69#endif
70 70
71static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 71static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
72 | ATMEL_LCDC_POL_POSITIVE 72 | ATMEL_LCDC_POL_POSITIVE
73 | ATMEL_LCDC_ENA_PWMENABLE; 73 | ATMEL_LCDC_ENA_PWMENABLE;
74 74
@@ -127,6 +127,7 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
127 return; 127 return;
128 128
129 memset(&props, 0, sizeof(struct backlight_properties)); 129 memset(&props, 0, sizeof(struct backlight_properties));
130 props.type = BACKLIGHT_RAW;
130 props.max_brightness = 0xff; 131 props.max_brightness = 0xff;
131 bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo, 132 bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo,
132 &atmel_lcdc_bl_ops, &props); 133 &atmel_lcdc_bl_ops, &props);
@@ -163,6 +164,10 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)
163 164
164static void init_contrast(struct atmel_lcdfb_info *sinfo) 165static void init_contrast(struct atmel_lcdfb_info *sinfo)
165{ 166{
167 /* contrast pwm can be 'inverted' */
168 if (sinfo->lcdcon_pol_negative)
169 contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
170
166 /* have some default contrast/backlight settings */ 171 /* have some default contrast/backlight settings */
167 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); 172 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
168 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); 173 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
@@ -632,7 +637,7 @@ static inline unsigned int chan_to_field(unsigned int chan, const struct fb_bitf
632 * magnitude which needs to be scaled in this function for the hardware. 637 * magnitude which needs to be scaled in this function for the hardware.
633 * Things to take into consideration are how many color registers, if 638 * Things to take into consideration are how many color registers, if
634 * any, are supported with the current color visual. With truecolor mode 639 * any, are supported with the current color visual. With truecolor mode
635 * no color palettes are supported. Here a psuedo palette is created 640 * no color palettes are supported. Here a pseudo palette is created
636 * which we store the value in pseudo_palette in struct fb_info. For 641 * which we store the value in pseudo_palette in struct fb_info. For
637 * pseudocolor mode we have a limited color palette. To deal with this 642 * pseudocolor mode we have a limited color palette. To deal with this
638 * we can program what color is displayed for a particular pixel value. 643 * we can program what color is displayed for a particular pixel value.
@@ -710,11 +715,35 @@ static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
710 return 0; 715 return 0;
711} 716}
712 717
718static int atmel_lcdfb_blank(int blank_mode, struct fb_info *info)
719{
720 struct atmel_lcdfb_info *sinfo = info->par;
721
722 switch (blank_mode) {
723 case FB_BLANK_UNBLANK:
724 case FB_BLANK_NORMAL:
725 atmel_lcdfb_start(sinfo);
726 break;
727 case FB_BLANK_VSYNC_SUSPEND:
728 case FB_BLANK_HSYNC_SUSPEND:
729 break;
730 case FB_BLANK_POWERDOWN:
731 atmel_lcdfb_stop(sinfo);
732 break;
733 default:
734 return -EINVAL;
735 }
736
737 /* let fbcon do a soft blank for us */
738 return ((blank_mode == FB_BLANK_NORMAL) ? 1 : 0);
739}
740
713static struct fb_ops atmel_lcdfb_ops = { 741static struct fb_ops atmel_lcdfb_ops = {
714 .owner = THIS_MODULE, 742 .owner = THIS_MODULE,
715 .fb_check_var = atmel_lcdfb_check_var, 743 .fb_check_var = atmel_lcdfb_check_var,
716 .fb_set_par = atmel_lcdfb_set_par, 744 .fb_set_par = atmel_lcdfb_set_par,
717 .fb_setcolreg = atmel_lcdfb_setcolreg, 745 .fb_setcolreg = atmel_lcdfb_setcolreg,
746 .fb_blank = atmel_lcdfb_blank,
718 .fb_pan_display = atmel_lcdfb_pan_display, 747 .fb_pan_display = atmel_lcdfb_pan_display,
719 .fb_fillrect = cfb_fillrect, 748 .fb_fillrect = cfb_fillrect,
720 .fb_copyarea = cfb_copyarea, 749 .fb_copyarea = cfb_copyarea,
@@ -816,6 +845,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
816 sinfo->guard_time = pdata_sinfo->guard_time; 845 sinfo->guard_time = pdata_sinfo->guard_time;
817 sinfo->smem_len = pdata_sinfo->smem_len; 846 sinfo->smem_len = pdata_sinfo->smem_len;
818 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; 847 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
848 sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative;
819 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; 849 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
820 } else { 850 } else {
821 dev_err(dev, "cannot get default configuration\n"); 851 dev_err(dev, "cannot get default configuration\n");
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 4cb6a576c567..b0b2ac335347 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1818,6 +1818,7 @@ static void aty128_bl_init(struct aty128fb_par *par)
1818 snprintf(name, sizeof(name), "aty128bl%d", info->node); 1818 snprintf(name, sizeof(name), "aty128bl%d", info->node);
1819 1819
1820 memset(&props, 0, sizeof(struct backlight_properties)); 1820 memset(&props, 0, sizeof(struct backlight_properties));
1821 props.type = BACKLIGHT_RAW;
1821 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 1822 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
1822 bd = backlight_device_register(name, info->dev, par, &aty128_bl_data, 1823 bd = backlight_device_register(name, info->dev, par, &aty128_bl_data,
1823 &props); 1824 &props);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 94e293fce1d2..ebb893c49e90 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2241,6 +2241,7 @@ static void aty_bl_init(struct atyfb_par *par)
2241 snprintf(name, sizeof(name), "atybl%d", info->node); 2241 snprintf(name, sizeof(name), "atybl%d", info->node);
2242 2242
2243 memset(&props, 0, sizeof(struct backlight_properties)); 2243 memset(&props, 0, sizeof(struct backlight_properties));
2244 props.type = BACKLIGHT_RAW;
2244 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 2245 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2245 bd = backlight_device_register(name, info->dev, par, &aty_bl_data, 2246 bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
2246 &props); 2247 &props);
@@ -3123,12 +3124,12 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
3123 M = pll_regs[2]; 3124 M = pll_regs[2];
3124 3125
3125 /* 3126 /*
3126 * PLL Feedback Divider N (Dependant on CLOCK_CNTL): 3127 * PLL Feedback Divider N (Dependent on CLOCK_CNTL):
3127 */ 3128 */
3128 N = pll_regs[7 + (clock_cntl & 3)]; 3129 N = pll_regs[7 + (clock_cntl & 3)];
3129 3130
3130 /* 3131 /*
3131 * PLL Post Divider P (Dependant on CLOCK_CNTL): 3132 * PLL Post Divider P (Dependent on CLOCK_CNTL):
3132 */ 3133 */
3133 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1)); 3134 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
3134 3135
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index 2ba8b3c421a1..46f72ed53510 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -51,7 +51,7 @@
51 * to a larger number and saturate CUR_HORZ_POSN to zero. 51 * to a larger number and saturate CUR_HORZ_POSN to zero.
52 * 52 *
53 * if Y becomes negative, CUR_VERT_OFFSET must be adjusted to a larger number, 53 * if Y becomes negative, CUR_VERT_OFFSET must be adjusted to a larger number,
54 * CUR_OFFSET must be adjusted to a point to the appropraite line in the cursor 54 * CUR_OFFSET must be adjusted to a point to the appropriate line in the cursor
55 * definitation and CUR_VERT_POSN must be saturated to zero. 55 * definitation and CUR_VERT_POSN must be saturated to zero.
56 */ 56 */
57 57
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 9b811ddbce83..db572df7e1ef 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -158,6 +158,7 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
158 snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); 158 snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
159 159
160 memset(&props, 0, sizeof(struct backlight_properties)); 160 memset(&props, 0, sizeof(struct backlight_properties));
161 props.type = BACKLIGHT_RAW;
161 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 162 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
162 bd = backlight_device_register(name, rinfo->info->dev, pdata, 163 bd = backlight_device_register(name, rinfo->info->dev, pdata,
163 &radeon_bl_data, &props); 164 &radeon_bl_data, &props);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 3c1e13ed1cba..32f8cf6200a7 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1248,7 +1248,7 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1248 1248
1249 /* Workaround from XFree */ 1249 /* Workaround from XFree */
1250 if (rinfo->is_mobility) { 1250 if (rinfo->is_mobility) {
1251 /* A temporal workaround for the occational blanking on certain laptop 1251 /* A temporal workaround for the occasional blanking on certain laptop
1252 * panels. This appears to related to the PLL divider registers 1252 * panels. This appears to related to the PLL divider registers
1253 * (fail to lock?). It occurs even when all dividers are the same 1253 * (fail to lock?). It occurs even when all dividers are the same
1254 * with their old settings. In this case we really don't need to 1254 * with their old settings. In this case we really don't need to
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 78d1f4cd1fe0..ab1d0fd76316 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -100,6 +100,9 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
100{ 100{
101 rinfo->i2c[0].rinfo = rinfo; 101 rinfo->i2c[0].rinfo = rinfo;
102 rinfo->i2c[0].ddc_reg = GPIO_MONID; 102 rinfo->i2c[0].ddc_reg = GPIO_MONID;
103#ifndef CONFIG_PPC
104 rinfo->i2c[0].adapter.class = I2C_CLASS_HWMON;
105#endif
103 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid"); 106 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
104 107
105 rinfo->i2c[1].rinfo = rinfo; 108 rinfo->i2c[1].rinfo = rinfo;
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 4ea187d93768..5dff32ac8044 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1572,7 +1572,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
1572 /* Copy monitor specs from panel data */ 1572 /* Copy monitor specs from panel data */
1573 /* fixme: we're setting up LCD controller windows, so these dont give a 1573 /* fixme: we're setting up LCD controller windows, so these dont give a
1574 damn as to what the monitor specs are (the panel itself does, but that 1574 damn as to what the monitor specs are (the panel itself does, but that
1575 isnt done here...so maybe need a generic catchall monitor setting??? */ 1575 isn't done here...so maybe need a generic catchall monitor setting??? */
1576 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs)); 1576 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
1577 1577
1578 /* We first try the user mode passed in argument. If that failed, 1578 /* We first try the user mode passed in argument. If that failed,
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index b224396b86d5..c8b520e9a11a 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -12,11 +12,12 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h>
15#include <linux/fb.h> 16#include <linux/fb.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/backlight.h> 18#include <linux/backlight.h>
19#include <linux/mfd/core.h>
18#include <linux/mfd/88pm860x.h> 20#include <linux/mfd/88pm860x.h>
19#include <linux/slab.h>
20 21
21#define MAX_BRIGHTNESS (0xFF) 22#define MAX_BRIGHTNESS (0xFF)
22#define MIN_BRIGHTNESS (0) 23#define MIN_BRIGHTNESS (0)
@@ -161,32 +162,13 @@ static const struct backlight_ops pm860x_backlight_ops = {
161 .get_brightness = pm860x_backlight_get_brightness, 162 .get_brightness = pm860x_backlight_get_brightness,
162}; 163};
163 164
164static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
165{
166 struct pm860x_backlight_pdata *p = pdata;
167 int ret = -EINVAL;
168
169 while (p && p->id) {
170 if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
171 break;
172
173 if (!strncmp(name, pm860x_backlight_name[p->flags],
174 MFD_NAME_SIZE)) {
175 ret = (int)p->flags;
176 break;
177 }
178 p++;
179 }
180 return ret;
181}
182
183static int pm860x_backlight_probe(struct platform_device *pdev) 165static int pm860x_backlight_probe(struct platform_device *pdev)
184{ 166{
185 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 167 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
186 struct pm860x_platform_data *pm860x_pdata;
187 struct pm860x_backlight_pdata *pdata = NULL; 168 struct pm860x_backlight_pdata *pdata = NULL;
188 struct pm860x_backlight_data *data; 169 struct pm860x_backlight_data *data;
189 struct backlight_device *bl; 170 struct backlight_device *bl;
171 struct mfd_cell *cell;
190 struct resource *res; 172 struct resource *res;
191 struct backlight_properties props; 173 struct backlight_properties props;
192 unsigned char value; 174 unsigned char value;
@@ -199,10 +181,10 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
199 return -EINVAL; 181 return -EINVAL;
200 } 182 }
201 183
202 if (pdev->dev.parent->platform_data) { 184 cell = pdev->dev.platform_data;
203 pm860x_pdata = pdev->dev.parent->platform_data; 185 if (cell == NULL)
204 pdata = pm860x_pdata->backlight; 186 return -ENODEV;
205 } 187 pdata = cell->mfd_data;
206 if (pdata == NULL) { 188 if (pdata == NULL) {
207 dev_err(&pdev->dev, "platform data isn't assigned to " 189 dev_err(&pdev->dev, "platform data isn't assigned to "
208 "backlight\n"); 190 "backlight\n");
@@ -219,7 +201,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
219 data->current_brightness = MAX_BRIGHTNESS; 201 data->current_brightness = MAX_BRIGHTNESS;
220 data->pwm = pdata->pwm; 202 data->pwm = pdata->pwm;
221 data->iset = pdata->iset; 203 data->iset = pdata->iset;
222 data->port = __check_device(pdata, name); 204 data->port = pdata->flags;
223 if (data->port < 0) { 205 if (data->port < 0) {
224 dev_err(&pdev->dev, "wrong platform data is assigned"); 206 dev_err(&pdev->dev, "wrong platform data is assigned");
225 kfree(data); 207 kfree(data);
@@ -227,6 +209,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
227 } 209 }
228 210
229 memset(&props, 0, sizeof(struct backlight_properties)); 211 memset(&props, 0, sizeof(struct backlight_properties));
212 props.type = BACKLIGHT_RAW;
230 props.max_brightness = MAX_BRIGHTNESS; 213 props.max_brightness = MAX_BRIGHTNESS;
231 bl = backlight_device_register(name, &pdev->dev, data, 214 bl = backlight_device_register(name, &pdev->dev, data,
232 &pm860x_backlight_ops, &props); 215 &pm860x_backlight_ops, &props);
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index e54a337227ea..0c9373bedd1f 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -109,6 +109,14 @@ config LCD_S6E63M0
109 If you have an S6E63M0 LCD Panel, say Y to enable its 109 If you have an S6E63M0 LCD Panel, say Y to enable its
110 LCD control driver. 110 LCD control driver.
111 111
112config LCD_LD9040
113 tristate "LD9040 AMOLED LCD Driver"
114 depends on SPI && BACKLIGHT_CLASS_DEVICE
115 default n
116 help
117 If you have an LD9040 Panel, say Y to enable its
118 control driver.
119
112endif # LCD_CLASS_DEVICE 120endif # LCD_CLASS_DEVICE
113 121
114# 122#
@@ -236,12 +244,12 @@ config BACKLIGHT_MAX8925
236 If you have a LCD backlight connected to the WLED output of MAX8925 244 If you have a LCD backlight connected to the WLED output of MAX8925
237 WLED output, say Y here to enable this driver. 245 WLED output, say Y here to enable this driver.
238 246
239config BACKLIGHT_MBP_NVIDIA 247config BACKLIGHT_APPLE
240 tristate "MacBook Pro Nvidia Backlight Driver" 248 tristate "Apple Backlight Driver"
241 depends on X86 249 depends on X86 && ACPI
242 help 250 help
243 If you have an Apple Macbook Pro with Nvidia graphics hardware say Y 251 If you have an Intel-based Apple say Y to enable a driver for its
244 to enable a driver for its backlight 252 backlight.
245 253
246config BACKLIGHT_TOSA 254config BACKLIGHT_TOSA
247 tristate "Sharp SL-6000 Backlight Driver" 255 tristate "Sharp SL-6000 Backlight Driver"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 44c0f81ad85d..b9ca8490df87 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
12obj-$(CONFIG_LCD_TDO24M) += tdo24m.o 12obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
13obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o 13obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
14obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o 14obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o
15obj-$(CONFIG_LCD_LD9040) += ld9040.o
15 16
16obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 17obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
17obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o 18obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
@@ -26,7 +27,7 @@ obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
26obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 27obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
27obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o 28obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
28obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o 29obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
29obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o 30obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
30obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 31obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
31obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 32obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
32obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o 33obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index 9f436e014f85..af3119707dbf 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -303,6 +303,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
303 mutex_init(&data->lock); 303 mutex_init(&data->lock);
304 304
305 memset(&props, 0, sizeof(struct backlight_properties)); 305 memset(&props, 0, sizeof(struct backlight_properties));
306 props.type = BACKLIGHT_RAW;
306 props.max_brightness = ADP5020_MAX_BRIGHTNESS; 307 props.max_brightness = ADP5020_MAX_BRIGHTNESS;
307 bl = backlight_device_register(pdev->name, data->master, data, 308 bl = backlight_device_register(pdev->name, data->master, data,
308 &adp5520_bl_ops, &props); 309 &adp5520_bl_ops, &props);
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 734c650a47c4..d2a96a421ffd 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -709,6 +709,7 @@ static int __devinit adp8860_probe(struct i2c_client *client,
709 i2c_set_clientdata(client, data); 709 i2c_set_clientdata(client, data);
710 710
711 memset(&props, 0, sizeof(props)); 711 memset(&props, 0, sizeof(props));
712 props.type = BACKLIGHT_RAW;
712 props.max_brightness = ADP8860_MAX_BRIGHTNESS; 713 props.max_brightness = ADP8860_MAX_BRIGHTNESS;
713 714
714 mutex_init(&data->lock); 715 mutex_init(&data->lock);
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c
index fe9af129c5dd..c861c41af442 100644
--- a/drivers/video/backlight/adx_bl.c
+++ b/drivers/video/backlight/adx_bl.c
@@ -104,6 +104,7 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev)
104 } 104 }
105 105
106 memset(&props, 0, sizeof(struct backlight_properties)); 106 memset(&props, 0, sizeof(struct backlight_properties));
107 props.type = BACKLIGHT_RAW;
107 props.max_brightness = 0xff; 108 props.max_brightness = 0xff;
108 bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, 109 bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
109 bl, &adx_backlight_ops, &props); 110 bl, &adx_backlight_ops, &props);
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c
new file mode 100644
index 000000000000..be98d152b7fd
--- /dev/null
+++ b/drivers/video/backlight/apple_bl.c
@@ -0,0 +1,241 @@
1/*
2 * Backlight Driver for Intel-based Apples
3 *
4 * Copyright (c) Red Hat <mjg@redhat.com>
5 * Based on code from Pommed:
6 * Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
7 * Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
8 * Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This driver triggers SMIs which cause the firmware to change the
15 * backlight brightness. This is icky in many ways, but it's impractical to
16 * get at the firmware code in order to figure out what it's actually doing.
17 */
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/backlight.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/pci.h>
26#include <linux/acpi.h>
27
28static struct backlight_device *apple_backlight_device;
29
30struct hw_data {
31 /* I/O resource to allocate. */
32 unsigned long iostart;
33 unsigned long iolen;
34 /* Backlight operations structure. */
35 const struct backlight_ops backlight_ops;
36 void (*set_brightness)(int);
37};
38
39static const struct hw_data *hw_data;
40
41#define DRIVER "apple_backlight: "
42
43/* Module parameters. */
44static int debug;
45module_param_named(debug, debug, int, 0644);
46MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
47
48/*
49 * Implementation for machines with Intel chipset.
50 */
51static void intel_chipset_set_brightness(int intensity)
52{
53 outb(0x04 | (intensity << 4), 0xb3);
54 outb(0xbf, 0xb2);
55}
56
57static int intel_chipset_send_intensity(struct backlight_device *bd)
58{
59 int intensity = bd->props.brightness;
60
61 if (debug)
62 printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
63 intensity);
64
65 intel_chipset_set_brightness(intensity);
66 return 0;
67}
68
69static int intel_chipset_get_intensity(struct backlight_device *bd)
70{
71 int intensity;
72
73 outb(0x03, 0xb3);
74 outb(0xbf, 0xb2);
75 intensity = inb(0xb3) >> 4;
76
77 if (debug)
78 printk(KERN_DEBUG DRIVER "read brightness of %d\n",
79 intensity);
80
81 return intensity;
82}
83
84static const struct hw_data intel_chipset_data = {
85 .iostart = 0xb2,
86 .iolen = 2,
87 .backlight_ops = {
88 .options = BL_CORE_SUSPENDRESUME,
89 .get_brightness = intel_chipset_get_intensity,
90 .update_status = intel_chipset_send_intensity,
91 },
92 .set_brightness = intel_chipset_set_brightness,
93};
94
95/*
96 * Implementation for machines with Nvidia chipset.
97 */
98static void nvidia_chipset_set_brightness(int intensity)
99{
100 outb(0x04 | (intensity << 4), 0x52f);
101 outb(0xbf, 0x52e);
102}
103
104static int nvidia_chipset_send_intensity(struct backlight_device *bd)
105{
106 int intensity = bd->props.brightness;
107
108 if (debug)
109 printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
110 intensity);
111
112 nvidia_chipset_set_brightness(intensity);
113 return 0;
114}
115
116static int nvidia_chipset_get_intensity(struct backlight_device *bd)
117{
118 int intensity;
119
120 outb(0x03, 0x52f);
121 outb(0xbf, 0x52e);
122 intensity = inb(0x52f) >> 4;
123
124 if (debug)
125 printk(KERN_DEBUG DRIVER "read brightness of %d\n",
126 intensity);
127
128 return intensity;
129}
130
131static const struct hw_data nvidia_chipset_data = {
132 .iostart = 0x52e,
133 .iolen = 2,
134 .backlight_ops = {
135 .options = BL_CORE_SUSPENDRESUME,
136 .get_brightness = nvidia_chipset_get_intensity,
137 .update_status = nvidia_chipset_send_intensity
138 },
139 .set_brightness = nvidia_chipset_set_brightness,
140};
141
142static int __devinit apple_bl_add(struct acpi_device *dev)
143{
144 struct backlight_properties props;
145 struct pci_dev *host;
146 int intensity;
147
148 host = pci_get_bus_and_slot(0, 0);
149
150 if (!host) {
151 printk(KERN_ERR DRIVER "unable to find PCI host\n");
152 return -ENODEV;
153 }
154
155 if (host->vendor == PCI_VENDOR_ID_INTEL)
156 hw_data = &intel_chipset_data;
157 else if (host->vendor == PCI_VENDOR_ID_NVIDIA)
158 hw_data = &nvidia_chipset_data;
159
160 pci_dev_put(host);
161
162 if (!hw_data) {
163 printk(KERN_ERR DRIVER "unknown hardware\n");
164 return -ENODEV;
165 }
166
167 /* Check that the hardware responds - this may not work under EFI */
168
169 intensity = hw_data->backlight_ops.get_brightness(NULL);
170
171 if (!intensity) {
172 hw_data->set_brightness(1);
173 if (!hw_data->backlight_ops.get_brightness(NULL))
174 return -ENODEV;
175
176 hw_data->set_brightness(0);
177 }
178
179 if (!request_region(hw_data->iostart, hw_data->iolen,
180 "Apple backlight"))
181 return -ENXIO;
182
183 memset(&props, 0, sizeof(struct backlight_properties));
184 props.type = BACKLIGHT_PLATFORM;
185 props.max_brightness = 15;
186 apple_backlight_device = backlight_device_register("apple_backlight",
187 NULL, NULL, &hw_data->backlight_ops, &props);
188
189 if (IS_ERR(apple_backlight_device)) {
190 release_region(hw_data->iostart, hw_data->iolen);
191 return PTR_ERR(apple_backlight_device);
192 }
193
194 apple_backlight_device->props.brightness =
195 hw_data->backlight_ops.get_brightness(apple_backlight_device);
196 backlight_update_status(apple_backlight_device);
197
198 return 0;
199}
200
201static int __devexit apple_bl_remove(struct acpi_device *dev, int type)
202{
203 backlight_device_unregister(apple_backlight_device);
204
205 release_region(hw_data->iostart, hw_data->iolen);
206 hw_data = NULL;
207 return 0;
208}
209
210static const struct acpi_device_id apple_bl_ids[] = {
211 {"APP0002", 0},
212 {"", 0},
213};
214
215static struct acpi_driver apple_bl_driver = {
216 .name = "Apple backlight",
217 .ids = apple_bl_ids,
218 .ops = {
219 .add = apple_bl_add,
220 .remove = apple_bl_remove,
221 },
222};
223
224static int __init apple_bl_init(void)
225{
226 return acpi_bus_register_driver(&apple_bl_driver);
227}
228
229static void __exit apple_bl_exit(void)
230{
231 acpi_bus_unregister_driver(&apple_bl_driver);
232}
233
234module_init(apple_bl_init);
235module_exit(apple_bl_exit);
236
237MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
238MODULE_DESCRIPTION("Apple Backlight Driver");
239MODULE_LICENSE("GPL");
240MODULE_DEVICE_TABLE(acpi, apple_bl_ids);
241MODULE_ALIAS("mbp_nvidia_bl");
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index e6a66dab088c..0443a4f71858 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -168,6 +168,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
168 } 168 }
169 169
170 memset(&props, 0, sizeof(struct backlight_properties)); 170 memset(&props, 0, sizeof(struct backlight_properties));
171 props.type = BACKLIGHT_RAW;
171 props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; 172 props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
172 bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl, 173 bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl,
173 &atmel_pwm_bl_ops, &props); 174 &atmel_pwm_bl_ops, &props);
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 08703299ef61..80d292fb92d8 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -19,6 +19,12 @@
19#include <asm/backlight.h> 19#include <asm/backlight.h>
20#endif 20#endif
21 21
22static const char const *backlight_types[] = {
23 [BACKLIGHT_RAW] = "raw",
24 [BACKLIGHT_PLATFORM] = "platform",
25 [BACKLIGHT_FIRMWARE] = "firmware",
26};
27
22#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ 28#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
23 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) 29 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
24/* This callback gets called when something important happens inside a 30/* This callback gets called when something important happens inside a
@@ -169,6 +175,14 @@ static ssize_t backlight_store_brightness(struct device *dev,
169 return rc; 175 return rc;
170} 176}
171 177
178static ssize_t backlight_show_type(struct device *dev,
179 struct device_attribute *attr, char *buf)
180{
181 struct backlight_device *bd = to_backlight_device(dev);
182
183 return sprintf(buf, "%s\n", backlight_types[bd->props.type]);
184}
185
172static ssize_t backlight_show_max_brightness(struct device *dev, 186static ssize_t backlight_show_max_brightness(struct device *dev,
173 struct device_attribute *attr, char *buf) 187 struct device_attribute *attr, char *buf)
174{ 188{
@@ -234,6 +248,7 @@ static struct device_attribute bl_device_attributes[] = {
234 __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, 248 __ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
235 NULL), 249 NULL),
236 __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), 250 __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
251 __ATTR(type, 0444, backlight_show_type, NULL),
237 __ATTR_NULL, 252 __ATTR_NULL,
238}; 253};
239 254
@@ -292,9 +307,16 @@ struct backlight_device *backlight_device_register(const char *name,
292 dev_set_drvdata(&new_bd->dev, devdata); 307 dev_set_drvdata(&new_bd->dev, devdata);
293 308
294 /* Set default properties */ 309 /* Set default properties */
295 if (props) 310 if (props) {
296 memcpy(&new_bd->props, props, 311 memcpy(&new_bd->props, props,
297 sizeof(struct backlight_properties)); 312 sizeof(struct backlight_properties));
313 if (props->type <= 0 || props->type >= BACKLIGHT_TYPE_MAX) {
314 WARN(1, "%s: invalid backlight type", name);
315 new_bd->props.type = BACKLIGHT_RAW;
316 }
317 } else {
318 new_bd->props.type = BACKLIGHT_RAW;
319 }
298 320
299 rc = device_register(&new_bd->dev); 321 rc = device_register(&new_bd->dev);
300 if (rc) { 322 if (rc) {
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index 1e71c35083bb..c6533bad26f8 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -109,7 +109,7 @@ static unsigned long corgibl_flags;
109#define CORGIBL_BATTLOW 0x02 109#define CORGIBL_BATTLOW 0x02
110 110
111/* 111/*
112 * This is only a psuedo I2C interface. We can't use the standard kernel 112 * This is only a pseudo I2C interface. We can't use the standard kernel
113 * routines as the interface is write only. We just assume the data is acked... 113 * routines as the interface is write only. We just assume the data is acked...
114 */ 114 */
115static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data) 115static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data)
@@ -562,6 +562,7 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi)
562 lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; 562 lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
563 563
564 memset(&props, 0, sizeof(struct backlight_properties)); 564 memset(&props, 0, sizeof(struct backlight_properties));
565 props.type = BACKLIGHT_RAW;
565 props.max_brightness = pdata->max_intensity; 566 props.max_brightness = pdata->max_intensity;
566 lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd, 567 lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd,
567 &corgi_bl_ops, &props); 568 &corgi_bl_ops, &props);
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index 397d15eb1ea8..6c8c54041fae 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -193,6 +193,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
193 } 193 }
194 194
195 memset(&props, 0, sizeof(struct backlight_properties)); 195 memset(&props, 0, sizeof(struct backlight_properties));
196 props.type = BACKLIGHT_RAW;
196 bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL, 197 bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL,
197 &cr_backlight_ops, &props); 198 &cr_backlight_ops, &props);
198 if (IS_ERR(bdp)) { 199 if (IS_ERR(bdp)) {
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index 87659ed79bd7..62043f12a5a4 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -136,6 +136,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
136 da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2, 136 da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
137 DA9034_WLED_ISET(pdata->output_current)); 137 DA9034_WLED_ISET(pdata->output_current));
138 138
139 props.type = BACKLIGHT_RAW;
139 props.max_brightness = max_brightness; 140 props.max_brightness = max_brightness;
140 bl = backlight_device_register(pdev->name, data->da903x_dev, data, 141 bl = backlight_device_register(pdev->name, data->da903x_dev, data,
141 &da903x_backlight_ops, &props); 142 &da903x_backlight_ops, &props);
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index b0cc49184803..9f1e389d51d2 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -87,6 +87,7 @@ static int __init ep93xxbl_probe(struct platform_device *dev)
87 ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS; 87 ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS;
88 88
89 memset(&props, 0, sizeof(struct backlight_properties)); 89 memset(&props, 0, sizeof(struct backlight_properties));
90 props.type = BACKLIGHT_RAW;
90 props.max_brightness = EP93XX_MAX_BRIGHT; 91 props.max_brightness = EP93XX_MAX_BRIGHT;
91 bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl, 92 bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl,
92 &ep93xxbl_ops, &props); 93 &ep93xxbl_ops, &props);
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c
index 312ca619735d..8c6befd65a33 100644
--- a/drivers/video/backlight/generic_bl.c
+++ b/drivers/video/backlight/generic_bl.c
@@ -91,6 +91,7 @@ static int genericbl_probe(struct platform_device *pdev)
91 name = machinfo->name; 91 name = machinfo->name;
92 92
93 memset(&props, 0, sizeof(struct backlight_properties)); 93 memset(&props, 0, sizeof(struct backlight_properties));
94 props.type = BACKLIGHT_RAW;
94 props.max_brightness = machinfo->max_intensity; 95 props.max_brightness = machinfo->max_intensity;
95 bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops, 96 bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
96 &props); 97 &props);
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 267d23f8d645..38aa00272141 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -109,6 +109,7 @@ static int __devinit hp680bl_probe(struct platform_device *pdev)
109 struct backlight_device *bd; 109 struct backlight_device *bd;
110 110
111 memset(&props, 0, sizeof(struct backlight_properties)); 111 memset(&props, 0, sizeof(struct backlight_properties));
112 props.type = BACKLIGHT_RAW;
112 props.max_brightness = HP680_MAX_INTENSITY; 113 props.max_brightness = HP680_MAX_INTENSITY;
113 bd = backlight_device_register("hp680-bl", &pdev->dev, NULL, 114 bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
114 &hp680bl_ops, &props); 115 &hp680bl_ops, &props);
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
index 2f177b3a4885..de65d80159be 100644
--- a/drivers/video/backlight/jornada720_bl.c
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -106,6 +106,7 @@ static int jornada_bl_probe(struct platform_device *pdev)
106 struct backlight_device *bd; 106 struct backlight_device *bd;
107 107
108 memset(&props, 0, sizeof(struct backlight_properties)); 108 memset(&props, 0, sizeof(struct backlight_properties));
109 props.type = BACKLIGHT_RAW;
109 props.max_brightness = BL_MAX_BRIGHT; 110 props.max_brightness = BL_MAX_BRIGHT;
110 bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, 111 bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
111 &jornada_bl_ops, &props); 112 &jornada_bl_ops, &props);
@@ -146,12 +147,12 @@ static struct platform_driver jornada_bl_driver = {
146 }, 147 },
147}; 148};
148 149
149int __init jornada_bl_init(void) 150static int __init jornada_bl_init(void)
150{ 151{
151 return platform_driver_register(&jornada_bl_driver); 152 return platform_driver_register(&jornada_bl_driver);
152} 153}
153 154
154void __exit jornada_bl_exit(void) 155static void __exit jornada_bl_exit(void)
155{ 156{
156 platform_driver_unregister(&jornada_bl_driver); 157 platform_driver_unregister(&jornada_bl_driver);
157} 158}
diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c
index cbbb167fd268..d2ff658b4144 100644
--- a/drivers/video/backlight/jornada720_lcd.c
+++ b/drivers/video/backlight/jornada720_lcd.c
@@ -135,12 +135,12 @@ static struct platform_driver jornada_lcd_driver = {
135 }, 135 },
136}; 136};
137 137
138int __init jornada_lcd_init(void) 138static int __init jornada_lcd_init(void)
139{ 139{
140 return platform_driver_register(&jornada_lcd_driver); 140 return platform_driver_register(&jornada_lcd_driver);
141} 141}
142 142
143void __exit jornada_lcd_exit(void) 143static void __exit jornada_lcd_exit(void)
144{ 144{
145 platform_driver_unregister(&jornada_lcd_driver); 145 platform_driver_unregister(&jornada_lcd_driver);
146} 146}
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
index f439a8632287..72dd5556a35b 100644
--- a/drivers/video/backlight/kb3886_bl.c
+++ b/drivers/video/backlight/kb3886_bl.c
@@ -149,6 +149,7 @@ static int kb3886bl_probe(struct platform_device *pdev)
149 machinfo->limit_mask = -1; 149 machinfo->limit_mask = -1;
150 150
151 memset(&props, 0, sizeof(struct backlight_properties)); 151 memset(&props, 0, sizeof(struct backlight_properties));
152 props.type = BACKLIGHT_RAW;
152 props.max_brightness = machinfo->max_intensity; 153 props.max_brightness = machinfo->max_intensity;
153 kb3886_backlight_device = backlight_device_register("kb3886-bl", 154 kb3886_backlight_device = backlight_device_register("kb3886-bl",
154 &pdev->dev, NULL, 155 &pdev->dev, NULL,
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
new file mode 100644
index 000000000000..7281b2506a67
--- /dev/null
+++ b/drivers/video/backlight/ld9040.c
@@ -0,0 +1,819 @@
1/*
2 * ld9040 AMOLED LCD panel driver.
3 *
4 * Copyright (c) 2011 Samsung Electronics
5 * Author: Donghwa Lee <dh09.lee@samsung.com>
6 * Derived from drivers/video/backlight/s6e63m0.c
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#include <linux/wait.h>
24#include <linux/fb.h>
25#include <linux/delay.h>
26#include <linux/gpio.h>
27#include <linux/spi/spi.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h>
30#include <linux/kernel.h>
31#include <linux/lcd.h>
32#include <linux/backlight.h>
33
34#include "ld9040_gamma.h"
35
36#define SLEEPMSEC 0x1000
37#define ENDDEF 0x2000
38#define DEFMASK 0xFF00
39#define COMMAND_ONLY 0xFE
40#define DATA_ONLY 0xFF
41
42#define MIN_BRIGHTNESS 0
43#define MAX_BRIGHTNESS 24
44#define power_is_on(pwr) ((pwr) <= FB_BLANK_NORMAL)
45
46struct ld9040 {
47 struct device *dev;
48 struct spi_device *spi;
49 unsigned int power;
50 unsigned int current_brightness;
51
52 struct lcd_device *ld;
53 struct backlight_device *bd;
54 struct lcd_platform_data *lcd_pd;
55};
56
57static const unsigned short seq_swreset[] = {
58 0x01, COMMAND_ONLY,
59 ENDDEF, 0x00
60};
61
62static const unsigned short seq_user_setting[] = {
63 0xF0, 0x5A,
64
65 DATA_ONLY, 0x5A,
66 ENDDEF, 0x00
67};
68
69static const unsigned short seq_elvss_on[] = {
70 0xB1, 0x0D,
71
72 DATA_ONLY, 0x00,
73 DATA_ONLY, 0x16,
74 ENDDEF, 0x00
75};
76
77static const unsigned short seq_gtcon[] = {
78 0xF7, 0x09,
79
80 DATA_ONLY, 0x00,
81 DATA_ONLY, 0x00,
82 ENDDEF, 0x00
83};
84
85static const unsigned short seq_panel_condition[] = {
86 0xF8, 0x05,
87
88 DATA_ONLY, 0x65,
89 DATA_ONLY, 0x96,
90 DATA_ONLY, 0x71,
91 DATA_ONLY, 0x7D,
92 DATA_ONLY, 0x19,
93 DATA_ONLY, 0x3B,
94 DATA_ONLY, 0x0D,
95 DATA_ONLY, 0x19,
96 DATA_ONLY, 0x7E,
97 DATA_ONLY, 0x0D,
98 DATA_ONLY, 0xE2,
99 DATA_ONLY, 0x00,
100 DATA_ONLY, 0x00,
101 DATA_ONLY, 0x7E,
102 DATA_ONLY, 0x7D,
103 DATA_ONLY, 0x07,
104 DATA_ONLY, 0x07,
105 DATA_ONLY, 0x20,
106 DATA_ONLY, 0x20,
107 DATA_ONLY, 0x20,
108 DATA_ONLY, 0x02,
109 DATA_ONLY, 0x02,
110 ENDDEF, 0x00
111};
112
113static const unsigned short seq_gamma_set1[] = {
114 0xF9, 0x00,
115
116 DATA_ONLY, 0xA7,
117 DATA_ONLY, 0xB4,
118 DATA_ONLY, 0xAE,
119 DATA_ONLY, 0xBF,
120 DATA_ONLY, 0x00,
121 DATA_ONLY, 0x91,
122 DATA_ONLY, 0x00,
123 DATA_ONLY, 0xB2,
124 DATA_ONLY, 0xB4,
125 DATA_ONLY, 0xAA,
126 DATA_ONLY, 0xBB,
127 DATA_ONLY, 0x00,
128 DATA_ONLY, 0xAC,
129 DATA_ONLY, 0x00,
130 DATA_ONLY, 0xB3,
131 DATA_ONLY, 0xB1,
132 DATA_ONLY, 0xAA,
133 DATA_ONLY, 0xBC,
134 DATA_ONLY, 0x00,
135 DATA_ONLY, 0xB3,
136 ENDDEF, 0x00
137};
138
139static const unsigned short seq_gamma_ctrl[] = {
140 0xFB, 0x02,
141
142 DATA_ONLY, 0x5A,
143 ENDDEF, 0x00
144};
145
146static const unsigned short seq_gamma_start[] = {
147 0xF9, COMMAND_ONLY,
148
149 ENDDEF, 0x00
150};
151
152static const unsigned short seq_apon[] = {
153 0xF3, 0x00,
154
155 DATA_ONLY, 0x00,
156 DATA_ONLY, 0x00,
157 DATA_ONLY, 0x0A,
158 DATA_ONLY, 0x02,
159 ENDDEF, 0x00
160};
161
162static const unsigned short seq_display_ctrl[] = {
163 0xF2, 0x02,
164
165 DATA_ONLY, 0x08,
166 DATA_ONLY, 0x08,
167 DATA_ONLY, 0x10,
168 DATA_ONLY, 0x10,
169 ENDDEF, 0x00
170};
171
172static const unsigned short seq_manual_pwr[] = {
173 0xB0, 0x04,
174 ENDDEF, 0x00
175};
176
177static const unsigned short seq_pwr_ctrl[] = {
178 0xF4, 0x0A,
179
180 DATA_ONLY, 0x87,
181 DATA_ONLY, 0x25,
182 DATA_ONLY, 0x6A,
183 DATA_ONLY, 0x44,
184 DATA_ONLY, 0x02,
185 DATA_ONLY, 0x88,
186 ENDDEF, 0x00
187};
188
189static const unsigned short seq_sleep_out[] = {
190 0x11, COMMAND_ONLY,
191 ENDDEF, 0x00
192};
193
194static const unsigned short seq_sleep_in[] = {
195 0x10, COMMAND_ONLY,
196 ENDDEF, 0x00
197};
198
199static const unsigned short seq_display_on[] = {
200 0x29, COMMAND_ONLY,
201 ENDDEF, 0x00
202};
203
204static const unsigned short seq_display_off[] = {
205 0x28, COMMAND_ONLY,
206 ENDDEF, 0x00
207};
208
209static const unsigned short seq_vci1_1st_en[] = {
210 0xF3, 0x10,
211
212 DATA_ONLY, 0x00,
213 DATA_ONLY, 0x00,
214 DATA_ONLY, 0x00,
215 DATA_ONLY, 0x02,
216 ENDDEF, 0x00
217};
218
219static const unsigned short seq_vl1_en[] = {
220 0xF3, 0x11,
221
222 DATA_ONLY, 0x00,
223 DATA_ONLY, 0x00,
224 DATA_ONLY, 0x00,
225 DATA_ONLY, 0x02,
226 ENDDEF, 0x00
227};
228
229static const unsigned short seq_vl2_en[] = {
230 0xF3, 0x13,
231
232 DATA_ONLY, 0x00,
233 DATA_ONLY, 0x00,
234 DATA_ONLY, 0x00,
235 DATA_ONLY, 0x02,
236 ENDDEF, 0x00
237};
238
239static const unsigned short seq_vci1_2nd_en[] = {
240 0xF3, 0x33,
241
242 DATA_ONLY, 0x00,
243 DATA_ONLY, 0x00,
244 DATA_ONLY, 0x00,
245 DATA_ONLY, 0x02,
246 ENDDEF, 0x00
247};
248
249static const unsigned short seq_vl3_en[] = {
250 0xF3, 0x37,
251
252 DATA_ONLY, 0x00,
253 DATA_ONLY, 0x00,
254 DATA_ONLY, 0x00,
255 DATA_ONLY, 0x02,
256 ENDDEF, 0x00
257};
258
259static const unsigned short seq_vreg1_amp_en[] = {
260 0xF3, 0x37,
261
262 DATA_ONLY, 0x01,
263 DATA_ONLY, 0x00,
264 DATA_ONLY, 0x00,
265 DATA_ONLY, 0x02,
266 ENDDEF, 0x00
267};
268
269static const unsigned short seq_vgh_amp_en[] = {
270 0xF3, 0x37,
271
272 DATA_ONLY, 0x11,
273 DATA_ONLY, 0x00,
274 DATA_ONLY, 0x00,
275 DATA_ONLY, 0x02,
276 ENDDEF, 0x00
277};
278
279static const unsigned short seq_vgl_amp_en[] = {
280 0xF3, 0x37,
281
282 DATA_ONLY, 0x31,
283 DATA_ONLY, 0x00,
284 DATA_ONLY, 0x00,
285 DATA_ONLY, 0x02,
286 ENDDEF, 0x00
287};
288
289static const unsigned short seq_vmos_amp_en[] = {
290 0xF3, 0x37,
291
292 DATA_ONLY, 0xB1,
293 DATA_ONLY, 0x00,
294 DATA_ONLY, 0x00,
295 DATA_ONLY, 0x03,
296 ENDDEF, 0x00
297};
298
299static const unsigned short seq_vint_amp_en[] = {
300 0xF3, 0x37,
301
302 DATA_ONLY, 0xF1,
303 /* DATA_ONLY, 0x71, VMOS/VBL/VBH not used */
304 DATA_ONLY, 0x00,
305 DATA_ONLY, 0x00,
306 DATA_ONLY, 0x03,
307 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
308 ENDDEF, 0x00
309};
310
311static const unsigned short seq_vbh_amp_en[] = {
312 0xF3, 0x37,
313
314 DATA_ONLY, 0xF9,
315 DATA_ONLY, 0x00,
316 DATA_ONLY, 0x00,
317 DATA_ONLY, 0x03,
318 ENDDEF, 0x00
319};
320
321static const unsigned short seq_vbl_amp_en[] = {
322 0xF3, 0x37,
323
324 DATA_ONLY, 0xFD,
325 DATA_ONLY, 0x00,
326 DATA_ONLY, 0x00,
327 DATA_ONLY, 0x03,
328 ENDDEF, 0x00
329};
330
331static const unsigned short seq_gam_amp_en[] = {
332 0xF3, 0x37,
333
334 DATA_ONLY, 0xFF,
335 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
336 DATA_ONLY, 0x00,
337 DATA_ONLY, 0x00,
338 DATA_ONLY, 0x03,
339 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
340 ENDDEF, 0x00
341};
342
343static const unsigned short seq_sd_amp_en[] = {
344 0xF3, 0x37,
345
346 DATA_ONLY, 0xFF,
347 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
348 DATA_ONLY, 0x80,
349 DATA_ONLY, 0x00,
350 DATA_ONLY, 0x03,
351 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
352 ENDDEF, 0x00
353};
354
355static const unsigned short seq_gls_en[] = {
356 0xF3, 0x37,
357
358 DATA_ONLY, 0xFF,
359 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
360 DATA_ONLY, 0x81,
361 DATA_ONLY, 0x00,
362 DATA_ONLY, 0x03,
363 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
364 ENDDEF, 0x00
365};
366
367static const unsigned short seq_els_en[] = {
368 0xF3, 0x37,
369
370 DATA_ONLY, 0xFF,
371 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
372 DATA_ONLY, 0x83,
373 DATA_ONLY, 0x00,
374 DATA_ONLY, 0x03,
375 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
376 ENDDEF, 0x00
377};
378
379static const unsigned short seq_el_on[] = {
380 0xF3, 0x37,
381
382 DATA_ONLY, 0xFF,
383 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
384 DATA_ONLY, 0x87,
385 DATA_ONLY, 0x00,
386 DATA_ONLY, 0x03,
387 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
388 ENDDEF, 0x00
389};
390
391static int ld9040_spi_write_byte(struct ld9040 *lcd, int addr, int data)
392{
393 u16 buf[1];
394 struct spi_message msg;
395
396 struct spi_transfer xfer = {
397 .len = 2,
398 .tx_buf = buf,
399 };
400
401 buf[0] = (addr << 8) | data;
402
403 spi_message_init(&msg);
404 spi_message_add_tail(&xfer, &msg);
405
406 return spi_sync(lcd->spi, &msg);
407}
408
409static int ld9040_spi_write(struct ld9040 *lcd, unsigned char address,
410 unsigned char command)
411{
412 int ret = 0;
413
414 if (address != DATA_ONLY)
415 ret = ld9040_spi_write_byte(lcd, 0x0, address);
416 if (command != COMMAND_ONLY)
417 ret = ld9040_spi_write_byte(lcd, 0x1, command);
418
419 return ret;
420}
421
422static int ld9040_panel_send_sequence(struct ld9040 *lcd,
423 const unsigned short *wbuf)
424{
425 int ret = 0, i = 0;
426
427 while ((wbuf[i] & DEFMASK) != ENDDEF) {
428 if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
429 ret = ld9040_spi_write(lcd, wbuf[i], wbuf[i+1]);
430 if (ret)
431 break;
432 } else
433 udelay(wbuf[i+1]*1000);
434 i += 2;
435 }
436
437 return ret;
438}
439
440static int _ld9040_gamma_ctl(struct ld9040 *lcd, const unsigned int *gamma)
441{
442 unsigned int i = 0;
443 int ret = 0;
444
445 /* start gamma table updating. */
446 ret = ld9040_panel_send_sequence(lcd, seq_gamma_start);
447 if (ret) {
448 dev_err(lcd->dev, "failed to disable gamma table updating.\n");
449 goto gamma_err;
450 }
451
452 for (i = 0 ; i < GAMMA_TABLE_COUNT; i++) {
453 ret = ld9040_spi_write(lcd, DATA_ONLY, gamma[i]);
454 if (ret) {
455 dev_err(lcd->dev, "failed to set gamma table.\n");
456 goto gamma_err;
457 }
458 }
459
460 /* update gamma table. */
461 ret = ld9040_panel_send_sequence(lcd, seq_gamma_ctrl);
462 if (ret)
463 dev_err(lcd->dev, "failed to update gamma table.\n");
464
465gamma_err:
466 return ret;
467}
468
469static int ld9040_gamma_ctl(struct ld9040 *lcd, int gamma)
470{
471 int ret = 0;
472
473 ret = _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
474
475 return ret;
476}
477
478
479static int ld9040_ldi_init(struct ld9040 *lcd)
480{
481 int ret, i;
482 static const unsigned short *init_seq[] = {
483 seq_user_setting,
484 seq_panel_condition,
485 seq_display_ctrl,
486 seq_manual_pwr,
487 seq_elvss_on,
488 seq_gtcon,
489 seq_gamma_set1,
490 seq_gamma_ctrl,
491 seq_sleep_out,
492 };
493
494 for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
495 ret = ld9040_panel_send_sequence(lcd, init_seq[i]);
496 /* workaround: minimum delay time for transferring CMD */
497 udelay(300);
498 if (ret)
499 break;
500 }
501
502 return ret;
503}
504
505static int ld9040_ldi_enable(struct ld9040 *lcd)
506{
507 int ret = 0;
508
509 ret = ld9040_panel_send_sequence(lcd, seq_display_on);
510
511 return ret;
512}
513
514static int ld9040_ldi_disable(struct ld9040 *lcd)
515{
516 int ret;
517
518 ret = ld9040_panel_send_sequence(lcd, seq_display_off);
519 ret = ld9040_panel_send_sequence(lcd, seq_sleep_in);
520
521 return ret;
522}
523
524static int ld9040_power_on(struct ld9040 *lcd)
525{
526 int ret = 0;
527 struct lcd_platform_data *pd = NULL;
528 pd = lcd->lcd_pd;
529 if (!pd) {
530 dev_err(lcd->dev, "platform data is NULL.\n");
531 return -EFAULT;
532 }
533
534 if (!pd->power_on) {
535 dev_err(lcd->dev, "power_on is NULL.\n");
536 return -EFAULT;
537 } else {
538 pd->power_on(lcd->ld, 1);
539 mdelay(pd->power_on_delay);
540 }
541
542 if (!pd->reset) {
543 dev_err(lcd->dev, "reset is NULL.\n");
544 return -EFAULT;
545 } else {
546 pd->reset(lcd->ld);
547 mdelay(pd->reset_delay);
548 }
549
550 ret = ld9040_ldi_init(lcd);
551 if (ret) {
552 dev_err(lcd->dev, "failed to initialize ldi.\n");
553 return ret;
554 }
555
556 ret = ld9040_ldi_enable(lcd);
557 if (ret) {
558 dev_err(lcd->dev, "failed to enable ldi.\n");
559 return ret;
560 }
561
562 return 0;
563}
564
565static int ld9040_power_off(struct ld9040 *lcd)
566{
567 int ret = 0;
568 struct lcd_platform_data *pd = NULL;
569
570 pd = lcd->lcd_pd;
571 if (!pd) {
572 dev_err(lcd->dev, "platform data is NULL.\n");
573 return -EFAULT;
574 }
575
576 ret = ld9040_ldi_disable(lcd);
577 if (ret) {
578 dev_err(lcd->dev, "lcd setting failed.\n");
579 return -EIO;
580 }
581
582 mdelay(pd->power_off_delay);
583
584 if (!pd->power_on) {
585 dev_err(lcd->dev, "power_on is NULL.\n");
586 return -EFAULT;
587 } else
588 pd->power_on(lcd->ld, 0);
589
590 return 0;
591}
592
593static int ld9040_power(struct ld9040 *lcd, int power)
594{
595 int ret = 0;
596
597 if (power_is_on(power) && !power_is_on(lcd->power))
598 ret = ld9040_power_on(lcd);
599 else if (!power_is_on(power) && power_is_on(lcd->power))
600 ret = ld9040_power_off(lcd);
601
602 if (!ret)
603 lcd->power = power;
604
605 return ret;
606}
607
608static int ld9040_set_power(struct lcd_device *ld, int power)
609{
610 struct ld9040 *lcd = lcd_get_data(ld);
611
612 if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
613 power != FB_BLANK_NORMAL) {
614 dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
615 return -EINVAL;
616 }
617
618 return ld9040_power(lcd, power);
619}
620
621static int ld9040_get_power(struct lcd_device *ld)
622{
623 struct ld9040 *lcd = lcd_get_data(ld);
624
625 return lcd->power;
626}
627
628static int ld9040_get_brightness(struct backlight_device *bd)
629{
630 return bd->props.brightness;
631}
632
633static int ld9040_set_brightness(struct backlight_device *bd)
634{
635 int ret = 0, brightness = bd->props.brightness;
636 struct ld9040 *lcd = bl_get_data(bd);
637
638 if (brightness < MIN_BRIGHTNESS ||
639 brightness > bd->props.max_brightness) {
640 dev_err(&bd->dev, "lcd brightness should be %d to %d.\n",
641 MIN_BRIGHTNESS, MAX_BRIGHTNESS);
642 return -EINVAL;
643 }
644
645 ret = ld9040_gamma_ctl(lcd, bd->props.brightness);
646 if (ret) {
647 dev_err(&bd->dev, "lcd brightness setting failed.\n");
648 return -EIO;
649 }
650
651 return ret;
652}
653
654static struct lcd_ops ld9040_lcd_ops = {
655 .set_power = ld9040_set_power,
656 .get_power = ld9040_get_power,
657};
658
659static const struct backlight_ops ld9040_backlight_ops = {
660 .get_brightness = ld9040_get_brightness,
661 .update_status = ld9040_set_brightness,
662};
663
664
665static int ld9040_probe(struct spi_device *spi)
666{
667 int ret = 0;
668 struct ld9040 *lcd = NULL;
669 struct lcd_device *ld = NULL;
670 struct backlight_device *bd = NULL;
671
672 lcd = kzalloc(sizeof(struct ld9040), GFP_KERNEL);
673 if (!lcd)
674 return -ENOMEM;
675
676 /* ld9040 lcd panel uses 3-wire 9bits SPI Mode. */
677 spi->bits_per_word = 9;
678
679 ret = spi_setup(spi);
680 if (ret < 0) {
681 dev_err(&spi->dev, "spi setup failed.\n");
682 goto out_free_lcd;
683 }
684
685 lcd->spi = spi;
686 lcd->dev = &spi->dev;
687
688 lcd->lcd_pd = spi->dev.platform_data;
689 if (!lcd->lcd_pd) {
690 dev_err(&spi->dev, "platform data is NULL.\n");
691 goto out_free_lcd;
692 }
693
694 ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
695 if (IS_ERR(ld)) {
696 ret = PTR_ERR(ld);
697 goto out_free_lcd;
698 }
699
700 lcd->ld = ld;
701
702 bd = backlight_device_register("ld9040-bl", &spi->dev,
703 lcd, &ld9040_backlight_ops, NULL);
704 if (IS_ERR(ld)) {
705 ret = PTR_ERR(ld);
706 goto out_free_lcd;
707 }
708
709 bd->props.max_brightness = MAX_BRIGHTNESS;
710 bd->props.brightness = MAX_BRIGHTNESS;
711 lcd->bd = bd;
712
713 /*
714 * if lcd panel was on from bootloader like u-boot then
715 * do not lcd on.
716 */
717 if (!lcd->lcd_pd->lcd_enabled) {
718 /*
719 * if lcd panel was off from bootloader then
720 * current lcd status is powerdown and then
721 * it enables lcd panel.
722 */
723 lcd->power = FB_BLANK_POWERDOWN;
724
725 ld9040_power(lcd, FB_BLANK_UNBLANK);
726 } else
727 lcd->power = FB_BLANK_UNBLANK;
728
729 dev_set_drvdata(&spi->dev, lcd);
730
731 dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");
732 return 0;
733
734out_free_lcd:
735 kfree(lcd);
736 return ret;
737}
738
739static int __devexit ld9040_remove(struct spi_device *spi)
740{
741 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
742
743 ld9040_power(lcd, FB_BLANK_POWERDOWN);
744 lcd_device_unregister(lcd->ld);
745 kfree(lcd);
746
747 return 0;
748}
749
750#if defined(CONFIG_PM)
751static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
752{
753 int ret = 0;
754 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
755
756 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
757
758 /*
759 * when lcd panel is suspend, lcd panel becomes off
760 * regardless of status.
761 */
762 ret = ld9040_power(lcd, FB_BLANK_POWERDOWN);
763
764 return ret;
765}
766
767static int ld9040_resume(struct spi_device *spi)
768{
769 int ret = 0;
770 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
771
772 lcd->power = FB_BLANK_POWERDOWN;
773
774 ret = ld9040_power(lcd, FB_BLANK_UNBLANK);
775
776 return ret;
777}
778#else
779#define ld9040_suspend NULL
780#define ld9040_resume NULL
781#endif
782
783/* Power down all displays on reboot, poweroff or halt. */
784static void ld9040_shutdown(struct spi_device *spi)
785{
786 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
787
788 ld9040_power(lcd, FB_BLANK_POWERDOWN);
789}
790
791static struct spi_driver ld9040_driver = {
792 .driver = {
793 .name = "ld9040",
794 .bus = &spi_bus_type,
795 .owner = THIS_MODULE,
796 },
797 .probe = ld9040_probe,
798 .remove = __devexit_p(ld9040_remove),
799 .shutdown = ld9040_shutdown,
800 .suspend = ld9040_suspend,
801 .resume = ld9040_resume,
802};
803
804static int __init ld9040_init(void)
805{
806 return spi_register_driver(&ld9040_driver);
807}
808
809static void __exit ld9040_exit(void)
810{
811 spi_unregister_driver(&ld9040_driver);
812}
813
814module_init(ld9040_init);
815module_exit(ld9040_exit);
816
817MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
818MODULE_DESCRIPTION("ld9040 LCD Driver");
819MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/ld9040_gamma.h b/drivers/video/backlight/ld9040_gamma.h
new file mode 100644
index 000000000000..038d9c86ec03
--- /dev/null
+++ b/drivers/video/backlight/ld9040_gamma.h
@@ -0,0 +1,200 @@
1/*
2 * Gamma level definitions.
3 *
4 * Copyright (c) 2011 Samsung Electronics
5 * InKi Dae <inki.dae@samsung.com>
6 * Donghwa Lee <dh09.lee@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef _LD9040_BRIGHTNESS_H
14#define _LD9040_BRIGHTNESS_H
15
16#define MAX_GAMMA_LEVEL 25
17#define GAMMA_TABLE_COUNT 21
18
19/* gamma value: 2.2 */
20static const unsigned int ld9040_22_300[] = {
21 0x00, 0xa7, 0xb4, 0xae, 0xbf, 0x00, 0x91,
22 0x00, 0xb2, 0xb4, 0xaa, 0xbb, 0x00, 0xac,
23 0x00, 0xb3, 0xb1, 0xaa, 0xbc, 0x00, 0xb3
24};
25
26static const unsigned int ld9040_22_290[] = {
27 0x00, 0xa9, 0xb7, 0xae, 0xbd, 0x00, 0x89,
28 0x00, 0xb7, 0xb6, 0xa8, 0xba, 0x00, 0xa4,
29 0x00, 0xb1, 0xb4, 0xaa, 0xbb, 0x00, 0xaa
30};
31
32static const unsigned int ld9040_22_280[] = {
33 0x00, 0xa9, 0xb6, 0xad, 0xbf, 0x00, 0x86,
34 0x00, 0xb8, 0xb5, 0xa8, 0xbc, 0x00, 0xa0,
35 0x00, 0xb3, 0xb3, 0xa9, 0xbc, 0x00, 0xa7
36};
37
38static const unsigned int ld9040_22_270[] = {
39 0x00, 0xa8, 0xb8, 0xae, 0xbe, 0x00, 0x84,
40 0x00, 0xb9, 0xb7, 0xa8, 0xbc, 0x00, 0x9d,
41 0x00, 0xb2, 0xb5, 0xaa, 0xbc, 0x00, 0xa4
42
43};
44static const unsigned int ld9040_22_260[] = {
45 0x00, 0xa4, 0xb8, 0xb0, 0xbf, 0x00, 0x80,
46 0x00, 0xb8, 0xb6, 0xaa, 0xbc, 0x00, 0x9a,
47 0x00, 0xb0, 0xb5, 0xab, 0xbd, 0x00, 0xa0
48};
49
50static const unsigned int ld9040_22_250[] = {
51 0x00, 0xa4, 0xb9, 0xaf, 0xc1, 0x00, 0x7d,
52 0x00, 0xb9, 0xb6, 0xaa, 0xbb, 0x00, 0x97,
53 0x00, 0xb1, 0xb5, 0xaa, 0xbf, 0x00, 0x9d
54};
55
56static const unsigned int ld9040_22_240[] = {
57 0x00, 0xa2, 0xb9, 0xaf, 0xc2, 0x00, 0x7a,
58 0x00, 0xb9, 0xb7, 0xaa, 0xbd, 0x00, 0x94,
59 0x00, 0xb0, 0xb5, 0xab, 0xbf, 0x00, 0x9a
60};
61
62static const unsigned int ld9040_22_230[] = {
63 0x00, 0xa0, 0xb9, 0xaf, 0xc3, 0x00, 0x77,
64 0x00, 0xb9, 0xb7, 0xab, 0xbe, 0x00, 0x90,
65 0x00, 0xb0, 0xb6, 0xab, 0xbf, 0x00, 0x97
66};
67
68static const unsigned int ld9040_22_220[] = {
69 0x00, 0x9e, 0xba, 0xb0, 0xc2, 0x00, 0x75,
70 0x00, 0xb9, 0xb8, 0xab, 0xbe, 0x00, 0x8e,
71 0x00, 0xb0, 0xb6, 0xac, 0xbf, 0x00, 0x94
72};
73
74static const unsigned int ld9040_22_210[] = {
75 0x00, 0x9c, 0xb9, 0xb0, 0xc4, 0x00, 0x72,
76 0x00, 0xb8, 0xb8, 0xac, 0xbf, 0x00, 0x8a,
77 0x00, 0xb0, 0xb6, 0xac, 0xc0, 0x00, 0x91
78};
79
80static const unsigned int ld9040_22_200[] = {
81 0x00, 0x9a, 0xba, 0xb1, 0xc4, 0x00, 0x6f,
82 0x00, 0xb8, 0xb8, 0xad, 0xc0, 0x00, 0x86,
83 0x00, 0xb0, 0xb7, 0xad, 0xc0, 0x00, 0x8d
84};
85
86static const unsigned int ld9040_22_190[] = {
87 0x00, 0x97, 0xba, 0xb2, 0xc5, 0x00, 0x6c,
88 0x00, 0xb8, 0xb8, 0xae, 0xc1, 0x00, 0x82,
89 0x00, 0xb0, 0xb6, 0xae, 0xc2, 0x00, 0x89
90};
91
92static const unsigned int ld9040_22_180[] = {
93 0x00, 0x93, 0xba, 0xb3, 0xc5, 0x00, 0x69,
94 0x00, 0xb8, 0xb9, 0xae, 0xc1, 0x00, 0x7f,
95 0x00, 0xb0, 0xb6, 0xae, 0xc3, 0x00, 0x85
96};
97
98static const unsigned int ld9040_22_170[] = {
99 0x00, 0x8b, 0xb9, 0xb3, 0xc7, 0x00, 0x65,
100 0x00, 0xb7, 0xb8, 0xaf, 0xc3, 0x00, 0x7a,
101 0x00, 0x80, 0xb6, 0xae, 0xc4, 0x00, 0x81
102};
103
104static const unsigned int ld9040_22_160[] = {
105 0x00, 0x89, 0xba, 0xb3, 0xc8, 0x00, 0x62,
106 0x00, 0xb6, 0xba, 0xaf, 0xc3, 0x00, 0x76,
107 0x00, 0xaf, 0xb7, 0xae, 0xc4, 0x00, 0x7e
108};
109
110static const unsigned int ld9040_22_150[] = {
111 0x00, 0x82, 0xba, 0xb4, 0xc7, 0x00, 0x5f,
112 0x00, 0xb5, 0xba, 0xb0, 0xc3, 0x00, 0x72,
113 0x00, 0xae, 0xb8, 0xb0, 0xc3, 0x00, 0x7a
114};
115
116static const unsigned int ld9040_22_140[] = {
117 0x00, 0x7b, 0xbb, 0xb4, 0xc8, 0x00, 0x5b,
118 0x00, 0xb5, 0xba, 0xb1, 0xc4, 0x00, 0x6e,
119 0x00, 0xae, 0xb9, 0xb0, 0xc5, 0x00, 0x75
120};
121
122static const unsigned int ld9040_22_130[] = {
123 0x00, 0x71, 0xbb, 0xb5, 0xc8, 0x00, 0x57,
124 0x00, 0xb5, 0xbb, 0xb0, 0xc5, 0x00, 0x6a,
125 0x00, 0xae, 0xb9, 0xb1, 0xc6, 0x00, 0x70
126};
127
128static const unsigned int ld9040_22_120[] = {
129 0x00, 0x47, 0xba, 0xb6, 0xca, 0x00, 0x53,
130 0x00, 0xb5, 0xbb, 0xb3, 0xc6, 0x00, 0x65,
131 0x00, 0xae, 0xb8, 0xb3, 0xc7, 0x00, 0x6c
132};
133
134static const unsigned int ld9040_22_110[] = {
135 0x00, 0x13, 0xbb, 0xb7, 0xca, 0x00, 0x4f,
136 0x00, 0xb4, 0xbb, 0xb3, 0xc7, 0x00, 0x60,
137 0x00, 0xad, 0xb8, 0xb4, 0xc7, 0x00, 0x67
138};
139
140static const unsigned int ld9040_22_100[] = {
141 0x00, 0x13, 0xba, 0xb8, 0xcb, 0x00, 0x4b,
142 0x00, 0xb3, 0xbc, 0xb4, 0xc7, 0x00, 0x5c,
143 0x00, 0xac, 0xb8, 0xb4, 0xc8, 0x00, 0x62
144};
145
146static const unsigned int ld9040_22_90[] = {
147 0x00, 0x13, 0xb9, 0xb8, 0xcd, 0x00, 0x46,
148 0x00, 0xb1, 0xbc, 0xb5, 0xc8, 0x00, 0x56,
149 0x00, 0xaa, 0xb8, 0xb4, 0xc9, 0x00, 0x5d
150};
151
152static const unsigned int ld9040_22_80[] = {
153 0x00, 0x13, 0xba, 0xb9, 0xcd, 0x00, 0x41,
154 0x00, 0xb0, 0xbe, 0xb5, 0xc9, 0x00, 0x51,
155 0x00, 0xa9, 0xb9, 0xb5, 0xca, 0x00, 0x57
156};
157
158static const unsigned int ld9040_22_70[] = {
159 0x00, 0x13, 0xb9, 0xb9, 0xd0, 0x00, 0x3c,
160 0x00, 0xaf, 0xbf, 0xb6, 0xcb, 0x00, 0x4b,
161 0x00, 0xa8, 0xb9, 0xb5, 0xcc, 0x00, 0x52
162};
163
164static const unsigned int ld9040_22_50[] = {
165 0x00, 0x13, 0xb2, 0xba, 0xd2, 0x00, 0x30,
166 0x00, 0xaf, 0xc0, 0xb8, 0xcd, 0x00, 0x3d,
167 0x00, 0xa8, 0xb8, 0xb7, 0xcd, 0x00, 0x44
168};
169
170struct ld9040_gamma {
171 unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
172} gamma_table = {
173 .gamma_22_table[0] = (unsigned int *)&ld9040_22_50,
174 .gamma_22_table[1] = (unsigned int *)&ld9040_22_70,
175 .gamma_22_table[2] = (unsigned int *)&ld9040_22_80,
176 .gamma_22_table[3] = (unsigned int *)&ld9040_22_90,
177 .gamma_22_table[4] = (unsigned int *)&ld9040_22_100,
178 .gamma_22_table[5] = (unsigned int *)&ld9040_22_110,
179 .gamma_22_table[6] = (unsigned int *)&ld9040_22_120,
180 .gamma_22_table[7] = (unsigned int *)&ld9040_22_130,
181 .gamma_22_table[8] = (unsigned int *)&ld9040_22_140,
182 .gamma_22_table[9] = (unsigned int *)&ld9040_22_150,
183 .gamma_22_table[10] = (unsigned int *)&ld9040_22_160,
184 .gamma_22_table[11] = (unsigned int *)&ld9040_22_170,
185 .gamma_22_table[12] = (unsigned int *)&ld9040_22_180,
186 .gamma_22_table[13] = (unsigned int *)&ld9040_22_190,
187 .gamma_22_table[14] = (unsigned int *)&ld9040_22_200,
188 .gamma_22_table[15] = (unsigned int *)&ld9040_22_210,
189 .gamma_22_table[16] = (unsigned int *)&ld9040_22_220,
190 .gamma_22_table[17] = (unsigned int *)&ld9040_22_230,
191 .gamma_22_table[18] = (unsigned int *)&ld9040_22_240,
192 .gamma_22_table[19] = (unsigned int *)&ld9040_22_250,
193 .gamma_22_table[20] = (unsigned int *)&ld9040_22_260,
194 .gamma_22_table[21] = (unsigned int *)&ld9040_22_270,
195 .gamma_22_table[22] = (unsigned int *)&ld9040_22_280,
196 .gamma_22_table[23] = (unsigned int *)&ld9040_22_290,
197 .gamma_22_table[24] = (unsigned int *)&ld9040_22_300,
198};
199
200#endif
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index d2f59015d517..be20b5cbe26c 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -6,7 +6,7 @@
6 * GPL v2 6 * GPL v2
7 * 7 *
8 * This driver assumes single CPU. That's okay, because collie is 8 * This driver assumes single CPU. That's okay, because collie is
9 * slightly old hardware, and noone is going to retrofit second CPU to 9 * slightly old hardware, and no one is going to retrofit second CPU to
10 * old PDA. 10 * old PDA.
11 */ 11 */
12 12
@@ -184,6 +184,7 @@ static int locomolcd_probe(struct locomo_dev *ldev)
184 local_irq_restore(flags); 184 local_irq_restore(flags);
185 185
186 memset(&props, 0, sizeof(struct backlight_properties)); 186 memset(&props, 0, sizeof(struct backlight_properties));
187 props.type = BACKLIGHT_RAW;
187 props.max_brightness = 4; 188 props.max_brightness = 4;
188 locomolcd_bl_device = backlight_device_register("locomo-bl", 189 locomolcd_bl_device = backlight_device_register("locomo-bl",
189 &ldev->dev, NULL, 190 &ldev->dev, NULL,
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index 209acc105cbc..07e8e273ced0 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -136,6 +136,7 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
136 data->current_brightness = 0; 136 data->current_brightness = 0;
137 137
138 memset(&props, 0, sizeof(struct backlight_properties)); 138 memset(&props, 0, sizeof(struct backlight_properties));
139 props.type = BACKLIGHT_RAW;
139 props.max_brightness = MAX_BRIGHTNESS; 140 props.max_brightness = MAX_BRIGHTNESS;
140 bl = backlight_device_register(name, &pdev->dev, data, 141 bl = backlight_device_register(name, &pdev->dev, data,
141 &max8925_backlight_ops, &props); 142 &max8925_backlight_ops, &props);
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
deleted file mode 100644
index 1485f7345f49..000000000000
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ /dev/null
@@ -1,400 +0,0 @@
1/*
2 * Backlight Driver for Nvidia 8600 in Macbook Pro
3 *
4 * Copyright (c) Red Hat <mjg@redhat.com>
5 * Based on code from Pommed:
6 * Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
7 * Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
8 * Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This driver triggers SMIs which cause the firmware to change the
15 * backlight brightness. This is icky in many ways, but it's impractical to
16 * get at the firmware code in order to figure out what it's actually doing.
17 */
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/backlight.h>
24#include <linux/err.h>
25#include <linux/dmi.h>
26#include <linux/io.h>
27
28static struct backlight_device *mbp_backlight_device;
29
30/* Structure to be passed to the DMI_MATCH function. */
31struct dmi_match_data {
32 /* I/O resource to allocate. */
33 unsigned long iostart;
34 unsigned long iolen;
35 /* Backlight operations structure. */
36 const struct backlight_ops backlight_ops;
37};
38
39/* Module parameters. */
40static int debug;
41module_param_named(debug, debug, int, 0644);
42MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
43
44/*
45 * Implementation for MacBooks with Intel chipset.
46 */
47static int intel_chipset_send_intensity(struct backlight_device *bd)
48{
49 int intensity = bd->props.brightness;
50
51 if (debug)
52 printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
53 intensity);
54
55 outb(0x04 | (intensity << 4), 0xb3);
56 outb(0xbf, 0xb2);
57 return 0;
58}
59
60static int intel_chipset_get_intensity(struct backlight_device *bd)
61{
62 int intensity;
63
64 outb(0x03, 0xb3);
65 outb(0xbf, 0xb2);
66 intensity = inb(0xb3) >> 4;
67
68 if (debug)
69 printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
70 intensity);
71
72 return intensity;
73}
74
75static const struct dmi_match_data intel_chipset_data = {
76 .iostart = 0xb2,
77 .iolen = 2,
78 .backlight_ops = {
79 .options = BL_CORE_SUSPENDRESUME,
80 .get_brightness = intel_chipset_get_intensity,
81 .update_status = intel_chipset_send_intensity,
82 }
83};
84
85/*
86 * Implementation for MacBooks with Nvidia chipset.
87 */
88static int nvidia_chipset_send_intensity(struct backlight_device *bd)
89{
90 int intensity = bd->props.brightness;
91
92 if (debug)
93 printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
94 intensity);
95
96 outb(0x04 | (intensity << 4), 0x52f);
97 outb(0xbf, 0x52e);
98 return 0;
99}
100
101static int nvidia_chipset_get_intensity(struct backlight_device *bd)
102{
103 int intensity;
104
105 outb(0x03, 0x52f);
106 outb(0xbf, 0x52e);
107 intensity = inb(0x52f) >> 4;
108
109 if (debug)
110 printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
111 intensity);
112
113 return intensity;
114}
115
116static const struct dmi_match_data nvidia_chipset_data = {
117 .iostart = 0x52e,
118 .iolen = 2,
119 .backlight_ops = {
120 .options = BL_CORE_SUSPENDRESUME,
121 .get_brightness = nvidia_chipset_get_intensity,
122 .update_status = nvidia_chipset_send_intensity
123 }
124};
125
126/*
127 * DMI matching.
128 */
129static /* const */ struct dmi_match_data *driver_data;
130
131static int mbp_dmi_match(const struct dmi_system_id *id)
132{
133 driver_data = id->driver_data;
134
135 printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident);
136 return 1;
137}
138
139static const struct dmi_system_id __initdata mbp_device_table[] = {
140 {
141 .callback = mbp_dmi_match,
142 .ident = "MacBook 1,1",
143 .matches = {
144 DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
145 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
146 },
147 .driver_data = (void *)&intel_chipset_data,
148 },
149 {
150 .callback = mbp_dmi_match,
151 .ident = "MacBook 2,1",
152 .matches = {
153 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
154 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
155 },
156 .driver_data = (void *)&intel_chipset_data,
157 },
158 {
159 .callback = mbp_dmi_match,
160 .ident = "MacBook 3,1",
161 .matches = {
162 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
163 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"),
164 },
165 .driver_data = (void *)&intel_chipset_data,
166 },
167 {
168 .callback = mbp_dmi_match,
169 .ident = "MacBook 4,1",
170 .matches = {
171 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
172 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"),
173 },
174 .driver_data = (void *)&intel_chipset_data,
175 },
176 {
177 .callback = mbp_dmi_match,
178 .ident = "MacBook 4,2",
179 .matches = {
180 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
181 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"),
182 },
183 .driver_data = (void *)&intel_chipset_data,
184 },
185 {
186 .callback = mbp_dmi_match,
187 .ident = "MacBookPro 1,1",
188 .matches = {
189 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
190 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"),
191 },
192 .driver_data = (void *)&intel_chipset_data,
193 },
194 {
195 .callback = mbp_dmi_match,
196 .ident = "MacBookPro 1,2",
197 .matches = {
198 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
199 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,2"),
200 },
201 .driver_data = (void *)&intel_chipset_data,
202 },
203 {
204 .callback = mbp_dmi_match,
205 .ident = "MacBookPro 2,1",
206 .matches = {
207 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
208 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,1"),
209 },
210 .driver_data = (void *)&intel_chipset_data,
211 },
212 {
213 .callback = mbp_dmi_match,
214 .ident = "MacBookPro 2,2",
215 .matches = {
216 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
217 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"),
218 },
219 .driver_data = (void *)&intel_chipset_data,
220 },
221 {
222 .callback = mbp_dmi_match,
223 .ident = "MacBookPro 3,1",
224 .matches = {
225 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
226 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
227 },
228 .driver_data = (void *)&intel_chipset_data,
229 },
230 {
231 .callback = mbp_dmi_match,
232 .ident = "MacBookPro 3,2",
233 .matches = {
234 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
235 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
236 },
237 .driver_data = (void *)&intel_chipset_data,
238 },
239 {
240 .callback = mbp_dmi_match,
241 .ident = "MacBookPro 4,1",
242 .matches = {
243 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
244 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
245 },
246 .driver_data = (void *)&intel_chipset_data,
247 },
248 {
249 .callback = mbp_dmi_match,
250 .ident = "MacBookAir 1,1",
251 .matches = {
252 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
253 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir1,1"),
254 },
255 .driver_data = (void *)&intel_chipset_data,
256 },
257 {
258 .callback = mbp_dmi_match,
259 .ident = "MacBook 5,1",
260 .matches = {
261 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
262 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"),
263 },
264 .driver_data = (void *)&nvidia_chipset_data,
265 },
266 {
267 .callback = mbp_dmi_match,
268 .ident = "MacBook 5,2",
269 .matches = {
270 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
271 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"),
272 },
273 .driver_data = (void *)&nvidia_chipset_data,
274 },
275 {
276 .callback = mbp_dmi_match,
277 .ident = "MacBook 6,1",
278 .matches = {
279 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
280 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"),
281 },
282 .driver_data = (void *)&nvidia_chipset_data,
283 },
284 {
285 .callback = mbp_dmi_match,
286 .ident = "MacBookAir 2,1",
287 .matches = {
288 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
289 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"),
290 },
291 .driver_data = (void *)&nvidia_chipset_data,
292 },
293 {
294 .callback = mbp_dmi_match,
295 .ident = "MacBookPro 5,1",
296 .matches = {
297 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
298 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"),
299 },
300 .driver_data = (void *)&nvidia_chipset_data,
301 },
302 {
303 .callback = mbp_dmi_match,
304 .ident = "MacBookPro 5,2",
305 .matches = {
306 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
307 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,2"),
308 },
309 .driver_data = (void *)&nvidia_chipset_data,
310 },
311 {
312 .callback = mbp_dmi_match,
313 .ident = "MacBookPro 5,3",
314 .matches = {
315 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
316 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3"),
317 },
318 .driver_data = (void *)&nvidia_chipset_data,
319 },
320 {
321 .callback = mbp_dmi_match,
322 .ident = "MacBookPro 5,4",
323 .matches = {
324 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
325 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4"),
326 },
327 .driver_data = (void *)&nvidia_chipset_data,
328 },
329 {
330 .callback = mbp_dmi_match,
331 .ident = "MacBookPro 5,5",
332 .matches = {
333 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
334 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"),
335 },
336 .driver_data = (void *)&nvidia_chipset_data,
337 },
338 {
339 .callback = mbp_dmi_match,
340 .ident = "MacBookAir 3,1",
341 .matches = {
342 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
343 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"),
344 },
345 .driver_data = (void *)&nvidia_chipset_data,
346 },
347 {
348 .callback = mbp_dmi_match,
349 .ident = "MacBookAir 3,2",
350 .matches = {
351 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
352 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"),
353 },
354 .driver_data = (void *)&nvidia_chipset_data,
355 },
356 { }
357};
358
359static int __init mbp_init(void)
360{
361 struct backlight_properties props;
362 if (!dmi_check_system(mbp_device_table))
363 return -ENODEV;
364
365 if (!request_region(driver_data->iostart, driver_data->iolen,
366 "Macbook Pro backlight"))
367 return -ENXIO;
368
369 memset(&props, 0, sizeof(struct backlight_properties));
370 props.max_brightness = 15;
371 mbp_backlight_device = backlight_device_register("mbp_backlight", NULL,
372 NULL,
373 &driver_data->backlight_ops,
374 &props);
375 if (IS_ERR(mbp_backlight_device)) {
376 release_region(driver_data->iostart, driver_data->iolen);
377 return PTR_ERR(mbp_backlight_device);
378 }
379
380 mbp_backlight_device->props.brightness =
381 driver_data->backlight_ops.get_brightness(mbp_backlight_device);
382 backlight_update_status(mbp_backlight_device);
383
384 return 0;
385}
386
387static void __exit mbp_exit(void)
388{
389 backlight_device_unregister(mbp_backlight_device);
390
391 release_region(driver_data->iostart, driver_data->iolen);
392}
393
394module_init(mbp_init);
395module_exit(mbp_exit);
396
397MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
398MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver");
399MODULE_LICENSE("GPL");
400MODULE_DEVICE_TABLE(dmi, mbp_device_table);
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index d3bc56296c8d..08d26a72394c 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -146,6 +146,7 @@ static int omapbl_probe(struct platform_device *pdev)
146 return -ENOMEM; 146 return -ENOMEM;
147 147
148 memset(&props, 0, sizeof(struct backlight_properties)); 148 memset(&props, 0, sizeof(struct backlight_properties));
149 props.type = BACKLIGHT_RAW;
149 props.max_brightness = OMAPBL_MAX_INTENSITY; 150 props.max_brightness = OMAPBL_MAX_INTENSITY;
150 dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops, 151 dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
151 &props); 152 &props);
diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c
index 3c424f7efdcc..ef5628d60563 100644
--- a/drivers/video/backlight/pcf50633-backlight.c
+++ b/drivers/video/backlight/pcf50633-backlight.c
@@ -112,6 +112,7 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
112 if (!pcf_bl) 112 if (!pcf_bl)
113 return -ENOMEM; 113 return -ENOMEM;
114 114
115 bl_props.type = BACKLIGHT_RAW;
115 bl_props.max_brightness = 0x3f; 116 bl_props.max_brightness = 0x3f;
116 bl_props.power = FB_BLANK_UNBLANK; 117 bl_props.power = FB_BLANK_UNBLANK;
117 118
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 809278c90738..6af183d6465e 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -84,6 +84,7 @@ static int progearbl_probe(struct platform_device *pdev)
84 pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); 84 pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
85 85
86 memset(&props, 0, sizeof(struct backlight_properties)); 86 memset(&props, 0, sizeof(struct backlight_properties));
87 props.type = BACKLIGHT_RAW;
87 props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; 88 props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
88 progear_backlight_device = backlight_device_register("progear-bl", 89 progear_backlight_device = backlight_device_register("progear-bl",
89 &pdev->dev, NULL, 90 &pdev->dev, NULL,
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 21866ec69656..b8f38ec6eb18 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -28,6 +28,7 @@ struct pwm_bl_data {
28 unsigned int lth_brightness; 28 unsigned int lth_brightness;
29 int (*notify)(struct device *, 29 int (*notify)(struct device *,
30 int brightness); 30 int brightness);
31 int (*check_fb)(struct device *, struct fb_info *);
31}; 32};
32 33
33static int pwm_backlight_update_status(struct backlight_device *bl) 34static int pwm_backlight_update_status(struct backlight_device *bl)
@@ -62,9 +63,18 @@ static int pwm_backlight_get_brightness(struct backlight_device *bl)
62 return bl->props.brightness; 63 return bl->props.brightness;
63} 64}
64 65
66static int pwm_backlight_check_fb(struct backlight_device *bl,
67 struct fb_info *info)
68{
69 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
70
71 return !pb->check_fb || pb->check_fb(pb->dev, info);
72}
73
65static const struct backlight_ops pwm_backlight_ops = { 74static const struct backlight_ops pwm_backlight_ops = {
66 .update_status = pwm_backlight_update_status, 75 .update_status = pwm_backlight_update_status,
67 .get_brightness = pwm_backlight_get_brightness, 76 .get_brightness = pwm_backlight_get_brightness,
77 .check_fb = pwm_backlight_check_fb,
68}; 78};
69 79
70static int pwm_backlight_probe(struct platform_device *pdev) 80static int pwm_backlight_probe(struct platform_device *pdev)
@@ -95,6 +105,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
95 105
96 pb->period = data->pwm_period_ns; 106 pb->period = data->pwm_period_ns;
97 pb->notify = data->notify; 107 pb->notify = data->notify;
108 pb->check_fb = data->check_fb;
98 pb->lth_brightness = data->lth_brightness * 109 pb->lth_brightness = data->lth_brightness *
99 (data->pwm_period_ns / data->max_brightness); 110 (data->pwm_period_ns / data->max_brightness);
100 pb->dev = &pdev->dev; 111 pb->dev = &pdev->dev;
@@ -108,6 +119,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
108 dev_dbg(&pdev->dev, "got pwm for backlight\n"); 119 dev_dbg(&pdev->dev, "got pwm for backlight\n");
109 120
110 memset(&props, 0, sizeof(struct backlight_properties)); 121 memset(&props, 0, sizeof(struct backlight_properties));
122 props.type = BACKLIGHT_RAW;
111 props.max_brightness = data->max_brightness; 123 props.max_brightness = data->max_brightness;
112 bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, 124 bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
113 &pwm_backlight_ops, &props); 125 &pwm_backlight_ops, &props);
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index 5927db0da999..322040f686c2 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -778,6 +778,7 @@ static int __devinit s6e63m0_probe(struct spi_device *spi)
778 778
779 bd->props.max_brightness = MAX_BRIGHTNESS; 779 bd->props.max_brightness = MAX_BRIGHTNESS;
780 bd->props.brightness = MAX_BRIGHTNESS; 780 bd->props.brightness = MAX_BRIGHTNESS;
781 bd->props.type = BACKLIGHT_RAW;
781 lcd->bd = bd; 782 lcd->bd = bd;
782 783
783 /* 784 /*
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 2a04b382ec48..425a7365470b 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -102,6 +102,7 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
102 data->i2c = client; 102 data->i2c = client;
103 103
104 memset(&props, 0, sizeof(struct backlight_properties)); 104 memset(&props, 0, sizeof(struct backlight_properties));
105 props.type = BACKLIGHT_RAW;
105 props.max_brightness = 512 - 1; 106 props.max_brightness = 512 - 1;
106 data->bl = backlight_device_register("tosa-bl", &client->dev, data, 107 data->bl = backlight_device_register("tosa-bl", &client->dev, data,
107 &bl_ops, &props); 108 &bl_ops, &props);
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index 08fd87f3aecc..d4c6eb248ff9 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -193,6 +193,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
193 data->current_brightness = 0; 193 data->current_brightness = 0;
194 data->isink_reg = isink_reg; 194 data->isink_reg = isink_reg;
195 195
196 props.type = BACKLIGHT_RAW;
196 props.max_brightness = max_isel; 197 props.max_brightness = max_isel;
197 bl = backlight_device_register("wm831x", &pdev->dev, data, 198 bl = backlight_device_register("wm831x", &pdev->dev, data,
198 &wm831x_backlight_ops, &props); 199 &wm831x_backlight_ops, &props);
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index e7d0f525041e..2464b910b590 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -649,6 +649,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
649 } 649 }
650#ifndef NO_BL_SUPPORT 650#ifndef NO_BL_SUPPORT
651 memset(&props, 0, sizeof(struct backlight_properties)); 651 memset(&props, 0, sizeof(struct backlight_properties));
652 props.type = BACKLIGHT_RAW;
652 props.max_brightness = 255; 653 props.max_brightness = 255;
653 bl_dev = backlight_device_register("bf54x-bl", NULL, NULL, 654 bl_dev = backlight_device_register("bf54x-bl", NULL, NULL,
654 &bfin_lq043fb_bl_ops, &props); 655 &bfin_lq043fb_bl_ops, &props);
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index c8e1f04941bd..23b6c4b62c78 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -154,8 +154,10 @@ static int __devinit lq035q1_spidev_probe(struct spi_device *spi)
154 154
155 ret = lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON); 155 ret = lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON);
156 ret |= lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode); 156 ret |= lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode);
157 if (ret) 157 if (ret) {
158 kfree(ctl);
158 return ret; 159 return ret;
160 }
159 161
160 spi_set_drvdata(spi, ctl); 162 spi_set_drvdata(spi, ctl);
161 163
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 3cf77676947c..d8de29f0dd8d 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -545,6 +545,7 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
545 } 545 }
546#ifndef NO_BL_SUPPORT 546#ifndef NO_BL_SUPPORT
547 memset(&props, 0, sizeof(struct backlight_properties)); 547 memset(&props, 0, sizeof(struct backlight_properties));
548 props.type = BACKLIGHT_RAW;
548 props.max_brightness = 255; 549 props.max_brightness = 255;
549 bl_dev = backlight_device_register("bf52x-bl", NULL, NULL, 550 bl_dev = backlight_device_register("bf52x-bl", NULL, NULL,
550 &bfin_lq043fb_bl_ops, &props); 551 &bfin_lq043fb_bl_ops, &props);
diff --git a/drivers/video/bfin_adv7393fb.h b/drivers/video/bfin_adv7393fb.h
index 8c7f9e4fc6eb..cd591b5152a5 100644
--- a/drivers/video/bfin_adv7393fb.h
+++ b/drivers/video/bfin_adv7393fb.h
@@ -87,12 +87,12 @@ static const u8 init_NTSC_TESTPATTERN[] = {
87 87
88static const u8 init_NTSC[] = { 88static const u8 init_NTSC[] = {
89 0x00, 0x1E, /* Power up all DACs and PLL */ 89 0x00, 0x1E, /* Power up all DACs and PLL */
90 0xC3, 0x26, /* Program RGB->YCrCb Color Space convertion matrix */ 90 0xC3, 0x26, /* Program RGB->YCrCb Color Space conversion matrix */
91 0xC5, 0x12, /* Program RGB->YCrCb Color Space convertion matrix */ 91 0xC5, 0x12, /* Program RGB->YCrCb Color Space conversion matrix */
92 0xC2, 0x4A, /* Program RGB->YCrCb Color Space convertion matrix */ 92 0xC2, 0x4A, /* Program RGB->YCrCb Color Space conversion matrix */
93 0xC6, 0x5E, /* Program RGB->YCrCb Color Space convertion matrix */ 93 0xC6, 0x5E, /* Program RGB->YCrCb Color Space conversion matrix */
94 0xBD, 0x19, /* Program RGB->YCrCb Color Space convertion matrix */ 94 0xBD, 0x19, /* Program RGB->YCrCb Color Space conversion matrix */
95 0xBF, 0x42, /* Program RGB->YCrCb Color Space convertion matrix */ 95 0xBF, 0x42, /* Program RGB->YCrCb Color Space conversion matrix */
96 0x8C, 0x1F, /* NTSC Subcarrier Frequency */ 96 0x8C, 0x1F, /* NTSC Subcarrier Frequency */
97 0x8D, 0x7C, /* NTSC Subcarrier Frequency */ 97 0x8D, 0x7C, /* NTSC Subcarrier Frequency */
98 0x8E, 0xF0, /* NTSC Subcarrier Frequency */ 98 0x8E, 0xF0, /* NTSC Subcarrier Frequency */
@@ -109,12 +109,12 @@ static const u8 init_NTSC[] = {
109 109
110static const u8 init_PAL[] = { 110static const u8 init_PAL[] = {
111 0x00, 0x1E, /* Power up all DACs and PLL */ 111 0x00, 0x1E, /* Power up all DACs and PLL */
112 0xC3, 0x26, /* Program RGB->YCrCb Color Space convertion matrix */ 112 0xC3, 0x26, /* Program RGB->YCrCb Color Space conversion matrix */
113 0xC5, 0x12, /* Program RGB->YCrCb Color Space convertion matrix */ 113 0xC5, 0x12, /* Program RGB->YCrCb Color Space conversion matrix */
114 0xC2, 0x4A, /* Program RGB->YCrCb Color Space convertion matrix */ 114 0xC2, 0x4A, /* Program RGB->YCrCb Color Space conversion matrix */
115 0xC6, 0x5E, /* Program RGB->YCrCb Color Space convertion matrix */ 115 0xC6, 0x5E, /* Program RGB->YCrCb Color Space conversion matrix */
116 0xBD, 0x19, /* Program RGB->YCrCb Color Space convertion matrix */ 116 0xBD, 0x19, /* Program RGB->YCrCb Color Space conversion matrix */
117 0xBF, 0x42, /* Program RGB->YCrCb Color Space convertion matrix */ 117 0xBF, 0x42, /* Program RGB->YCrCb Color Space conversion matrix */
118 0x8C, 0xCB, /* PAL Subcarrier Frequency */ 118 0x8C, 0xCB, /* PAL Subcarrier Frequency */
119 0x8D, 0x8A, /* PAL Subcarrier Frequency */ 119 0x8D, 0x8A, /* PAL Subcarrier Frequency */
120 0x8E, 0x09, /* PAL Subcarrier Frequency */ 120 0x8E, 0x09, /* PAL Subcarrier Frequency */
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index e2c85b0db632..f18895006627 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -565,6 +565,7 @@ out_dealloc_cmap:
565 565
566out_unmap_regs: 566out_unmap_regs:
567 cg14_unmap_regs(op, info, par); 567 cg14_unmap_regs(op, info, par);
568 framebuffer_release(info);
568 569
569out_err: 570out_err:
570 return err; 571 return err;
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 4ffad90bde42..179e96cdb323 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -821,6 +821,7 @@ out_dealloc_cmap:
821 821
822out_unmap_regs: 822out_unmap_regs:
823 cg6_unmap_regs(op, info, par); 823 cg6_unmap_regs(op, info, par);
824 framebuffer_release(info);
824 825
825out_err: 826out_err:
826 return err; 827 return err;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 9c092b8d64e6..8745637e4b7e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -370,7 +370,6 @@ static void fb_flashcursor(struct work_struct *work)
370{ 370{
371 struct fb_info *info = container_of(work, struct fb_info, queue); 371 struct fb_info *info = container_of(work, struct fb_info, queue);
372 struct fbcon_ops *ops = info->fbcon_par; 372 struct fbcon_ops *ops = info->fbcon_par;
373 struct display *p;
374 struct vc_data *vc = NULL; 373 struct vc_data *vc = NULL;
375 int c; 374 int c;
376 int mode; 375 int mode;
@@ -386,7 +385,6 @@ static void fb_flashcursor(struct work_struct *work)
386 return; 385 return;
387 } 386 }
388 387
389 p = &fb_display[vc->vc_num];
390 c = scr_readw((u16 *) vc->vc_pos); 388 c = scr_readw((u16 *) vc->vc_pos);
391 mode = (!ops->cursor_flash || ops->cursor_state.enable) ? 389 mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
392 CM_ERASE : CM_DRAW; 390 CM_ERASE : CM_DRAW;
@@ -823,10 +821,10 @@ static int set_con2fb_map(int unit, int newidx, int user)
823 if (oldidx == newidx) 821 if (oldidx == newidx)
824 return 0; 822 return 0;
825 823
826 if (!info || fbcon_has_exited) 824 if (!info)
827 return -EINVAL; 825 return -EINVAL;
828 826
829 if (!err && !search_for_mapped_con()) { 827 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
830 info_idx = newidx; 828 info_idx = newidx;
831 return fbcon_takeover(0); 829 return fbcon_takeover(0);
832 } 830 }
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index a19a7f33133e..fa6e698e63c4 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -1,5 +1,5 @@
1 1
2/* Hand composed "Miniscule" 4x6 font, with binary data generated using 2/* Hand composed "Minuscule" 4x6 font, with binary data generated using
3 * Perl stub. 3 * Perl stub.
4 * 4 *
5 * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate 5 * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 0056a41e5c35..15e8e1a89c45 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -83,7 +83,7 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
83 int softback_lines, int fg, int bg) 83 int softback_lines, int fg, int bg)
84{ 84{
85 struct fb_tilecursor cursor; 85 struct fb_tilecursor cursor;
86 int use_sw = (vc->vc_cursor_type & 0x01); 86 int use_sw = (vc->vc_cursor_type & 0x10);
87 87
88 cursor.sx = vc->vc_x; 88 cursor.sx = vc->vc_x;
89 cursor.sy = vc->vc_y; 89 cursor.sy = vc->vc_y;
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 8d61ef96eedd..8b7d47386f39 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -763,7 +763,7 @@ static int fb_wait_for_vsync(struct fb_info *info)
763 763
764 /* 764 /*
765 * Set flag to 0 and wait for isr to set to 1. It would seem there is a 765 * Set flag to 0 and wait for isr to set to 1. It would seem there is a
766 * race condition here where the ISR could have occured just before or 766 * race condition here where the ISR could have occurred just before or
767 * just after this set. But since we are just coarsely waiting for 767 * just after this set. But since we are just coarsely waiting for
768 * a frame to complete then that's OK. i.e. if the frame completed 768 * a frame to complete then that's OK. i.e. if the frame completed
769 * just before this code executed then we have to wait another full 769 * just before this code executed then we have to wait another full
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
index f6a09ab0dac6..0c647d7af0ee 100644
--- a/drivers/video/display/display-sysfs.c
+++ b/drivers/video/display/display-sysfs.c
@@ -182,7 +182,7 @@ void display_device_unregister(struct display_device *ddev)
182 mutex_lock(&ddev->lock); 182 mutex_lock(&ddev->lock);
183 device_unregister(ddev->dev); 183 device_unregister(ddev->dev);
184 mutex_unlock(&ddev->lock); 184 mutex_unlock(&ddev->lock);
185 // Mark device index as avaliable 185 // Mark device index as available
186 mutex_lock(&allocated_dsp_lock); 186 mutex_lock(&allocated_dsp_lock);
187 idr_remove(&allocated_dsp, ddev->idx); 187 idr_remove(&allocated_dsp, ddev->idx);
188 mutex_unlock(&allocated_dsp_lock); 188 mutex_unlock(&allocated_dsp_lock);
diff --git a/drivers/video/edid.h b/drivers/video/edid.h
index bd89fb3be8c2..d03a232d90b2 100644
--- a/drivers/video/edid.h
+++ b/drivers/video/edid.h
@@ -101,8 +101,8 @@
101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO ) 101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO )
102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO ) 102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO )
103 103
104#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO ) 104#define H_SYNC_WIDTH COMBINE_HI_8LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
105#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO ) 105#define H_SYNC_OFFSET COMBINE_HI_8LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
106 106
107#define H_SIZE_LO (unsigned)block[ 12 ] 107#define H_SIZE_LO (unsigned)block[ 12 ]
108#define V_SIZE_LO (unsigned)block[ 13 ] 108#define V_SIZE_LO (unsigned)block[ 13 ]
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 70477c2e4b61..4eb38db36e4b 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -53,6 +53,7 @@ enum {
53 M_MB_7_1, /* MacBook, 7th rev. */ 53 M_MB_7_1, /* MacBook, 7th rev. */
54 M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ 54 M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
55 M_MBA, /* MacBook Air */ 55 M_MBA, /* MacBook Air */
56 M_MBA_3, /* Macbook Air, 3rd rev */
56 M_MBP, /* MacBook Pro */ 57 M_MBP, /* MacBook Pro */
57 M_MBP_2, /* MacBook Pro 2nd gen */ 58 M_MBP_2, /* MacBook Pro 2nd gen */
58 M_MBP_2_2, /* MacBook Pro 2,2nd gen */ 59 M_MBP_2_2, /* MacBook Pro 2,2nd gen */
@@ -64,43 +65,54 @@ enum {
64 M_MBP_6_1, /* MacBook Pro, 6,1th gen */ 65 M_MBP_6_1, /* MacBook Pro, 6,1th gen */
65 M_MBP_6_2, /* MacBook Pro, 6,2th gen */ 66 M_MBP_6_2, /* MacBook Pro, 6,2th gen */
66 M_MBP_7_1, /* MacBook Pro, 7,1th gen */ 67 M_MBP_7_1, /* MacBook Pro, 7,1th gen */
68 M_MBP_8_2, /* MacBook Pro, 8,2nd gen */
67 M_UNKNOWN /* placeholder */ 69 M_UNKNOWN /* placeholder */
68}; 70};
69 71
72#define OVERRIDE_NONE 0x0
73#define OVERRIDE_BASE 0x1
74#define OVERRIDE_STRIDE 0x2
75#define OVERRIDE_HEIGHT 0x4
76#define OVERRIDE_WIDTH 0x8
77
70static struct efifb_dmi_info { 78static struct efifb_dmi_info {
71 char *optname; 79 char *optname;
72 unsigned long base; 80 unsigned long base;
73 int stride; 81 int stride;
74 int width; 82 int width;
75 int height; 83 int height;
84 int flags;
76} dmi_list[] __initdata = { 85} dmi_list[] __initdata = {
77 [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 }, 86 [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
78 [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ 87 [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */
79 [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, 88 [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE },
80 [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ 89 [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */
81 [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 }, 90 [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
82 [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 }, 91 [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE },
83 [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 }, 92 [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE },
84 [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, 93 [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE },
85 [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 }, 94 [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE },
86 [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 }, 95 [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
87 [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, 96 [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
88 [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 }, 97 [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
89 [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 }, 98 [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
90 [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 }, 99 [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
91 [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, 100 [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
92 [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, 101 /* 11" Macbook Air 3,1 passes the wrong stride */
93 [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ 102 [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE },
94 [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 }, 103 [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
95 [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, 104 [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */
96 [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, 105 [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
97 [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 }, 106 [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
98 [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 }, 107 [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
99 [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 }, 108 [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
100 [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 }, 109 [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
101 [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 }, 110 [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
102 [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 }, 111 [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
103 [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } 112 [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE },
113 [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
114 [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
115 [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE }
104}; 116};
105 117
106static int set_system(const struct dmi_system_id *id); 118static int set_system(const struct dmi_system_id *id);
@@ -138,6 +150,7 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
138 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), 150 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
139 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), 151 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
140 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), 152 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
153 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3),
141 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), 154 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
142 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), 155 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
143 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), 156 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
@@ -151,19 +164,26 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
151 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), 164 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1),
152 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), 165 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2),
153 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), 166 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1),
167 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2),
154 {}, 168 {},
155}; 169};
156 170
171#define choose_value(dmivalue, fwvalue, field, flags) ({ \
172 typeof(fwvalue) _ret_ = fwvalue; \
173 if ((flags) & (field)) \
174 _ret_ = dmivalue; \
175 else if ((fwvalue) == 0) \
176 _ret_ = dmivalue; \
177 _ret_; \
178 })
179
157static int set_system(const struct dmi_system_id *id) 180static int set_system(const struct dmi_system_id *id)
158{ 181{
159 struct efifb_dmi_info *info = id->driver_data; 182 struct efifb_dmi_info *info = id->driver_data;
160 if (info->base == 0)
161 return 0;
162 183
163 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " 184 if (info->base == 0 && info->height == 0 && info->width == 0
164 "(%dx%d, stride %d)\n", id->ident, 185 && info->stride == 0)
165 (void *)info->base, info->width, info->height, 186 return 0;
166 info->stride);
167 187
168 /* Trust the bootloader over the DMI tables */ 188 /* Trust the bootloader over the DMI tables */
169 if (screen_info.lfb_base == 0) { 189 if (screen_info.lfb_base == 0) {
@@ -171,40 +191,47 @@ static int set_system(const struct dmi_system_id *id)
171 struct pci_dev *dev = NULL; 191 struct pci_dev *dev = NULL;
172 int found_bar = 0; 192 int found_bar = 0;
173#endif 193#endif
174 screen_info.lfb_base = info->base; 194 if (info->base) {
195 screen_info.lfb_base = choose_value(info->base,
196 screen_info.lfb_base, OVERRIDE_BASE,
197 info->flags);
175 198
176#if defined(CONFIG_PCI) 199#if defined(CONFIG_PCI)
177 /* make sure that the address in the table is actually on a 200 /* make sure that the address in the table is actually
178 * VGA device's PCI BAR */ 201 * on a VGA device's PCI BAR */
179 202
180 for_each_pci_dev(dev) { 203 for_each_pci_dev(dev) {
181 int i; 204 int i;
182 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) 205 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
183 continue; 206 continue;
184 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 207 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
185 resource_size_t start, end; 208 resource_size_t start, end;
186 209
187 start = pci_resource_start(dev, i); 210 start = pci_resource_start(dev, i);
188 if (start == 0) 211 if (start == 0)
189 break; 212 break;
190 end = pci_resource_end(dev, i); 213 end = pci_resource_end(dev, i);
191 if (screen_info.lfb_base >= start && 214 if (screen_info.lfb_base >= start &&
192 screen_info.lfb_base < end) { 215 screen_info.lfb_base < end) {
193 found_bar = 1; 216 found_bar = 1;
217 }
194 } 218 }
195 } 219 }
196 } 220 if (!found_bar)
197 if (!found_bar) 221 screen_info.lfb_base = 0;
198 screen_info.lfb_base = 0;
199#endif 222#endif
223 }
200 } 224 }
201 if (screen_info.lfb_base) { 225 if (screen_info.lfb_base) {
202 if (screen_info.lfb_linelength == 0) 226 screen_info.lfb_linelength = choose_value(info->stride,
203 screen_info.lfb_linelength = info->stride; 227 screen_info.lfb_linelength, OVERRIDE_STRIDE,
204 if (screen_info.lfb_width == 0) 228 info->flags);
205 screen_info.lfb_width = info->width; 229 screen_info.lfb_width = choose_value(info->width,
206 if (screen_info.lfb_height == 0) 230 screen_info.lfb_width, OVERRIDE_WIDTH,
207 screen_info.lfb_height = info->height; 231 info->flags);
232 screen_info.lfb_height = choose_value(info->height,
233 screen_info.lfb_height, OVERRIDE_HEIGHT,
234 info->flags);
208 if (screen_info.orig_video_isVGA == 0) 235 if (screen_info.orig_video_isVGA == 0)
209 screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; 236 screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
210 } else { 237 } else {
@@ -214,6 +241,13 @@ static int set_system(const struct dmi_system_id *id)
214 screen_info.orig_video_isVGA = 0; 241 screen_info.orig_video_isVGA = 0;
215 return 0; 242 return 0;
216 } 243 }
244
245 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
246 "(%dx%d, stride %d)\n", id->ident,
247 (void *)screen_info.lfb_base, screen_info.lfb_width,
248 screen_info.lfb_height, screen_info.lfb_linelength);
249
250
217 return 1; 251 return 1;
218} 252}
219 253
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index b358d045f130..cbdb1bd77c21 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -456,7 +456,7 @@ static int __init ep93xxfb_alloc_videomem(struct fb_info *info)
456 * There is a bug in the ep93xx framebuffer which causes problems 456 * There is a bug in the ep93xx framebuffer which causes problems
457 * if bit 27 of the physical address is set. 457 * if bit 27 of the physical address is set.
458 * See: http://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2 458 * See: http://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2
459 * There does not seem to be any offical errata for this, but I 459 * There does not seem to be any official errata for this, but I
460 * have confirmed the problem exists on my hardware (ep9315) at 460 * have confirmed the problem exists on my hardware (ep9315) at
461 * least. 461 * least.
462 */ 462 */
diff --git a/drivers/video/fb-puv3.c b/drivers/video/fb-puv3.c
index dbd2dc4745d1..27f2c57e06e9 100644
--- a/drivers/video/fb-puv3.c
+++ b/drivers/video/fb-puv3.c
@@ -13,7 +13,6 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/vmalloc.h>
17#include <linux/platform_device.h> 16#include <linux/platform_device.h>
18#include <linux/clk.h> 17#include <linux/clk.h>
19#include <linux/fb.h> 18#include <linux/fb.h>
@@ -531,7 +530,7 @@ static int unifb_set_par(struct fb_info *info)
531 return -EINVAL; 530 return -EINVAL;
532 } 531 }
533 532
534 writel(PKUNITY_UNIGFX_MMAP_BASE, UDE_FSA); 533 writel(info->fix.smem_start, UDE_FSA);
535 writel(info->var.yres, UDE_LS); 534 writel(info->var.yres, UDE_LS);
536 writel(get_line_length(info->var.xres, 535 writel(get_line_length(info->var.xres,
537 info->var.bits_per_pixel) >> 3, UDE_PS); 536 info->var.bits_per_pixel) >> 3, UDE_PS);
@@ -680,13 +679,27 @@ static int unifb_probe(struct platform_device *dev)
680 struct fb_info *info; 679 struct fb_info *info;
681 u32 unifb_regs[UNIFB_REGS_NUM]; 680 u32 unifb_regs[UNIFB_REGS_NUM];
682 int retval = -ENOMEM; 681 int retval = -ENOMEM;
683 struct resource *iomem, *mapmem; 682 struct resource *iomem;
683 void *videomemory;
684
685 videomemory = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP,
686 get_order(UNIFB_MEMSIZE));
687 if (!videomemory)
688 goto err;
689
690 memset(videomemory, 0, UNIFB_MEMSIZE);
691
692 unifb_fix.smem_start = virt_to_phys(videomemory);
693 unifb_fix.smem_len = UNIFB_MEMSIZE;
694
695 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
696 unifb_fix.mmio_start = iomem->start;
684 697
685 info = framebuffer_alloc(sizeof(u32)*256, &dev->dev); 698 info = framebuffer_alloc(sizeof(u32)*256, &dev->dev);
686 if (!info) 699 if (!info)
687 goto err; 700 goto err;
688 701
689 info->screen_base = (char __iomem *)KUSER_UNIGFX_BASE; 702 info->screen_base = (char __iomem *)videomemory;
690 info->fbops = &unifb_ops; 703 info->fbops = &unifb_ops;
691 704
692 retval = fb_find_mode(&info->var, info, NULL, 705 retval = fb_find_mode(&info->var, info, NULL,
@@ -695,13 +708,6 @@ static int unifb_probe(struct platform_device *dev)
695 if (!retval || (retval == 4)) 708 if (!retval || (retval == 4))
696 info->var = unifb_default; 709 info->var = unifb_default;
697 710
698 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
699 unifb_fix.mmio_start = iomem->start;
700
701 mapmem = platform_get_resource(dev, IORESOURCE_MEM, 1);
702 unifb_fix.smem_start = mapmem->start;
703 unifb_fix.smem_len = UNIFB_MEMSIZE;
704
705 info->fix = unifb_fix; 711 info->fix = unifb_fix;
706 info->pseudo_palette = info->par; 712 info->pseudo_palette = info->par;
707 info->par = NULL; 713 info->par = NULL;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e2bf95370e40..e0c2284924b6 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1507,7 +1507,7 @@ void remove_conflicting_framebuffers(struct apertures_struct *a,
1507 (primary && gen_aper && gen_aper->count && 1507 (primary && gen_aper && gen_aper->count &&
1508 gen_aper->ranges[0].base == VGA_FB_PHYS)) { 1508 gen_aper->ranges[0].base == VGA_FB_PHYS)) {
1509 1509
1510 printk(KERN_ERR "fb: conflicting fb hw usage " 1510 printk(KERN_INFO "fb: conflicting fb hw usage "
1511 "%s vs %s - removing generic driver\n", 1511 "%s vs %s - removing generic driver\n",
1512 name, registered_fb[i]->fix.id); 1512 name, registered_fb[i]->fix.id);
1513 unregister_framebuffer(registered_fb[i]); 1513 unregister_framebuffer(registered_fb[i]);
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index f4a32779168b..04251ce89184 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -33,7 +33,7 @@
33 * for driver private data (info->par). info->par (if any) will be 33 * for driver private data (info->par). info->par (if any) will be
34 * aligned to sizeof(long). 34 * aligned to sizeof(long).
35 * 35 *
36 * Returns the new structure, or NULL if an error occured. 36 * Returns the new structure, or NULL if an error occurred.
37 * 37 *
38 */ 38 */
39struct fb_info *framebuffer_alloc(size_t size, struct device *dev) 39struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 910c5e6f6702..14102a3f70f5 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -1010,7 +1010,7 @@ out_dealloc_cmap:
1010 fb_dealloc_cmap(&info->cmap); 1010 fb_dealloc_cmap(&info->cmap);
1011 1011
1012out_unmap_dac: 1012out_unmap_dac:
1013 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1013 of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
1014 1014
1015out_unmap_fbc: 1015out_unmap_fbc:
1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index 1b0feb8e7244..d0533b7aad79 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -45,7 +45,7 @@
45 * buffer needs an amount of memory of 1.769.472 bytes which 45 * buffer needs an amount of memory of 1.769.472 bytes which
46 * is near to 2 MByte (the allocated address space of Zorro2). 46 * is near to 2 MByte (the allocated address space of Zorro2).
47 * The memory is channel interleaved. That means every channel 47 * The memory is channel interleaved. That means every channel
48 * owns four VRAMs. Unfortunatly most FrameMasters II are 48 * owns four VRAMs. Unfortunately most FrameMasters II are
49 * not assembled with memory for the alpha channel. In this 49 * not assembled with memory for the alpha channel. In this
50 * case it could be possible to add the frame buffer into the 50 * case it could be possible to add the frame buffer into the
51 * normal memory pool. 51 * normal memory pool.
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 9048f87fa8c1..bedf5be27f05 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -882,7 +882,7 @@ static inline __u32 CNVT_TOHW(__u32 val, __u32 width)
882 * which needs to be scaled in this function for the hardware. Things to take 882 * which needs to be scaled in this function for the hardware. Things to take
883 * into consideration are how many color registers, if any, are supported with 883 * into consideration are how many color registers, if any, are supported with
884 * the current color visual. With truecolor mode no color palettes are 884 * the current color visual. With truecolor mode no color palettes are
885 * supported. Here a psuedo palette is created which we store the value in 885 * supported. Here a pseudo palette is created which we store the value in
886 * pseudo_palette in struct fb_info. For pseudocolor mode we have a limited 886 * pseudo_palette in struct fb_info. For pseudocolor mode we have a limited
887 * color palette. 887 * color palette.
888 */ 888 */
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 933899dca33a..7e7b7a9ba274 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -721,7 +721,7 @@ static int gbefb_set_par(struct fb_info *info)
721 721
722 Tiles have the advantage that they can be allocated individually in 722 Tiles have the advantage that they can be allocated individually in
723 memory. However, this mapping is not linear at all, which is not 723 memory. However, this mapping is not linear at all, which is not
724 really convienient. In order to support linear addressing, the GBE 724 really convenient. In order to support linear addressing, the GBE
725 DMA hardware is fooled into thinking the screen is only one tile 725 DMA hardware is fooled into thinking the screen is only one tile
726 large and but has a greater height, so that the DMA transfer covers 726 large and but has a greater height, so that the DMA transfer covers
727 the same region. 727 the same region.
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h
index be8ccb47ebe0..cfcd8090f313 100644
--- a/drivers/video/geode/lxfb.h
+++ b/drivers/video/geode/lxfb.h
@@ -117,7 +117,7 @@ enum gp_registers {
117}; 117};
118 118
119#define GP_BLT_STATUS_CE (1 << 4) /* cmd buf empty */ 119#define GP_BLT_STATUS_CE (1 << 4) /* cmd buf empty */
120#define GP_BLT_STATUS_PB (1 << 0) /* primative busy */ 120#define GP_BLT_STATUS_PB (1 << 0) /* primitive busy */
121 121
122 122
123/* Display Controller registers (table 6-47 from the data book) */ 123/* Display Controller registers (table 6-47 from the data book) */
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index c77bcc6ab463..1b94643ecbcf 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -299,7 +299,7 @@ static int __devexit hecubafb_remove(struct platform_device *dev)
299 299
300static struct platform_driver hecubafb_driver = { 300static struct platform_driver hecubafb_driver = {
301 .probe = hecubafb_probe, 301 .probe = hecubafb_probe,
302 .remove = hecubafb_remove, 302 .remove = __devexit_p(hecubafb_remove),
303 .driver = { 303 .driver = {
304 .owner = THIS_MODULE, 304 .owner = THIS_MODULE,
305 .name = "hecubafb", 305 .name = "hecubafb",
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index c8e280f1bb0b..ebf8495ff198 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -321,11 +321,11 @@ static int __devinit hpfb_dio_probe(struct dio_dev * d, const struct dio_device_
321 unsigned long paddr, vaddr; 321 unsigned long paddr, vaddr;
322 322
323 paddr = d->resource.start; 323 paddr = d->resource.start;
324 if (!request_mem_region(d->resource.start, d->resource.end - d->resource.start, d->name)) 324 if (!request_mem_region(d->resource.start, resource_size(&d->resource), d->name))
325 return -EBUSY; 325 return -EBUSY;
326 326
327 if (d->scode >= DIOII_SCBASE) { 327 if (d->scode >= DIOII_SCBASE) {
328 vaddr = (unsigned long)ioremap(paddr, d->resource.end - d->resource.start); 328 vaddr = (unsigned long)ioremap(paddr, resource_size(&d->resource));
329 } else { 329 } else {
330 vaddr = paddr + DIO_VIRADDRBASE; 330 vaddr = paddr + DIO_VIRADDRBASE;
331 } 331 }
@@ -344,7 +344,7 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
344 unregister_framebuffer(&fb_info); 344 unregister_framebuffer(&fb_info);
345 if (d->scode >= DIOII_SCBASE) 345 if (d->scode >= DIOII_SCBASE)
346 iounmap((void *)fb_regs); 346 iounmap((void *)fb_regs);
347 release_mem_region(d->resource.start, d->resource.end - d->resource.start); 347 release_mem_region(d->resource.start, resource_size(&d->resource));
348} 348}
349 349
350static struct dio_device_id hpfb_dio_tbl[] = { 350static struct dio_device_id hpfb_dio_tbl[] = {
diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c
index f5bedee4310a..7672d2ea9b35 100644
--- a/drivers/video/i810/i810_accel.c
+++ b/drivers/video/i810/i810_accel.c
@@ -112,7 +112,7 @@ static inline int wait_for_engine_idle(struct fb_info *info)
112 * @par: pointer to i810fb_par structure 112 * @par: pointer to i810fb_par structure
113 * 113 *
114 * DESCRIPTION: 114 * DESCRIPTION:
115 * Checks/waits for sufficent space in ringbuffer of size 115 * Checks/waits for sufficient space in ringbuffer of size
116 * space. Returns the tail of the buffer 116 * space. Returns the tail of the buffer
117 */ 117 */
118static inline u32 begin_iring(struct fb_info *info, u32 space) 118static inline u32 begin_iring(struct fb_info *info, u32 space)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 69bd4a581d4a..ef72cb483834 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -499,6 +499,7 @@ static void imxfb_init_backlight(struct imxfb_info *fbi)
499 499
500 memset(&props, 0, sizeof(struct backlight_properties)); 500 memset(&props, 0, sizeof(struct backlight_properties));
501 props.max_brightness = 0xff; 501 props.max_brightness = 0xff;
502 props.type = BACKLIGHT_RAW;
502 writel(fbi->pwmr, fbi->regs + LCDC_PWMR); 503 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
503 504
504 bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi, 505 bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi,
diff --git a/drivers/video/intelfb/Makefile b/drivers/video/intelfb/Makefile
index 6c782d3ae1be..f7d631ebee8e 100644
--- a/drivers/video/intelfb/Makefile
+++ b/drivers/video/intelfb/Makefile
@@ -4,7 +4,4 @@ intelfb-y := intelfbdrv.o intelfbhw.o
4intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o 4intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o
5intelfb-objs := $(intelfb-y) 5intelfb-objs := $(intelfb-y)
6 6
7ifdef CONFIG_FB_INTEL_DEBUG 7ccflags-$(CONFIG_FB_INTEL_DEBUG) := -DDEBUG -DREGDUMP
8#EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP
9EXTRA_CFLAGS += -DDEBUG -DREGDUMP
10endif
diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/kyro/STG4000OverlayDevice.c
index a8c9713413e6..0aeeaa10708b 100644
--- a/drivers/video/kyro/STG4000OverlayDevice.c
+++ b/drivers/video/kyro/STG4000OverlayDevice.c
@@ -417,7 +417,7 @@ int SetOverlayViewPort(volatile STG4000REG __iomem *pSTGReg,
417 /***************** Horizontal decimation/scaling ***************************/ 417 /***************** Horizontal decimation/scaling ***************************/
418 418
419 /* 419 /*
420 * Now we handle the horizontal case, this is a simplified verison of 420 * Now we handle the horizontal case, this is a simplified version of
421 * the vertical case in that we decimate by factors of 2. as we are 421 * the vertical case in that we decimate by factors of 2. as we are
422 * working in words we should always be able to decimate by these 422 * working in words we should always be able to decimate by these
423 * factors. as we always have to have a buffer which is aligned to a 423 * factors. as we always have to have a buffer which is aligned to a
diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/kyro/STG4000Reg.h
index 244549e61368..5d6269882589 100644
--- a/drivers/video/kyro/STG4000Reg.h
+++ b/drivers/video/kyro/STG4000Reg.h
@@ -16,7 +16,7 @@
16 16
17/* 17/*
18 * Macros that access memory mapped card registers in PCI space 18 * Macros that access memory mapped card registers in PCI space
19 * Add an appropraite section for your OS or processor architecture. 19 * Add an appropriate section for your OS or processor architecture.
20 */ 20 */
21#if defined(__KERNEL__) 21#if defined(__KERNEL__)
22#include <asm/page.h> 22#include <asm/page.h>
diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h
index c6ed7801efe2..1e6e45b57b78 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.h
+++ b/drivers/video/matrox/matroxfb_DAC1064.h
@@ -46,7 +46,7 @@ void DAC1064_global_restore(struct matrox_fb_info *minfo);
46#define M1064_XDVICLKCTRL_DVILOOPCTL 0x30 46#define M1064_XDVICLKCTRL_DVILOOPCTL 0x30
47 /* CRTC2 pixel clock allowed to(0)/blocked from(1) driving CRTC2 */ 47 /* CRTC2 pixel clock allowed to(0)/blocked from(1) driving CRTC2 */
48#define M1064_XDVICLKCTRL_C2DVICLKEN 0x40 48#define M1064_XDVICLKCTRL_C2DVICLKEN 0x40
49 /* P1PLL loop filter bandwith selection */ 49 /* P1PLL loop filter bandwidth selection */
50#define M1064_XDVICLKCTRL_P1LOOPBWDTCTL 0x80 50#define M1064_XDVICLKCTRL_P1LOOPBWDTCTL 0x80
51#define M1064_XCURCOL0RED 0x08 51#define M1064_XCURCOL0RED 0x08
52#define M1064_XCURCOL0GREEN 0x09 52#define M1064_XCURCOL0GREEN 0x09
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c
index 835aaaae6b96..9a44cec394b5 100644
--- a/drivers/video/matrox/matroxfb_Ti3026.c
+++ b/drivers/video/matrox/matroxfb_Ti3026.c
@@ -387,7 +387,7 @@ static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m)
387 hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW; 387 hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
388 break; 388 break;
389 case 16: 389 case 16:
390 /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */ 390 /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used every time) */
391 hw->DACreg[POS3026_XTRUECOLORCTRL] = (minfo->fbcon.var.green.length == 5) ? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565); 391 hw->DACreg[POS3026_XTRUECOLORCTRL] = (minfo->fbcon.var.green.length == 5) ? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);
392 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT; 392 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;
393 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2; 393 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;
@@ -399,7 +399,7 @@ static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m)
399 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4; 399 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
400 break; 400 break;
401 case 32: 401 case 32:
402 /* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used everytime) */ 402 /* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used every time) */
403 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT; 403 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
404 break; 404 break;
405 default: 405 default:
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index a082debe824b..44bf8d4a216b 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -101,8 +101,6 @@
101 101
102#include <linux/version.h> 102#include <linux/version.h>
103 103
104#define __OLD_VIDIOC_
105
106#include "matroxfb_base.h" 104#include "matroxfb_base.h"
107#include "matroxfb_misc.h" 105#include "matroxfb_misc.h"
108#include "matroxfb_accel.h" 106#include "matroxfb_accel.h"
@@ -623,7 +621,7 @@ static int matroxfb_decode_var(const struct matrox_fb_info *minfo,
623 var->yoffset = var->yres_virtual - var->yres; 621 var->yoffset = var->yres_virtual - var->yres;
624 622
625 if (bpp == 16 && var->green.length == 5) { 623 if (bpp == 16 && var->green.length == 5) {
626 bpp--; /* an artifical value - 15 */ 624 bpp--; /* an artificial value - 15 */
627 } 625 }
628 626
629 for (rgbt = table; rgbt->bpp < bpp; rgbt++); 627 for (rgbt = table; rgbt->bpp < bpp; rgbt++);
@@ -1152,7 +1150,6 @@ static int matroxfb_ioctl(struct fb_info *info,
1152 return -EFAULT; 1150 return -EFAULT;
1153 return err; 1151 return err;
1154 } 1152 }
1155 case VIDIOC_S_CTRL_OLD:
1156 case VIDIOC_S_CTRL: 1153 case VIDIOC_S_CTRL:
1157 { 1154 {
1158 struct v4l2_control ctrl; 1155 struct v4l2_control ctrl;
@@ -1461,13 +1458,6 @@ static struct board {
1461 MGA_G100, 1458 MGA_G100,
1462 &vbG100, 1459 &vbG100,
1463 "MGA-G100 (AGP)"}, 1460 "MGA-G100 (AGP)"},
1464 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, 0xFF,
1465 0, 0,
1466 DEVF_G200,
1467 230000,
1468 MGA_G200,
1469 &vbG200,
1470 "MGA-G200eV (PCI)"},
1471 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, 1461 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
1472 0, 0, 1462 0, 0,
1473 DEVF_G200, 1463 DEVF_G200,
@@ -2119,8 +2109,6 @@ static struct pci_device_id matroxfb_devices[] = {
2119 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2109 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2120 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 2110 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
2121 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2111 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2122 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI,
2123 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2124 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 2112 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI,
2125 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2113 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2126 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 2114 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index f96a471cb1a8..11ed57bb704e 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -12,7 +12,7 @@
12#undef MATROXFB_DEBUG 12#undef MATROXFB_DEBUG
13 13
14/* heavy debugging: */ 14/* heavy debugging: */
15/* -- logs putc[s], so everytime a char is displayed, it's logged */ 15/* -- logs putc[s], so every time a char is displayed, it's logged */
16#undef MATROXFB_DEBUG_HEAVY 16#undef MATROXFB_DEBUG_HEAVY
17 17
18/* This one _could_ cause infinite loops */ 18/* This one _could_ cause infinite loops */
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index 63ed3b72b01c..ed64edfd2c43 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -765,7 +765,7 @@ static int __devexit metronomefb_remove(struct platform_device *dev)
765 765
766static struct platform_driver metronomefb_driver = { 766static struct platform_driver metronomefb_driver = {
767 .probe = metronomefb_probe, 767 .probe = metronomefb_probe,
768 .remove = metronomefb_remove, 768 .remove = __devexit_p(metronomefb_remove),
769 .driver = { 769 .driver = {
770 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
771 .name = "metronomefb", 771 .name = "metronomefb",
diff --git a/drivers/video/nuc900fb.h b/drivers/video/nuc900fb.h
index 6c23aa3d3b89..bc7c9300f276 100644
--- a/drivers/video/nuc900fb.h
+++ b/drivers/video/nuc900fb.h
@@ -8,7 +8,7 @@
8 * the Free Software Foundation; either version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * Auther: 11 * Author:
12 * Wang Qiang(rurality.linux@gmail.com) 2009/12/16 12 * Wang Qiang(rurality.linux@gmail.com) 2009/12/16
13 */ 13 */
14 14
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 6aac6d1b937b..8471008aa6ff 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -111,6 +111,7 @@ void nvidia_bl_init(struct nvidia_par *par)
111 snprintf(name, sizeof(name), "nvidiabl%d", info->node); 111 snprintf(name, sizeof(name), "nvidiabl%d", info->node);
112 112
113 memset(&props, 0, sizeof(struct backlight_properties)); 113 memset(&props, 0, sizeof(struct backlight_properties));
114 props.type = BACKLIGHT_RAW;
114 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 115 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
115 bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops, 116 bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops,
116 &props); 117 &props);
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 083c8fe53e24..196fa2e7f438 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -5,13 +5,18 @@ config FB_OMAP
5 select FB_CFB_FILLRECT 5 select FB_CFB_FILLRECT
6 select FB_CFB_COPYAREA 6 select FB_CFB_COPYAREA
7 select FB_CFB_IMAGEBLIT 7 select FB_CFB_IMAGEBLIT
8 select TWL4030_CORE if MACH_OMAP_2430SDP
8 help 9 help
9 Frame buffer driver for OMAP based boards. 10 Frame buffer driver for OMAP based boards.
10 11
11config FB_OMAP_LCD_VGA 12config FB_OMAP_LCD_VGA
12 bool "Use LCD in VGA mode" 13 bool "Use LCD in VGA mode"
13 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP 14 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
14 15 help
16 Set LCD resolution as VGA (640 X 480).
17 Default resolution without this option is QVGA(320 X 240).
18 Please take a look at drivers/video/omap/lcd_ldp.c file
19 for lcd driver code.
15choice 20choice
16 depends on FB_OMAP && MACH_OVERO 21 depends on FB_OMAP && MACH_OVERO
17 prompt "Screen resolution" 22 prompt "Screen resolution"
@@ -59,7 +64,7 @@ config FB_OMAP_MANUAL_UPDATE
59 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL 64 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
60 help 65 help
61 Say Y here, if your user-space applications are capable of 66 Say Y here, if your user-space applications are capable of
62 notifying the frame buffer driver when a change has occured in 67 notifying the frame buffer driver when a change has occurred in
63 the frame buffer content and thus a reload of the image data to 68 the frame buffer content and thus a reload of the image data to
64 the external frame buffer is required. If unsure, say N. 69 the external frame buffer is required. If unsure, say N.
65 70
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index 87785c215a52..c0504a8a5079 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -397,8 +397,7 @@ static inline void free_req(struct blizzard_request *req)
397 397
398 spin_lock_irqsave(&blizzard.req_lock, flags); 398 spin_lock_irqsave(&blizzard.req_lock, flags);
399 399
400 list_del(&req->entry); 400 list_move(&req->entry, &blizzard.free_req_list);
401 list_add(&req->entry, &blizzard.free_req_list);
402 if (!(req->flags & REQ_FROM_IRQ_POOL)) 401 if (!(req->flags & REQ_FROM_IRQ_POOL))
403 up(&blizzard.req_sema); 402 up(&blizzard.req_sema);
404 403
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 0016f77cd13f..084aa0ac562b 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -269,8 +269,7 @@ static inline void free_req(struct hwa742_request *req)
269 269
270 spin_lock_irqsave(&hwa742.req_lock, flags); 270 spin_lock_irqsave(&hwa742.req_lock, flags);
271 271
272 list_del(&req->entry); 272 list_move(&req->entry, &hwa742.free_req_list);
273 list_add(&req->entry, &hwa742.free_req_list);
274 if (!(req->flags & REQ_FROM_IRQ_POOL)) 273 if (!(req->flags & REQ_FROM_IRQ_POOL))
275 up(&hwa742.req_sema); 274 up(&hwa742.req_sema);
276 275
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 940cab394c2e..d18ad6b2372a 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -9,6 +9,12 @@ config PANEL_GENERIC_DPI
9 Supports LCD Panel used in TI SDP3430 and EVM boards, 9 Supports LCD Panel used in TI SDP3430 and EVM boards,
10 OMAP3517 EVM boards and CM-T35. 10 OMAP3517 EVM boards and CM-T35.
11 11
12config PANEL_LGPHILIPS_LB035Q02
13 tristate "LG.Philips LB035Q02 LCD Panel"
14 depends on OMAP2_DSS && SPI
15 help
16 LCD Panel used on the Gumstix Overo Palo35
17
12config PANEL_SHARP_LS037V7DW01 18config PANEL_SHARP_LS037V7DW01
13 tristate "Sharp LS037V7DW01 LCD Panel" 19 tristate "Sharp LS037V7DW01 LCD Panel"
14 depends on OMAP2_DSS 20 depends on OMAP2_DSS
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 861f0255ec6b..0f601ab3abf4 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o 1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
2obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 3obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
3obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o 4obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
4 5
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index e77310653207..7e04c921aa2a 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -534,6 +534,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
534 534
535 props.fb_blank = FB_BLANK_UNBLANK; 535 props.fb_blank = FB_BLANK_UNBLANK;
536 props.power = FB_BLANK_UNBLANK; 536 props.power = FB_BLANK_UNBLANK;
537 props.type = BACKLIGHT_RAW;
537 538
538 bldev = backlight_device_register("acx565akm", &md->spi->dev, 539 bldev = backlight_device_register("acx565akm", &md->spi->dev,
539 md, &acx565akm_bl_ops, &props); 540 md, &acx565akm_bl_ops, &props);
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 07eb30ee59c8..4a9b9ff59467 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -156,6 +156,31 @@ static struct panel_config generic_dpi_panels[] = {
156 .power_off_delay = 0, 156 .power_off_delay = 0,
157 .name = "toppoly_tdo35s", 157 .name = "toppoly_tdo35s",
158 }, 158 },
159
160 /* Samsung LTE430WQ-F0C */
161 {
162 {
163 .x_res = 480,
164 .y_res = 272,
165
166 .pixel_clock = 9200,
167
168 .hfp = 8,
169 .hsw = 41,
170 .hbp = 45 - 41,
171
172 .vfp = 4,
173 .vsw = 10,
174 .vbp = 12 - 10,
175 },
176 .acbi = 0x0,
177 .acb = 0x0,
178 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
179 OMAP_DSS_LCD_IHS,
180 .power_on_delay = 0,
181 .power_off_delay = 0,
182 .name = "samsung_lte430wq_f0c",
183 },
159}; 184};
160 185
161struct panel_drv_data { 186struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
new file mode 100644
index 000000000000..271324db2436
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -0,0 +1,279 @@
1/*
2 * LCD panel driver for LG.Philips LB035Q02
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/spi/spi.h>
22#include <linux/mutex.h>
23
24#include <plat/display.h>
25
26struct lb035q02_data {
27 struct mutex lock;
28};
29
30static struct omap_video_timings lb035q02_timings = {
31 .x_res = 320,
32 .y_res = 240,
33
34 .pixel_clock = 6500,
35
36 .hsw = 2,
37 .hfp = 20,
38 .hbp = 68,
39
40 .vsw = 2,
41 .vfp = 4,
42 .vbp = 18,
43};
44
45static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
46{
47 int r;
48
49 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
50 return 0;
51
52 r = omapdss_dpi_display_enable(dssdev);
53 if (r)
54 goto err0;
55
56 if (dssdev->platform_enable) {
57 r = dssdev->platform_enable(dssdev);
58 if (r)
59 goto err1;
60 }
61
62 return 0;
63err1:
64 omapdss_dpi_display_disable(dssdev);
65err0:
66 return r;
67}
68
69static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
70{
71 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
72 return;
73
74 if (dssdev->platform_disable)
75 dssdev->platform_disable(dssdev);
76
77 omapdss_dpi_display_disable(dssdev);
78}
79
80static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
81{
82 struct lb035q02_data *ld;
83 int r;
84
85 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
86 OMAP_DSS_LCD_IHS;
87 dssdev->panel.timings = lb035q02_timings;
88
89 ld = kzalloc(sizeof(*ld), GFP_KERNEL);
90 if (!ld) {
91 r = -ENOMEM;
92 goto err;
93 }
94 mutex_init(&ld->lock);
95 dev_set_drvdata(&dssdev->dev, ld);
96 return 0;
97err:
98 return r;
99}
100
101static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
102{
103 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
104
105 kfree(ld);
106}
107
108static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
109{
110 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
111 int r;
112
113 mutex_lock(&ld->lock);
114
115 r = lb035q02_panel_power_on(dssdev);
116 if (r)
117 goto err;
118 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
119
120 mutex_unlock(&ld->lock);
121 return 0;
122err:
123 mutex_unlock(&ld->lock);
124 return r;
125}
126
127static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
128{
129 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
130
131 mutex_lock(&ld->lock);
132
133 lb035q02_panel_power_off(dssdev);
134 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
135
136 mutex_unlock(&ld->lock);
137}
138
139static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
140{
141 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
142
143 mutex_lock(&ld->lock);
144
145 lb035q02_panel_power_off(dssdev);
146 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
147
148 mutex_unlock(&ld->lock);
149 return 0;
150}
151
152static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
153{
154 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
155 int r;
156
157 mutex_lock(&ld->lock);
158
159 r = lb035q02_panel_power_on(dssdev);
160 if (r)
161 goto err;
162 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
163
164 mutex_unlock(&ld->lock);
165 return 0;
166err:
167 mutex_unlock(&ld->lock);
168 return r;
169}
170
171static struct omap_dss_driver lb035q02_driver = {
172 .probe = lb035q02_panel_probe,
173 .remove = lb035q02_panel_remove,
174
175 .enable = lb035q02_panel_enable,
176 .disable = lb035q02_panel_disable,
177 .suspend = lb035q02_panel_suspend,
178 .resume = lb035q02_panel_resume,
179
180 .driver = {
181 .name = "lgphilips_lb035q02_panel",
182 .owner = THIS_MODULE,
183 },
184};
185
186static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val)
187{
188 struct spi_message msg;
189 struct spi_transfer index_xfer = {
190 .len = 3,
191 .cs_change = 1,
192 };
193 struct spi_transfer value_xfer = {
194 .len = 3,
195 };
196 u8 buffer[16];
197
198 spi_message_init(&msg);
199
200 /* register index */
201 buffer[0] = 0x70;
202 buffer[1] = 0x00;
203 buffer[2] = reg & 0x7f;
204 index_xfer.tx_buf = buffer;
205 spi_message_add_tail(&index_xfer, &msg);
206
207 /* register value */
208 buffer[4] = 0x72;
209 buffer[5] = val >> 8;
210 buffer[6] = val;
211 value_xfer.tx_buf = buffer + 4;
212 spi_message_add_tail(&value_xfer, &msg);
213
214 return spi_sync(spi, &msg);
215}
216
217static void init_lb035q02_panel(struct spi_device *spi)
218{
219 /* Init sequence from page 28 of the lb035q02 spec */
220 lb035q02_write_reg(spi, 0x01, 0x6300);
221 lb035q02_write_reg(spi, 0x02, 0x0200);
222 lb035q02_write_reg(spi, 0x03, 0x0177);
223 lb035q02_write_reg(spi, 0x04, 0x04c7);
224 lb035q02_write_reg(spi, 0x05, 0xffc0);
225 lb035q02_write_reg(spi, 0x06, 0xe806);
226 lb035q02_write_reg(spi, 0x0a, 0x4008);
227 lb035q02_write_reg(spi, 0x0b, 0x0000);
228 lb035q02_write_reg(spi, 0x0d, 0x0030);
229 lb035q02_write_reg(spi, 0x0e, 0x2800);
230 lb035q02_write_reg(spi, 0x0f, 0x0000);
231 lb035q02_write_reg(spi, 0x16, 0x9f80);
232 lb035q02_write_reg(spi, 0x17, 0x0a0f);
233 lb035q02_write_reg(spi, 0x1e, 0x00c1);
234 lb035q02_write_reg(spi, 0x30, 0x0300);
235 lb035q02_write_reg(spi, 0x31, 0x0007);
236 lb035q02_write_reg(spi, 0x32, 0x0000);
237 lb035q02_write_reg(spi, 0x33, 0x0000);
238 lb035q02_write_reg(spi, 0x34, 0x0707);
239 lb035q02_write_reg(spi, 0x35, 0x0004);
240 lb035q02_write_reg(spi, 0x36, 0x0302);
241 lb035q02_write_reg(spi, 0x37, 0x0202);
242 lb035q02_write_reg(spi, 0x3a, 0x0a0d);
243 lb035q02_write_reg(spi, 0x3b, 0x0806);
244}
245
246static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi)
247{
248 init_lb035q02_panel(spi);
249 return omap_dss_register_driver(&lb035q02_driver);
250}
251
252static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi)
253{
254 omap_dss_unregister_driver(&lb035q02_driver);
255 return 0;
256}
257
258static struct spi_driver lb035q02_spi_driver = {
259 .driver = {
260 .name = "lgphilips_lb035q02_panel-spi",
261 .owner = THIS_MODULE,
262 },
263 .probe = lb035q02_panel_spi_probe,
264 .remove = __devexit_p(lb035q02_panel_spi_remove),
265};
266
267static int __init lb035q02_panel_drv_init(void)
268{
269 return spi_register_driver(&lb035q02_spi_driver);
270}
271
272static void __exit lb035q02_panel_drv_exit(void)
273{
274 spi_unregister_driver(&lb035q02_spi_driver);
275}
276
277module_init(lb035q02_panel_drv_init);
278module_exit(lb035q02_panel_drv_exit);
279MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 9a138f650e05..d2b35d2df2a6 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -99,6 +99,7 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
99 99
100 memset(&props, 0, sizeof(struct backlight_properties)); 100 memset(&props, 0, sizeof(struct backlight_properties));
101 props.max_brightness = dssdev->max_backlight_level; 101 props.max_brightness = dssdev->max_backlight_level;
102 props.type = BACKLIGHT_RAW;
102 103
103 bl = backlight_device_register("sharp-ls", &dssdev->dev, dssdev, 104 bl = backlight_device_register("sharp-ls", &dssdev->dev, dssdev,
104 &sharp_ls_bl_ops, &props); 105 &sharp_ls_bl_ops, &props);
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 61026f96ad20..adc9900458e1 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -218,6 +218,8 @@ struct taal_data {
218 u16 w; 218 u16 w;
219 u16 h; 219 u16 h;
220 } update_region; 220 } update_region;
221 int channel;
222
221 struct delayed_work te_timeout_work; 223 struct delayed_work te_timeout_work;
222 224
223 bool use_dsi_bl; 225 bool use_dsi_bl;
@@ -257,12 +259,12 @@ static void hw_guard_wait(struct taal_data *td)
257 } 259 }
258} 260}
259 261
260static int taal_dcs_read_1(u8 dcs_cmd, u8 *data) 262static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
261{ 263{
262 int r; 264 int r;
263 u8 buf[1]; 265 u8 buf[1];
264 266
265 r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1); 267 r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
266 268
267 if (r < 0) 269 if (r < 0)
268 return r; 270 return r;
@@ -272,17 +274,17 @@ static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
272 return 0; 274 return 0;
273} 275}
274 276
275static int taal_dcs_write_0(u8 dcs_cmd) 277static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
276{ 278{
277 return dsi_vc_dcs_write(TCH, &dcs_cmd, 1); 279 return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
278} 280}
279 281
280static int taal_dcs_write_1(u8 dcs_cmd, u8 param) 282static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
281{ 283{
282 u8 buf[2]; 284 u8 buf[2];
283 buf[0] = dcs_cmd; 285 buf[0] = dcs_cmd;
284 buf[1] = param; 286 buf[1] = param;
285 return dsi_vc_dcs_write(TCH, buf, 2); 287 return dsi_vc_dcs_write(td->channel, buf, 2);
286} 288}
287 289
288static int taal_sleep_in(struct taal_data *td) 290static int taal_sleep_in(struct taal_data *td)
@@ -294,7 +296,7 @@ static int taal_sleep_in(struct taal_data *td)
294 hw_guard_wait(td); 296 hw_guard_wait(td);
295 297
296 cmd = DCS_SLEEP_IN; 298 cmd = DCS_SLEEP_IN;
297 r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1); 299 r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
298 if (r) 300 if (r)
299 return r; 301 return r;
300 302
@@ -312,7 +314,7 @@ static int taal_sleep_out(struct taal_data *td)
312 314
313 hw_guard_wait(td); 315 hw_guard_wait(td);
314 316
315 r = taal_dcs_write_0(DCS_SLEEP_OUT); 317 r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
316 if (r) 318 if (r)
317 return r; 319 return r;
318 320
@@ -324,30 +326,30 @@ static int taal_sleep_out(struct taal_data *td)
324 return 0; 326 return 0;
325} 327}
326 328
327static int taal_get_id(u8 *id1, u8 *id2, u8 *id3) 329static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
328{ 330{
329 int r; 331 int r;
330 332
331 r = taal_dcs_read_1(DCS_GET_ID1, id1); 333 r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
332 if (r) 334 if (r)
333 return r; 335 return r;
334 r = taal_dcs_read_1(DCS_GET_ID2, id2); 336 r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
335 if (r) 337 if (r)
336 return r; 338 return r;
337 r = taal_dcs_read_1(DCS_GET_ID3, id3); 339 r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
338 if (r) 340 if (r)
339 return r; 341 return r;
340 342
341 return 0; 343 return 0;
342} 344}
343 345
344static int taal_set_addr_mode(u8 rotate, bool mirror) 346static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
345{ 347{
346 int r; 348 int r;
347 u8 mode; 349 u8 mode;
348 int b5, b6, b7; 350 int b5, b6, b7;
349 351
350 r = taal_dcs_read_1(DCS_READ_MADCTL, &mode); 352 r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
351 if (r) 353 if (r)
352 return r; 354 return r;
353 355
@@ -381,10 +383,11 @@ static int taal_set_addr_mode(u8 rotate, bool mirror)
381 mode &= ~((1<<7) | (1<<6) | (1<<5)); 383 mode &= ~((1<<7) | (1<<6) | (1<<5));
382 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5); 384 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
383 385
384 return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode); 386 return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
385} 387}
386 388
387static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h) 389static int taal_set_update_window(struct taal_data *td,
390 u16 x, u16 y, u16 w, u16 h)
388{ 391{
389 int r; 392 int r;
390 u16 x1 = x; 393 u16 x1 = x;
@@ -399,7 +402,7 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
399 buf[3] = (x2 >> 8) & 0xff; 402 buf[3] = (x2 >> 8) & 0xff;
400 buf[4] = (x2 >> 0) & 0xff; 403 buf[4] = (x2 >> 0) & 0xff;
401 404
402 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 405 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
403 if (r) 406 if (r)
404 return r; 407 return r;
405 408
@@ -409,11 +412,11 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
409 buf[3] = (y2 >> 8) & 0xff; 412 buf[3] = (y2 >> 8) & 0xff;
410 buf[4] = (y2 >> 0) & 0xff; 413 buf[4] = (y2 >> 0) & 0xff;
411 414
412 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 415 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
413 if (r) 416 if (r)
414 return r; 417 return r;
415 418
416 dsi_vc_send_bta_sync(TCH); 419 dsi_vc_send_bta_sync(td->channel);
417 420
418 return r; 421 return r;
419} 422}
@@ -439,7 +442,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
439 if (td->use_dsi_bl) { 442 if (td->use_dsi_bl) {
440 if (td->enabled) { 443 if (td->enabled) {
441 dsi_bus_lock(); 444 dsi_bus_lock();
442 r = taal_dcs_write_1(DCS_BRIGHTNESS, level); 445 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
443 dsi_bus_unlock(); 446 dsi_bus_unlock();
444 } else { 447 } else {
445 r = 0; 448 r = 0;
@@ -502,7 +505,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
502 505
503 if (td->enabled) { 506 if (td->enabled) {
504 dsi_bus_lock(); 507 dsi_bus_lock();
505 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors); 508 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
506 dsi_bus_unlock(); 509 dsi_bus_unlock();
507 } else { 510 } else {
508 r = -ENODEV; 511 r = -ENODEV;
@@ -528,7 +531,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
528 531
529 if (td->enabled) { 532 if (td->enabled) {
530 dsi_bus_lock(); 533 dsi_bus_lock();
531 r = taal_get_id(&id1, &id2, &id3); 534 r = taal_get_id(td, &id1, &id2, &id3);
532 dsi_bus_unlock(); 535 dsi_bus_unlock();
533 } else { 536 } else {
534 r = -ENODEV; 537 r = -ENODEV;
@@ -590,7 +593,7 @@ static ssize_t store_cabc_mode(struct device *dev,
590 if (td->enabled) { 593 if (td->enabled) {
591 dsi_bus_lock(); 594 dsi_bus_lock();
592 if (!td->cabc_broken) 595 if (!td->cabc_broken)
593 taal_dcs_write_1(DCS_WRITE_CABC, i); 596 taal_dcs_write_1(td, DCS_WRITE_CABC, i);
594 dsi_bus_unlock(); 597 dsi_bus_unlock();
595 } 598 }
596 599
@@ -729,6 +732,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
729 props.max_brightness = 255; 732 props.max_brightness = 255;
730 else 733 else
731 props.max_brightness = 127; 734 props.max_brightness = 127;
735
736 props.type = BACKLIGHT_RAW;
732 bldev = backlight_device_register("taal", &dssdev->dev, dssdev, 737 bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
733 &taal_bl_ops, &props); 738 &taal_bl_ops, &props);
734 if (IS_ERR(bldev)) { 739 if (IS_ERR(bldev)) {
@@ -774,14 +779,29 @@ static int taal_probe(struct omap_dss_device *dssdev)
774 dev_dbg(&dssdev->dev, "Using GPIO TE\n"); 779 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
775 } 780 }
776 781
782 r = omap_dsi_request_vc(dssdev, &td->channel);
783 if (r) {
784 dev_err(&dssdev->dev, "failed to get virtual channel\n");
785 goto err_req_vc;
786 }
787
788 r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
789 if (r) {
790 dev_err(&dssdev->dev, "failed to set VC_ID\n");
791 goto err_vc_id;
792 }
793
777 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 794 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
778 if (r) { 795 if (r) {
779 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 796 dev_err(&dssdev->dev, "failed to create sysfs files\n");
780 goto err_sysfs; 797 goto err_vc_id;
781 } 798 }
782 799
783 return 0; 800 return 0;
784err_sysfs: 801
802err_vc_id:
803 omap_dsi_release_vc(dssdev, td->channel);
804err_req_vc:
785 if (panel_data->use_ext_te) 805 if (panel_data->use_ext_te)
786 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); 806 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
787err_irq: 807err_irq:
@@ -808,6 +828,7 @@ static void taal_remove(struct omap_dss_device *dssdev)
808 dev_dbg(&dssdev->dev, "remove\n"); 828 dev_dbg(&dssdev->dev, "remove\n");
809 829
810 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 830 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
831 omap_dsi_release_vc(dssdev, td->channel);
811 832
812 if (panel_data->use_ext_te) { 833 if (panel_data->use_ext_te) {
813 int gpio = panel_data->ext_te_gpio; 834 int gpio = panel_data->ext_te_gpio;
@@ -846,13 +867,13 @@ static int taal_power_on(struct omap_dss_device *dssdev)
846 867
847 taal_hw_reset(dssdev); 868 taal_hw_reset(dssdev);
848 869
849 omapdss_dsi_vc_enable_hs(TCH, false); 870 omapdss_dsi_vc_enable_hs(td->channel, false);
850 871
851 r = taal_sleep_out(td); 872 r = taal_sleep_out(td);
852 if (r) 873 if (r)
853 goto err; 874 goto err;
854 875
855 r = taal_get_id(&id1, &id2, &id3); 876 r = taal_get_id(td, &id1, &id2, &id3);
856 if (r) 877 if (r)
857 goto err; 878 goto err;
858 879
@@ -861,30 +882,30 @@ static int taal_power_on(struct omap_dss_device *dssdev)
861 (id2 == 0x00 || id2 == 0xff || id2 == 0x81)) 882 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
862 td->cabc_broken = true; 883 td->cabc_broken = true;
863 884
864 r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); 885 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
865 if (r) 886 if (r)
866 goto err; 887 goto err;
867 888
868 r = taal_dcs_write_1(DCS_CTRL_DISPLAY, 889 r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
869 (1<<2) | (1<<5)); /* BL | BCTRL */ 890 (1<<2) | (1<<5)); /* BL | BCTRL */
870 if (r) 891 if (r)
871 goto err; 892 goto err;
872 893
873 r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 894 r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
874 if (r) 895 if (r)
875 goto err; 896 goto err;
876 897
877 r = taal_set_addr_mode(td->rotate, td->mirror); 898 r = taal_set_addr_mode(td, td->rotate, td->mirror);
878 if (r) 899 if (r)
879 goto err; 900 goto err;
880 901
881 if (!td->cabc_broken) { 902 if (!td->cabc_broken) {
882 r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); 903 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
883 if (r) 904 if (r)
884 goto err; 905 goto err;
885 } 906 }
886 907
887 r = taal_dcs_write_0(DCS_DISPLAY_ON); 908 r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
888 if (r) 909 if (r)
889 goto err; 910 goto err;
890 911
@@ -903,7 +924,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
903 td->intro_printed = true; 924 td->intro_printed = true;
904 } 925 }
905 926
906 omapdss_dsi_vc_enable_hs(TCH, true); 927 omapdss_dsi_vc_enable_hs(td->channel, true);
907 928
908 return 0; 929 return 0;
909err: 930err:
@@ -921,7 +942,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
921 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 942 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
922 int r; 943 int r;
923 944
924 r = taal_dcs_write_0(DCS_DISPLAY_OFF); 945 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
925 if (!r) { 946 if (!r) {
926 r = taal_sleep_in(td); 947 r = taal_sleep_in(td);
927 /* HACK: wait a bit so that the message goes through */ 948 /* HACK: wait a bit so that the message goes through */
@@ -1089,7 +1110,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
1089 if (old) { 1110 if (old) {
1090 cancel_delayed_work(&td->te_timeout_work); 1111 cancel_delayed_work(&td->te_timeout_work);
1091 1112
1092 r = omap_dsi_update(dssdev, TCH, 1113 r = omap_dsi_update(dssdev, td->channel,
1093 td->update_region.x, 1114 td->update_region.x,
1094 td->update_region.y, 1115 td->update_region.y,
1095 td->update_region.w, 1116 td->update_region.w,
@@ -1139,7 +1160,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1139 if (r) 1160 if (r)
1140 goto err; 1161 goto err;
1141 1162
1142 r = taal_set_update_window(x, y, w, h); 1163 r = taal_set_update_window(td, x, y, w, h);
1143 if (r) 1164 if (r)
1144 goto err; 1165 goto err;
1145 1166
@@ -1153,7 +1174,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1153 msecs_to_jiffies(250)); 1174 msecs_to_jiffies(250));
1154 atomic_set(&td->do_update, 1); 1175 atomic_set(&td->do_update, 1);
1155 } else { 1176 } else {
1156 r = omap_dsi_update(dssdev, TCH, x, y, w, h, 1177 r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
1157 taal_framedone_cb, dssdev); 1178 taal_framedone_cb, dssdev);
1158 if (r) 1179 if (r)
1159 goto err; 1180 goto err;
@@ -1191,9 +1212,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1191 int r; 1212 int r;
1192 1213
1193 if (enable) 1214 if (enable)
1194 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1215 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1195 else 1216 else
1196 r = taal_dcs_write_0(DCS_TEAR_OFF); 1217 r = taal_dcs_write_0(td, DCS_TEAR_OFF);
1197 1218
1198 if (!panel_data->use_ext_te) 1219 if (!panel_data->use_ext_te)
1199 omapdss_dsi_enable_te(dssdev, enable); 1220 omapdss_dsi_enable_te(dssdev, enable);
@@ -1263,7 +1284,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1263 dsi_bus_lock(); 1284 dsi_bus_lock();
1264 1285
1265 if (td->enabled) { 1286 if (td->enabled) {
1266 r = taal_set_addr_mode(rotate, td->mirror); 1287 r = taal_set_addr_mode(td, rotate, td->mirror);
1267 if (r) 1288 if (r)
1268 goto err; 1289 goto err;
1269 } 1290 }
@@ -1306,7 +1327,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1306 1327
1307 dsi_bus_lock(); 1328 dsi_bus_lock();
1308 if (td->enabled) { 1329 if (td->enabled) {
1309 r = taal_set_addr_mode(td->rotate, enable); 1330 r = taal_set_addr_mode(td, td->rotate, enable);
1310 if (r) 1331 if (r)
1311 goto err; 1332 goto err;
1312 } 1333 }
@@ -1350,13 +1371,13 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1350 1371
1351 dsi_bus_lock(); 1372 dsi_bus_lock();
1352 1373
1353 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1374 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1354 if (r) 1375 if (r)
1355 goto err2; 1376 goto err2;
1356 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 1377 r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1357 if (r) 1378 if (r)
1358 goto err2; 1379 goto err2;
1359 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 1380 r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1360 if (r) 1381 if (r)
1361 goto err2; 1382 goto err2;
1362 1383
@@ -1404,9 +1425,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1404 else 1425 else
1405 plen = 2; 1426 plen = 2;
1406 1427
1407 taal_set_update_window(x, y, w, h); 1428 taal_set_update_window(td, x, y, w, h);
1408 1429
1409 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 1430 r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
1410 if (r) 1431 if (r)
1411 goto err2; 1432 goto err2;
1412 1433
@@ -1414,7 +1435,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1414 u8 dcs_cmd = first ? 0x2e : 0x3e; 1435 u8 dcs_cmd = first ? 0x2e : 0x3e;
1415 first = 0; 1436 first = 0;
1416 1437
1417 r = dsi_vc_dcs_read(TCH, dcs_cmd, 1438 r = dsi_vc_dcs_read(td->channel, dcs_cmd,
1418 buf + buf_used, size - buf_used); 1439 buf + buf_used, size - buf_used);
1419 1440
1420 if (r < 0) { 1441 if (r < 0) {
@@ -1440,7 +1461,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1440 r = buf_used; 1461 r = buf_used;
1441 1462
1442err3: 1463err3:
1443 dsi_vc_set_max_rx_packet_size(TCH, 1); 1464 dsi_vc_set_max_rx_packet_size(td->channel, 1);
1444err2: 1465err2:
1445 dsi_bus_unlock(); 1466 dsi_bus_unlock();
1446err1: 1467err1:
@@ -1466,7 +1487,7 @@ static void taal_esd_work(struct work_struct *work)
1466 1487
1467 dsi_bus_lock(); 1488 dsi_bus_lock();
1468 1489
1469 r = taal_dcs_read_1(DCS_RDDSDR, &state1); 1490 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
1470 if (r) { 1491 if (r) {
1471 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1492 dev_err(&dssdev->dev, "failed to read Taal status\n");
1472 goto err; 1493 goto err;
@@ -1479,7 +1500,7 @@ static void taal_esd_work(struct work_struct *work)
1479 goto err; 1500 goto err;
1480 } 1501 }
1481 1502
1482 r = taal_dcs_read_1(DCS_RDDSDR, &state2); 1503 r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
1483 if (r) { 1504 if (r) {
1484 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1505 dev_err(&dssdev->dev, "failed to read Taal status\n");
1485 goto err; 1506 goto err;
@@ -1495,7 +1516,7 @@ static void taal_esd_work(struct work_struct *work)
1495 /* Self-diagnostics result is also shown on TE GPIO line. We need 1516 /* Self-diagnostics result is also shown on TE GPIO line. We need
1496 * to re-enable TE after self diagnostics */ 1517 * to re-enable TE after self diagnostics */
1497 if (td->te_enabled && panel_data->use_ext_te) { 1518 if (td->te_enabled && panel_data->use_ext_te) {
1498 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1519 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1499 if (r) 1520 if (r)
1500 goto err; 1521 goto err;
1501 } 1522 }
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43b64403eaa4..bfc5da0e9700 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,8 +1,8 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)" 2 tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
3 depends on ARCH_OMAP2 || ARCH_OMAP3 3 depends on ARCH_OMAP2PLUS
4 help 4 help
5 OMAP2/3 Display Subsystem support. 5 OMAP2+ Display Subsystem support.
6 6
7if OMAP2_DSS 7if OMAP2_DSS
8 8
@@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
60 help 60 help
61 OMAP Video Encoder support for S-Video and composite TV-out. 61 OMAP Video Encoder support for S-Video and composite TV-out.
62 62
63config OMAP4_DSS_HDMI
64 bool "HDMI support"
65 depends on ARCH_OMAP4
66 default y
67 help
68 HDMI Interface. This adds the High Definition Multimedia Interface.
69 See http://www.hdmi.org/ for HDMI specification.
70
63config OMAP2_DSS_SDI 71config OMAP2_DSS_SDI
64 bool "SDI support" 72 bool "SDI support"
65 depends on ARCH_OMAP3 73 depends on ARCH_OMAP3
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 7db17b5e570c..10d9d3bb3e24 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -5,3 +5,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
8omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
9 hdmi_omap4_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 8e89f6049280..1aa2ed1e786e 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -34,332 +34,26 @@
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36#include <plat/display.h> 36#include <plat/display.h>
37#include <plat/clock.h>
38 37
39#include "dss.h" 38#include "dss.h"
40#include "dss_features.h" 39#include "dss_features.h"
41 40
42static struct { 41static struct {
43 struct platform_device *pdev; 42 struct platform_device *pdev;
44 int ctx_id;
45
46 struct clk *dss_ick;
47 struct clk *dss1_fck;
48 struct clk *dss2_fck;
49 struct clk *dss_54m_fck;
50 struct clk *dss_96m_fck;
51 unsigned num_clks_enabled;
52 43
53 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
54 struct regulator *vdds_sdi_reg; 45 struct regulator *vdds_sdi_reg;
55 struct regulator *vdda_dac_reg;
56} core; 46} core;
57 47
58static void dss_clk_enable_all_no_ctx(void);
59static void dss_clk_disable_all_no_ctx(void);
60static void dss_clk_enable_no_ctx(enum dss_clock clks);
61static void dss_clk_disable_no_ctx(enum dss_clock clks);
62
63static char *def_disp_name; 48static char *def_disp_name;
64module_param_named(def_disp, def_disp_name, charp, 0); 49module_param_named(def_disp, def_disp_name, charp, 0);
65MODULE_PARM_DESC(def_disp_name, "default display name"); 50MODULE_PARM_DESC(def_disp, "default display name");
66 51
67#ifdef DEBUG 52#ifdef DEBUG
68unsigned int dss_debug; 53unsigned int dss_debug;
69module_param_named(debug, dss_debug, bool, 0644); 54module_param_named(debug, dss_debug, bool, 0644);
70#endif 55#endif
71 56
72/* CONTEXT */
73static int dss_get_ctx_id(void)
74{
75 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
76 int r;
77
78 if (!pdata->get_last_off_on_transaction_id)
79 return 0;
80 r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
81 if (r < 0) {
82 dev_err(&core.pdev->dev, "getting transaction ID failed, "
83 "will force context restore\n");
84 r = -1;
85 }
86 return r;
87}
88
89int dss_need_ctx_restore(void)
90{
91 int id = dss_get_ctx_id();
92
93 if (id < 0 || id != core.ctx_id) {
94 DSSDBG("ctx id %d -> id %d\n",
95 core.ctx_id, id);
96 core.ctx_id = id;
97 return 1;
98 } else {
99 return 0;
100 }
101}
102
103static void save_all_ctx(void)
104{
105 DSSDBG("save context\n");
106
107 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
108
109 dss_save_context();
110 dispc_save_context();
111#ifdef CONFIG_OMAP2_DSS_DSI
112 dsi_save_context();
113#endif
114
115 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
116}
117
118static void restore_all_ctx(void)
119{
120 DSSDBG("restore context\n");
121
122 dss_clk_enable_all_no_ctx();
123
124 dss_restore_context();
125 dispc_restore_context();
126#ifdef CONFIG_OMAP2_DSS_DSI
127 dsi_restore_context();
128#endif
129
130 dss_clk_disable_all_no_ctx();
131}
132
133#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
134/* CLOCKS */
135static void core_dump_clocks(struct seq_file *s)
136{
137 int i;
138 struct clk *clocks[5] = {
139 core.dss_ick,
140 core.dss1_fck,
141 core.dss2_fck,
142 core.dss_54m_fck,
143 core.dss_96m_fck
144 };
145
146 seq_printf(s, "- CORE -\n");
147
148 seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
149
150 for (i = 0; i < 5; i++) {
151 if (!clocks[i])
152 continue;
153 seq_printf(s, "%-15s\t%lu\t%d\n",
154 clocks[i]->name,
155 clk_get_rate(clocks[i]),
156 clocks[i]->usecount);
157 }
158}
159#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
160
161static int dss_get_clock(struct clk **clock, const char *clk_name)
162{
163 struct clk *clk;
164
165 clk = clk_get(&core.pdev->dev, clk_name);
166
167 if (IS_ERR(clk)) {
168 DSSERR("can't get clock %s", clk_name);
169 return PTR_ERR(clk);
170 }
171
172 *clock = clk;
173
174 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
175
176 return 0;
177}
178
179static int dss_get_clocks(void)
180{
181 int r;
182
183 core.dss_ick = NULL;
184 core.dss1_fck = NULL;
185 core.dss2_fck = NULL;
186 core.dss_54m_fck = NULL;
187 core.dss_96m_fck = NULL;
188
189 r = dss_get_clock(&core.dss_ick, "ick");
190 if (r)
191 goto err;
192
193 r = dss_get_clock(&core.dss1_fck, "dss1_fck");
194 if (r)
195 goto err;
196
197 r = dss_get_clock(&core.dss2_fck, "dss2_fck");
198 if (r)
199 goto err;
200
201 r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
202 if (r)
203 goto err;
204
205 r = dss_get_clock(&core.dss_96m_fck, "video_fck");
206 if (r)
207 goto err;
208
209 return 0;
210
211err:
212 if (core.dss_ick)
213 clk_put(core.dss_ick);
214 if (core.dss1_fck)
215 clk_put(core.dss1_fck);
216 if (core.dss2_fck)
217 clk_put(core.dss2_fck);
218 if (core.dss_54m_fck)
219 clk_put(core.dss_54m_fck);
220 if (core.dss_96m_fck)
221 clk_put(core.dss_96m_fck);
222
223 return r;
224}
225
226static void dss_put_clocks(void)
227{
228 if (core.dss_96m_fck)
229 clk_put(core.dss_96m_fck);
230 clk_put(core.dss_54m_fck);
231 clk_put(core.dss1_fck);
232 clk_put(core.dss2_fck);
233 clk_put(core.dss_ick);
234}
235
236unsigned long dss_clk_get_rate(enum dss_clock clk)
237{
238 switch (clk) {
239 case DSS_CLK_ICK:
240 return clk_get_rate(core.dss_ick);
241 case DSS_CLK_FCK1:
242 return clk_get_rate(core.dss1_fck);
243 case DSS_CLK_FCK2:
244 return clk_get_rate(core.dss2_fck);
245 case DSS_CLK_54M:
246 return clk_get_rate(core.dss_54m_fck);
247 case DSS_CLK_96M:
248 return clk_get_rate(core.dss_96m_fck);
249 }
250
251 BUG();
252 return 0;
253}
254
255static unsigned count_clk_bits(enum dss_clock clks)
256{
257 unsigned num_clks = 0;
258
259 if (clks & DSS_CLK_ICK)
260 ++num_clks;
261 if (clks & DSS_CLK_FCK1)
262 ++num_clks;
263 if (clks & DSS_CLK_FCK2)
264 ++num_clks;
265 if (clks & DSS_CLK_54M)
266 ++num_clks;
267 if (clks & DSS_CLK_96M)
268 ++num_clks;
269
270 return num_clks;
271}
272
273static void dss_clk_enable_no_ctx(enum dss_clock clks)
274{
275 unsigned num_clks = count_clk_bits(clks);
276
277 if (clks & DSS_CLK_ICK)
278 clk_enable(core.dss_ick);
279 if (clks & DSS_CLK_FCK1)
280 clk_enable(core.dss1_fck);
281 if (clks & DSS_CLK_FCK2)
282 clk_enable(core.dss2_fck);
283 if (clks & DSS_CLK_54M)
284 clk_enable(core.dss_54m_fck);
285 if (clks & DSS_CLK_96M)
286 clk_enable(core.dss_96m_fck);
287
288 core.num_clks_enabled += num_clks;
289}
290
291void dss_clk_enable(enum dss_clock clks)
292{
293 bool check_ctx = core.num_clks_enabled == 0;
294
295 dss_clk_enable_no_ctx(clks);
296
297 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
298 restore_all_ctx();
299}
300
301static void dss_clk_disable_no_ctx(enum dss_clock clks)
302{
303 unsigned num_clks = count_clk_bits(clks);
304
305 if (clks & DSS_CLK_ICK)
306 clk_disable(core.dss_ick);
307 if (clks & DSS_CLK_FCK1)
308 clk_disable(core.dss1_fck);
309 if (clks & DSS_CLK_FCK2)
310 clk_disable(core.dss2_fck);
311 if (clks & DSS_CLK_54M)
312 clk_disable(core.dss_54m_fck);
313 if (clks & DSS_CLK_96M)
314 clk_disable(core.dss_96m_fck);
315
316 core.num_clks_enabled -= num_clks;
317}
318
319void dss_clk_disable(enum dss_clock clks)
320{
321 if (cpu_is_omap34xx()) {
322 unsigned num_clks = count_clk_bits(clks);
323
324 BUG_ON(core.num_clks_enabled < num_clks);
325
326 if (core.num_clks_enabled == num_clks)
327 save_all_ctx();
328 }
329
330 dss_clk_disable_no_ctx(clks);
331}
332
333static void dss_clk_enable_all_no_ctx(void)
334{
335 enum dss_clock clks;
336
337 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
338 if (cpu_is_omap34xx())
339 clks |= DSS_CLK_96M;
340 dss_clk_enable_no_ctx(clks);
341}
342
343static void dss_clk_disable_all_no_ctx(void)
344{
345 enum dss_clock clks;
346
347 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
348 if (cpu_is_omap34xx())
349 clks |= DSS_CLK_96M;
350 dss_clk_disable_no_ctx(clks);
351}
352
353static void dss_clk_disable_all(void)
354{
355 enum dss_clock clks;
356
357 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
358 if (cpu_is_omap34xx())
359 clks |= DSS_CLK_96M;
360 dss_clk_disable(clks);
361}
362
363/* REGULATORS */ 57/* REGULATORS */
364 58
365struct regulator *dss_get_vdds_dsi(void) 59struct regulator *dss_get_vdds_dsi(void)
@@ -390,32 +84,7 @@ struct regulator *dss_get_vdds_sdi(void)
390 return reg; 84 return reg;
391} 85}
392 86
393struct regulator *dss_get_vdda_dac(void)
394{
395 struct regulator *reg;
396
397 if (core.vdda_dac_reg != NULL)
398 return core.vdda_dac_reg;
399
400 reg = regulator_get(&core.pdev->dev, "vdda_dac");
401 if (!IS_ERR(reg))
402 core.vdda_dac_reg = reg;
403
404 return reg;
405}
406
407/* DEBUGFS */
408#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 87#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
409static void dss_debug_dump_clocks(struct seq_file *s)
410{
411 core_dump_clocks(s);
412 dss_dump_clocks(s);
413 dispc_dump_clocks(s);
414#ifdef CONFIG_OMAP2_DSS_DSI
415 dsi_dump_clocks(s);
416#endif
417}
418
419static int dss_debug_show(struct seq_file *s, void *unused) 88static int dss_debug_show(struct seq_file *s, void *unused)
420{ 89{
421 void (*func)(struct seq_file *) = s->private; 90 void (*func)(struct seq_file *) = s->private;
@@ -497,7 +166,6 @@ static inline void dss_uninitialize_debugfs(void)
497static int omap_dss_probe(struct platform_device *pdev) 166static int omap_dss_probe(struct platform_device *pdev)
498{ 167{
499 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 168 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
500 int skip_init = 0;
501 int r; 169 int r;
502 int i; 170 int i;
503 171
@@ -508,63 +176,43 @@ static int omap_dss_probe(struct platform_device *pdev)
508 dss_init_overlay_managers(pdev); 176 dss_init_overlay_managers(pdev);
509 dss_init_overlays(pdev); 177 dss_init_overlays(pdev);
510 178
511 r = dss_get_clocks(); 179 r = dss_init_platform_driver();
512 if (r)
513 goto err_clocks;
514
515 dss_clk_enable_all_no_ctx();
516
517 core.ctx_id = dss_get_ctx_id();
518 DSSDBG("initial ctx id %u\n", core.ctx_id);
519
520#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
521 /* DISPC_CONTROL */
522 if (omap_readl(0x48050440) & 1) /* LCD enabled? */
523 skip_init = 1;
524#endif
525
526 r = dss_init(skip_init);
527 if (r) { 180 if (r) {
528 DSSERR("Failed to initialize DSS\n"); 181 DSSERR("Failed to initialize DSS platform driver\n");
529 goto err_dss; 182 goto err_dss;
530 } 183 }
531 184
532 r = rfbi_init(); 185 /* keep clocks enabled to prevent context saves/restores during init */
533 if (r) { 186 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
534 DSSERR("Failed to initialize rfbi\n");
535 goto err_rfbi;
536 }
537 187
538 r = dpi_init(pdev); 188 r = rfbi_init_platform_driver();
539 if (r) { 189 if (r) {
540 DSSERR("Failed to initialize dpi\n"); 190 DSSERR("Failed to initialize rfbi platform driver\n");
541 goto err_dpi; 191 goto err_rfbi;
542 } 192 }
543 193
544 r = dispc_init(); 194 r = dispc_init_platform_driver();
545 if (r) { 195 if (r) {
546 DSSERR("Failed to initialize dispc\n"); 196 DSSERR("Failed to initialize dispc platform driver\n");
547 goto err_dispc; 197 goto err_dispc;
548 } 198 }
549 199
550 r = venc_init(pdev); 200 r = venc_init_platform_driver();
551 if (r) { 201 if (r) {
552 DSSERR("Failed to initialize venc\n"); 202 DSSERR("Failed to initialize venc platform driver\n");
553 goto err_venc; 203 goto err_venc;
554 } 204 }
555 205
556 if (cpu_is_omap34xx()) { 206 r = dsi_init_platform_driver();
557 r = sdi_init(skip_init); 207 if (r) {
558 if (r) { 208 DSSERR("Failed to initialize DSI platform driver\n");
559 DSSERR("Failed to initialize SDI\n"); 209 goto err_dsi;
560 goto err_sdi; 210 }
561 }
562 211
563 r = dsi_init(pdev); 212 r = hdmi_init_platform_driver();
564 if (r) { 213 if (r) {
565 DSSERR("Failed to initialize DSI\n"); 214 DSSERR("Failed to initialize hdmi\n");
566 goto err_dsi; 215 goto err_hdmi;
567 }
568 } 216 }
569 217
570 r = dss_initialize_debugfs(); 218 r = dss_initialize_debugfs();
@@ -589,32 +237,25 @@ static int omap_dss_probe(struct platform_device *pdev)
589 pdata->default_device = dssdev; 237 pdata->default_device = dssdev;
590 } 238 }
591 239
592 dss_clk_disable_all(); 240 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
593 241
594 return 0; 242 return 0;
595 243
596err_register: 244err_register:
597 dss_uninitialize_debugfs(); 245 dss_uninitialize_debugfs();
598err_debugfs: 246err_debugfs:
599 if (cpu_is_omap34xx()) 247 hdmi_uninit_platform_driver();
600 dsi_exit(); 248err_hdmi:
249 dsi_uninit_platform_driver();
601err_dsi: 250err_dsi:
602 if (cpu_is_omap34xx()) 251 venc_uninit_platform_driver();
603 sdi_exit();
604err_sdi:
605 venc_exit();
606err_venc: 252err_venc:
607 dispc_exit(); 253 dispc_uninit_platform_driver();
608err_dispc: 254err_dispc:
609 dpi_exit(); 255 rfbi_uninit_platform_driver();
610err_dpi:
611 rfbi_exit();
612err_rfbi: 256err_rfbi:
613 dss_exit(); 257 dss_uninit_platform_driver();
614err_dss: 258err_dss:
615 dss_clk_disable_all_no_ctx();
616 dss_put_clocks();
617err_clocks:
618 259
619 return r; 260 return r;
620} 261}
@@ -623,61 +264,15 @@ static int omap_dss_remove(struct platform_device *pdev)
623{ 264{
624 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 265 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
625 int i; 266 int i;
626 int c;
627 267
628 dss_uninitialize_debugfs(); 268 dss_uninitialize_debugfs();
629 269
630 venc_exit(); 270 venc_uninit_platform_driver();
631 dispc_exit(); 271 dispc_uninit_platform_driver();
632 dpi_exit(); 272 rfbi_uninit_platform_driver();
633 rfbi_exit(); 273 dsi_uninit_platform_driver();
634 if (cpu_is_omap34xx()) { 274 hdmi_uninit_platform_driver();
635 dsi_exit(); 275 dss_uninit_platform_driver();
636 sdi_exit();
637 }
638
639 dss_exit();
640
641 /* these should be removed at some point */
642 c = core.dss_ick->usecount;
643 if (c > 0) {
644 DSSERR("warning: dss_ick usecount %d, disabling\n", c);
645 while (c-- > 0)
646 clk_disable(core.dss_ick);
647 }
648
649 c = core.dss1_fck->usecount;
650 if (c > 0) {
651 DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
652 while (c-- > 0)
653 clk_disable(core.dss1_fck);
654 }
655
656 c = core.dss2_fck->usecount;
657 if (c > 0) {
658 DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
659 while (c-- > 0)
660 clk_disable(core.dss2_fck);
661 }
662
663 c = core.dss_54m_fck->usecount;
664 if (c > 0) {
665 DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
666 while (c-- > 0)
667 clk_disable(core.dss_54m_fck);
668 }
669
670 if (core.dss_96m_fck) {
671 c = core.dss_96m_fck->usecount;
672 if (c > 0) {
673 DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
674 c);
675 while (c-- > 0)
676 clk_disable(core.dss_96m_fck);
677 }
678 }
679
680 dss_put_clocks();
681 276
682 dss_uninit_overlays(pdev); 277 dss_uninit_overlays(pdev);
683 dss_uninit_overlay_managers(pdev); 278 dss_uninit_overlay_managers(pdev);
@@ -965,11 +560,6 @@ static void __exit omap_dss_exit(void)
965 core.vdds_sdi_reg = NULL; 560 core.vdds_sdi_reg = NULL;
966 } 561 }
967 562
968 if (core.vdda_dac_reg != NULL) {
969 regulator_put(core.vdda_dac_reg);
970 core.vdda_dac_reg = NULL;
971 }
972
973 platform_driver_unregister(&omap_dss_driver); 563 platform_driver_unregister(&omap_dss_driver);
974 564
975 omap_dss_bus_unregister(); 565 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 9f8c69f16e61..7804779c9da1 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/interrupt.h>
35 36
36#include <plat/sram.h> 37#include <plat/sram.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -42,8 +43,6 @@
42#include "dss_features.h" 43#include "dss_features.h"
43 44
44/* DISPC */ 45/* DISPC */
45#define DISPC_BASE 0x48050400
46
47#define DISPC_SZ_REGS SZ_4K 46#define DISPC_SZ_REGS SZ_4K
48 47
49struct dispc_reg { u16 idx; }; 48struct dispc_reg { u16 idx; };
@@ -74,7 +73,7 @@ struct dispc_reg { u16 idx; };
74#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400) 73#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
75#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404) 74#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
76#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408) 75#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
77#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C) 76#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
78#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) 77#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
79#define DISPC_SIZE_DIG DISPC_REG(0x0078) 78#define DISPC_SIZE_DIG DISPC_REG(0x0078)
80#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC) 79#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
@@ -129,6 +128,7 @@ struct dispc_reg { u16 idx; };
129 128
130#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04) 129#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
131 130
131#define DISPC_DIVISOR DISPC_REG(0x0804)
132 132
133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ 133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
134 DISPC_IRQ_OCP_ERR | \ 134 DISPC_IRQ_OCP_ERR | \
@@ -178,7 +178,9 @@ struct dispc_irq_stats {
178}; 178};
179 179
180static struct { 180static struct {
181 struct platform_device *pdev;
181 void __iomem *base; 182 void __iomem *base;
183 int irq;
182 184
183 u32 fifo_size[3]; 185 u32 fifo_size[3];
184 186
@@ -230,7 +232,7 @@ void dispc_save_context(void)
230 SR(TIMING_H(0)); 232 SR(TIMING_H(0));
231 SR(TIMING_V(0)); 233 SR(TIMING_V(0));
232 SR(POL_FREQ(0)); 234 SR(POL_FREQ(0));
233 SR(DIVISOR(0)); 235 SR(DIVISORo(0));
234 SR(GLOBAL_ALPHA); 236 SR(GLOBAL_ALPHA);
235 SR(SIZE_DIG); 237 SR(SIZE_DIG);
236 SR(SIZE_LCD(0)); 238 SR(SIZE_LCD(0));
@@ -242,7 +244,7 @@ void dispc_save_context(void)
242 SR(TIMING_H(2)); 244 SR(TIMING_H(2));
243 SR(TIMING_V(2)); 245 SR(TIMING_V(2));
244 SR(POL_FREQ(2)); 246 SR(POL_FREQ(2));
245 SR(DIVISOR(2)); 247 SR(DIVISORo(2));
246 SR(CONFIG2); 248 SR(CONFIG2);
247 } 249 }
248 250
@@ -373,6 +375,9 @@ void dispc_save_context(void)
373 SR(VID_FIR_COEF_V(1, 7)); 375 SR(VID_FIR_COEF_V(1, 7));
374 376
375 SR(VID_PRELOAD(1)); 377 SR(VID_PRELOAD(1));
378
379 if (dss_has_feature(FEAT_CORE_CLK_DIV))
380 SR(DIVISOR);
376} 381}
377 382
378void dispc_restore_context(void) 383void dispc_restore_context(void)
@@ -389,7 +394,7 @@ void dispc_restore_context(void)
389 RR(TIMING_H(0)); 394 RR(TIMING_H(0));
390 RR(TIMING_V(0)); 395 RR(TIMING_V(0));
391 RR(POL_FREQ(0)); 396 RR(POL_FREQ(0));
392 RR(DIVISOR(0)); 397 RR(DIVISORo(0));
393 RR(GLOBAL_ALPHA); 398 RR(GLOBAL_ALPHA);
394 RR(SIZE_DIG); 399 RR(SIZE_DIG);
395 RR(SIZE_LCD(0)); 400 RR(SIZE_LCD(0));
@@ -400,7 +405,7 @@ void dispc_restore_context(void)
400 RR(TIMING_H(2)); 405 RR(TIMING_H(2));
401 RR(TIMING_V(2)); 406 RR(TIMING_V(2));
402 RR(POL_FREQ(2)); 407 RR(POL_FREQ(2));
403 RR(DIVISOR(2)); 408 RR(DIVISORo(2));
404 RR(CONFIG2); 409 RR(CONFIG2);
405 } 410 }
406 411
@@ -532,6 +537,9 @@ void dispc_restore_context(void)
532 537
533 RR(VID_PRELOAD(1)); 538 RR(VID_PRELOAD(1));
534 539
540 if (dss_has_feature(FEAT_CORE_CLK_DIV))
541 RR(DIVISOR);
542
535 /* enable last, because LCD & DIGIT enable are here */ 543 /* enable last, because LCD & DIGIT enable are here */
536 RR(CONTROL); 544 RR(CONTROL);
537 if (dss_has_feature(FEAT_MGR_LCD2)) 545 if (dss_has_feature(FEAT_MGR_LCD2))
@@ -552,9 +560,9 @@ void dispc_restore_context(void)
552static inline void enable_clocks(bool enable) 560static inline void enable_clocks(bool enable)
553{ 561{
554 if (enable) 562 if (enable)
555 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 563 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
556 else 564 else
557 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 565 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
558} 566}
559 567
560bool dispc_go_busy(enum omap_channel channel) 568bool dispc_go_busy(enum omap_channel channel)
@@ -1000,6 +1008,20 @@ void dispc_set_burst_size(enum omap_plane plane,
1000 enable_clocks(0); 1008 enable_clocks(0);
1001} 1009}
1002 1010
1011void dispc_enable_gamma_table(bool enable)
1012{
1013 /*
1014 * This is partially implemented to support only disabling of
1015 * the gamma table.
1016 */
1017 if (enable) {
1018 DSSWARN("Gamma table enabling for TV not yet supported");
1019 return;
1020 }
1021
1022 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1023}
1024
1003static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) 1025static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
1004{ 1026{
1005 u32 val; 1027 u32 val;
@@ -1129,10 +1151,16 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1129 u32 val; 1151 u32 val;
1130 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0), 1152 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
1131 DISPC_VID_ACCU0(1) }; 1153 DISPC_VID_ACCU0(1) };
1154 u8 hor_start, hor_end, vert_start, vert_end;
1132 1155
1133 BUG_ON(plane == OMAP_DSS_GFX); 1156 BUG_ON(plane == OMAP_DSS_GFX);
1134 1157
1135 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1158 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1159 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1160
1161 val = FLD_VAL(vaccu, vert_start, vert_end) |
1162 FLD_VAL(haccu, hor_start, hor_end);
1163
1136 dispc_write_reg(ac0_reg[plane-1], val); 1164 dispc_write_reg(ac0_reg[plane-1], val);
1137} 1165}
1138 1166
@@ -1141,10 +1169,16 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1141 u32 val; 1169 u32 val;
1142 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0), 1170 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
1143 DISPC_VID_ACCU1(1) }; 1171 DISPC_VID_ACCU1(1) };
1172 u8 hor_start, hor_end, vert_start, vert_end;
1144 1173
1145 BUG_ON(plane == OMAP_DSS_GFX); 1174 BUG_ON(plane == OMAP_DSS_GFX);
1146 1175
1147 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1176 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1177 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1178
1179 val = FLD_VAL(vaccu, vert_start, vert_end) |
1180 FLD_VAL(haccu, hor_start, hor_end);
1181
1148 dispc_write_reg(ac1_reg[plane-1], val); 1182 dispc_write_reg(ac1_reg[plane-1], val);
1149} 1183}
1150 1184
@@ -1182,16 +1216,25 @@ static void _dispc_set_scaling(enum omap_plane plane,
1182 _dispc_set_fir(plane, fir_hinc, fir_vinc); 1216 _dispc_set_fir(plane, fir_hinc, fir_vinc);
1183 1217
1184 l = dispc_read_reg(dispc_reg_att[plane]); 1218 l = dispc_read_reg(dispc_reg_att[plane]);
1185 l &= ~((0x0f << 5) | (0x3 << 21));
1186 1219
1220 /* RESIZEENABLE and VERTICALTAPS */
1221 l &= ~((0x3 << 5) | (0x1 << 21));
1187 l |= fir_hinc ? (1 << 5) : 0; 1222 l |= fir_hinc ? (1 << 5) : 0;
1188 l |= fir_vinc ? (1 << 6) : 0; 1223 l |= fir_vinc ? (1 << 6) : 0;
1224 l |= five_taps ? (1 << 21) : 0;
1189 1225
1190 l |= hscaleup ? 0 : (1 << 7); 1226 /* VRESIZECONF and HRESIZECONF */
1191 l |= vscaleup ? 0 : (1 << 8); 1227 if (dss_has_feature(FEAT_RESIZECONF)) {
1228 l &= ~(0x3 << 7);
1229 l |= hscaleup ? 0 : (1 << 7);
1230 l |= vscaleup ? 0 : (1 << 8);
1231 }
1192 1232
1193 l |= five_taps ? (1 << 21) : 0; 1233 /* LINEBUFFERSPLIT */
1194 l |= five_taps ? (1 << 22) : 0; 1234 if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
1235 l &= ~(0x1 << 22);
1236 l |= five_taps ? (1 << 22) : 0;
1237 }
1195 1238
1196 dispc_write_reg(dispc_reg_att[plane], l); 1239 dispc_write_reg(dispc_reg_att[plane], l);
1197 1240
@@ -1215,9 +1258,11 @@ static void _dispc_set_scaling(enum omap_plane plane,
1215static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1258static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1216 bool mirroring, enum omap_color_mode color_mode) 1259 bool mirroring, enum omap_color_mode color_mode)
1217{ 1260{
1261 bool row_repeat = false;
1262 int vidrot = 0;
1263
1218 if (color_mode == OMAP_DSS_COLOR_YUV2 || 1264 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1219 color_mode == OMAP_DSS_COLOR_UYVY) { 1265 color_mode == OMAP_DSS_COLOR_UYVY) {
1220 int vidrot = 0;
1221 1266
1222 if (mirroring) { 1267 if (mirroring) {
1223 switch (rotation) { 1268 switch (rotation) {
@@ -1251,16 +1296,15 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1251 } 1296 }
1252 } 1297 }
1253 1298
1254 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1255
1256 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270) 1299 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270)
1257 REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18); 1300 row_repeat = true;
1258 else 1301 else
1259 REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18); 1302 row_repeat = false;
1260 } else {
1261 REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
1262 REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
1263 } 1303 }
1304
1305 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1306 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1307 REG_FLD_MOD(dispc_reg_att[plane], row_repeat ? 1 : 0, 18, 18);
1264} 1308}
1265 1309
1266static int color_mode_to_bpp(enum omap_color_mode color_mode) 1310static int color_mode_to_bpp(enum omap_color_mode color_mode)
@@ -2293,7 +2337,7 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2293 BUG_ON(pck_div < 2); 2337 BUG_ON(pck_div < 2);
2294 2338
2295 enable_clocks(1); 2339 enable_clocks(1);
2296 dispc_write_reg(DISPC_DIVISOR(channel), 2340 dispc_write_reg(DISPC_DIVISORo(channel),
2297 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2341 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2298 enable_clocks(0); 2342 enable_clocks(0);
2299} 2343}
@@ -2302,7 +2346,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2302 int *pck_div) 2346 int *pck_div)
2303{ 2347{
2304 u32 l; 2348 u32 l;
2305 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2349 l = dispc_read_reg(DISPC_DIVISORo(channel));
2306 *lck_div = FLD_GET(l, 23, 16); 2350 *lck_div = FLD_GET(l, 23, 16);
2307 *pck_div = FLD_GET(l, 7, 0); 2351 *pck_div = FLD_GET(l, 7, 0);
2308} 2352}
@@ -2311,14 +2355,17 @@ unsigned long dispc_fclk_rate(void)
2311{ 2355{
2312 unsigned long r = 0; 2356 unsigned long r = 0;
2313 2357
2314 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) 2358 switch (dss_get_dispc_clk_source()) {
2315 r = dss_clk_get_rate(DSS_CLK_FCK1); 2359 case DSS_CLK_SRC_FCK:
2316 else 2360 r = dss_clk_get_rate(DSS_CLK_FCK);
2317#ifdef CONFIG_OMAP2_DSS_DSI 2361 break;
2318 r = dsi_get_dsi1_pll_rate(); 2362 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2319#else 2363 r = dsi_get_pll_hsdiv_dispc_rate();
2320 BUG(); 2364 break;
2321#endif 2365 default:
2366 BUG();
2367 }
2368
2322 return r; 2369 return r;
2323} 2370}
2324 2371
@@ -2328,47 +2375,72 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2328 unsigned long r; 2375 unsigned long r;
2329 u32 l; 2376 u32 l;
2330 2377
2331 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2378 l = dispc_read_reg(DISPC_DIVISORo(channel));
2332 2379
2333 lcd = FLD_GET(l, 23, 16); 2380 lcd = FLD_GET(l, 23, 16);
2334 2381
2335 r = dispc_fclk_rate(); 2382 switch (dss_get_lcd_clk_source(channel)) {
2383 case DSS_CLK_SRC_FCK:
2384 r = dss_clk_get_rate(DSS_CLK_FCK);
2385 break;
2386 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2387 r = dsi_get_pll_hsdiv_dispc_rate();
2388 break;
2389 default:
2390 BUG();
2391 }
2336 2392
2337 return r / lcd; 2393 return r / lcd;
2338} 2394}
2339 2395
2340unsigned long dispc_pclk_rate(enum omap_channel channel) 2396unsigned long dispc_pclk_rate(enum omap_channel channel)
2341{ 2397{
2342 int lcd, pcd; 2398 int pcd;
2343 unsigned long r; 2399 unsigned long r;
2344 u32 l; 2400 u32 l;
2345 2401
2346 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2402 l = dispc_read_reg(DISPC_DIVISORo(channel));
2347 2403
2348 lcd = FLD_GET(l, 23, 16);
2349 pcd = FLD_GET(l, 7, 0); 2404 pcd = FLD_GET(l, 7, 0);
2350 2405
2351 r = dispc_fclk_rate(); 2406 r = dispc_lclk_rate(channel);
2352 2407
2353 return r / lcd / pcd; 2408 return r / pcd;
2354} 2409}
2355 2410
2356void dispc_dump_clocks(struct seq_file *s) 2411void dispc_dump_clocks(struct seq_file *s)
2357{ 2412{
2358 int lcd, pcd; 2413 int lcd, pcd;
2414 u32 l;
2415 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2416 enum dss_clk_source lcd_clk_src;
2359 2417
2360 enable_clocks(1); 2418 enable_clocks(1);
2361 2419
2362 seq_printf(s, "- DISPC -\n"); 2420 seq_printf(s, "- DISPC -\n");
2363 2421
2364 seq_printf(s, "dispc fclk source = %s\n", 2422 seq_printf(s, "dispc fclk source = %s (%s)\n",
2365 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 2423 dss_get_generic_clk_source_name(dispc_clk_src),
2366 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2424 dss_feat_get_clk_source_name(dispc_clk_src));
2367 2425
2368 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2426 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
2369 2427
2428 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
2429 seq_printf(s, "- DISPC-CORE-CLK -\n");
2430 l = dispc_read_reg(DISPC_DIVISOR);
2431 lcd = FLD_GET(l, 23, 16);
2432
2433 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2434 (dispc_fclk_rate()/lcd), lcd);
2435 }
2370 seq_printf(s, "- LCD1 -\n"); 2436 seq_printf(s, "- LCD1 -\n");
2371 2437
2438 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2439
2440 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2441 dss_get_generic_clk_source_name(lcd_clk_src),
2442 dss_feat_get_clk_source_name(lcd_clk_src));
2443
2372 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); 2444 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2373 2445
2374 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2446 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2378,6 +2450,12 @@ void dispc_dump_clocks(struct seq_file *s)
2378 if (dss_has_feature(FEAT_MGR_LCD2)) { 2450 if (dss_has_feature(FEAT_MGR_LCD2)) {
2379 seq_printf(s, "- LCD2 -\n"); 2451 seq_printf(s, "- LCD2 -\n");
2380 2452
2453 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2454
2455 seq_printf(s, "lcd2_clk source = %s (%s)\n",
2456 dss_get_generic_clk_source_name(lcd_clk_src),
2457 dss_feat_get_clk_source_name(lcd_clk_src));
2458
2381 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2459 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2382 2460
2383 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2461 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2440,7 +2518,7 @@ void dispc_dump_regs(struct seq_file *s)
2440{ 2518{
2441#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) 2519#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
2442 2520
2443 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 2521 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
2444 2522
2445 DUMPREG(DISPC_REVISION); 2523 DUMPREG(DISPC_REVISION);
2446 DUMPREG(DISPC_SYSCONFIG); 2524 DUMPREG(DISPC_SYSCONFIG);
@@ -2459,7 +2537,7 @@ void dispc_dump_regs(struct seq_file *s)
2459 DUMPREG(DISPC_TIMING_H(0)); 2537 DUMPREG(DISPC_TIMING_H(0));
2460 DUMPREG(DISPC_TIMING_V(0)); 2538 DUMPREG(DISPC_TIMING_V(0));
2461 DUMPREG(DISPC_POL_FREQ(0)); 2539 DUMPREG(DISPC_POL_FREQ(0));
2462 DUMPREG(DISPC_DIVISOR(0)); 2540 DUMPREG(DISPC_DIVISORo(0));
2463 DUMPREG(DISPC_GLOBAL_ALPHA); 2541 DUMPREG(DISPC_GLOBAL_ALPHA);
2464 DUMPREG(DISPC_SIZE_DIG); 2542 DUMPREG(DISPC_SIZE_DIG);
2465 DUMPREG(DISPC_SIZE_LCD(0)); 2543 DUMPREG(DISPC_SIZE_LCD(0));
@@ -2471,7 +2549,7 @@ void dispc_dump_regs(struct seq_file *s)
2471 DUMPREG(DISPC_TIMING_H(2)); 2549 DUMPREG(DISPC_TIMING_H(2));
2472 DUMPREG(DISPC_TIMING_V(2)); 2550 DUMPREG(DISPC_TIMING_V(2));
2473 DUMPREG(DISPC_POL_FREQ(2)); 2551 DUMPREG(DISPC_POL_FREQ(2));
2474 DUMPREG(DISPC_DIVISOR(2)); 2552 DUMPREG(DISPC_DIVISORo(2));
2475 DUMPREG(DISPC_SIZE_LCD(2)); 2553 DUMPREG(DISPC_SIZE_LCD(2));
2476 } 2554 }
2477 2555
@@ -2597,7 +2675,7 @@ void dispc_dump_regs(struct seq_file *s)
2597 DUMPREG(DISPC_VID_PRELOAD(0)); 2675 DUMPREG(DISPC_VID_PRELOAD(0));
2598 DUMPREG(DISPC_VID_PRELOAD(1)); 2676 DUMPREG(DISPC_VID_PRELOAD(1));
2599 2677
2600 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 2678 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
2601#undef DUMPREG 2679#undef DUMPREG
2602} 2680}
2603 2681
@@ -2713,8 +2791,8 @@ int dispc_get_clock_div(enum omap_channel channel,
2713 2791
2714 fck = dispc_fclk_rate(); 2792 fck = dispc_fclk_rate();
2715 2793
2716 cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16); 2794 cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
2717 cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0); 2795 cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
2718 2796
2719 cinfo->lck = fck / cinfo->lck_div; 2797 cinfo->lck = fck / cinfo->lck_div;
2720 cinfo->pck = cinfo->lck / cinfo->pck_div; 2798 cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -2791,6 +2869,9 @@ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
2791 break; 2869 break;
2792 } 2870 }
2793 2871
2872 if (ret)
2873 goto err;
2874
2794 _omap_dispc_set_irqs(); 2875 _omap_dispc_set_irqs();
2795 2876
2796 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2877 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -2866,10 +2947,10 @@ static void print_irq_status(u32 status)
2866 * but we presume they are on because we got an IRQ. However, 2947 * but we presume they are on because we got an IRQ. However,
2867 * an irq handler may turn the clocks off, so we may not have 2948 * an irq handler may turn the clocks off, so we may not have
2868 * clock later in the function. */ 2949 * clock later in the function. */
2869void dispc_irq_handler(void) 2950static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
2870{ 2951{
2871 int i; 2952 int i;
2872 u32 irqstatus; 2953 u32 irqstatus, irqenable;
2873 u32 handledirqs = 0; 2954 u32 handledirqs = 0;
2874 u32 unhandled_errors; 2955 u32 unhandled_errors;
2875 struct omap_dispc_isr_data *isr_data; 2956 struct omap_dispc_isr_data *isr_data;
@@ -2878,6 +2959,13 @@ void dispc_irq_handler(void)
2878 spin_lock(&dispc.irq_lock); 2959 spin_lock(&dispc.irq_lock);
2879 2960
2880 irqstatus = dispc_read_reg(DISPC_IRQSTATUS); 2961 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
2962 irqenable = dispc_read_reg(DISPC_IRQENABLE);
2963
2964 /* IRQ is not for us */
2965 if (!(irqstatus & irqenable)) {
2966 spin_unlock(&dispc.irq_lock);
2967 return IRQ_NONE;
2968 }
2881 2969
2882#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 2970#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2883 spin_lock(&dispc.irq_stats_lock); 2971 spin_lock(&dispc.irq_stats_lock);
@@ -2929,6 +3017,8 @@ void dispc_irq_handler(void)
2929 } 3017 }
2930 3018
2931 spin_unlock(&dispc.irq_lock); 3019 spin_unlock(&dispc.irq_lock);
3020
3021 return IRQ_HANDLED;
2932} 3022}
2933 3023
2934static void dispc_error_worker(struct work_struct *work) 3024static void dispc_error_worker(struct work_struct *work)
@@ -3253,6 +3343,15 @@ static void _omap_dispc_initial_config(void)
3253 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ 3343 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
3254 dispc_write_reg(DISPC_SYSCONFIG, l); 3344 dispc_write_reg(DISPC_SYSCONFIG, l);
3255 3345
3346 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
3347 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
3348 l = dispc_read_reg(DISPC_DIVISOR);
3349 /* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
3350 l = FLD_MOD(l, 1, 0, 0);
3351 l = FLD_MOD(l, 1, 23, 16);
3352 dispc_write_reg(DISPC_DIVISOR, l);
3353 }
3354
3256 /* FUNCGATED */ 3355 /* FUNCGATED */
3257 if (dss_has_feature(FEAT_FUNCGATED)) 3356 if (dss_has_feature(FEAT_FUNCGATED))
3258 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3357 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
@@ -3269,47 +3368,6 @@ static void _omap_dispc_initial_config(void)
3269 dispc_read_plane_fifo_sizes(); 3368 dispc_read_plane_fifo_sizes();
3270} 3369}
3271 3370
3272int dispc_init(void)
3273{
3274 u32 rev;
3275
3276 spin_lock_init(&dispc.irq_lock);
3277
3278#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3279 spin_lock_init(&dispc.irq_stats_lock);
3280 dispc.irq_stats.last_reset = jiffies;
3281#endif
3282
3283 INIT_WORK(&dispc.error_work, dispc_error_worker);
3284
3285 dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
3286 if (!dispc.base) {
3287 DSSERR("can't ioremap DISPC\n");
3288 return -ENOMEM;
3289 }
3290
3291 enable_clocks(1);
3292
3293 _omap_dispc_initial_config();
3294
3295 _omap_dispc_initialize_irq();
3296
3297 dispc_save_context();
3298
3299 rev = dispc_read_reg(DISPC_REVISION);
3300 printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
3301 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3302
3303 enable_clocks(0);
3304
3305 return 0;
3306}
3307
3308void dispc_exit(void)
3309{
3310 iounmap(dispc.base);
3311}
3312
3313int dispc_enable_plane(enum omap_plane plane, bool enable) 3371int dispc_enable_plane(enum omap_plane plane, bool enable)
3314{ 3372{
3315 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 3373 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -3359,3 +3417,94 @@ int dispc_setup_plane(enum omap_plane plane,
3359 3417
3360 return r; 3418 return r;
3361} 3419}
3420
3421/* DISPC HW IP initialisation */
3422static int omap_dispchw_probe(struct platform_device *pdev)
3423{
3424 u32 rev;
3425 int r = 0;
3426 struct resource *dispc_mem;
3427
3428 dispc.pdev = pdev;
3429
3430 spin_lock_init(&dispc.irq_lock);
3431
3432#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3433 spin_lock_init(&dispc.irq_stats_lock);
3434 dispc.irq_stats.last_reset = jiffies;
3435#endif
3436
3437 INIT_WORK(&dispc.error_work, dispc_error_worker);
3438
3439 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3440 if (!dispc_mem) {
3441 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3442 r = -EINVAL;
3443 goto fail0;
3444 }
3445 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3446 if (!dispc.base) {
3447 DSSERR("can't ioremap DISPC\n");
3448 r = -ENOMEM;
3449 goto fail0;
3450 }
3451 dispc.irq = platform_get_irq(dispc.pdev, 0);
3452 if (dispc.irq < 0) {
3453 DSSERR("platform_get_irq failed\n");
3454 r = -ENODEV;
3455 goto fail1;
3456 }
3457
3458 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3459 "OMAP DISPC", dispc.pdev);
3460 if (r < 0) {
3461 DSSERR("request_irq failed\n");
3462 goto fail1;
3463 }
3464
3465 enable_clocks(1);
3466
3467 _omap_dispc_initial_config();
3468
3469 _omap_dispc_initialize_irq();
3470
3471 dispc_save_context();
3472
3473 rev = dispc_read_reg(DISPC_REVISION);
3474 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
3475 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3476
3477 enable_clocks(0);
3478
3479 return 0;
3480fail1:
3481 iounmap(dispc.base);
3482fail0:
3483 return r;
3484}
3485
3486static int omap_dispchw_remove(struct platform_device *pdev)
3487{
3488 free_irq(dispc.irq, dispc.pdev);
3489 iounmap(dispc.base);
3490 return 0;
3491}
3492
3493static struct platform_driver omap_dispchw_driver = {
3494 .probe = omap_dispchw_probe,
3495 .remove = omap_dispchw_remove,
3496 .driver = {
3497 .name = "omapdss_dispc",
3498 .owner = THIS_MODULE,
3499 },
3500};
3501
3502int dispc_init_platform_driver(void)
3503{
3504 return platform_driver_register(&omap_dispchw_driver);
3505}
3506
3507void dispc_uninit_platform_driver(void)
3508{
3509 return platform_driver_unregister(&omap_dispchw_driver);
3510}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 22dd7a474f79..a85a6f38b40c 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -25,14 +25,11 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/list.h>
29#include <linux/platform_device.h> 28#include <linux/platform_device.h>
30 29
31#include <plat/display.h> 30#include <plat/display.h>
32#include "dss.h" 31#include "dss.h"
33 32
34static LIST_HEAD(display_list);
35
36static ssize_t display_enabled_show(struct device *dev, 33static ssize_t display_enabled_show(struct device *dev,
37 struct device_attribute *attr, char *buf) 34 struct device_attribute *attr, char *buf)
38{ 35{
@@ -345,6 +342,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
345 return 16; 342 return 16;
346 case OMAP_DISPLAY_TYPE_VENC: 343 case OMAP_DISPLAY_TYPE_VENC:
347 case OMAP_DISPLAY_TYPE_SDI: 344 case OMAP_DISPLAY_TYPE_SDI:
345 case OMAP_DISPLAY_TYPE_HDMI:
348 return 24; 346 return 24;
349 default: 347 default:
350 BUG(); 348 BUG();
@@ -371,6 +369,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
371 case OMAP_DISPLAY_TYPE_DPI: 369 case OMAP_DISPLAY_TYPE_DPI:
372 bpp = dssdev->phy.dpi.data_lines; 370 bpp = dssdev->phy.dpi.data_lines;
373 break; 371 break;
372 case OMAP_DISPLAY_TYPE_HDMI:
374 case OMAP_DISPLAY_TYPE_VENC: 373 case OMAP_DISPLAY_TYPE_VENC:
375 case OMAP_DISPLAY_TYPE_SDI: 374 case OMAP_DISPLAY_TYPE_SDI:
376 bpp = 24; 375 bpp = 24;
@@ -396,29 +395,6 @@ void dss_init_device(struct platform_device *pdev,
396 switch (dssdev->type) { 395 switch (dssdev->type) {
397#ifdef CONFIG_OMAP2_DSS_DPI 396#ifdef CONFIG_OMAP2_DSS_DPI
398 case OMAP_DISPLAY_TYPE_DPI: 397 case OMAP_DISPLAY_TYPE_DPI:
399#endif
400#ifdef CONFIG_OMAP2_DSS_RFBI
401 case OMAP_DISPLAY_TYPE_DBI:
402#endif
403#ifdef CONFIG_OMAP2_DSS_SDI
404 case OMAP_DISPLAY_TYPE_SDI:
405#endif
406#ifdef CONFIG_OMAP2_DSS_DSI
407 case OMAP_DISPLAY_TYPE_DSI:
408#endif
409#ifdef CONFIG_OMAP2_DSS_VENC
410 case OMAP_DISPLAY_TYPE_VENC:
411#endif
412 break;
413 default:
414 DSSERR("Support for display '%s' not compiled in.\n",
415 dssdev->name);
416 return;
417 }
418
419 switch (dssdev->type) {
420#ifdef CONFIG_OMAP2_DSS_DPI
421 case OMAP_DISPLAY_TYPE_DPI:
422 r = dpi_init_display(dssdev); 398 r = dpi_init_display(dssdev);
423 break; 399 break;
424#endif 400#endif
@@ -442,8 +418,13 @@ void dss_init_device(struct platform_device *pdev,
442 r = dsi_init_display(dssdev); 418 r = dsi_init_display(dssdev);
443 break; 419 break;
444#endif 420#endif
421 case OMAP_DISPLAY_TYPE_HDMI:
422 r = hdmi_init_display(dssdev);
423 break;
445 default: 424 default:
446 BUG(); 425 DSSERR("Support for display '%s' not compiled in.\n",
426 dssdev->name);
427 return;
447 } 428 }
448 429
449 if (r) { 430 if (r) {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 75fb0a515430..2d3ca4ca4a05 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -57,13 +57,13 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
57 if (r) 57 if (r)
58 return r; 58 return r;
59 59
60 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 60 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
61 61
62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
63 if (r) 63 if (r)
64 return r; 64 return r;
65 65
66 *fck = dsi_cinfo.dsi1_pll_fclk; 66 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
67 *lck_div = dispc_cinfo.lck_div; 67 *lck_div = dispc_cinfo.lck_div;
68 *pck_div = dispc_cinfo.pck_div; 68 *pck_div = dispc_cinfo.pck_div;
69 69
@@ -107,7 +107,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
107 bool is_tft; 107 bool is_tft;
108 int r = 0; 108 int r = 0;
109 109
110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
111 111
112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
113 dssdev->panel.acbi, dssdev->panel.acb); 113 dssdev->panel.acbi, dssdev->panel.acb);
@@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
137 dispc_set_lcd_timings(dssdev->manager->id, t); 137 dispc_set_lcd_timings(dssdev->manager->id, t);
138 138
139err0: 139err0:
140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
141 return r; 141 return r;
142} 142}
143 143
@@ -173,14 +173,14 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
173 goto err1; 173 goto err1;
174 } 174 }
175 175
176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
177 177
178 r = dpi_basic_init(dssdev); 178 r = dpi_basic_init(dssdev);
179 if (r) 179 if (r)
180 goto err2; 180 goto err2;
181 181
182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
183 dss_clk_enable(DSS_CLK_FCK2); 183 dss_clk_enable(DSS_CLK_SYSCK);
184 r = dsi_pll_init(dssdev, 0, 1); 184 r = dsi_pll_init(dssdev, 0, 1);
185 if (r) 185 if (r)
186 goto err3; 186 goto err3;
@@ -199,10 +199,10 @@ err4:
199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
200 dsi_pll_uninit(); 200 dsi_pll_uninit();
201err3: 201err3:
202 dss_clk_disable(DSS_CLK_FCK2); 202 dss_clk_disable(DSS_CLK_SYSCK);
203#endif 203#endif
204err2: 204err2:
205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
206 if (cpu_is_omap34xx()) 206 if (cpu_is_omap34xx())
207 regulator_disable(dpi.vdds_dsi_reg); 207 regulator_disable(dpi.vdds_dsi_reg);
208err1: 208err1:
@@ -217,12 +217,12 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
217 dssdev->manager->disable(dssdev->manager); 217 dssdev->manager->disable(dssdev->manager);
218 218
219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
220 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 220 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
221 dsi_pll_uninit(); 221 dsi_pll_uninit();
222 dss_clk_disable(DSS_CLK_FCK2); 222 dss_clk_disable(DSS_CLK_SYSCK);
223#endif 223#endif
224 224
225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
226 226
227 if (cpu_is_omap34xx()) 227 if (cpu_is_omap34xx())
228 regulator_disable(dpi.vdds_dsi_reg); 228 regulator_disable(dpi.vdds_dsi_reg);
@@ -271,7 +271,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
271 if (r) 271 if (r)
272 return r; 272 return r;
273 273
274 fck = dsi_cinfo.dsi1_pll_fclk; 274 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
275 lck_div = dispc_cinfo.lck_div; 275 lck_div = dispc_cinfo.lck_div;
276 pck_div = dispc_cinfo.pck_div; 276 pck_div = dispc_cinfo.pck_div;
277 } 277 }
@@ -303,22 +303,27 @@ int dpi_init_display(struct omap_dss_device *dssdev)
303{ 303{
304 DSSDBG("init_display\n"); 304 DSSDBG("init_display\n");
305 305
306 return 0; 306 if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
307} 307 struct regulator *vdds_dsi;
308 308
309int dpi_init(struct platform_device *pdev) 309 vdds_dsi = dss_get_vdds_dsi();
310{ 310
311 if (cpu_is_omap34xx()) { 311 if (IS_ERR(vdds_dsi)) {
312 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
313 if (IS_ERR(dpi.vdds_dsi_reg)) {
314 DSSERR("can't get VDDS_DSI regulator\n"); 312 DSSERR("can't get VDDS_DSI regulator\n");
315 return PTR_ERR(dpi.vdds_dsi_reg); 313 return PTR_ERR(vdds_dsi);
316 } 314 }
315
316 dpi.vdds_dsi_reg = vdds_dsi;
317 } 317 }
318 318
319 return 0; 319 return 0;
320} 320}
321 321
322int dpi_init(void)
323{
324 return 0;
325}
326
322void dpi_exit(void) 327void dpi_exit(void)
323{ 328{
324} 329}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ddf3a0560822..0a7f1a47f8e3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -38,12 +38,11 @@
38#include <plat/clock.h> 38#include <plat/clock.h>
39 39
40#include "dss.h" 40#include "dss.h"
41#include "dss_features.h"
41 42
42/*#define VERBOSE_IRQ*/ 43/*#define VERBOSE_IRQ*/
43#define DSI_CATCH_MISSING_TE 44#define DSI_CATCH_MISSING_TE
44 45
45#define DSI_BASE 0x4804FC00
46
47struct dsi_reg { u16 idx; }; 46struct dsi_reg { u16 idx; };
48 47
49#define DSI_REG(idx) ((const struct dsi_reg) { idx }) 48#define DSI_REG(idx) ((const struct dsi_reg) { idx })
@@ -186,13 +185,15 @@ struct dsi_reg { u16 idx; };
186#define DSI_DT_RX_SHORT_READ_1 0x21 185#define DSI_DT_RX_SHORT_READ_1 0x21
187#define DSI_DT_RX_SHORT_READ_2 0x22 186#define DSI_DT_RX_SHORT_READ_2 0x22
188 187
189#define FINT_MAX 2100000 188typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
190#define FINT_MIN 750000 189
191#define REGN_MAX (1 << 7) 190#define DSI_MAX_NR_ISRS 2
192#define REGM_MAX ((1 << 11) - 1) 191
193#define REGM3_MAX (1 << 4) 192struct dsi_isr_data {
194#define REGM4_MAX (1 << 4) 193 omap_dsi_isr_t isr;
195#define LP_DIV_MAX ((1 << 13) - 1) 194 void *arg;
195 u32 mask;
196};
196 197
197enum fifo_size { 198enum fifo_size {
198 DSI_FIFO_SIZE_0 = 0, 199 DSI_FIFO_SIZE_0 = 0,
@@ -220,9 +221,17 @@ struct dsi_irq_stats {
220 unsigned cio_irqs[32]; 221 unsigned cio_irqs[32];
221}; 222};
222 223
224struct dsi_isr_tables {
225 struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
226 struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
227 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
228};
229
223static struct 230static struct
224{ 231{
232 struct platform_device *pdev;
225 void __iomem *base; 233 void __iomem *base;
234 int irq;
226 235
227 struct dsi_clock_info current_cinfo; 236 struct dsi_clock_info current_cinfo;
228 237
@@ -232,6 +241,7 @@ static struct
232 enum dsi_vc_mode mode; 241 enum dsi_vc_mode mode;
233 struct omap_dss_device *dssdev; 242 struct omap_dss_device *dssdev;
234 enum fifo_size fifo_size; 243 enum fifo_size fifo_size;
244 int vc_id;
235 } vc[4]; 245 } vc[4];
236 246
237 struct mutex lock; 247 struct mutex lock;
@@ -239,8 +249,10 @@ static struct
239 249
240 unsigned pll_locked; 250 unsigned pll_locked;
241 251
242 struct completion bta_completion; 252 spinlock_t irq_lock;
243 void (*bta_callback)(void); 253 struct dsi_isr_tables isr_tables;
254 /* space for a copy used by the interrupt handler */
255 struct dsi_isr_tables isr_tables_copy;
244 256
245 int update_channel; 257 int update_channel;
246 struct dsi_update_region update_region; 258 struct dsi_update_region update_region;
@@ -275,6 +287,11 @@ static struct
275 spinlock_t irq_stats_lock; 287 spinlock_t irq_stats_lock;
276 struct dsi_irq_stats irq_stats; 288 struct dsi_irq_stats irq_stats;
277#endif 289#endif
290 /* DSI PLL Parameter Ranges */
291 unsigned long regm_max, regn_max;
292 unsigned long regm_dispc_max, regm_dsi_max;
293 unsigned long fint_min, fint_max;
294 unsigned long lpdiv_max;
278} dsi; 295} dsi;
279 296
280#ifdef DEBUG 297#ifdef DEBUG
@@ -318,6 +335,11 @@ static bool dsi_bus_is_locked(void)
318 return dsi.bus_lock.count == 0; 335 return dsi.bus_lock.count == 0;
319} 336}
320 337
338static void dsi_completion_handler(void *data, u32 mask)
339{
340 complete((struct completion *)data);
341}
342
321static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 343static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
322 int value) 344 int value)
323{ 345{
@@ -387,6 +409,9 @@ static void dsi_perf_show(const char *name)
387 409
388static void print_irq_status(u32 status) 410static void print_irq_status(u32 status)
389{ 411{
412 if (status == 0)
413 return;
414
390#ifndef VERBOSE_IRQ 415#ifndef VERBOSE_IRQ
391 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0) 416 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
392 return; 417 return;
@@ -422,6 +447,9 @@ static void print_irq_status(u32 status)
422 447
423static void print_irq_status_vc(int channel, u32 status) 448static void print_irq_status_vc(int channel, u32 status)
424{ 449{
450 if (status == 0)
451 return;
452
425#ifndef VERBOSE_IRQ 453#ifndef VERBOSE_IRQ
426 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0) 454 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
427 return; 455 return;
@@ -448,6 +476,9 @@ static void print_irq_status_vc(int channel, u32 status)
448 476
449static void print_irq_status_cio(u32 status) 477static void print_irq_status_cio(u32 status)
450{ 478{
479 if (status == 0)
480 return;
481
451 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); 482 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
452 483
453#define PIS(x) \ 484#define PIS(x) \
@@ -478,22 +509,33 @@ static void print_irq_status_cio(u32 status)
478 printk("\n"); 509 printk("\n");
479} 510}
480 511
481static int debug_irq; 512#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
482 513static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
483/* called from dss */
484void dsi_irq_handler(void)
485{ 514{
486 u32 irqstatus, vcstatus, ciostatus;
487 int i; 515 int i;
488 516
489 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
490
491#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
492 spin_lock(&dsi.irq_stats_lock); 517 spin_lock(&dsi.irq_stats_lock);
518
493 dsi.irq_stats.irq_count++; 519 dsi.irq_stats.irq_count++;
494 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); 520 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs);
521
522 for (i = 0; i < 4; ++i)
523 dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]);
524
525 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
526
527 spin_unlock(&dsi.irq_stats_lock);
528}
529#else
530#define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus)
495#endif 531#endif
496 532
533static int debug_irq;
534
535static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
536{
537 int i;
538
497 if (irqstatus & DSI_IRQ_ERROR_MASK) { 539 if (irqstatus & DSI_IRQ_ERROR_MASK) {
498 DSSERR("DSI error, irqstatus %x\n", irqstatus); 540 DSSERR("DSI error, irqstatus %x\n", irqstatus);
499 print_irq_status(irqstatus); 541 print_irq_status(irqstatus);
@@ -504,37 +546,88 @@ void dsi_irq_handler(void)
504 print_irq_status(irqstatus); 546 print_irq_status(irqstatus);
505 } 547 }
506 548
507#ifdef DSI_CATCH_MISSING_TE 549 for (i = 0; i < 4; ++i) {
508 if (irqstatus & DSI_IRQ_TE_TRIGGER) 550 if (vcstatus[i] & DSI_VC_IRQ_ERROR_MASK) {
509 del_timer(&dsi.te_timer); 551 DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
510#endif 552 i, vcstatus[i]);
553 print_irq_status_vc(i, vcstatus[i]);
554 } else if (debug_irq) {
555 print_irq_status_vc(i, vcstatus[i]);
556 }
557 }
558
559 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) {
560 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
561 print_irq_status_cio(ciostatus);
562 } else if (debug_irq) {
563 print_irq_status_cio(ciostatus);
564 }
565}
566
567static void dsi_call_isrs(struct dsi_isr_data *isr_array,
568 unsigned isr_array_size, u32 irqstatus)
569{
570 struct dsi_isr_data *isr_data;
571 int i;
572
573 for (i = 0; i < isr_array_size; i++) {
574 isr_data = &isr_array[i];
575 if (isr_data->isr && isr_data->mask & irqstatus)
576 isr_data->isr(isr_data->arg, irqstatus);
577 }
578}
579
580static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
581 u32 irqstatus, u32 *vcstatus, u32 ciostatus)
582{
583 int i;
584
585 dsi_call_isrs(isr_tables->isr_table,
586 ARRAY_SIZE(isr_tables->isr_table),
587 irqstatus);
511 588
512 for (i = 0; i < 4; ++i) { 589 for (i = 0; i < 4; ++i) {
513 if ((irqstatus & (1<<i)) == 0) 590 if (vcstatus[i] == 0)
514 continue; 591 continue;
592 dsi_call_isrs(isr_tables->isr_table_vc[i],
593 ARRAY_SIZE(isr_tables->isr_table_vc[i]),
594 vcstatus[i]);
595 }
515 596
516 vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 597 if (ciostatus != 0)
598 dsi_call_isrs(isr_tables->isr_table_cio,
599 ARRAY_SIZE(isr_tables->isr_table_cio),
600 ciostatus);
601}
517 602
518#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 603static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
519 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); 604{
520#endif 605 u32 irqstatus, vcstatus[4], ciostatus;
606 int i;
521 607
522 if (vcstatus & DSI_VC_IRQ_BTA) { 608 spin_lock(&dsi.irq_lock);
523 complete(&dsi.bta_completion);
524 609
525 if (dsi.bta_callback) 610 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
526 dsi.bta_callback();
527 }
528 611
529 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { 612 /* IRQ is not for us */
530 DSSERR("DSI VC(%d) error, vc irqstatus %x\n", 613 if (!irqstatus) {
531 i, vcstatus); 614 spin_unlock(&dsi.irq_lock);
532 print_irq_status_vc(i, vcstatus); 615 return IRQ_NONE;
533 } else if (debug_irq) { 616 }
534 print_irq_status_vc(i, vcstatus); 617
618 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
619 /* flush posted write */
620 dsi_read_reg(DSI_IRQSTATUS);
621
622 for (i = 0; i < 4; ++i) {
623 if ((irqstatus & (1 << i)) == 0) {
624 vcstatus[i] = 0;
625 continue;
535 } 626 }
536 627
537 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus); 628 vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i));
629
630 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]);
538 /* flush posted write */ 631 /* flush posted write */
539 dsi_read_reg(DSI_VC_IRQSTATUS(i)); 632 dsi_read_reg(DSI_VC_IRQSTATUS(i));
540 } 633 }
@@ -542,117 +635,307 @@ void dsi_irq_handler(void)
542 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { 635 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
543 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 636 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
544 637
545#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
546 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
547#endif
548
549 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); 638 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
550 /* flush posted write */ 639 /* flush posted write */
551 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 640 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
641 } else {
642 ciostatus = 0;
643 }
552 644
553 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) { 645#ifdef DSI_CATCH_MISSING_TE
554 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); 646 if (irqstatus & DSI_IRQ_TE_TRIGGER)
555 print_irq_status_cio(ciostatus); 647 del_timer(&dsi.te_timer);
556 } else if (debug_irq) { 648#endif
557 print_irq_status_cio(ciostatus); 649
558 } 650 /* make a copy and unlock, so that isrs can unregister
651 * themselves */
652 memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables));
653
654 spin_unlock(&dsi.irq_lock);
655
656 dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus);
657
658 dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus);
659
660 dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus);
661
662 return IRQ_HANDLED;
663}
664
665/* dsi.irq_lock has to be locked by the caller */
666static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array,
667 unsigned isr_array_size, u32 default_mask,
668 const struct dsi_reg enable_reg,
669 const struct dsi_reg status_reg)
670{
671 struct dsi_isr_data *isr_data;
672 u32 mask;
673 u32 old_mask;
674 int i;
675
676 mask = default_mask;
677
678 for (i = 0; i < isr_array_size; i++) {
679 isr_data = &isr_array[i];
680
681 if (isr_data->isr == NULL)
682 continue;
683
684 mask |= isr_data->mask;
559 } 685 }
560 686
561 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 687 old_mask = dsi_read_reg(enable_reg);
562 /* flush posted write */ 688 /* clear the irqstatus for newly enabled irqs */
563 dsi_read_reg(DSI_IRQSTATUS); 689 dsi_write_reg(status_reg, (mask ^ old_mask) & mask);
690 dsi_write_reg(enable_reg, mask);
564 691
565#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 692 /* flush posted writes */
566 spin_unlock(&dsi.irq_stats_lock); 693 dsi_read_reg(enable_reg);
694 dsi_read_reg(status_reg);
695}
696
697/* dsi.irq_lock has to be locked by the caller */
698static void _omap_dsi_set_irqs(void)
699{
700 u32 mask = DSI_IRQ_ERROR_MASK;
701#ifdef DSI_CATCH_MISSING_TE
702 mask |= DSI_IRQ_TE_TRIGGER;
567#endif 703#endif
704 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table,
705 ARRAY_SIZE(dsi.isr_tables.isr_table), mask,
706 DSI_IRQENABLE, DSI_IRQSTATUS);
707}
708
709/* dsi.irq_lock has to be locked by the caller */
710static void _omap_dsi_set_irqs_vc(int vc)
711{
712 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc],
713 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]),
714 DSI_VC_IRQ_ERROR_MASK,
715 DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
568} 716}
569 717
718/* dsi.irq_lock has to be locked by the caller */
719static void _omap_dsi_set_irqs_cio(void)
720{
721 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio,
722 ARRAY_SIZE(dsi.isr_tables.isr_table_cio),
723 DSI_CIO_IRQ_ERROR_MASK,
724 DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
725}
570 726
571static void _dsi_initialize_irq(void) 727static void _dsi_initialize_irq(void)
572{ 728{
573 u32 l; 729 unsigned long flags;
730 int vc;
731
732 spin_lock_irqsave(&dsi.irq_lock, flags);
733
734 memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables));
735
736 _omap_dsi_set_irqs();
737 for (vc = 0; vc < 4; ++vc)
738 _omap_dsi_set_irqs_vc(vc);
739 _omap_dsi_set_irqs_cio();
740
741 spin_unlock_irqrestore(&dsi.irq_lock, flags);
742}
743
744static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
745 struct dsi_isr_data *isr_array, unsigned isr_array_size)
746{
747 struct dsi_isr_data *isr_data;
748 int free_idx;
574 int i; 749 int i;
575 750
576 /* disable all interrupts */ 751 BUG_ON(isr == NULL);
577 dsi_write_reg(DSI_IRQENABLE, 0);
578 for (i = 0; i < 4; ++i)
579 dsi_write_reg(DSI_VC_IRQENABLE(i), 0);
580 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0);
581 752
582 /* clear interrupt status */ 753 /* check for duplicate entry and find a free slot */
583 l = dsi_read_reg(DSI_IRQSTATUS); 754 free_idx = -1;
584 dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK); 755 for (i = 0; i < isr_array_size; i++) {
756 isr_data = &isr_array[i];
585 757
586 for (i = 0; i < 4; ++i) { 758 if (isr_data->isr == isr && isr_data->arg == arg &&
587 l = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 759 isr_data->mask == mask) {
588 dsi_write_reg(DSI_VC_IRQSTATUS(i), l); 760 return -EINVAL;
761 }
762
763 if (isr_data->isr == NULL && free_idx == -1)
764 free_idx = i;
589 } 765 }
590 766
591 l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 767 if (free_idx == -1)
592 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l); 768 return -EBUSY;
593 769
594 /* enable error irqs */ 770 isr_data = &isr_array[free_idx];
595 l = DSI_IRQ_ERROR_MASK; 771 isr_data->isr = isr;
596#ifdef DSI_CATCH_MISSING_TE 772 isr_data->arg = arg;
597 l |= DSI_IRQ_TE_TRIGGER; 773 isr_data->mask = mask;
598#endif
599 dsi_write_reg(DSI_IRQENABLE, l);
600 774
601 l = DSI_VC_IRQ_ERROR_MASK; 775 return 0;
602 for (i = 0; i < 4; ++i) 776}
603 dsi_write_reg(DSI_VC_IRQENABLE(i), l); 777
778static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
779 struct dsi_isr_data *isr_array, unsigned isr_array_size)
780{
781 struct dsi_isr_data *isr_data;
782 int i;
783
784 for (i = 0; i < isr_array_size; i++) {
785 isr_data = &isr_array[i];
786 if (isr_data->isr != isr || isr_data->arg != arg ||
787 isr_data->mask != mask)
788 continue;
789
790 isr_data->isr = NULL;
791 isr_data->arg = NULL;
792 isr_data->mask = 0;
793
794 return 0;
795 }
604 796
605 l = DSI_CIO_IRQ_ERROR_MASK; 797 return -EINVAL;
606 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, l);
607} 798}
608 799
609static u32 dsi_get_errors(void) 800static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
610{ 801{
611 unsigned long flags; 802 unsigned long flags;
612 u32 e; 803 int r;
613 spin_lock_irqsave(&dsi.errors_lock, flags); 804
614 e = dsi.errors; 805 spin_lock_irqsave(&dsi.irq_lock, flags);
615 dsi.errors = 0; 806
616 spin_unlock_irqrestore(&dsi.errors_lock, flags); 807 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table,
617 return e; 808 ARRAY_SIZE(dsi.isr_tables.isr_table));
809
810 if (r == 0)
811 _omap_dsi_set_irqs();
812
813 spin_unlock_irqrestore(&dsi.irq_lock, flags);
814
815 return r;
618} 816}
619 817
620static void dsi_vc_enable_bta_irq(int channel) 818static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
621{ 819{
622 u32 l; 820 unsigned long flags;
821 int r;
822
823 spin_lock_irqsave(&dsi.irq_lock, flags);
824
825 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table,
826 ARRAY_SIZE(dsi.isr_tables.isr_table));
827
828 if (r == 0)
829 _omap_dsi_set_irqs();
623 830
624 dsi_write_reg(DSI_VC_IRQSTATUS(channel), DSI_VC_IRQ_BTA); 831 spin_unlock_irqrestore(&dsi.irq_lock, flags);
625 832
626 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 833 return r;
627 l |= DSI_VC_IRQ_BTA;
628 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
629} 834}
630 835
631static void dsi_vc_disable_bta_irq(int channel) 836static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
837 u32 mask)
632{ 838{
633 u32 l; 839 unsigned long flags;
840 int r;
841
842 spin_lock_irqsave(&dsi.irq_lock, flags);
843
844 r = _dsi_register_isr(isr, arg, mask,
845 dsi.isr_tables.isr_table_vc[channel],
846 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
847
848 if (r == 0)
849 _omap_dsi_set_irqs_vc(channel);
850
851 spin_unlock_irqrestore(&dsi.irq_lock, flags);
852
853 return r;
854}
855
856static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
857 u32 mask)
858{
859 unsigned long flags;
860 int r;
861
862 spin_lock_irqsave(&dsi.irq_lock, flags);
863
864 r = _dsi_unregister_isr(isr, arg, mask,
865 dsi.isr_tables.isr_table_vc[channel],
866 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
867
868 if (r == 0)
869 _omap_dsi_set_irqs_vc(channel);
870
871 spin_unlock_irqrestore(&dsi.irq_lock, flags);
872
873 return r;
874}
875
876static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
877{
878 unsigned long flags;
879 int r;
880
881 spin_lock_irqsave(&dsi.irq_lock, flags);
882
883 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
884 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
885
886 if (r == 0)
887 _omap_dsi_set_irqs_cio();
888
889 spin_unlock_irqrestore(&dsi.irq_lock, flags);
890
891 return r;
892}
893
894static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
895{
896 unsigned long flags;
897 int r;
898
899 spin_lock_irqsave(&dsi.irq_lock, flags);
900
901 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
902 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
903
904 if (r == 0)
905 _omap_dsi_set_irqs_cio();
906
907 spin_unlock_irqrestore(&dsi.irq_lock, flags);
634 908
635 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 909 return r;
636 l &= ~DSI_VC_IRQ_BTA;
637 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
638} 910}
639 911
640/* DSI func clock. this could also be DSI2_PLL_FCLK */ 912static u32 dsi_get_errors(void)
913{
914 unsigned long flags;
915 u32 e;
916 spin_lock_irqsave(&dsi.errors_lock, flags);
917 e = dsi.errors;
918 dsi.errors = 0;
919 spin_unlock_irqrestore(&dsi.errors_lock, flags);
920 return e;
921}
922
923/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */
641static inline void enable_clocks(bool enable) 924static inline void enable_clocks(bool enable)
642{ 925{
643 if (enable) 926 if (enable)
644 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 927 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
645 else 928 else
646 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 929 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
647} 930}
648 931
649/* source clock for DSI PLL. this could also be PCLKFREE */ 932/* source clock for DSI PLL. this could also be PCLKFREE */
650static inline void dsi_enable_pll_clock(bool enable) 933static inline void dsi_enable_pll_clock(bool enable)
651{ 934{
652 if (enable) 935 if (enable)
653 dss_clk_enable(DSS_CLK_FCK2); 936 dss_clk_enable(DSS_CLK_SYSCK);
654 else 937 else
655 dss_clk_disable(DSS_CLK_FCK2); 938 dss_clk_disable(DSS_CLK_SYSCK);
656 939
657 if (enable && dsi.pll_locked) { 940 if (enable && dsi.pll_locked) {
658 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) 941 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
@@ -707,14 +990,14 @@ static inline int dsi_if_enable(bool enable)
707 return 0; 990 return 0;
708} 991}
709 992
710unsigned long dsi_get_dsi1_pll_rate(void) 993unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
711{ 994{
712 return dsi.current_cinfo.dsi1_pll_fclk; 995 return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk;
713} 996}
714 997
715static unsigned long dsi_get_dsi2_pll_rate(void) 998static unsigned long dsi_get_pll_hsdiv_dsi_rate(void)
716{ 999{
717 return dsi.current_cinfo.dsi2_pll_fclk; 1000 return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk;
718} 1001}
719 1002
720static unsigned long dsi_get_txbyteclkhs(void) 1003static unsigned long dsi_get_txbyteclkhs(void)
@@ -726,12 +1009,12 @@ static unsigned long dsi_fclk_rate(void)
726{ 1009{
727 unsigned long r; 1010 unsigned long r;
728 1011
729 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { 1012 if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) {
730 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 1013 /* DSI FCLK source is DSS_CLK_FCK */
731 r = dss_clk_get_rate(DSS_CLK_FCK1); 1014 r = dss_clk_get_rate(DSS_CLK_FCK);
732 } else { 1015 } else {
733 /* DSI FCLK source is DSI2_PLL_FCLK */ 1016 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
734 r = dsi_get_dsi2_pll_rate(); 1017 r = dsi_get_pll_hsdiv_dsi_rate();
735 } 1018 }
736 1019
737 return r; 1020 return r;
@@ -745,7 +1028,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
745 1028
746 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; 1029 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div;
747 1030
748 if (lp_clk_div == 0 || lp_clk_div > LP_DIV_MAX) 1031 if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max)
749 return -EINVAL; 1032 return -EINVAL;
750 1033
751 dsi_fclk = dsi_fclk_rate(); 1034 dsi_fclk = dsi_fclk_rate();
@@ -795,22 +1078,22 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
795static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, 1078static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
796 struct dsi_clock_info *cinfo) 1079 struct dsi_clock_info *cinfo)
797{ 1080{
798 if (cinfo->regn == 0 || cinfo->regn > REGN_MAX) 1081 if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max)
799 return -EINVAL; 1082 return -EINVAL;
800 1083
801 if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) 1084 if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max)
802 return -EINVAL; 1085 return -EINVAL;
803 1086
804 if (cinfo->regm3 > REGM3_MAX) 1087 if (cinfo->regm_dispc > dsi.regm_dispc_max)
805 return -EINVAL; 1088 return -EINVAL;
806 1089
807 if (cinfo->regm4 > REGM4_MAX) 1090 if (cinfo->regm_dsi > dsi.regm_dsi_max)
808 return -EINVAL; 1091 return -EINVAL;
809 1092
810 if (cinfo->use_dss2_fck) { 1093 if (cinfo->use_sys_clk) {
811 cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2); 1094 cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK);
812 /* XXX it is unclear if highfreq should be used 1095 /* XXX it is unclear if highfreq should be used
813 * with DSS2_FCK source also */ 1096 * with DSS_SYS_CLK source also */
814 cinfo->highfreq = 0; 1097 cinfo->highfreq = 0;
815 } else { 1098 } else {
816 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id); 1099 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id);
@@ -823,7 +1106,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
823 1106
824 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); 1107 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
825 1108
826 if (cinfo->fint > FINT_MAX || cinfo->fint < FINT_MIN) 1109 if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min)
827 return -EINVAL; 1110 return -EINVAL;
828 1111
829 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; 1112 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
@@ -831,15 +1114,17 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
831 if (cinfo->clkin4ddr > 1800 * 1000 * 1000) 1114 if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
832 return -EINVAL; 1115 return -EINVAL;
833 1116
834 if (cinfo->regm3 > 0) 1117 if (cinfo->regm_dispc > 0)
835 cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3; 1118 cinfo->dsi_pll_hsdiv_dispc_clk =
1119 cinfo->clkin4ddr / cinfo->regm_dispc;
836 else 1120 else
837 cinfo->dsi1_pll_fclk = 0; 1121 cinfo->dsi_pll_hsdiv_dispc_clk = 0;
838 1122
839 if (cinfo->regm4 > 0) 1123 if (cinfo->regm_dsi > 0)
840 cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4; 1124 cinfo->dsi_pll_hsdiv_dsi_clk =
1125 cinfo->clkin4ddr / cinfo->regm_dsi;
841 else 1126 else
842 cinfo->dsi2_pll_fclk = 0; 1127 cinfo->dsi_pll_hsdiv_dsi_clk = 0;
843 1128
844 return 0; 1129 return 0;
845} 1130}
@@ -852,23 +1137,25 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
852 struct dispc_clock_info best_dispc; 1137 struct dispc_clock_info best_dispc;
853 int min_fck_per_pck; 1138 int min_fck_per_pck;
854 int match = 0; 1139 int match = 0;
855 unsigned long dss_clk_fck2; 1140 unsigned long dss_sys_clk, max_dss_fck;
1141
1142 dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK);
856 1143
857 dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); 1144 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
858 1145
859 if (req_pck == dsi.cache_req_pck && 1146 if (req_pck == dsi.cache_req_pck &&
860 dsi.cache_cinfo.clkin == dss_clk_fck2) { 1147 dsi.cache_cinfo.clkin == dss_sys_clk) {
861 DSSDBG("DSI clock info found from cache\n"); 1148 DSSDBG("DSI clock info found from cache\n");
862 *dsi_cinfo = dsi.cache_cinfo; 1149 *dsi_cinfo = dsi.cache_cinfo;
863 dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk, 1150 dispc_find_clk_divs(is_tft, req_pck,
864 dispc_cinfo); 1151 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo);
865 return 0; 1152 return 0;
866 } 1153 }
867 1154
868 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 1155 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
869 1156
870 if (min_fck_per_pck && 1157 if (min_fck_per_pck &&
871 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 1158 req_pck * min_fck_per_pck > max_dss_fck) {
872 DSSERR("Requested pixel clock not possible with the current " 1159 DSSERR("Requested pixel clock not possible with the current "
873 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 1160 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
874 "the constraint off.\n"); 1161 "the constraint off.\n");
@@ -882,24 +1169,24 @@ retry:
882 memset(&best_dispc, 0, sizeof(best_dispc)); 1169 memset(&best_dispc, 0, sizeof(best_dispc));
883 1170
884 memset(&cur, 0, sizeof(cur)); 1171 memset(&cur, 0, sizeof(cur));
885 cur.clkin = dss_clk_fck2; 1172 cur.clkin = dss_sys_clk;
886 cur.use_dss2_fck = 1; 1173 cur.use_sys_clk = 1;
887 cur.highfreq = 0; 1174 cur.highfreq = 0;
888 1175
889 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1176 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
890 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ 1177 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
891 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1178 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
892 for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { 1179 for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) {
893 if (cur.highfreq == 0) 1180 if (cur.highfreq == 0)
894 cur.fint = cur.clkin / cur.regn; 1181 cur.fint = cur.clkin / cur.regn;
895 else 1182 else
896 cur.fint = cur.clkin / (2 * cur.regn); 1183 cur.fint = cur.clkin / (2 * cur.regn);
897 1184
898 if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) 1185 if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min)
899 continue; 1186 continue;
900 1187
901 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ 1188 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
902 for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { 1189 for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) {
903 unsigned long a, b; 1190 unsigned long a, b;
904 1191
905 a = 2 * cur.regm * (cur.clkin/1000); 1192 a = 2 * cur.regm * (cur.clkin/1000);
@@ -909,30 +1196,32 @@ retry:
909 if (cur.clkin4ddr > 1800 * 1000 * 1000) 1196 if (cur.clkin4ddr > 1800 * 1000 * 1000)
910 break; 1197 break;
911 1198
912 /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ 1199 /* dsi_pll_hsdiv_dispc_clk(MHz) =
913 for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; 1200 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
914 ++cur.regm3) { 1201 for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max;
1202 ++cur.regm_dispc) {
915 struct dispc_clock_info cur_dispc; 1203 struct dispc_clock_info cur_dispc;
916 cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3; 1204 cur.dsi_pll_hsdiv_dispc_clk =
1205 cur.clkin4ddr / cur.regm_dispc;
917 1206
918 /* this will narrow down the search a bit, 1207 /* this will narrow down the search a bit,
919 * but still give pixclocks below what was 1208 * but still give pixclocks below what was
920 * requested */ 1209 * requested */
921 if (cur.dsi1_pll_fclk < req_pck) 1210 if (cur.dsi_pll_hsdiv_dispc_clk < req_pck)
922 break; 1211 break;
923 1212
924 if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) 1213 if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck)
925 continue; 1214 continue;
926 1215
927 if (min_fck_per_pck && 1216 if (min_fck_per_pck &&
928 cur.dsi1_pll_fclk < 1217 cur.dsi_pll_hsdiv_dispc_clk <
929 req_pck * min_fck_per_pck) 1218 req_pck * min_fck_per_pck)
930 continue; 1219 continue;
931 1220
932 match = 1; 1221 match = 1;
933 1222
934 dispc_find_clk_divs(is_tft, req_pck, 1223 dispc_find_clk_divs(is_tft, req_pck,
935 cur.dsi1_pll_fclk, 1224 cur.dsi_pll_hsdiv_dispc_clk,
936 &cur_dispc); 1225 &cur_dispc);
937 1226
938 if (abs(cur_dispc.pck - req_pck) < 1227 if (abs(cur_dispc.pck - req_pck) <
@@ -961,9 +1250,9 @@ found:
961 return -EINVAL; 1250 return -EINVAL;
962 } 1251 }
963 1252
964 /* DSI2_PLL_FCLK (regm4) is not used */ 1253 /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */
965 best.regm4 = 0; 1254 best.regm_dsi = 0;
966 best.dsi2_pll_fclk = 0; 1255 best.dsi_pll_hsdiv_dsi_clk = 0;
967 1256
968 if (dsi_cinfo) 1257 if (dsi_cinfo)
969 *dsi_cinfo = best; 1258 *dsi_cinfo = best;
@@ -982,23 +1271,27 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
982 int r = 0; 1271 int r = 0;
983 u32 l; 1272 u32 l;
984 int f; 1273 int f;
1274 u8 regn_start, regn_end, regm_start, regm_end;
1275 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
985 1276
986 DSSDBGF(); 1277 DSSDBGF();
987 1278
988 dsi.current_cinfo.fint = cinfo->fint; 1279 dsi.current_cinfo.fint = cinfo->fint;
989 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; 1280 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr;
990 dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk; 1281 dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk =
991 dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk; 1282 cinfo->dsi_pll_hsdiv_dispc_clk;
1283 dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk =
1284 cinfo->dsi_pll_hsdiv_dsi_clk;
992 1285
993 dsi.current_cinfo.regn = cinfo->regn; 1286 dsi.current_cinfo.regn = cinfo->regn;
994 dsi.current_cinfo.regm = cinfo->regm; 1287 dsi.current_cinfo.regm = cinfo->regm;
995 dsi.current_cinfo.regm3 = cinfo->regm3; 1288 dsi.current_cinfo.regm_dispc = cinfo->regm_dispc;
996 dsi.current_cinfo.regm4 = cinfo->regm4; 1289 dsi.current_cinfo.regm_dsi = cinfo->regm_dsi;
997 1290
998 DSSDBG("DSI Fint %ld\n", cinfo->fint); 1291 DSSDBG("DSI Fint %ld\n", cinfo->fint);
999 1292
1000 DSSDBG("clkin (%s) rate %ld, highfreq %d\n", 1293 DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
1001 cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", 1294 cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree",
1002 cinfo->clkin, 1295 cinfo->clkin,
1003 cinfo->highfreq); 1296 cinfo->highfreq);
1004 1297
@@ -1015,24 +1308,39 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1015 1308
1016 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); 1309 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
1017 1310
1018 DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", 1311 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
1019 cinfo->regm3, cinfo->dsi1_pll_fclk); 1312 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1020 DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", 1313 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1021 cinfo->regm4, cinfo->dsi2_pll_fclk); 1314 cinfo->dsi_pll_hsdiv_dispc_clk);
1315 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
1316 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1317 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1318 cinfo->dsi_pll_hsdiv_dsi_clk);
1319
1320 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
1321 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, &regm_start, &regm_end);
1322 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, &regm_dispc_start,
1323 &regm_dispc_end);
1324 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
1325 &regm_dsi_end);
1022 1326
1023 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ 1327 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
1024 1328
1025 l = dsi_read_reg(DSI_PLL_CONFIGURATION1); 1329 l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
1026 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ 1330 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
1027 l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ 1331 /* DSI_PLL_REGN */
1028 l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ 1332 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
1029 l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0, 1333 /* DSI_PLL_REGM */
1030 22, 19); /* DSI_CLOCK_DIV */ 1334 l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
1031 l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0, 1335 /* DSI_CLOCK_DIV */
1032 26, 23); /* DSIPROTO_CLOCK_DIV */ 1336 l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
1337 regm_dispc_start, regm_dispc_end);
1338 /* DSIPROTO_CLOCK_DIV */
1339 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
1340 regm_dsi_start, regm_dsi_end);
1033 dsi_write_reg(DSI_PLL_CONFIGURATION1, l); 1341 dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
1034 1342
1035 BUG_ON(cinfo->fint < 750000 || cinfo->fint > 2100000); 1343 BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
1036 if (cinfo->fint < 1000000) 1344 if (cinfo->fint < 1000000)
1037 f = 0x3; 1345 f = 0x3;
1038 else if (cinfo->fint < 1250000) 1346 else if (cinfo->fint < 1250000)
@@ -1046,7 +1354,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1046 1354
1047 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1355 l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
1048 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ 1356 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
1049 l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, 1357 l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
1050 11, 11); /* DSI_PLL_CLKSEL */ 1358 11, 11); /* DSI_PLL_CLKSEL */
1051 l = FLD_MOD(l, cinfo->highfreq, 1359 l = FLD_MOD(l, cinfo->highfreq,
1052 12, 12); /* DSI_PLL_HIGHFREQ */ 1360 12, 12); /* DSI_PLL_HIGHFREQ */
@@ -1101,6 +1409,26 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1101 1409
1102 DSSDBG("PLL init\n"); 1410 DSSDBG("PLL init\n");
1103 1411
1412#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
1413 /*
1414 * HACK: this is just a quick hack to get the USE_DSI_PLL
1415 * option working. USE_DSI_PLL is itself a big hack, and
1416 * should be removed.
1417 */
1418 if (dsi.vdds_dsi_reg == NULL) {
1419 struct regulator *vdds_dsi;
1420
1421 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
1422
1423 if (IS_ERR(vdds_dsi)) {
1424 DSSERR("can't get VDDS_DSI regulator\n");
1425 return PTR_ERR(vdds_dsi);
1426 }
1427
1428 dsi.vdds_dsi_reg = vdds_dsi;
1429 }
1430#endif
1431
1104 enable_clocks(1); 1432 enable_clocks(1);
1105 dsi_enable_pll_clock(1); 1433 dsi_enable_pll_clock(1);
1106 1434
@@ -1162,6 +1490,10 @@ void dsi_dump_clocks(struct seq_file *s)
1162{ 1490{
1163 int clksel; 1491 int clksel;
1164 struct dsi_clock_info *cinfo = &dsi.current_cinfo; 1492 struct dsi_clock_info *cinfo = &dsi.current_cinfo;
1493 enum dss_clk_source dispc_clk_src, dsi_clk_src;
1494
1495 dispc_clk_src = dss_get_dispc_clk_source();
1496 dsi_clk_src = dss_get_dsi_clk_source();
1165 1497
1166 enable_clocks(1); 1498 enable_clocks(1);
1167 1499
@@ -1171,30 +1503,34 @@ void dsi_dump_clocks(struct seq_file *s)
1171 1503
1172 seq_printf(s, "dsi pll source = %s\n", 1504 seq_printf(s, "dsi pll source = %s\n",
1173 clksel == 0 ? 1505 clksel == 0 ?
1174 "dss2_alwon_fclk" : "pclkfree"); 1506 "dss_sys_clk" : "pclkfree");
1175 1507
1176 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1508 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
1177 1509
1178 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", 1510 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
1179 cinfo->clkin4ddr, cinfo->regm); 1511 cinfo->clkin4ddr, cinfo->regm);
1180 1512
1181 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1513 seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n",
1182 cinfo->dsi1_pll_fclk, 1514 dss_get_generic_clk_source_name(dispc_clk_src),
1183 cinfo->regm3, 1515 dss_feat_get_clk_source_name(dispc_clk_src),
1184 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1516 cinfo->dsi_pll_hsdiv_dispc_clk,
1517 cinfo->regm_dispc,
1518 dispc_clk_src == DSS_CLK_SRC_FCK ?
1185 "off" : "on"); 1519 "off" : "on");
1186 1520
1187 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1521 seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
1188 cinfo->dsi2_pll_fclk, 1522 dss_get_generic_clk_source_name(dsi_clk_src),
1189 cinfo->regm4, 1523 dss_feat_get_clk_source_name(dsi_clk_src),
1190 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1524 cinfo->dsi_pll_hsdiv_dsi_clk,
1525 cinfo->regm_dsi,
1526 dsi_clk_src == DSS_CLK_SRC_FCK ?
1191 "off" : "on"); 1527 "off" : "on");
1192 1528
1193 seq_printf(s, "- DSI -\n"); 1529 seq_printf(s, "- DSI -\n");
1194 1530
1195 seq_printf(s, "dsi fclk source = %s\n", 1531 seq_printf(s, "dsi fclk source = %s (%s)\n",
1196 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1532 dss_get_generic_clk_source_name(dsi_clk_src),
1197 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1533 dss_feat_get_clk_source_name(dsi_clk_src));
1198 1534
1199 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1535 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate());
1200 1536
@@ -1306,7 +1642,7 @@ void dsi_dump_regs(struct seq_file *s)
1306{ 1642{
1307#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) 1643#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
1308 1644
1309 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1645 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1310 1646
1311 DUMPREG(DSI_REVISION); 1647 DUMPREG(DSI_REVISION);
1312 DUMPREG(DSI_SYSCONFIG); 1648 DUMPREG(DSI_SYSCONFIG);
@@ -1378,7 +1714,7 @@ void dsi_dump_regs(struct seq_file *s)
1378 DUMPREG(DSI_PLL_CONFIGURATION1); 1714 DUMPREG(DSI_PLL_CONFIGURATION1);
1379 DUMPREG(DSI_PLL_CONFIGURATION2); 1715 DUMPREG(DSI_PLL_CONFIGURATION2);
1380 1716
1381 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1717 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1382#undef DUMPREG 1718#undef DUMPREG
1383} 1719}
1384 1720
@@ -1622,20 +1958,6 @@ static int _dsi_reset(void)
1622 return _dsi_wait_reset(); 1958 return _dsi_wait_reset();
1623} 1959}
1624 1960
1625static void dsi_reset_tx_fifo(int channel)
1626{
1627 u32 mask;
1628 u32 l;
1629
1630 /* set fifosize of the channel to 0, then return the old size */
1631 l = dsi_read_reg(DSI_TX_FIFO_VC_SIZE);
1632
1633 mask = FLD_MASK((8 * channel) + 7, (8 * channel) + 4);
1634 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l & ~mask);
1635
1636 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l);
1637}
1638
1639static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, 1961static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
1640 enum fifo_size size3, enum fifo_size size4) 1962 enum fifo_size size3, enum fifo_size size4)
1641{ 1963{
@@ -1753,8 +2075,6 @@ static void dsi_vc_initial_config(int channel)
1753 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2075 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
1754 2076
1755 dsi_write_reg(DSI_VC_CTRL(channel), r); 2077 dsi_write_reg(DSI_VC_CTRL(channel), r);
1756
1757 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1758} 2078}
1759 2079
1760static int dsi_vc_config_l4(int channel) 2080static int dsi_vc_config_l4(int channel)
@@ -1922,33 +2242,44 @@ static int dsi_vc_send_bta(int channel)
1922 2242
1923int dsi_vc_send_bta_sync(int channel) 2243int dsi_vc_send_bta_sync(int channel)
1924{ 2244{
2245 DECLARE_COMPLETION_ONSTACK(completion);
1925 int r = 0; 2246 int r = 0;
1926 u32 err; 2247 u32 err;
1927 2248
1928 INIT_COMPLETION(dsi.bta_completion); 2249 r = dsi_register_isr_vc(channel, dsi_completion_handler,
2250 &completion, DSI_VC_IRQ_BTA);
2251 if (r)
2252 goto err0;
1929 2253
1930 dsi_vc_enable_bta_irq(channel); 2254 r = dsi_register_isr(dsi_completion_handler, &completion,
2255 DSI_IRQ_ERROR_MASK);
2256 if (r)
2257 goto err1;
1931 2258
1932 r = dsi_vc_send_bta(channel); 2259 r = dsi_vc_send_bta(channel);
1933 if (r) 2260 if (r)
1934 goto err; 2261 goto err2;
1935 2262
1936 if (wait_for_completion_timeout(&dsi.bta_completion, 2263 if (wait_for_completion_timeout(&completion,
1937 msecs_to_jiffies(500)) == 0) { 2264 msecs_to_jiffies(500)) == 0) {
1938 DSSERR("Failed to receive BTA\n"); 2265 DSSERR("Failed to receive BTA\n");
1939 r = -EIO; 2266 r = -EIO;
1940 goto err; 2267 goto err2;
1941 } 2268 }
1942 2269
1943 err = dsi_get_errors(); 2270 err = dsi_get_errors();
1944 if (err) { 2271 if (err) {
1945 DSSERR("Error while sending BTA: %x\n", err); 2272 DSSERR("Error while sending BTA: %x\n", err);
1946 r = -EIO; 2273 r = -EIO;
1947 goto err; 2274 goto err2;
1948 } 2275 }
1949err: 2276err2:
1950 dsi_vc_disable_bta_irq(channel); 2277 dsi_unregister_isr(dsi_completion_handler, &completion,
1951 2278 DSI_IRQ_ERROR_MASK);
2279err1:
2280 dsi_unregister_isr_vc(channel, dsi_completion_handler,
2281 &completion, DSI_VC_IRQ_BTA);
2282err0:
1952 return r; 2283 return r;
1953} 2284}
1954EXPORT_SYMBOL(dsi_vc_send_bta_sync); 2285EXPORT_SYMBOL(dsi_vc_send_bta_sync);
@@ -1961,7 +2292,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type,
1961 2292
1962 WARN_ON(!dsi_bus_is_locked()); 2293 WARN_ON(!dsi_bus_is_locked());
1963 2294
1964 data_id = data_type | channel << 6; 2295 data_id = data_type | dsi.vc[channel].vc_id << 6;
1965 2296
1966 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 2297 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
1967 FLD_VAL(ecc, 31, 24); 2298 FLD_VAL(ecc, 31, 24);
@@ -2064,7 +2395,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2064 return -EINVAL; 2395 return -EINVAL;
2065 } 2396 }
2066 2397
2067 data_id = data_type | channel << 6; 2398 data_id = data_type | dsi.vc[channel].vc_id << 6;
2068 2399
2069 r = (data_id << 0) | (data << 8) | (ecc << 24); 2400 r = (data_id << 0) | (data << 8) | (ecc << 24);
2070 2401
@@ -2762,19 +3093,20 @@ static void dsi_te_timeout(unsigned long arg)
2762} 3093}
2763#endif 3094#endif
2764 3095
3096static void dsi_framedone_bta_callback(void *data, u32 mask);
3097
2765static void dsi_handle_framedone(int error) 3098static void dsi_handle_framedone(int error)
2766{ 3099{
2767 const int channel = dsi.update_channel; 3100 const int channel = dsi.update_channel;
2768 3101
2769 cancel_delayed_work(&dsi.framedone_timeout_work); 3102 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3103 NULL, DSI_VC_IRQ_BTA);
2770 3104
2771 dsi_vc_disable_bta_irq(channel); 3105 cancel_delayed_work(&dsi.framedone_timeout_work);
2772 3106
2773 /* SIDLEMODE back to smart-idle */ 3107 /* SIDLEMODE back to smart-idle */
2774 dispc_enable_sidle(); 3108 dispc_enable_sidle();
2775 3109
2776 dsi.bta_callback = NULL;
2777
2778 if (dsi.te_enabled) { 3110 if (dsi.te_enabled) {
2779 /* enable LP_RX_TO again after the TE */ 3111 /* enable LP_RX_TO again after the TE */
2780 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 3112 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
@@ -2808,7 +3140,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2808 dsi_handle_framedone(-ETIMEDOUT); 3140 dsi_handle_framedone(-ETIMEDOUT);
2809} 3141}
2810 3142
2811static void dsi_framedone_bta_callback(void) 3143static void dsi_framedone_bta_callback(void *data, u32 mask)
2812{ 3144{
2813 dsi_handle_framedone(0); 3145 dsi_handle_framedone(0);
2814 3146
@@ -2848,15 +3180,19 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
2848 * asynchronously. 3180 * asynchronously.
2849 * */ 3181 * */
2850 3182
2851 dsi.bta_callback = dsi_framedone_bta_callback; 3183 r = dsi_register_isr_vc(channel, dsi_framedone_bta_callback,
2852 3184 NULL, DSI_VC_IRQ_BTA);
2853 barrier(); 3185 if (r) {
2854 3186 DSSERR("Failed to register BTA ISR\n");
2855 dsi_vc_enable_bta_irq(channel); 3187 dsi_handle_framedone(-EIO);
3188 return;
3189 }
2856 3190
2857 r = dsi_vc_send_bta(channel); 3191 r = dsi_vc_send_bta(channel);
2858 if (r) { 3192 if (r) {
2859 DSSERR("BTA after framedone failed\n"); 3193 DSSERR("BTA after framedone failed\n");
3194 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3195 NULL, DSI_VC_IRQ_BTA);
2860 dsi_handle_framedone(-EIO); 3196 dsi_handle_framedone(-EIO);
2861 } 3197 }
2862} 3198}
@@ -2984,12 +3320,12 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
2984 struct dsi_clock_info cinfo; 3320 struct dsi_clock_info cinfo;
2985 int r; 3321 int r;
2986 3322
2987 /* we always use DSS2_FCK as input clock */ 3323 /* we always use DSS_CLK_SYSCK as input clock */
2988 cinfo.use_dss2_fck = true; 3324 cinfo.use_sys_clk = true;
2989 cinfo.regn = dssdev->phy.dsi.div.regn; 3325 cinfo.regn = dssdev->phy.dsi.div.regn;
2990 cinfo.regm = dssdev->phy.dsi.div.regm; 3326 cinfo.regm = dssdev->phy.dsi.div.regm;
2991 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 3327 cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc;
2992 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 3328 cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi;
2993 r = dsi_calc_clock_rates(dssdev, &cinfo); 3329 r = dsi_calc_clock_rates(dssdev, &cinfo);
2994 if (r) { 3330 if (r) {
2995 DSSERR("Failed to calc dsi clocks\n"); 3331 DSSERR("Failed to calc dsi clocks\n");
@@ -3011,7 +3347,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3011 int r; 3347 int r;
3012 unsigned long long fck; 3348 unsigned long long fck;
3013 3349
3014 fck = dsi_get_dsi1_pll_rate(); 3350 fck = dsi_get_pll_hsdiv_dispc_rate();
3015 3351
3016 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; 3352 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div;
3017 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; 3353 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div;
@@ -3045,8 +3381,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3045 if (r) 3381 if (r)
3046 goto err1; 3382 goto err1;
3047 3383
3048 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 3384 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
3049 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); 3385 dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI);
3050 3386
3051 DSSDBG("PLL OK\n"); 3387 DSSDBG("PLL OK\n");
3052 3388
@@ -3082,8 +3418,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3082err3: 3418err3:
3083 dsi_complexio_uninit(); 3419 dsi_complexio_uninit();
3084err2: 3420err2:
3085 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3421 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3086 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3422 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3087err1: 3423err1:
3088 dsi_pll_uninit(); 3424 dsi_pll_uninit();
3089err0: 3425err0:
@@ -3099,8 +3435,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3099 dsi_vc_enable(2, 0); 3435 dsi_vc_enable(2, 0);
3100 dsi_vc_enable(3, 0); 3436 dsi_vc_enable(3, 0);
3101 3437
3102 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3438 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3103 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3439 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3104 dsi_complexio_uninit(); 3440 dsi_complexio_uninit();
3105 dsi_pll_uninit(); 3441 dsi_pll_uninit();
3106} 3442}
@@ -3220,29 +3556,107 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3220 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 3556 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3221 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 3557 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
3222 3558
3223 dsi.vc[0].dssdev = dssdev; 3559 if (dsi.vdds_dsi_reg == NULL) {
3224 dsi.vc[1].dssdev = dssdev; 3560 struct regulator *vdds_dsi;
3561
3562 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
3563
3564 if (IS_ERR(vdds_dsi)) {
3565 DSSERR("can't get VDDS_DSI regulator\n");
3566 return PTR_ERR(vdds_dsi);
3567 }
3568
3569 dsi.vdds_dsi_reg = vdds_dsi;
3570 }
3225 3571
3226 return 0; 3572 return 0;
3227} 3573}
3228 3574
3229void dsi_wait_dsi1_pll_active(void) 3575int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
3576{
3577 int i;
3578
3579 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3580 if (!dsi.vc[i].dssdev) {
3581 dsi.vc[i].dssdev = dssdev;
3582 *channel = i;
3583 return 0;
3584 }
3585 }
3586
3587 DSSERR("cannot get VC for display %s", dssdev->name);
3588 return -ENOSPC;
3589}
3590EXPORT_SYMBOL(omap_dsi_request_vc);
3591
3592int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
3593{
3594 if (vc_id < 0 || vc_id > 3) {
3595 DSSERR("VC ID out of range\n");
3596 return -EINVAL;
3597 }
3598
3599 if (channel < 0 || channel > 3) {
3600 DSSERR("Virtual Channel out of range\n");
3601 return -EINVAL;
3602 }
3603
3604 if (dsi.vc[channel].dssdev != dssdev) {
3605 DSSERR("Virtual Channel not allocated to display %s\n",
3606 dssdev->name);
3607 return -EINVAL;
3608 }
3609
3610 dsi.vc[channel].vc_id = vc_id;
3611
3612 return 0;
3613}
3614EXPORT_SYMBOL(omap_dsi_set_vc_id);
3615
3616void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
3617{
3618 if ((channel >= 0 && channel <= 3) &&
3619 dsi.vc[channel].dssdev == dssdev) {
3620 dsi.vc[channel].dssdev = NULL;
3621 dsi.vc[channel].vc_id = 0;
3622 }
3623}
3624EXPORT_SYMBOL(omap_dsi_release_vc);
3625
3626void dsi_wait_pll_hsdiv_dispc_active(void)
3230{ 3627{
3231 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) 3628 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1)
3232 DSSERR("DSI1 PLL clock not active\n"); 3629 DSSERR("%s (%s) not active\n",
3630 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
3631 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
3233} 3632}
3234 3633
3235void dsi_wait_dsi2_pll_active(void) 3634void dsi_wait_pll_hsdiv_dsi_active(void)
3236{ 3635{
3237 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) 3636 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1)
3238 DSSERR("DSI2 PLL clock not active\n"); 3637 DSSERR("%s (%s) not active\n",
3638 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
3639 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
3640}
3641
3642static void dsi_calc_clock_param_ranges(void)
3643{
3644 dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
3645 dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
3646 dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
3647 dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
3648 dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
3649 dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
3650 dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
3239} 3651}
3240 3652
3241int dsi_init(struct platform_device *pdev) 3653static int dsi_init(struct platform_device *pdev)
3242{ 3654{
3243 u32 rev; 3655 u32 rev;
3244 int r; 3656 int r, i;
3657 struct resource *dsi_mem;
3245 3658
3659 spin_lock_init(&dsi.irq_lock);
3246 spin_lock_init(&dsi.errors_lock); 3660 spin_lock_init(&dsi.errors_lock);
3247 dsi.errors = 0; 3661 dsi.errors = 0;
3248 3662
@@ -3251,8 +3665,6 @@ int dsi_init(struct platform_device *pdev)
3251 dsi.irq_stats.last_reset = jiffies; 3665 dsi.irq_stats.last_reset = jiffies;
3252#endif 3666#endif
3253 3667
3254 init_completion(&dsi.bta_completion);
3255
3256 mutex_init(&dsi.lock); 3668 mutex_init(&dsi.lock);
3257 sema_init(&dsi.bus_lock, 1); 3669 sema_init(&dsi.bus_lock, 1);
3258 3670
@@ -3268,24 +3680,45 @@ int dsi_init(struct platform_device *pdev)
3268 dsi.te_timer.function = dsi_te_timeout; 3680 dsi.te_timer.function = dsi_te_timeout;
3269 dsi.te_timer.data = 0; 3681 dsi.te_timer.data = 0;
3270#endif 3682#endif
3271 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 3683 dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0);
3684 if (!dsi_mem) {
3685 DSSERR("can't get IORESOURCE_MEM DSI\n");
3686 r = -EINVAL;
3687 goto err1;
3688 }
3689 dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem));
3272 if (!dsi.base) { 3690 if (!dsi.base) {
3273 DSSERR("can't ioremap DSI\n"); 3691 DSSERR("can't ioremap DSI\n");
3274 r = -ENOMEM; 3692 r = -ENOMEM;
3275 goto err1; 3693 goto err1;
3276 } 3694 }
3695 dsi.irq = platform_get_irq(dsi.pdev, 0);
3696 if (dsi.irq < 0) {
3697 DSSERR("platform_get_irq failed\n");
3698 r = -ENODEV;
3699 goto err2;
3700 }
3277 3701
3278 dsi.vdds_dsi_reg = dss_get_vdds_dsi(); 3702 r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED,
3279 if (IS_ERR(dsi.vdds_dsi_reg)) { 3703 "OMAP DSI1", dsi.pdev);
3280 DSSERR("can't get VDDS_DSI regulator\n"); 3704 if (r < 0) {
3281 r = PTR_ERR(dsi.vdds_dsi_reg); 3705 DSSERR("request_irq failed\n");
3282 goto err2; 3706 goto err2;
3283 } 3707 }
3284 3708
3709 /* DSI VCs initialization */
3710 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3711 dsi.vc[i].mode = DSI_VC_MODE_L4;
3712 dsi.vc[i].dssdev = NULL;
3713 dsi.vc[i].vc_id = 0;
3714 }
3715
3716 dsi_calc_clock_param_ranges();
3717
3285 enable_clocks(1); 3718 enable_clocks(1);
3286 3719
3287 rev = dsi_read_reg(DSI_REVISION); 3720 rev = dsi_read_reg(DSI_REVISION);
3288 printk(KERN_INFO "OMAP DSI rev %d.%d\n", 3721 dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n",
3289 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 3722 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3290 3723
3291 enable_clocks(0); 3724 enable_clocks(0);
@@ -3298,8 +3731,14 @@ err1:
3298 return r; 3731 return r;
3299} 3732}
3300 3733
3301void dsi_exit(void) 3734static void dsi_exit(void)
3302{ 3735{
3736 if (dsi.vdds_dsi_reg != NULL) {
3737 regulator_put(dsi.vdds_dsi_reg);
3738 dsi.vdds_dsi_reg = NULL;
3739 }
3740
3741 free_irq(dsi.irq, dsi.pdev);
3303 iounmap(dsi.base); 3742 iounmap(dsi.base);
3304 3743
3305 destroy_workqueue(dsi.workqueue); 3744 destroy_workqueue(dsi.workqueue);
@@ -3307,3 +3746,41 @@ void dsi_exit(void)
3307 DSSDBG("omap_dsi_exit\n"); 3746 DSSDBG("omap_dsi_exit\n");
3308} 3747}
3309 3748
3749/* DSI1 HW IP initialisation */
3750static int omap_dsi1hw_probe(struct platform_device *pdev)
3751{
3752 int r;
3753 dsi.pdev = pdev;
3754 r = dsi_init(pdev);
3755 if (r) {
3756 DSSERR("Failed to initialize DSI\n");
3757 goto err_dsi;
3758 }
3759err_dsi:
3760 return r;
3761}
3762
3763static int omap_dsi1hw_remove(struct platform_device *pdev)
3764{
3765 dsi_exit();
3766 return 0;
3767}
3768
3769static struct platform_driver omap_dsi1hw_driver = {
3770 .probe = omap_dsi1hw_probe,
3771 .remove = omap_dsi1hw_remove,
3772 .driver = {
3773 .name = "omapdss_dsi1",
3774 .owner = THIS_MODULE,
3775 },
3776};
3777
3778int dsi_init_platform_driver(void)
3779{
3780 return platform_driver_register(&omap_dsi1hw_driver);
3781}
3782
3783void dsi_uninit_platform_driver(void)
3784{
3785 return platform_driver_unregister(&omap_dsi1hw_driver);
3786}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c3621c9171..3f1fee63c678 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -26,14 +26,13 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/seq_file.h> 29#include <linux/seq_file.h>
31#include <linux/clk.h> 30#include <linux/clk.h>
32 31
33#include <plat/display.h> 32#include <plat/display.h>
33#include <plat/clock.h>
34#include "dss.h" 34#include "dss.h"
35 35#include "dss_features.h"
36#define DSS_BASE 0x48050000
37 36
38#define DSS_SZ_REGS SZ_512 37#define DSS_SZ_REGS SZ_512
39 38
@@ -59,9 +58,17 @@ struct dss_reg {
59 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 58 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
60 59
61static struct { 60static struct {
61 struct platform_device *pdev;
62 void __iomem *base; 62 void __iomem *base;
63 int ctx_id;
63 64
64 struct clk *dpll4_m4_ck; 65 struct clk *dpll4_m4_ck;
66 struct clk *dss_ick;
67 struct clk *dss_fck;
68 struct clk *dss_sys_clk;
69 struct clk *dss_tv_fck;
70 struct clk *dss_video_fck;
71 unsigned num_clks_enabled;
65 72
66 unsigned long cache_req_pck; 73 unsigned long cache_req_pck;
67 unsigned long cache_prate; 74 unsigned long cache_prate;
@@ -70,10 +77,22 @@ static struct {
70 77
71 enum dss_clk_source dsi_clk_source; 78 enum dss_clk_source dsi_clk_source;
72 enum dss_clk_source dispc_clk_source; 79 enum dss_clk_source dispc_clk_source;
80 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
73 81
74 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 82 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
75} dss; 83} dss;
76 84
85static const char * const dss_generic_clk_source_names[] = {
86 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
87 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
88 [DSS_CLK_SRC_FCK] = "DSS_FCK",
89};
90
91static void dss_clk_enable_all_no_ctx(void);
92static void dss_clk_disable_all_no_ctx(void);
93static void dss_clk_enable_no_ctx(enum dss_clock clks);
94static void dss_clk_disable_no_ctx(enum dss_clock clks);
95
77static int _omap_dss_wait_reset(void); 96static int _omap_dss_wait_reset(void);
78 97
79static inline void dss_write_reg(const struct dss_reg idx, u32 val) 98static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -99,10 +118,11 @@ void dss_save_context(void)
99 SR(SYSCONFIG); 118 SR(SYSCONFIG);
100 SR(CONTROL); 119 SR(CONTROL);
101 120
102#ifdef CONFIG_OMAP2_DSS_SDI 121 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
103 SR(SDI_CONTROL); 122 OMAP_DISPLAY_TYPE_SDI) {
104 SR(PLL_CONTROL); 123 SR(SDI_CONTROL);
105#endif 124 SR(PLL_CONTROL);
125 }
106} 126}
107 127
108void dss_restore_context(void) 128void dss_restore_context(void)
@@ -113,10 +133,11 @@ void dss_restore_context(void)
113 RR(SYSCONFIG); 133 RR(SYSCONFIG);
114 RR(CONTROL); 134 RR(CONTROL);
115 135
116#ifdef CONFIG_OMAP2_DSS_SDI 136 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
117 RR(SDI_CONTROL); 137 OMAP_DISPLAY_TYPE_SDI) {
118 RR(PLL_CONTROL); 138 RR(SDI_CONTROL);
119#endif 139 RR(PLL_CONTROL);
140 }
120} 141}
121 142
122#undef SR 143#undef SR
@@ -209,66 +230,96 @@ void dss_sdi_disable(void)
209 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 230 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
210} 231}
211 232
233const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src)
234{
235 return dss_generic_clk_source_names[clk_src];
236}
237
212void dss_dump_clocks(struct seq_file *s) 238void dss_dump_clocks(struct seq_file *s)
213{ 239{
214 unsigned long dpll4_ck_rate; 240 unsigned long dpll4_ck_rate;
215 unsigned long dpll4_m4_ck_rate; 241 unsigned long dpll4_m4_ck_rate;
242 const char *fclk_name, *fclk_real_name;
243 unsigned long fclk_rate;
216 244
217 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 245 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
218
219 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
220 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
221 246
222 seq_printf(s, "- DSS -\n"); 247 seq_printf(s, "- DSS -\n");
223 248
224 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); 249 fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK);
250 fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK);
251 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
225 252
226 if (cpu_is_omap3630()) 253 if (dss.dpll4_m4_ck) {
227 seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", 254 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
228 dpll4_ck_rate, 255 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
229 dpll4_ck_rate / dpll4_m4_ck_rate, 256
230 dss_clk_get_rate(DSS_CLK_FCK1)); 257 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
231 else
232 seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
233 dpll4_ck_rate,
234 dpll4_ck_rate / dpll4_m4_ck_rate,
235 dss_clk_get_rate(DSS_CLK_FCK1));
236 258
237 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 259 if (cpu_is_omap3630() || cpu_is_omap44xx())
260 seq_printf(s, "%s (%s) = %lu / %lu = %lu\n",
261 fclk_name, fclk_real_name,
262 dpll4_ck_rate,
263 dpll4_ck_rate / dpll4_m4_ck_rate,
264 fclk_rate);
265 else
266 seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
267 fclk_name, fclk_real_name,
268 dpll4_ck_rate,
269 dpll4_ck_rate / dpll4_m4_ck_rate,
270 fclk_rate);
271 } else {
272 seq_printf(s, "%s (%s) = %lu\n",
273 fclk_name, fclk_real_name,
274 fclk_rate);
275 }
276
277 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
238} 278}
239 279
240void dss_dump_regs(struct seq_file *s) 280void dss_dump_regs(struct seq_file *s)
241{ 281{
242#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 282#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
243 283
244 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 284 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
245 285
246 DUMPREG(DSS_REVISION); 286 DUMPREG(DSS_REVISION);
247 DUMPREG(DSS_SYSCONFIG); 287 DUMPREG(DSS_SYSCONFIG);
248 DUMPREG(DSS_SYSSTATUS); 288 DUMPREG(DSS_SYSSTATUS);
249 DUMPREG(DSS_IRQSTATUS); 289 DUMPREG(DSS_IRQSTATUS);
250 DUMPREG(DSS_CONTROL); 290 DUMPREG(DSS_CONTROL);
251 DUMPREG(DSS_SDI_CONTROL);
252 DUMPREG(DSS_PLL_CONTROL);
253 DUMPREG(DSS_SDI_STATUS);
254 291
255 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 292 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
293 OMAP_DISPLAY_TYPE_SDI) {
294 DUMPREG(DSS_SDI_CONTROL);
295 DUMPREG(DSS_PLL_CONTROL);
296 DUMPREG(DSS_SDI_STATUS);
297 }
298
299 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
256#undef DUMPREG 300#undef DUMPREG
257} 301}
258 302
259void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 303void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
260{ 304{
261 int b; 305 int b;
306 u8 start, end;
307
308 switch (clk_src) {
309 case DSS_CLK_SRC_FCK:
310 b = 0;
311 break;
312 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
313 b = 1;
314 dsi_wait_pll_hsdiv_dispc_active();
315 break;
316 default:
317 BUG();
318 }
262 319
263 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && 320 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
264 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
265
266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
267
268 if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
269 dsi_wait_dsi1_pll_active();
270 321
271 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 322 REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
272 323
273 dss.dispc_clk_source = clk_src; 324 dss.dispc_clk_source = clk_src;
274} 325}
@@ -277,19 +328,51 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
277{ 328{
278 int b; 329 int b;
279 330
280 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && 331 switch (clk_src) {
281 clk_src != DSS_SRC_DSS1_ALWON_FCLK); 332 case DSS_CLK_SRC_FCK:
282 333 b = 0;
283 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 334 break;
284 335 case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
285 if (clk_src == DSS_SRC_DSI2_PLL_FCLK) 336 b = 1;
286 dsi_wait_dsi2_pll_active(); 337 dsi_wait_pll_hsdiv_dsi_active();
338 break;
339 default:
340 BUG();
341 }
287 342
288 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 343 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
289 344
290 dss.dsi_clk_source = clk_src; 345 dss.dsi_clk_source = clk_src;
291} 346}
292 347
348void dss_select_lcd_clk_source(enum omap_channel channel,
349 enum dss_clk_source clk_src)
350{
351 int b, ix, pos;
352
353 if (!dss_has_feature(FEAT_LCD_CLK_SRC))
354 return;
355
356 switch (clk_src) {
357 case DSS_CLK_SRC_FCK:
358 b = 0;
359 break;
360 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
361 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
362 b = 1;
363 dsi_wait_pll_hsdiv_dispc_active();
364 break;
365 default:
366 BUG();
367 }
368
369 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
370 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
371
372 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
373 dss.lcd_clk_source[ix] = clk_src;
374}
375
293enum dss_clk_source dss_get_dispc_clk_source(void) 376enum dss_clk_source dss_get_dispc_clk_source(void)
294{ 377{
295 return dss.dispc_clk_source; 378 return dss.dispc_clk_source;
@@ -300,34 +383,52 @@ enum dss_clk_source dss_get_dsi_clk_source(void)
300 return dss.dsi_clk_source; 383 return dss.dsi_clk_source;
301} 384}
302 385
386enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
387{
388 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
389 return dss.lcd_clk_source[ix];
390}
391
303/* calculate clock rates using dividers in cinfo */ 392/* calculate clock rates using dividers in cinfo */
304int dss_calc_clock_rates(struct dss_clock_info *cinfo) 393int dss_calc_clock_rates(struct dss_clock_info *cinfo)
305{ 394{
306 unsigned long prate; 395 if (dss.dpll4_m4_ck) {
396 unsigned long prate;
397 u16 fck_div_max = 16;
307 398
308 if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) || 399 if (cpu_is_omap3630() || cpu_is_omap44xx())
309 cinfo->fck_div == 0) 400 fck_div_max = 32;
310 return -EINVAL; 401
402 if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
403 return -EINVAL;
311 404
312 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 405 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
313 406
314 cinfo->fck = prate / cinfo->fck_div; 407 cinfo->fck = prate / cinfo->fck_div;
408 } else {
409 if (cinfo->fck_div != 0)
410 return -EINVAL;
411 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
412 }
315 413
316 return 0; 414 return 0;
317} 415}
318 416
319int dss_set_clock_div(struct dss_clock_info *cinfo) 417int dss_set_clock_div(struct dss_clock_info *cinfo)
320{ 418{
321 unsigned long prate; 419 if (dss.dpll4_m4_ck) {
322 int r; 420 unsigned long prate;
421 int r;
323 422
324 if (cpu_is_omap34xx()) {
325 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 423 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
326 DSSDBG("dpll4_m4 = %ld\n", prate); 424 DSSDBG("dpll4_m4 = %ld\n", prate);
327 425
328 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div); 426 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
329 if (r) 427 if (r)
330 return r; 428 return r;
429 } else {
430 if (cinfo->fck_div != 0)
431 return -EINVAL;
331 } 432 }
332 433
333 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 434 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
@@ -337,12 +438,14 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
337 438
338int dss_get_clock_div(struct dss_clock_info *cinfo) 439int dss_get_clock_div(struct dss_clock_info *cinfo)
339{ 440{
340 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); 441 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
341 442
342 if (cpu_is_omap34xx()) { 443 if (dss.dpll4_m4_ck) {
343 unsigned long prate; 444 unsigned long prate;
445
344 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 446 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
345 if (cpu_is_omap3630()) 447
448 if (cpu_is_omap3630() || cpu_is_omap44xx())
346 cinfo->fck_div = prate / (cinfo->fck); 449 cinfo->fck_div = prate / (cinfo->fck);
347 else 450 else
348 cinfo->fck_div = prate / (cinfo->fck / 2); 451 cinfo->fck_div = prate / (cinfo->fck / 2);
@@ -355,7 +458,7 @@ int dss_get_clock_div(struct dss_clock_info *cinfo)
355 458
356unsigned long dss_get_dpll4_rate(void) 459unsigned long dss_get_dpll4_rate(void)
357{ 460{
358 if (cpu_is_omap34xx()) 461 if (dss.dpll4_m4_ck)
359 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 462 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
360 else 463 else
361 return 0; 464 return 0;
@@ -369,16 +472,18 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
369 struct dss_clock_info best_dss; 472 struct dss_clock_info best_dss;
370 struct dispc_clock_info best_dispc; 473 struct dispc_clock_info best_dispc;
371 474
372 unsigned long fck; 475 unsigned long fck, max_dss_fck;
373 476
374 u16 fck_div; 477 u16 fck_div, fck_div_max = 16;
375 478
376 int match = 0; 479 int match = 0;
377 int min_fck_per_pck; 480 int min_fck_per_pck;
378 481
379 prate = dss_get_dpll4_rate(); 482 prate = dss_get_dpll4_rate();
380 483
381 fck = dss_clk_get_rate(DSS_CLK_FCK1); 484 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
485
486 fck = dss_clk_get_rate(DSS_CLK_FCK);
382 if (req_pck == dss.cache_req_pck && 487 if (req_pck == dss.cache_req_pck &&
383 ((cpu_is_omap34xx() && prate == dss.cache_prate) || 488 ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
384 dss.cache_dss_cinfo.fck == fck)) { 489 dss.cache_dss_cinfo.fck == fck)) {
@@ -391,7 +496,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
391 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 496 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
392 497
393 if (min_fck_per_pck && 498 if (min_fck_per_pck &&
394 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 499 req_pck * min_fck_per_pck > max_dss_fck) {
395 DSSERR("Requested pixel clock not possible with the current " 500 DSSERR("Requested pixel clock not possible with the current "
396 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 501 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
397 "the constraint off.\n"); 502 "the constraint off.\n");
@@ -402,10 +507,10 @@ retry:
402 memset(&best_dss, 0, sizeof(best_dss)); 507 memset(&best_dss, 0, sizeof(best_dss));
403 memset(&best_dispc, 0, sizeof(best_dispc)); 508 memset(&best_dispc, 0, sizeof(best_dispc));
404 509
405 if (cpu_is_omap24xx()) { 510 if (dss.dpll4_m4_ck == NULL) {
406 struct dispc_clock_info cur_dispc; 511 struct dispc_clock_info cur_dispc;
407 /* XXX can we change the clock on omap2? */ 512 /* XXX can we change the clock on omap2? */
408 fck = dss_clk_get_rate(DSS_CLK_FCK1); 513 fck = dss_clk_get_rate(DSS_CLK_FCK);
409 fck_div = 1; 514 fck_div = 1;
410 515
411 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 516 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
@@ -417,17 +522,19 @@ retry:
417 best_dispc = cur_dispc; 522 best_dispc = cur_dispc;
418 523
419 goto found; 524 goto found;
420 } else if (cpu_is_omap34xx()) { 525 } else {
421 for (fck_div = (cpu_is_omap3630() ? 32 : 16); 526 if (cpu_is_omap3630() || cpu_is_omap44xx())
422 fck_div > 0; --fck_div) { 527 fck_div_max = 32;
528
529 for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
423 struct dispc_clock_info cur_dispc; 530 struct dispc_clock_info cur_dispc;
424 531
425 if (cpu_is_omap3630()) 532 if (fck_div_max == 32)
426 fck = prate / fck_div; 533 fck = prate / fck_div;
427 else 534 else
428 fck = prate / fck_div * 2; 535 fck = prate / fck_div * 2;
429 536
430 if (fck > DISPC_MAX_FCK) 537 if (fck > max_dss_fck)
431 continue; 538 continue;
432 539
433 if (min_fck_per_pck && 540 if (min_fck_per_pck &&
@@ -450,8 +557,6 @@ retry:
450 goto found; 557 goto found;
451 } 558 }
452 } 559 }
453 } else {
454 BUG();
455 } 560 }
456 561
457found: 562found:
@@ -482,31 +587,6 @@ found:
482 return 0; 587 return 0;
483} 588}
484 589
485
486
487static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
488{
489 dispc_irq_handler();
490
491 return IRQ_HANDLED;
492}
493
494static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
495{
496 u32 irqstatus;
497
498 irqstatus = dss_read_reg(DSS_IRQSTATUS);
499
500 if (irqstatus & (1<<0)) /* DISPC_IRQ */
501 dispc_irq_handler();
502#ifdef CONFIG_OMAP2_DSS_DSI
503 if (irqstatus & (1<<1)) /* DSI_IRQ */
504 dsi_irq_handler();
505#endif
506
507 return IRQ_HANDLED;
508}
509
510static int _omap_dss_wait_reset(void) 590static int _omap_dss_wait_reset(void)
511{ 591{
512 int t = 0; 592 int t = 0;
@@ -549,34 +629,45 @@ void dss_set_dac_pwrdn_bgz(bool enable)
549 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ 629 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
550} 630}
551 631
552int dss_init(bool skip_init) 632void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
633{
634 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
635}
636
637static int dss_init(void)
553{ 638{
554 int r; 639 int r;
555 u32 rev; 640 u32 rev;
641 struct resource *dss_mem;
642 struct clk *dpll4_m4_ck;
556 643
557 dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); 644 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
645 if (!dss_mem) {
646 DSSERR("can't get IORESOURCE_MEM DSS\n");
647 r = -EINVAL;
648 goto fail0;
649 }
650 dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
558 if (!dss.base) { 651 if (!dss.base) {
559 DSSERR("can't ioremap DSS\n"); 652 DSSERR("can't ioremap DSS\n");
560 r = -ENOMEM; 653 r = -ENOMEM;
561 goto fail0; 654 goto fail0;
562 } 655 }
563 656
564 if (!skip_init) { 657 /* disable LCD and DIGIT output. This seems to fix the synclost
565 /* disable LCD and DIGIT output. This seems to fix the synclost 658 * problem that we get, if the bootloader starts the DSS and
566 * problem that we get, if the bootloader starts the DSS and 659 * the kernel resets it */
567 * the kernel resets it */ 660 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
568 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
569 661
570 /* We need to wait here a bit, otherwise we sometimes start to 662 /* We need to wait here a bit, otherwise we sometimes start to
571 * get synclost errors, and after that only power cycle will 663 * get synclost errors, and after that only power cycle will
572 * restore DSS functionality. I have no idea why this happens. 664 * restore DSS functionality. I have no idea why this happens.
573 * And we have to wait _before_ resetting the DSS, but after 665 * And we have to wait _before_ resetting the DSS, but after
574 * enabling clocks. 666 * enabling clocks.
575 */ 667 */
576 msleep(50); 668 msleep(50);
577 669
578 _omap_dss_reset(); 670 _omap_dss_reset();
579 }
580 671
581 /* autoidle */ 672 /* autoidle */
582 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); 673 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
@@ -589,29 +680,30 @@ int dss_init(bool skip_init)
589 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 680 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
590 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 681 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
591#endif 682#endif
592
593 r = request_irq(INT_24XX_DSS_IRQ,
594 cpu_is_omap24xx()
595 ? dss_irq_handler_omap2
596 : dss_irq_handler_omap3,
597 0, "OMAP DSS", NULL);
598
599 if (r < 0) {
600 DSSERR("omap2 dss: request_irq failed\n");
601 goto fail1;
602 }
603
604 if (cpu_is_omap34xx()) { 683 if (cpu_is_omap34xx()) {
605 dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 684 dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
606 if (IS_ERR(dss.dpll4_m4_ck)) { 685 if (IS_ERR(dpll4_m4_ck)) {
607 DSSERR("Failed to get dpll4_m4_ck\n"); 686 DSSERR("Failed to get dpll4_m4_ck\n");
608 r = PTR_ERR(dss.dpll4_m4_ck); 687 r = PTR_ERR(dpll4_m4_ck);
609 goto fail2; 688 goto fail1;
610 } 689 }
690 } else if (cpu_is_omap44xx()) {
691 dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
692 if (IS_ERR(dpll4_m4_ck)) {
693 DSSERR("Failed to get dpll4_m4_ck\n");
694 r = PTR_ERR(dpll4_m4_ck);
695 goto fail1;
696 }
697 } else { /* omap24xx */
698 dpll4_m4_ck = NULL;
611 } 699 }
612 700
613 dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 701 dss.dpll4_m4_ck = dpll4_m4_ck;
614 dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 702
703 dss.dsi_clk_source = DSS_CLK_SRC_FCK;
704 dss.dispc_clk_source = DSS_CLK_SRC_FCK;
705 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
706 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
615 707
616 dss_save_context(); 708 dss_save_context();
617 709
@@ -621,21 +713,416 @@ int dss_init(bool skip_init)
621 713
622 return 0; 714 return 0;
623 715
624fail2:
625 free_irq(INT_24XX_DSS_IRQ, NULL);
626fail1: 716fail1:
627 iounmap(dss.base); 717 iounmap(dss.base);
628fail0: 718fail0:
629 return r; 719 return r;
630} 720}
631 721
632void dss_exit(void) 722static void dss_exit(void)
633{ 723{
634 if (cpu_is_omap34xx()) 724 if (dss.dpll4_m4_ck)
635 clk_put(dss.dpll4_m4_ck); 725 clk_put(dss.dpll4_m4_ck);
636 726
637 free_irq(INT_24XX_DSS_IRQ, NULL);
638
639 iounmap(dss.base); 727 iounmap(dss.base);
640} 728}
641 729
730/* CONTEXT */
731static int dss_get_ctx_id(void)
732{
733 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
734 int r;
735
736 if (!pdata->board_data->get_last_off_on_transaction_id)
737 return 0;
738 r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
739 if (r < 0) {
740 dev_err(&dss.pdev->dev, "getting transaction ID failed, "
741 "will force context restore\n");
742 r = -1;
743 }
744 return r;
745}
746
747int dss_need_ctx_restore(void)
748{
749 int id = dss_get_ctx_id();
750
751 if (id < 0 || id != dss.ctx_id) {
752 DSSDBG("ctx id %d -> id %d\n",
753 dss.ctx_id, id);
754 dss.ctx_id = id;
755 return 1;
756 } else {
757 return 0;
758 }
759}
760
761static void save_all_ctx(void)
762{
763 DSSDBG("save context\n");
764
765 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
766
767 dss_save_context();
768 dispc_save_context();
769#ifdef CONFIG_OMAP2_DSS_DSI
770 dsi_save_context();
771#endif
772
773 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
774}
775
776static void restore_all_ctx(void)
777{
778 DSSDBG("restore context\n");
779
780 dss_clk_enable_all_no_ctx();
781
782 dss_restore_context();
783 dispc_restore_context();
784#ifdef CONFIG_OMAP2_DSS_DSI
785 dsi_restore_context();
786#endif
787
788 dss_clk_disable_all_no_ctx();
789}
790
791static int dss_get_clock(struct clk **clock, const char *clk_name)
792{
793 struct clk *clk;
794
795 clk = clk_get(&dss.pdev->dev, clk_name);
796
797 if (IS_ERR(clk)) {
798 DSSERR("can't get clock %s", clk_name);
799 return PTR_ERR(clk);
800 }
801
802 *clock = clk;
803
804 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
805
806 return 0;
807}
808
809static int dss_get_clocks(void)
810{
811 int r;
812 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
813
814 dss.dss_ick = NULL;
815 dss.dss_fck = NULL;
816 dss.dss_sys_clk = NULL;
817 dss.dss_tv_fck = NULL;
818 dss.dss_video_fck = NULL;
819
820 r = dss_get_clock(&dss.dss_ick, "ick");
821 if (r)
822 goto err;
823
824 r = dss_get_clock(&dss.dss_fck, "fck");
825 if (r)
826 goto err;
827
828 if (!pdata->opt_clock_available) {
829 r = -ENODEV;
830 goto err;
831 }
832
833 if (pdata->opt_clock_available("sys_clk")) {
834 r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
835 if (r)
836 goto err;
837 }
838
839 if (pdata->opt_clock_available("tv_clk")) {
840 r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
841 if (r)
842 goto err;
843 }
844
845 if (pdata->opt_clock_available("video_clk")) {
846 r = dss_get_clock(&dss.dss_video_fck, "video_clk");
847 if (r)
848 goto err;
849 }
850
851 return 0;
852
853err:
854 if (dss.dss_ick)
855 clk_put(dss.dss_ick);
856 if (dss.dss_fck)
857 clk_put(dss.dss_fck);
858 if (dss.dss_sys_clk)
859 clk_put(dss.dss_sys_clk);
860 if (dss.dss_tv_fck)
861 clk_put(dss.dss_tv_fck);
862 if (dss.dss_video_fck)
863 clk_put(dss.dss_video_fck);
864
865 return r;
866}
867
868static void dss_put_clocks(void)
869{
870 if (dss.dss_video_fck)
871 clk_put(dss.dss_video_fck);
872 if (dss.dss_tv_fck)
873 clk_put(dss.dss_tv_fck);
874 if (dss.dss_sys_clk)
875 clk_put(dss.dss_sys_clk);
876 clk_put(dss.dss_fck);
877 clk_put(dss.dss_ick);
878}
879
880unsigned long dss_clk_get_rate(enum dss_clock clk)
881{
882 switch (clk) {
883 case DSS_CLK_ICK:
884 return clk_get_rate(dss.dss_ick);
885 case DSS_CLK_FCK:
886 return clk_get_rate(dss.dss_fck);
887 case DSS_CLK_SYSCK:
888 return clk_get_rate(dss.dss_sys_clk);
889 case DSS_CLK_TVFCK:
890 return clk_get_rate(dss.dss_tv_fck);
891 case DSS_CLK_VIDFCK:
892 return clk_get_rate(dss.dss_video_fck);
893 }
894
895 BUG();
896 return 0;
897}
898
899static unsigned count_clk_bits(enum dss_clock clks)
900{
901 unsigned num_clks = 0;
902
903 if (clks & DSS_CLK_ICK)
904 ++num_clks;
905 if (clks & DSS_CLK_FCK)
906 ++num_clks;
907 if (clks & DSS_CLK_SYSCK)
908 ++num_clks;
909 if (clks & DSS_CLK_TVFCK)
910 ++num_clks;
911 if (clks & DSS_CLK_VIDFCK)
912 ++num_clks;
913
914 return num_clks;
915}
916
917static void dss_clk_enable_no_ctx(enum dss_clock clks)
918{
919 unsigned num_clks = count_clk_bits(clks);
920
921 if (clks & DSS_CLK_ICK)
922 clk_enable(dss.dss_ick);
923 if (clks & DSS_CLK_FCK)
924 clk_enable(dss.dss_fck);
925 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
926 clk_enable(dss.dss_sys_clk);
927 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
928 clk_enable(dss.dss_tv_fck);
929 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
930 clk_enable(dss.dss_video_fck);
931
932 dss.num_clks_enabled += num_clks;
933}
934
935void dss_clk_enable(enum dss_clock clks)
936{
937 bool check_ctx = dss.num_clks_enabled == 0;
938
939 dss_clk_enable_no_ctx(clks);
940
941 /*
942 * HACK: On omap4 the registers may not be accessible right after
943 * enabling the clocks. At some point this will be handled by
944 * pm_runtime, but for the time begin this should make things work.
945 */
946 if (cpu_is_omap44xx() && check_ctx)
947 udelay(10);
948
949 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
950 restore_all_ctx();
951}
952
953static void dss_clk_disable_no_ctx(enum dss_clock clks)
954{
955 unsigned num_clks = count_clk_bits(clks);
956
957 if (clks & DSS_CLK_ICK)
958 clk_disable(dss.dss_ick);
959 if (clks & DSS_CLK_FCK)
960 clk_disable(dss.dss_fck);
961 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
962 clk_disable(dss.dss_sys_clk);
963 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
964 clk_disable(dss.dss_tv_fck);
965 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
966 clk_disable(dss.dss_video_fck);
967
968 dss.num_clks_enabled -= num_clks;
969}
970
971void dss_clk_disable(enum dss_clock clks)
972{
973 if (cpu_is_omap34xx()) {
974 unsigned num_clks = count_clk_bits(clks);
975
976 BUG_ON(dss.num_clks_enabled < num_clks);
977
978 if (dss.num_clks_enabled == num_clks)
979 save_all_ctx();
980 }
981
982 dss_clk_disable_no_ctx(clks);
983}
984
985static void dss_clk_enable_all_no_ctx(void)
986{
987 enum dss_clock clks;
988
989 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
990 if (cpu_is_omap34xx())
991 clks |= DSS_CLK_VIDFCK;
992 dss_clk_enable_no_ctx(clks);
993}
994
995static void dss_clk_disable_all_no_ctx(void)
996{
997 enum dss_clock clks;
998
999 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
1000 if (cpu_is_omap34xx())
1001 clks |= DSS_CLK_VIDFCK;
1002 dss_clk_disable_no_ctx(clks);
1003}
1004
1005#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1006/* CLOCKS */
1007static void core_dump_clocks(struct seq_file *s)
1008{
1009 int i;
1010 struct clk *clocks[5] = {
1011 dss.dss_ick,
1012 dss.dss_fck,
1013 dss.dss_sys_clk,
1014 dss.dss_tv_fck,
1015 dss.dss_video_fck
1016 };
1017
1018 seq_printf(s, "- CORE -\n");
1019
1020 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
1021
1022 for (i = 0; i < 5; i++) {
1023 if (!clocks[i])
1024 continue;
1025 seq_printf(s, "%-15s\t%lu\t%d\n",
1026 clocks[i]->name,
1027 clk_get_rate(clocks[i]),
1028 clocks[i]->usecount);
1029 }
1030}
1031#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
1032
1033/* DEBUGFS */
1034#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1035void dss_debug_dump_clocks(struct seq_file *s)
1036{
1037 core_dump_clocks(s);
1038 dss_dump_clocks(s);
1039 dispc_dump_clocks(s);
1040#ifdef CONFIG_OMAP2_DSS_DSI
1041 dsi_dump_clocks(s);
1042#endif
1043}
1044#endif
1045
1046
1047/* DSS HW IP initialisation */
1048static int omap_dsshw_probe(struct platform_device *pdev)
1049{
1050 int r;
1051
1052 dss.pdev = pdev;
1053
1054 r = dss_get_clocks();
1055 if (r)
1056 goto err_clocks;
1057
1058 dss_clk_enable_all_no_ctx();
1059
1060 dss.ctx_id = dss_get_ctx_id();
1061 DSSDBG("initial ctx id %u\n", dss.ctx_id);
1062
1063 r = dss_init();
1064 if (r) {
1065 DSSERR("Failed to initialize DSS\n");
1066 goto err_dss;
1067 }
1068
1069 r = dpi_init();
1070 if (r) {
1071 DSSERR("Failed to initialize DPI\n");
1072 goto err_dpi;
1073 }
1074
1075 r = sdi_init();
1076 if (r) {
1077 DSSERR("Failed to initialize SDI\n");
1078 goto err_sdi;
1079 }
1080
1081 dss_clk_disable_all_no_ctx();
1082 return 0;
1083err_sdi:
1084 dpi_exit();
1085err_dpi:
1086 dss_exit();
1087err_dss:
1088 dss_clk_disable_all_no_ctx();
1089 dss_put_clocks();
1090err_clocks:
1091 return r;
1092}
1093
1094static int omap_dsshw_remove(struct platform_device *pdev)
1095{
1096
1097 dss_exit();
1098
1099 /*
1100 * As part of hwmod changes, DSS is not the only controller of dss
1101 * clocks; hwmod framework itself will also enable clocks during hwmod
1102 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
1103 * need to disable clocks if their usecounts > 1.
1104 */
1105 WARN_ON(dss.num_clks_enabled > 0);
1106
1107 dss_put_clocks();
1108 return 0;
1109}
1110
1111static struct platform_driver omap_dsshw_driver = {
1112 .probe = omap_dsshw_probe,
1113 .remove = omap_dsshw_remove,
1114 .driver = {
1115 .name = "omapdss_dss",
1116 .owner = THIS_MODULE,
1117 },
1118};
1119
1120int dss_init_platform_driver(void)
1121{
1122 return platform_driver_register(&omap_dsshw_driver);
1123}
1124
1125void dss_uninit_platform_driver(void)
1126{
1127 return platform_driver_unregister(&omap_dsshw_driver);
1128}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b394951120ac..c2f582bb19c0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,8 +97,6 @@ extern unsigned int dss_debug;
97#define FLD_MOD(orig, val, start, end) \ 97#define FLD_MOD(orig, val, start, end) \
98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
99 99
100#define DISPC_MAX_FCK 173000000
101
102enum omap_burst_size { 100enum omap_burst_size {
103 OMAP_DSS_BURST_4x32 = 0, 101 OMAP_DSS_BURST_4x32 = 0,
104 OMAP_DSS_BURST_8x32 = 1, 102 OMAP_DSS_BURST_8x32 = 1,
@@ -112,17 +110,25 @@ enum omap_parallel_interface_mode {
112}; 110};
113 111
114enum dss_clock { 112enum dss_clock {
115 DSS_CLK_ICK = 1 << 0, 113 DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
116 DSS_CLK_FCK1 = 1 << 1, 114 DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
117 DSS_CLK_FCK2 = 1 << 2, 115 DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
118 DSS_CLK_54M = 1 << 3, 116 DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
119 DSS_CLK_96M = 1 << 4, 117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
120}; 118};
121 119
122enum dss_clk_source { 120enum dss_clk_source {
123 DSS_SRC_DSI1_PLL_FCLK, 121 DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
124 DSS_SRC_DSI2_PLL_FCLK, 122 * OMAP4: PLL1_CLK1 */
125 DSS_SRC_DSS1_ALWON_FCLK, 123 DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
124 * OMAP4: PLL1_CLK2 */
125 DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
126 * OMAP4: DSS_FCLK */
127};
128
129enum dss_hdmi_venc_clk_source_select {
130 DSS_VENC_TV_CLK = 0,
131 DSS_HDMI_M_PCLK = 1,
126}; 132};
127 133
128struct dss_clock_info { 134struct dss_clock_info {
@@ -148,36 +154,42 @@ struct dsi_clock_info {
148 unsigned long fint; 154 unsigned long fint;
149 unsigned long clkin4ddr; 155 unsigned long clkin4ddr;
150 unsigned long clkin; 156 unsigned long clkin;
151 unsigned long dsi1_pll_fclk; 157 unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
152 unsigned long dsi2_pll_fclk; 158 * OMAP4: PLLx_CLK1 */
153 159 unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
160 * OMAP4: PLLx_CLK2 */
154 unsigned long lp_clk; 161 unsigned long lp_clk;
155 162
156 /* dividers */ 163 /* dividers */
157 u16 regn; 164 u16 regn;
158 u16 regm; 165 u16 regm;
159 u16 regm3; 166 u16 regm_dispc; /* OMAP3: REGM3
160 u16 regm4; 167 * OMAP4: REGM4 */
161 168 u16 regm_dsi; /* OMAP3: REGM4
169 * OMAP4: REGM5 */
162 u16 lp_clk_div; 170 u16 lp_clk_div;
163 171
164 u8 highfreq; 172 u8 highfreq;
165 bool use_dss2_fck; 173 bool use_sys_clk;
174};
175
176/* HDMI PLL structure */
177struct hdmi_pll_info {
178 u16 regn;
179 u16 regm;
180 u32 regmf;
181 u16 regm2;
182 u16 regsd;
183 u16 dcofreq;
166}; 184};
167 185
168struct seq_file; 186struct seq_file;
169struct platform_device; 187struct platform_device;
170 188
171/* core */ 189/* core */
172void dss_clk_enable(enum dss_clock clks);
173void dss_clk_disable(enum dss_clock clks);
174unsigned long dss_clk_get_rate(enum dss_clock clk);
175int dss_need_ctx_restore(void);
176void dss_dump_clocks(struct seq_file *s);
177struct bus_type *dss_get_bus(void); 190struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void); 191struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void); 192struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
181 193
182/* display */ 194/* display */
183int dss_suspend_all_devices(void); 195int dss_suspend_all_devices(void);
@@ -214,13 +226,23 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
214void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 226void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
215 227
216/* DSS */ 228/* DSS */
217int dss_init(bool skip_init); 229int dss_init_platform_driver(void);
218void dss_exit(void); 230void dss_uninit_platform_driver(void);
219 231
232void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
220void dss_save_context(void); 233void dss_save_context(void);
221void dss_restore_context(void); 234void dss_restore_context(void);
235void dss_clk_enable(enum dss_clock clks);
236void dss_clk_disable(enum dss_clock clks);
237unsigned long dss_clk_get_rate(enum dss_clock clk);
238int dss_need_ctx_restore(void);
239const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src);
240void dss_dump_clocks(struct seq_file *s);
222 241
223void dss_dump_regs(struct seq_file *s); 242void dss_dump_regs(struct seq_file *s);
243#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
244void dss_debug_dump_clocks(struct seq_file *s);
245#endif
224 246
225void dss_sdi_init(u8 datapairs); 247void dss_sdi_init(u8 datapairs);
226int dss_sdi_enable(void); 248int dss_sdi_enable(void);
@@ -228,8 +250,11 @@ void dss_sdi_disable(void);
228 250
229void dss_select_dispc_clk_source(enum dss_clk_source clk_src); 251void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
230void dss_select_dsi_clk_source(enum dss_clk_source clk_src); 252void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
253void dss_select_lcd_clk_source(enum omap_channel channel,
254 enum dss_clk_source clk_src);
231enum dss_clk_source dss_get_dispc_clk_source(void); 255enum dss_clk_source dss_get_dispc_clk_source(void);
232enum dss_clk_source dss_get_dsi_clk_source(void); 256enum dss_clk_source dss_get_dsi_clk_source(void);
257enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
233 258
234void dss_set_venc_output(enum omap_dss_venc_type type); 259void dss_set_venc_output(enum omap_dss_venc_type type);
235void dss_set_dac_pwrdn_bgz(bool enable); 260void dss_set_dac_pwrdn_bgz(bool enable);
@@ -244,11 +269,11 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
244 269
245/* SDI */ 270/* SDI */
246#ifdef CONFIG_OMAP2_DSS_SDI 271#ifdef CONFIG_OMAP2_DSS_SDI
247int sdi_init(bool skip_init); 272int sdi_init(void);
248void sdi_exit(void); 273void sdi_exit(void);
249int sdi_init_display(struct omap_dss_device *display); 274int sdi_init_display(struct omap_dss_device *display);
250#else 275#else
251static inline int sdi_init(bool skip_init) 276static inline int sdi_init(void)
252{ 277{
253 return 0; 278 return 0;
254} 279}
@@ -259,8 +284,8 @@ static inline void sdi_exit(void)
259 284
260/* DSI */ 285/* DSI */
261#ifdef CONFIG_OMAP2_DSS_DSI 286#ifdef CONFIG_OMAP2_DSS_DSI
262int dsi_init(struct platform_device *pdev); 287int dsi_init_platform_driver(void);
263void dsi_exit(void); 288void dsi_uninit_platform_driver(void);
264 289
265void dsi_dump_clocks(struct seq_file *s); 290void dsi_dump_clocks(struct seq_file *s);
266void dsi_dump_irqs(struct seq_file *s); 291void dsi_dump_irqs(struct seq_file *s);
@@ -271,7 +296,7 @@ void dsi_restore_context(void);
271 296
272int dsi_init_display(struct omap_dss_device *display); 297int dsi_init_display(struct omap_dss_device *display);
273void dsi_irq_handler(void); 298void dsi_irq_handler(void);
274unsigned long dsi_get_dsi1_pll_rate(void); 299unsigned long dsi_get_pll_hsdiv_dispc_rate(void);
275int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); 300int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
276int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 301int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
277 struct dsi_clock_info *cinfo, 302 struct dsi_clock_info *cinfo,
@@ -282,31 +307,36 @@ void dsi_pll_uninit(void);
282void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 307void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
283 u32 fifo_size, enum omap_burst_size *burst_size, 308 u32 fifo_size, enum omap_burst_size *burst_size,
284 u32 *fifo_low, u32 *fifo_high); 309 u32 *fifo_low, u32 *fifo_high);
285void dsi_wait_dsi1_pll_active(void); 310void dsi_wait_pll_hsdiv_dispc_active(void);
286void dsi_wait_dsi2_pll_active(void); 311void dsi_wait_pll_hsdiv_dsi_active(void);
287#else 312#else
288static inline int dsi_init(struct platform_device *pdev) 313static inline int dsi_init_platform_driver(void)
289{ 314{
290 return 0; 315 return 0;
291} 316}
292static inline void dsi_exit(void) 317static inline void dsi_uninit_platform_driver(void)
293{ 318{
294} 319}
295static inline void dsi_wait_dsi1_pll_active(void) 320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
296{ 321{
322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
323 return 0;
297} 324}
298static inline void dsi_wait_dsi2_pll_active(void) 325static inline void dsi_wait_pll_hsdiv_dispc_active(void)
326{
327}
328static inline void dsi_wait_pll_hsdiv_dsi_active(void)
299{ 329{
300} 330}
301#endif 331#endif
302 332
303/* DPI */ 333/* DPI */
304#ifdef CONFIG_OMAP2_DSS_DPI 334#ifdef CONFIG_OMAP2_DSS_DPI
305int dpi_init(struct platform_device *pdev); 335int dpi_init(void);
306void dpi_exit(void); 336void dpi_exit(void);
307int dpi_init_display(struct omap_dss_device *dssdev); 337int dpi_init_display(struct omap_dss_device *dssdev);
308#else 338#else
309static inline int dpi_init(struct platform_device *pdev) 339static inline int dpi_init(void)
310{ 340{
311 return 0; 341 return 0;
312} 342}
@@ -316,8 +346,8 @@ static inline void dpi_exit(void)
316#endif 346#endif
317 347
318/* DISPC */ 348/* DISPC */
319int dispc_init(void); 349int dispc_init_platform_driver(void);
320void dispc_exit(void); 350void dispc_uninit_platform_driver(void);
321void dispc_dump_clocks(struct seq_file *s); 351void dispc_dump_clocks(struct seq_file *s);
322void dispc_dump_irqs(struct seq_file *s); 352void dispc_dump_irqs(struct seq_file *s);
323void dispc_dump_regs(struct seq_file *s); 353void dispc_dump_regs(struct seq_file *s);
@@ -350,6 +380,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
350void dispc_set_channel_out(enum omap_plane plane, 380void dispc_set_channel_out(enum omap_plane plane,
351 enum omap_channel channel_out); 381 enum omap_channel channel_out);
352 382
383void dispc_enable_gamma_table(bool enable);
353int dispc_setup_plane(enum omap_plane plane, 384int dispc_setup_plane(enum omap_plane plane,
354 u32 paddr, u16 screen_width, 385 u32 paddr, u16 screen_width,
355 u16 pos_x, u16 pos_y, 386 u16 pos_x, u16 pos_y,
@@ -409,24 +440,50 @@ int dispc_get_clock_div(enum omap_channel channel,
409 440
410/* VENC */ 441/* VENC */
411#ifdef CONFIG_OMAP2_DSS_VENC 442#ifdef CONFIG_OMAP2_DSS_VENC
412int venc_init(struct platform_device *pdev); 443int venc_init_platform_driver(void);
413void venc_exit(void); 444void venc_uninit_platform_driver(void);
414void venc_dump_regs(struct seq_file *s); 445void venc_dump_regs(struct seq_file *s);
415int venc_init_display(struct omap_dss_device *display); 446int venc_init_display(struct omap_dss_device *display);
416#else 447#else
417static inline int venc_init(struct platform_device *pdev) 448static inline int venc_init_platform_driver(void)
449{
450 return 0;
451}
452static inline void venc_uninit_platform_driver(void)
453{
454}
455#endif
456
457/* HDMI */
458#ifdef CONFIG_OMAP4_DSS_HDMI
459int hdmi_init_platform_driver(void);
460void hdmi_uninit_platform_driver(void);
461int hdmi_init_display(struct omap_dss_device *dssdev);
462#else
463static inline int hdmi_init_display(struct omap_dss_device *dssdev)
464{
465 return 0;
466}
467static inline int hdmi_init_platform_driver(void)
418{ 468{
419 return 0; 469 return 0;
420} 470}
421static inline void venc_exit(void) 471static inline void hdmi_uninit_platform_driver(void)
422{ 472{
423} 473}
424#endif 474#endif
475int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
476void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
477void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
478int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
479 struct omap_video_timings *timings);
480int hdmi_panel_init(void);
481void hdmi_panel_exit(void);
425 482
426/* RFBI */ 483/* RFBI */
427#ifdef CONFIG_OMAP2_DSS_RFBI 484#ifdef CONFIG_OMAP2_DSS_RFBI
428int rfbi_init(void); 485int rfbi_init_platform_driver(void);
429void rfbi_exit(void); 486void rfbi_uninit_platform_driver(void);
430void rfbi_dump_regs(struct seq_file *s); 487void rfbi_dump_regs(struct seq_file *s);
431 488
432int rfbi_configure(int rfbi_module, int bpp, int lines); 489int rfbi_configure(int rfbi_module, int bpp, int lines);
@@ -437,11 +494,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
437unsigned long rfbi_get_max_tx_rate(void); 494unsigned long rfbi_get_max_tx_rate(void);
438int rfbi_init_display(struct omap_dss_device *display); 495int rfbi_init_display(struct omap_dss_device *display);
439#else 496#else
440static inline int rfbi_init(void) 497static inline int rfbi_init_platform_driver(void)
441{ 498{
442 return 0; 499 return 0;
443} 500}
444static inline void rfbi_exit(void) 501static inline void rfbi_uninit_platform_driver(void)
445{ 502{
446} 503}
447#endif 504#endif
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index cf3ef696e141..aa1622241d0d 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -25,14 +25,18 @@
25#include <plat/display.h> 25#include <plat/display.h>
26#include <plat/cpu.h> 26#include <plat/cpu.h>
27 27
28#include "dss.h"
28#include "dss_features.h" 29#include "dss_features.h"
29 30
30/* Defines a generic omap register field */ 31/* Defines a generic omap register field */
31struct dss_reg_field { 32struct dss_reg_field {
32 enum dss_feat_reg_field id;
33 u8 start, end; 33 u8 start, end;
34}; 34};
35 35
36struct dss_param_range {
37 int min, max;
38};
39
36struct omap_dss_features { 40struct omap_dss_features {
37 const struct dss_reg_field *reg_fields; 41 const struct dss_reg_field *reg_fields;
38 const int num_reg_fields; 42 const int num_reg_fields;
@@ -43,29 +47,68 @@ struct omap_dss_features {
43 const int num_ovls; 47 const int num_ovls;
44 const enum omap_display_type *supported_displays; 48 const enum omap_display_type *supported_displays;
45 const enum omap_color_mode *supported_color_modes; 49 const enum omap_color_mode *supported_color_modes;
50 const char * const *clksrc_names;
51 const struct dss_param_range *dss_params;
46}; 52};
47 53
48/* This struct is assigned to one of the below during initialization */ 54/* This struct is assigned to one of the below during initialization */
49static struct omap_dss_features *omap_current_dss_features; 55static struct omap_dss_features *omap_current_dss_features;
50 56
51static const struct dss_reg_field omap2_dss_reg_fields[] = { 57static const struct dss_reg_field omap2_dss_reg_fields[] = {
52 { FEAT_REG_FIRHINC, 11, 0 }, 58 [FEAT_REG_FIRHINC] = { 11, 0 },
53 { FEAT_REG_FIRVINC, 27, 16 }, 59 [FEAT_REG_FIRVINC] = { 27, 16 },
54 { FEAT_REG_FIFOLOWTHRESHOLD, 8, 0 }, 60 [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
55 { FEAT_REG_FIFOHIGHTHRESHOLD, 24, 16 }, 61 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
56 { FEAT_REG_FIFOSIZE, 8, 0 }, 62 [FEAT_REG_FIFOSIZE] = { 8, 0 },
63 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
64 [FEAT_REG_VERTICALACCU] = { 25, 16 },
65 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
66 [FEAT_REG_DSIPLL_REGN] = { 0, 0 },
67 [FEAT_REG_DSIPLL_REGM] = { 0, 0 },
68 [FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
69 [FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
57}; 70};
58 71
59static const struct dss_reg_field omap3_dss_reg_fields[] = { 72static const struct dss_reg_field omap3_dss_reg_fields[] = {
60 { FEAT_REG_FIRHINC, 12, 0 }, 73 [FEAT_REG_FIRHINC] = { 12, 0 },
61 { FEAT_REG_FIRVINC, 28, 16 }, 74 [FEAT_REG_FIRVINC] = { 28, 16 },
62 { FEAT_REG_FIFOLOWTHRESHOLD, 11, 0 }, 75 [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
63 { FEAT_REG_FIFOHIGHTHRESHOLD, 27, 16 }, 76 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
64 { FEAT_REG_FIFOSIZE, 10, 0 }, 77 [FEAT_REG_FIFOSIZE] = { 10, 0 },
78 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
79 [FEAT_REG_VERTICALACCU] = { 25, 16 },
80 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
81 [FEAT_REG_DSIPLL_REGN] = { 7, 1 },
82 [FEAT_REG_DSIPLL_REGM] = { 18, 8 },
83 [FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
84 [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
85};
86
87static const struct dss_reg_field omap4_dss_reg_fields[] = {
88 [FEAT_REG_FIRHINC] = { 12, 0 },
89 [FEAT_REG_FIRVINC] = { 28, 16 },
90 [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
91 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
92 [FEAT_REG_FIFOSIZE] = { 15, 0 },
93 [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
94 [FEAT_REG_VERTICALACCU] = { 26, 16 },
95 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
96 [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
97 [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
98 [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
99 [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
65}; 100};
66 101
67static const enum omap_display_type omap2_dss_supported_displays[] = { 102static const enum omap_display_type omap2_dss_supported_displays[] = {
68 /* OMAP_DSS_CHANNEL_LCD */ 103 /* OMAP_DSS_CHANNEL_LCD */
104 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
105
106 /* OMAP_DSS_CHANNEL_DIGIT */
107 OMAP_DISPLAY_TYPE_VENC,
108};
109
110static const enum omap_display_type omap3430_dss_supported_displays[] = {
111 /* OMAP_DSS_CHANNEL_LCD */
69 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 112 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
70 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 113 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
71 114
@@ -73,10 +116,10 @@ static const enum omap_display_type omap2_dss_supported_displays[] = {
73 OMAP_DISPLAY_TYPE_VENC, 116 OMAP_DISPLAY_TYPE_VENC,
74}; 117};
75 118
76static const enum omap_display_type omap3_dss_supported_displays[] = { 119static const enum omap_display_type omap3630_dss_supported_displays[] = {
77 /* OMAP_DSS_CHANNEL_LCD */ 120 /* OMAP_DSS_CHANNEL_LCD */
78 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 121 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
79 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 122 OMAP_DISPLAY_TYPE_DSI,
80 123
81 /* OMAP_DSS_CHANNEL_DIGIT */ 124 /* OMAP_DSS_CHANNEL_DIGIT */
82 OMAP_DISPLAY_TYPE_VENC, 125 OMAP_DISPLAY_TYPE_VENC,
@@ -87,7 +130,7 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
87 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, 130 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
88 131
89 /* OMAP_DSS_CHANNEL_DIGIT */ 132 /* OMAP_DSS_CHANNEL_DIGIT */
90 OMAP_DISPLAY_TYPE_VENC, 133 OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
91 134
92 /* OMAP_DSS_CHANNEL_LCD2 */ 135 /* OMAP_DSS_CHANNEL_LCD2 */
93 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 136 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
@@ -134,6 +177,54 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
134 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, 177 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
135}; 178};
136 179
180static const char * const omap2_dss_clk_source_names[] = {
181 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
182 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
183 [DSS_CLK_SRC_FCK] = "DSS_FCLK1",
184};
185
186static const char * const omap3_dss_clk_source_names[] = {
187 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
188 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
189 [DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
190};
191
192static const char * const omap4_dss_clk_source_names[] = {
193 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
194 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
195 [DSS_CLK_SRC_FCK] = "DSS_FCLK",
196};
197
198static const struct dss_param_range omap2_dss_param_range[] = {
199 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
200 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
201 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
202 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
203 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
204 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
205 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
206};
207
208static const struct dss_param_range omap3_dss_param_range[] = {
209 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
210 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
211 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
212 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
213 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
214 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
215 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
216};
217
218static const struct dss_param_range omap4_dss_param_range[] = {
219 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
220 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
221 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
222 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
223 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
224 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
225 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
226};
227
137/* OMAP2 DSS Features */ 228/* OMAP2 DSS Features */
138static struct omap_dss_features omap2_dss_features = { 229static struct omap_dss_features omap2_dss_features = {
139 .reg_fields = omap2_dss_reg_fields, 230 .reg_fields = omap2_dss_reg_fields,
@@ -141,12 +232,15 @@ static struct omap_dss_features omap2_dss_features = {
141 232
142 .has_feature = 233 .has_feature =
143 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | 234 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL |
144 FEAT_PCKFREEENABLE | FEAT_FUNCGATED, 235 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
236 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
145 237
146 .num_mgrs = 2, 238 .num_mgrs = 2,
147 .num_ovls = 3, 239 .num_ovls = 3,
148 .supported_displays = omap2_dss_supported_displays, 240 .supported_displays = omap2_dss_supported_displays,
149 .supported_color_modes = omap2_dss_supported_color_modes, 241 .supported_color_modes = omap2_dss_supported_color_modes,
242 .clksrc_names = omap2_dss_clk_source_names,
243 .dss_params = omap2_dss_param_range,
150}; 244};
151 245
152/* OMAP3 DSS Features */ 246/* OMAP3 DSS Features */
@@ -157,12 +251,15 @@ static struct omap_dss_features omap3430_dss_features = {
157 .has_feature = 251 .has_feature =
158 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 252 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
159 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 253 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
160 FEAT_FUNCGATED, 254 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
255 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF,
161 256
162 .num_mgrs = 2, 257 .num_mgrs = 2,
163 .num_ovls = 3, 258 .num_ovls = 3,
164 .supported_displays = omap3_dss_supported_displays, 259 .supported_displays = omap3430_dss_supported_displays,
165 .supported_color_modes = omap3_dss_supported_color_modes, 260 .supported_color_modes = omap3_dss_supported_color_modes,
261 .clksrc_names = omap3_dss_clk_source_names,
262 .dss_params = omap3_dss_param_range,
166}; 263};
167 264
168static struct omap_dss_features omap3630_dss_features = { 265static struct omap_dss_features omap3630_dss_features = {
@@ -172,27 +269,34 @@ static struct omap_dss_features omap3630_dss_features = {
172 .has_feature = 269 .has_feature =
173 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 270 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
174 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 271 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
175 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED, 272 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
273 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
274 FEAT_RESIZECONF,
176 275
177 .num_mgrs = 2, 276 .num_mgrs = 2,
178 .num_ovls = 3, 277 .num_ovls = 3,
179 .supported_displays = omap3_dss_supported_displays, 278 .supported_displays = omap3630_dss_supported_displays,
180 .supported_color_modes = omap3_dss_supported_color_modes, 279 .supported_color_modes = omap3_dss_supported_color_modes,
280 .clksrc_names = omap3_dss_clk_source_names,
281 .dss_params = omap3_dss_param_range,
181}; 282};
182 283
183/* OMAP4 DSS Features */ 284/* OMAP4 DSS Features */
184static struct omap_dss_features omap4_dss_features = { 285static struct omap_dss_features omap4_dss_features = {
185 .reg_fields = omap3_dss_reg_fields, 286 .reg_fields = omap4_dss_reg_fields,
186 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 287 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
187 288
188 .has_feature = 289 .has_feature =
189 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 290 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
190 FEAT_MGR_LCD2, 291 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
292 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
191 293
192 .num_mgrs = 3, 294 .num_mgrs = 3,
193 .num_ovls = 3, 295 .num_ovls = 3,
194 .supported_displays = omap4_dss_supported_displays, 296 .supported_displays = omap4_dss_supported_displays,
195 .supported_color_modes = omap3_dss_supported_color_modes, 297 .supported_color_modes = omap3_dss_supported_color_modes,
298 .clksrc_names = omap4_dss_clk_source_names,
299 .dss_params = omap4_dss_param_range,
196}; 300};
197 301
198/* Functions returning values related to a DSS feature */ 302/* Functions returning values related to a DSS feature */
@@ -206,6 +310,16 @@ int dss_feat_get_num_ovls(void)
206 return omap_current_dss_features->num_ovls; 310 return omap_current_dss_features->num_ovls;
207} 311}
208 312
313unsigned long dss_feat_get_param_min(enum dss_range_param param)
314{
315 return omap_current_dss_features->dss_params[param].min;
316}
317
318unsigned long dss_feat_get_param_max(enum dss_range_param param)
319{
320 return omap_current_dss_features->dss_params[param].max;
321}
322
209enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) 323enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
210{ 324{
211 return omap_current_dss_features->supported_displays[channel]; 325 return omap_current_dss_features->supported_displays[channel];
@@ -223,6 +337,11 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
223 color_mode; 337 color_mode;
224} 338}
225 339
340const char *dss_feat_get_clk_source_name(enum dss_clk_source id)
341{
342 return omap_current_dss_features->clksrc_names[id];
343}
344
226/* DSS has_feature check */ 345/* DSS has_feature check */
227bool dss_has_feature(enum dss_feat_id id) 346bool dss_has_feature(enum dss_feat_id id)
228{ 347{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index b9c70be92588..12e9c4ef0dec 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -22,6 +22,7 @@
22 22
23#define MAX_DSS_MANAGERS 3 23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 24#define MAX_DSS_OVERLAYS 3
25#define MAX_DSS_LCD_MANAGERS 2
25 26
26/* DSS has feature id */ 27/* DSS has feature id */
27enum dss_feat_id { 28enum dss_feat_id {
@@ -33,6 +34,12 @@ enum dss_feat_id {
33 FEAT_PCKFREEENABLE = 1 << 5, 34 FEAT_PCKFREEENABLE = 1 << 5,
34 FEAT_FUNCGATED = 1 << 6, 35 FEAT_FUNCGATED = 1 << 6,
35 FEAT_MGR_LCD2 = 1 << 7, 36 FEAT_MGR_LCD2 = 1 << 7,
37 FEAT_LINEBUFFERSPLIT = 1 << 8,
38 FEAT_ROWREPEATENABLE = 1 << 9,
39 FEAT_RESIZECONF = 1 << 10,
40 /* Independent core clk divider */
41 FEAT_CORE_CLK_DIV = 1 << 11,
42 FEAT_LCD_CLK_SRC = 1 << 12,
36}; 43};
37 44
38/* DSS register field id */ 45/* DSS register field id */
@@ -42,15 +49,35 @@ enum dss_feat_reg_field {
42 FEAT_REG_FIFOHIGHTHRESHOLD, 49 FEAT_REG_FIFOHIGHTHRESHOLD,
43 FEAT_REG_FIFOLOWTHRESHOLD, 50 FEAT_REG_FIFOLOWTHRESHOLD,
44 FEAT_REG_FIFOSIZE, 51 FEAT_REG_FIFOSIZE,
52 FEAT_REG_HORIZONTALACCU,
53 FEAT_REG_VERTICALACCU,
54 FEAT_REG_DISPC_CLK_SWITCH,
55 FEAT_REG_DSIPLL_REGN,
56 FEAT_REG_DSIPLL_REGM,
57 FEAT_REG_DSIPLL_REGM_DISPC,
58 FEAT_REG_DSIPLL_REGM_DSI,
59};
60
61enum dss_range_param {
62 FEAT_PARAM_DSS_FCK,
63 FEAT_PARAM_DSIPLL_REGN,
64 FEAT_PARAM_DSIPLL_REGM,
65 FEAT_PARAM_DSIPLL_REGM_DISPC,
66 FEAT_PARAM_DSIPLL_REGM_DSI,
67 FEAT_PARAM_DSIPLL_FINT,
68 FEAT_PARAM_DSIPLL_LPDIV,
45}; 69};
46 70
47/* DSS Feature Functions */ 71/* DSS Feature Functions */
48int dss_feat_get_num_mgrs(void); 72int dss_feat_get_num_mgrs(void);
49int dss_feat_get_num_ovls(void); 73int dss_feat_get_num_ovls(void);
74unsigned long dss_feat_get_param_min(enum dss_range_param param);
75unsigned long dss_feat_get_param_max(enum dss_range_param param);
50enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 76enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
51enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 77enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
52bool dss_feat_color_mode_supported(enum omap_plane plane, 78bool dss_feat_color_mode_supported(enum omap_plane plane,
53 enum omap_color_mode color_mode); 79 enum omap_color_mode color_mode);
80const char *dss_feat_get_clk_source_name(enum dss_clk_source id);
54 81
55bool dss_has_feature(enum dss_feat_id id); 82bool dss_has_feature(enum dss_feat_id id);
56void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 83void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
new file mode 100644
index 000000000000..a981def8099a
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -0,0 +1,1332 @@
1/*
2 * hdmi.c
3 *
4 * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6 * Authors: Yong Zhi
7 * Mythri pk <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#define DSS_SUBSYS_NAME "HDMI"
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/mutex.h>
30#include <linux/delay.h>
31#include <linux/string.h>
32#include <plat/display.h>
33
34#include "dss.h"
35#include "hdmi.h"
36
37static struct {
38 struct mutex lock;
39 struct omap_display_platform_data *pdata;
40 struct platform_device *pdev;
41 void __iomem *base_wp; /* HDMI wrapper */
42 int code;
43 int mode;
44 u8 edid[HDMI_EDID_MAX_LENGTH];
45 u8 edid_set;
46 bool custom_set;
47 struct hdmi_config cfg;
48} hdmi;
49
50/*
51 * Logic for the below structure :
52 * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
53 * There is a correspondence between CEA/VESA timing and code, please
54 * refer to section 6.3 in HDMI 1.3 specification for timing code.
55 *
56 * In the below structure, cea_vesa_timings corresponds to all OMAP4
57 * supported CEA and VESA timing values.code_cea corresponds to the CEA
58 * code, It is used to get the timing from cea_vesa_timing array.Similarly
59 * with code_vesa. Code_index is used for back mapping, that is once EDID
60 * is read from the TV, EDID is parsed to find the timing values and then
61 * map it to corresponding CEA or VESA index.
62 */
63
64static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
65 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
66 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
67 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
68 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
69 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
70 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
71 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
72 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
73 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
74 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
75 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
76 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
77 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
78 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
79 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
80 /* VESA From Here */
81 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
82 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
83 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
84 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
85 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
86 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
87 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
88 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
89 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
90 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
91 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
92 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
93 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
94 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
95 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
96 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
97 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
98 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
99 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
100};
101
102/*
103 * This is a static mapping array which maps the timing values
104 * with corresponding CEA / VESA code
105 */
106static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
107 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
108 /* <--15 CEA 17--> vesa*/
109 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
110 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
111};
112
113/*
114 * This is reverse static mapping which maps the CEA / VESA code
115 * to the corresponding timing values
116 */
117static const int code_cea[39] = {
118 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
119 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
120 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
121 11, 12, 14, -1, -1, 13, 13, 4, 4
122};
123
124static const int code_vesa[85] = {
125 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
126 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
127 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
128 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
129 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
130 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
131 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
132 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
133 -1, 27, 28, -1, 33};
134
135static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
136
137static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
138{
139 __raw_writel(val, hdmi.base_wp + idx.idx);
140}
141
142static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
143{
144 return __raw_readl(hdmi.base_wp + idx.idx);
145}
146
147static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
148 int b2, int b1, u32 val)
149{
150 u32 t = 0;
151 while (val != REG_GET(idx, b2, b1)) {
152 udelay(1);
153 if (t++ > 10000)
154 return !val;
155 }
156 return val;
157}
158
159int hdmi_init_display(struct omap_dss_device *dssdev)
160{
161 DSSDBG("init_display\n");
162
163 return 0;
164}
165
166static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
167 struct hdmi_pll_info *fmt, u16 sd)
168{
169 u32 r;
170
171 /* PLL start always use manual mode */
172 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
173
174 r = hdmi_read_reg(PLLCTRL_CFG1);
175 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
176 r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
177
178 hdmi_write_reg(PLLCTRL_CFG1, r);
179
180 r = hdmi_read_reg(PLLCTRL_CFG2);
181
182 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
183 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
184 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
185
186 if (dcofreq) {
187 /* divider programming for frequency beyond 1000Mhz */
188 REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
189 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
190 } else {
191 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
192 }
193
194 hdmi_write_reg(PLLCTRL_CFG2, r);
195
196 r = hdmi_read_reg(PLLCTRL_CFG4);
197 r = FLD_MOD(r, fmt->regm2, 24, 18);
198 r = FLD_MOD(r, fmt->regmf, 17, 0);
199
200 hdmi_write_reg(PLLCTRL_CFG4, r);
201
202 /* go now */
203 REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
204
205 /* wait for bit change */
206 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
207 DSSERR("PLL GO bit not set\n");
208 return -ETIMEDOUT;
209 }
210
211 /* Wait till the lock bit is set in PLL status */
212 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
213 DSSWARN("cannot lock PLL\n");
214 DSSWARN("CFG1 0x%x\n",
215 hdmi_read_reg(PLLCTRL_CFG1));
216 DSSWARN("CFG2 0x%x\n",
217 hdmi_read_reg(PLLCTRL_CFG2));
218 DSSWARN("CFG4 0x%x\n",
219 hdmi_read_reg(PLLCTRL_CFG4));
220 return -ETIMEDOUT;
221 }
222
223 DSSDBG("PLL locked!\n");
224
225 return 0;
226}
227
228/* PHY_PWR_CMD */
229static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
230{
231 /* Command for power control of HDMI PHY */
232 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
233
234 /* Status of the power control of HDMI PHY */
235 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
236 DSSERR("Failed to set PHY power mode to %d\n", val);
237 return -ETIMEDOUT;
238 }
239
240 return 0;
241}
242
243/* PLL_PWR_CMD */
244static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
245{
246 /* Command for power control of HDMI PLL */
247 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
248
249 /* wait till PHY_PWR_STATUS is set */
250 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
251 DSSERR("Failed to set PHY_PWR_STATUS\n");
252 return -ETIMEDOUT;
253 }
254
255 return 0;
256}
257
258static int hdmi_pll_reset(void)
259{
260 /* SYSRESET controlled by power FSM */
261 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
262
263 /* READ 0x0 reset is in progress */
264 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
265 DSSERR("Failed to sysreset PLL\n");
266 return -ETIMEDOUT;
267 }
268
269 return 0;
270}
271
272static int hdmi_phy_init(void)
273{
274 u16 r = 0;
275
276 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
277 if (r)
278 return r;
279
280 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
281 if (r)
282 return r;
283
284 /*
285 * Read address 0 in order to get the SCP reset done completed
286 * Dummy access performed to make sure reset is done
287 */
288 hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
289
290 /*
291 * Write to phy address 0 to configure the clock
292 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
293 */
294 REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
295
296 /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
297 hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
298
299 /* Setup max LDO voltage */
300 REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
301
302 /* Write to phy address 3 to change the polarity control */
303 REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
304
305 return 0;
306}
307
308static int hdmi_wait_softreset(void)
309{
310 /* reset W1 */
311 REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
312
313 /* wait till SOFTRESET == 0 */
314 if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
315 DSSERR("sysconfig reset failed\n");
316 return -ETIMEDOUT;
317 }
318
319 return 0;
320}
321
322static int hdmi_pll_program(struct hdmi_pll_info *fmt)
323{
324 u16 r = 0;
325 enum hdmi_clk_refsel refsel;
326
327 /* wait for wrapper reset */
328 r = hdmi_wait_softreset();
329 if (r)
330 return r;
331
332 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
333 if (r)
334 return r;
335
336 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
337 if (r)
338 return r;
339
340 r = hdmi_pll_reset();
341 if (r)
342 return r;
343
344 refsel = HDMI_REFSEL_SYSCLK;
345
346 r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
347 if (r)
348 return r;
349
350 return 0;
351}
352
353static void hdmi_phy_off(void)
354{
355 hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
356}
357
358static int hdmi_core_ddc_edid(u8 *pedid, int ext)
359{
360 u32 i, j;
361 char checksum = 0;
362 u32 offset = 0;
363
364 /* Turn on CLK for DDC */
365 REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
366
367 /*
368 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
369 * right shifted values( The behavior is not consistent and seen only
370 * with some TV's)
371 */
372 usleep_range(800, 1000);
373
374 if (!ext) {
375 /* Clk SCL Devices */
376 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
377
378 /* HDMI_CORE_DDC_STATUS_IN_PROG */
379 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
380 4, 4, 0) != 0) {
381 DSSERR("Failed to program DDC\n");
382 return -ETIMEDOUT;
383 }
384
385 /* Clear FIFO */
386 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
387
388 /* HDMI_CORE_DDC_STATUS_IN_PROG */
389 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
390 4, 4, 0) != 0) {
391 DSSERR("Failed to program DDC\n");
392 return -ETIMEDOUT;
393 }
394
395 } else {
396 if (ext % 2 != 0)
397 offset = 0x80;
398 }
399
400 /* Load Segment Address Register */
401 REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
402
403 /* Load Slave Address Register */
404 REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
405
406 /* Load Offset Address Register */
407 REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
408
409 /* Load Byte Count */
410 REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
411 REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
412
413 /* Set DDC_CMD */
414 if (ext)
415 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
416 else
417 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
418
419 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
420 if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
421 DSSWARN("I2C Bus Low?\n");
422 return -EIO;
423 }
424 /* HDMI_CORE_DDC_STATUS_NO_ACK */
425 if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
426 DSSWARN("I2C No Ack\n");
427 return -EIO;
428 }
429
430 i = ext * 128;
431 j = 0;
432 while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
433 (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
434 j < 128) {
435
436 if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
437 /* FIFO not empty */
438 pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
439 j++;
440 }
441 }
442
443 for (j = 0; j < 128; j++)
444 checksum += pedid[j];
445
446 if (checksum != 0) {
447 DSSERR("E-EDID checksum failed!!\n");
448 return -EIO;
449 }
450
451 return 0;
452}
453
454static int read_edid(u8 *pedid, u16 max_length)
455{
456 int r = 0, n = 0, i = 0;
457 int max_ext_blocks = (max_length / 128) - 1;
458
459 r = hdmi_core_ddc_edid(pedid, 0);
460 if (r) {
461 return r;
462 } else {
463 n = pedid[0x7e];
464
465 /*
466 * README: need to comply with max_length set by the caller.
467 * Better implementation should be to allocate necessary
468 * memory to store EDID according to nb_block field found
469 * in first block
470 */
471 if (n > max_ext_blocks)
472 n = max_ext_blocks;
473
474 for (i = 1; i <= n; i++) {
475 r = hdmi_core_ddc_edid(pedid, i);
476 if (r)
477 return r;
478 }
479 }
480 return 0;
481}
482
483static int get_timings_index(void)
484{
485 int code;
486
487 if (hdmi.mode == 0)
488 code = code_vesa[hdmi.code];
489 else
490 code = code_cea[hdmi.code];
491
492 if (code == -1) {
493 /* HDMI code 4 corresponds to 640 * 480 VGA */
494 hdmi.code = 4;
495 /* DVI mode 1 corresponds to HDMI 0 to DVI */
496 hdmi.mode = HDMI_DVI;
497
498 code = code_vesa[hdmi.code];
499 }
500 return code;
501}
502
503static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
504{
505 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
506 int timing_vsync = 0, timing_hsync = 0;
507 struct omap_video_timings temp;
508 struct hdmi_cm cm = {-1};
509 DSSDBG("hdmi_get_code\n");
510
511 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
512 temp = cea_vesa_timings[i].timings;
513 if ((temp.pixel_clock == timing->pixel_clock) &&
514 (temp.x_res == timing->x_res) &&
515 (temp.y_res == timing->y_res)) {
516
517 temp_hsync = temp.hfp + temp.hsw + temp.hbp;
518 timing_hsync = timing->hfp + timing->hsw + timing->hbp;
519 temp_vsync = temp.vfp + temp.vsw + temp.vbp;
520 timing_vsync = timing->vfp + timing->vsw + timing->vbp;
521
522 DSSDBG("temp_hsync = %d , temp_vsync = %d"
523 "timing_hsync = %d, timing_vsync = %d\n",
524 temp_hsync, temp_hsync,
525 timing_hsync, timing_vsync);
526
527 if ((temp_hsync == timing_hsync) &&
528 (temp_vsync == timing_vsync)) {
529 code = i;
530 cm.code = code_index[i];
531 if (code < 14)
532 cm.mode = HDMI_HDMI;
533 else
534 cm.mode = HDMI_DVI;
535 DSSDBG("Hdmi_code = %d mode = %d\n",
536 cm.code, cm.mode);
537 break;
538 }
539 }
540 }
541
542 return cm;
543}
544
545static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
546 struct omap_video_timings *timings)
547{
548 /* X and Y resolution */
549 timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
550 edid[current_descriptor_addrs + 2]);
551 timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
552 edid[current_descriptor_addrs + 5]);
553
554 timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
555 edid[current_descriptor_addrs]);
556
557 timings->pixel_clock = 10 * timings->pixel_clock;
558
559 /* HORIZONTAL FRONT PORCH */
560 timings->hfp = edid[current_descriptor_addrs + 8] |
561 ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
562 /* HORIZONTAL SYNC WIDTH */
563 timings->hsw = edid[current_descriptor_addrs + 9] |
564 ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
565 /* HORIZONTAL BACK PORCH */
566 timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
567 edid[current_descriptor_addrs + 3]) -
568 (timings->hfp + timings->hsw);
569 /* VERTICAL FRONT PORCH */
570 timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
571 ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
572 /* VERTICAL SYNC WIDTH */
573 timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
574 ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
575 /* VERTICAL BACK PORCH */
576 timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
577 edid[current_descriptor_addrs + 6]) -
578 (timings->vfp + timings->vsw);
579
580}
581
582/* Description : This function gets the resolution information from EDID */
583static void get_edid_timing_data(u8 *edid)
584{
585 u8 count;
586 u16 current_descriptor_addrs;
587 struct hdmi_cm cm;
588 struct omap_video_timings edid_timings;
589
590 /* search block 0, there are 4 DTDs arranged in priority order */
591 for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
592 current_descriptor_addrs =
593 EDID_DESCRIPTOR_BLOCK0_ADDRESS +
594 count * EDID_TIMING_DESCRIPTOR_SIZE;
595 get_horz_vert_timing_info(current_descriptor_addrs,
596 edid, &edid_timings);
597 cm = hdmi_get_code(&edid_timings);
598 DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
599 count, cm.code, cm.mode);
600 if (cm.code == -1) {
601 continue;
602 } else {
603 hdmi.code = cm.code;
604 hdmi.mode = cm.mode;
605 DSSDBG("code = %d , mode = %d\n",
606 hdmi.code, hdmi.mode);
607 return;
608 }
609 }
610 if (edid[0x7e] != 0x00) {
611 for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
612 count++) {
613 current_descriptor_addrs =
614 EDID_DESCRIPTOR_BLOCK1_ADDRESS +
615 count * EDID_TIMING_DESCRIPTOR_SIZE;
616 get_horz_vert_timing_info(current_descriptor_addrs,
617 edid, &edid_timings);
618 cm = hdmi_get_code(&edid_timings);
619 DSSDBG("Block1[%d] value matches code = %d, mode = %d",
620 count, cm.code, cm.mode);
621 if (cm.code == -1) {
622 continue;
623 } else {
624 hdmi.code = cm.code;
625 hdmi.mode = cm.mode;
626 DSSDBG("code = %d , mode = %d\n",
627 hdmi.code, hdmi.mode);
628 return;
629 }
630 }
631 }
632
633 DSSINFO("no valid timing found , falling back to VGA\n");
634 hdmi.code = 4; /* setting default value of 640 480 VGA */
635 hdmi.mode = HDMI_DVI;
636}
637
638static void hdmi_read_edid(struct omap_video_timings *dp)
639{
640 int ret = 0, code;
641
642 memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
643
644 if (!hdmi.edid_set)
645 ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
646
647 if (!ret) {
648 if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
649 /* search for timings of default resolution */
650 get_edid_timing_data(hdmi.edid);
651 hdmi.edid_set = true;
652 }
653 } else {
654 DSSWARN("failed to read E-EDID\n");
655 }
656
657 if (!hdmi.edid_set) {
658 DSSINFO("fallback to VGA\n");
659 hdmi.code = 4; /* setting default value of 640 480 VGA */
660 hdmi.mode = HDMI_DVI;
661 }
662
663 code = get_timings_index();
664
665 *dp = cea_vesa_timings[code].timings;
666}
667
668static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
669 struct hdmi_core_infoframe_avi *avi_cfg,
670 struct hdmi_core_packet_enable_repeat *repeat_cfg)
671{
672 DSSDBG("Enter hdmi_core_init\n");
673
674 /* video core */
675 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
676 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
677 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
678 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
679 video_cfg->hdmi_dvi = HDMI_DVI;
680 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
681
682 /* info frame */
683 avi_cfg->db1_format = 0;
684 avi_cfg->db1_active_info = 0;
685 avi_cfg->db1_bar_info_dv = 0;
686 avi_cfg->db1_scan_info = 0;
687 avi_cfg->db2_colorimetry = 0;
688 avi_cfg->db2_aspect_ratio = 0;
689 avi_cfg->db2_active_fmt_ar = 0;
690 avi_cfg->db3_itc = 0;
691 avi_cfg->db3_ec = 0;
692 avi_cfg->db3_q_range = 0;
693 avi_cfg->db3_nup_scaling = 0;
694 avi_cfg->db4_videocode = 0;
695 avi_cfg->db5_pixel_repeat = 0;
696 avi_cfg->db6_7_line_eoftop = 0 ;
697 avi_cfg->db8_9_line_sofbottom = 0;
698 avi_cfg->db10_11_pixel_eofleft = 0;
699 avi_cfg->db12_13_pixel_sofright = 0;
700
701 /* packet enable and repeat */
702 repeat_cfg->audio_pkt = 0;
703 repeat_cfg->audio_pkt_repeat = 0;
704 repeat_cfg->avi_infoframe = 0;
705 repeat_cfg->avi_infoframe_repeat = 0;
706 repeat_cfg->gen_cntrl_pkt = 0;
707 repeat_cfg->gen_cntrl_pkt_repeat = 0;
708 repeat_cfg->generic_pkt = 0;
709 repeat_cfg->generic_pkt_repeat = 0;
710}
711
712static void hdmi_core_powerdown_disable(void)
713{
714 DSSDBG("Enter hdmi_core_powerdown_disable\n");
715 REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
716}
717
718static void hdmi_core_swreset_release(void)
719{
720 DSSDBG("Enter hdmi_core_swreset_release\n");
721 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
722}
723
724static void hdmi_core_swreset_assert(void)
725{
726 DSSDBG("Enter hdmi_core_swreset_assert\n");
727 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
728}
729
730/* DSS_HDMI_CORE_VIDEO_CONFIG */
731static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
732{
733 u32 r = 0;
734
735 /* sys_ctrl1 default configuration not tunable */
736 r = hdmi_read_reg(HDMI_CORE_CTRL1);
737 r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
738 r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
739 r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
740 r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
741 hdmi_write_reg(HDMI_CORE_CTRL1, r);
742
743 REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
744
745 /* Vid_Mode */
746 r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
747
748 /* dither truncation configuration */
749 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
750 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
751 r = FLD_MOD(r, 1, 5, 5);
752 } else {
753 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
754 r = FLD_MOD(r, 0, 5, 5);
755 }
756 hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
757
758 /* HDMI_Ctrl */
759 r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
760 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
761 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
762 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
763 hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
764
765 /* TMDS_CTRL */
766 REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
767 cfg->tclk_sel_clkmult, 6, 5);
768}
769
770static void hdmi_core_aux_infoframe_avi_config(
771 struct hdmi_core_infoframe_avi info_avi)
772{
773 u32 val;
774 char sum = 0, checksum = 0;
775
776 sum += 0x82 + 0x002 + 0x00D;
777 hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
778 hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
779 hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
780
781 val = (info_avi.db1_format << 5) |
782 (info_avi.db1_active_info << 4) |
783 (info_avi.db1_bar_info_dv << 2) |
784 (info_avi.db1_scan_info);
785 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
786 sum += val;
787
788 val = (info_avi.db2_colorimetry << 6) |
789 (info_avi.db2_aspect_ratio << 4) |
790 (info_avi.db2_active_fmt_ar);
791 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
792 sum += val;
793
794 val = (info_avi.db3_itc << 7) |
795 (info_avi.db3_ec << 4) |
796 (info_avi.db3_q_range << 2) |
797 (info_avi.db3_nup_scaling);
798 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
799 sum += val;
800
801 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
802 sum += info_avi.db4_videocode;
803
804 val = info_avi.db5_pixel_repeat;
805 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
806 sum += val;
807
808 val = info_avi.db6_7_line_eoftop & 0x00FF;
809 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
810 sum += val;
811
812 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
813 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
814 sum += val;
815
816 val = info_avi.db8_9_line_sofbottom & 0x00FF;
817 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
818 sum += val;
819
820 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
821 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
822 sum += val;
823
824 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
825 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
826 sum += val;
827
828 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
829 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
830 sum += val;
831
832 val = info_avi.db12_13_pixel_sofright & 0x00FF;
833 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
834 sum += val;
835
836 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
837 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
838 sum += val;
839
840 checksum = 0x100 - sum;
841 hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
842}
843
844static void hdmi_core_av_packet_config(
845 struct hdmi_core_packet_enable_repeat repeat_cfg)
846{
847 /* enable/repeat the infoframe */
848 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
849 (repeat_cfg.audio_pkt << 5) |
850 (repeat_cfg.audio_pkt_repeat << 4) |
851 (repeat_cfg.avi_infoframe << 1) |
852 (repeat_cfg.avi_infoframe_repeat));
853
854 /* enable/repeat the packet */
855 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
856 (repeat_cfg.gen_cntrl_pkt << 3) |
857 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
858 (repeat_cfg.generic_pkt << 1) |
859 (repeat_cfg.generic_pkt_repeat));
860}
861
862static void hdmi_wp_init(struct omap_video_timings *timings,
863 struct hdmi_video_format *video_fmt,
864 struct hdmi_video_interface *video_int)
865{
866 DSSDBG("Enter hdmi_wp_init\n");
867
868 timings->hbp = 0;
869 timings->hfp = 0;
870 timings->hsw = 0;
871 timings->vbp = 0;
872 timings->vfp = 0;
873 timings->vsw = 0;
874
875 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
876 video_fmt->y_res = 0;
877 video_fmt->x_res = 0;
878
879 video_int->vsp = 0;
880 video_int->hsp = 0;
881
882 video_int->interlacing = 0;
883 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
884
885}
886
887static void hdmi_wp_video_start(bool start)
888{
889 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
890}
891
892static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
893 struct omap_video_timings *timings, struct hdmi_config *param)
894{
895 DSSDBG("Enter hdmi_wp_video_init_format\n");
896
897 video_fmt->y_res = param->timings.timings.y_res;
898 video_fmt->x_res = param->timings.timings.x_res;
899
900 timings->hbp = param->timings.timings.hbp;
901 timings->hfp = param->timings.timings.hfp;
902 timings->hsw = param->timings.timings.hsw;
903 timings->vbp = param->timings.timings.vbp;
904 timings->vfp = param->timings.timings.vfp;
905 timings->vsw = param->timings.timings.vsw;
906}
907
908static void hdmi_wp_video_config_format(
909 struct hdmi_video_format *video_fmt)
910{
911 u32 l = 0;
912
913 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
914
915 l |= FLD_VAL(video_fmt->y_res, 31, 16);
916 l |= FLD_VAL(video_fmt->x_res, 15, 0);
917 hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
918}
919
920static void hdmi_wp_video_config_interface(
921 struct hdmi_video_interface *video_int)
922{
923 u32 r;
924 DSSDBG("Enter hdmi_wp_video_config_interface\n");
925
926 r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
927 r = FLD_MOD(r, video_int->vsp, 7, 7);
928 r = FLD_MOD(r, video_int->hsp, 6, 6);
929 r = FLD_MOD(r, video_int->interlacing, 3, 3);
930 r = FLD_MOD(r, video_int->tm, 1, 0);
931 hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
932}
933
934static void hdmi_wp_video_config_timing(
935 struct omap_video_timings *timings)
936{
937 u32 timing_h = 0;
938 u32 timing_v = 0;
939
940 DSSDBG("Enter hdmi_wp_video_config_timing\n");
941
942 timing_h |= FLD_VAL(timings->hbp, 31, 20);
943 timing_h |= FLD_VAL(timings->hfp, 19, 8);
944 timing_h |= FLD_VAL(timings->hsw, 7, 0);
945 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
946
947 timing_v |= FLD_VAL(timings->vbp, 31, 20);
948 timing_v |= FLD_VAL(timings->vfp, 19, 8);
949 timing_v |= FLD_VAL(timings->vsw, 7, 0);
950 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
951}
952
953static void hdmi_basic_configure(struct hdmi_config *cfg)
954{
955 /* HDMI */
956 struct omap_video_timings video_timing;
957 struct hdmi_video_format video_format;
958 struct hdmi_video_interface video_interface;
959 /* HDMI core */
960 struct hdmi_core_infoframe_avi avi_cfg;
961 struct hdmi_core_video_config v_core_cfg;
962 struct hdmi_core_packet_enable_repeat repeat_cfg;
963
964 hdmi_wp_init(&video_timing, &video_format,
965 &video_interface);
966
967 hdmi_core_init(&v_core_cfg,
968 &avi_cfg,
969 &repeat_cfg);
970
971 hdmi_wp_video_init_format(&video_format,
972 &video_timing, cfg);
973
974 hdmi_wp_video_config_timing(&video_timing);
975
976 /* video config */
977 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
978
979 hdmi_wp_video_config_format(&video_format);
980
981 video_interface.vsp = cfg->timings.vsync_pol;
982 video_interface.hsp = cfg->timings.hsync_pol;
983 video_interface.interlacing = cfg->interlace;
984 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
985
986 hdmi_wp_video_config_interface(&video_interface);
987
988 /*
989 * configure core video part
990 * set software reset in the core
991 */
992 hdmi_core_swreset_assert();
993
994 /* power down off */
995 hdmi_core_powerdown_disable();
996
997 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
998 v_core_cfg.hdmi_dvi = cfg->cm.mode;
999
1000 hdmi_core_video_config(&v_core_cfg);
1001
1002 /* release software reset in the core */
1003 hdmi_core_swreset_release();
1004
1005 /*
1006 * configure packet
1007 * info frame video see doc CEA861-D page 65
1008 */
1009 avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
1010 avi_cfg.db1_active_info =
1011 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
1012 avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
1013 avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
1014 avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
1015 avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
1016 avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
1017 avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
1018 avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
1019 avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
1020 avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
1021 avi_cfg.db4_videocode = cfg->cm.code;
1022 avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
1023 avi_cfg.db6_7_line_eoftop = 0;
1024 avi_cfg.db8_9_line_sofbottom = 0;
1025 avi_cfg.db10_11_pixel_eofleft = 0;
1026 avi_cfg.db12_13_pixel_sofright = 0;
1027
1028 hdmi_core_aux_infoframe_avi_config(avi_cfg);
1029
1030 /* enable/repeat the infoframe */
1031 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
1032 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
1033 /* wakeup */
1034 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
1035 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
1036 hdmi_core_av_packet_config(repeat_cfg);
1037}
1038
1039static void update_hdmi_timings(struct hdmi_config *cfg,
1040 struct omap_video_timings *timings, int code)
1041{
1042 cfg->timings.timings.x_res = timings->x_res;
1043 cfg->timings.timings.y_res = timings->y_res;
1044 cfg->timings.timings.hbp = timings->hbp;
1045 cfg->timings.timings.hfp = timings->hfp;
1046 cfg->timings.timings.hsw = timings->hsw;
1047 cfg->timings.timings.vbp = timings->vbp;
1048 cfg->timings.timings.vfp = timings->vfp;
1049 cfg->timings.timings.vsw = timings->vsw;
1050 cfg->timings.timings.pixel_clock = timings->pixel_clock;
1051 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
1052 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
1053}
1054
1055static void hdmi_compute_pll(unsigned long clkin, int phy,
1056 int n, struct hdmi_pll_info *pi)
1057{
1058 unsigned long refclk;
1059 u32 mf;
1060
1061 /*
1062 * Input clock is predivided by N + 1
1063 * out put of which is reference clk
1064 */
1065 refclk = clkin / (n + 1);
1066 pi->regn = n;
1067
1068 /*
1069 * multiplier is pixel_clk/ref_clk
1070 * Multiplying by 100 to avoid fractional part removal
1071 */
1072 pi->regm = (phy * 100/(refclk))/100;
1073 pi->regm2 = 1;
1074
1075 /*
1076 * fractional multiplier is remainder of the difference between
1077 * multiplier and actual phy(required pixel clock thus should be
1078 * multiplied by 2^18(262144) divided by the reference clock
1079 */
1080 mf = (phy - pi->regm * refclk) * 262144;
1081 pi->regmf = mf/(refclk);
1082
1083 /*
1084 * Dcofreq should be set to 1 if required pixel clock
1085 * is greater than 1000MHz
1086 */
1087 pi->dcofreq = phy > 1000 * 100;
1088 pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
1089
1090 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1091 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
1092}
1093
1094static void hdmi_enable_clocks(int enable)
1095{
1096 if (enable)
1097 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
1098 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1099 else
1100 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
1101 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1102}
1103
1104static int hdmi_power_on(struct omap_dss_device *dssdev)
1105{
1106 int r, code = 0;
1107 struct hdmi_pll_info pll_data;
1108 struct omap_video_timings *p;
1109 int clkin, n, phy;
1110
1111 hdmi_enable_clocks(1);
1112
1113 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1114
1115 p = &dssdev->panel.timings;
1116
1117 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
1118 dssdev->panel.timings.x_res,
1119 dssdev->panel.timings.y_res);
1120
1121 if (!hdmi.custom_set) {
1122 DSSDBG("Read EDID as no EDID is not set on poweron\n");
1123 hdmi_read_edid(p);
1124 }
1125 code = get_timings_index();
1126 dssdev->panel.timings = cea_vesa_timings[code].timings;
1127 update_hdmi_timings(&hdmi.cfg, p, code);
1128
1129 clkin = 3840; /* 38.4 MHz */
1130 n = 15; /* this is a constant for our math */
1131 phy = p->pixel_clock;
1132
1133 hdmi_compute_pll(clkin, phy, n, &pll_data);
1134
1135 hdmi_wp_video_start(0);
1136
1137 /* config the PLL and PHY first */
1138 r = hdmi_pll_program(&pll_data);
1139 if (r) {
1140 DSSDBG("Failed to lock PLL\n");
1141 goto err;
1142 }
1143
1144 r = hdmi_phy_init();
1145 if (r) {
1146 DSSDBG("Failed to start PHY\n");
1147 goto err;
1148 }
1149
1150 hdmi.cfg.cm.mode = hdmi.mode;
1151 hdmi.cfg.cm.code = hdmi.code;
1152 hdmi_basic_configure(&hdmi.cfg);
1153
1154 /* Make selection of HDMI in DSS */
1155 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
1156
1157 /* Select the dispc clock source as PRCM clock, to ensure that it is not
1158 * DSI PLL source as the clock selected by DSI PLL might not be
1159 * sufficient for the resolution selected / that can be changed
1160 * dynamically by user. This can be moved to single location , say
1161 * Boardfile.
1162 */
1163 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
1164
1165 /* bypass TV gamma table */
1166 dispc_enable_gamma_table(0);
1167
1168 /* tv size */
1169 dispc_set_digit_size(dssdev->panel.timings.x_res,
1170 dssdev->panel.timings.y_res);
1171
1172 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
1173
1174 hdmi_wp_video_start(1);
1175
1176 return 0;
1177err:
1178 hdmi_enable_clocks(0);
1179 return -EIO;
1180}
1181
1182static void hdmi_power_off(struct omap_dss_device *dssdev)
1183{
1184 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1185
1186 hdmi_wp_video_start(0);
1187 hdmi_phy_off();
1188 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
1189 hdmi_enable_clocks(0);
1190
1191 hdmi.edid_set = 0;
1192}
1193
1194int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
1195 struct omap_video_timings *timings)
1196{
1197 struct hdmi_cm cm;
1198
1199 cm = hdmi_get_code(timings);
1200 if (cm.code == -1) {
1201 DSSERR("Invalid timing entered\n");
1202 return -EINVAL;
1203 }
1204
1205 return 0;
1206
1207}
1208
1209void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
1210{
1211 struct hdmi_cm cm;
1212
1213 hdmi.custom_set = 1;
1214 cm = hdmi_get_code(&dssdev->panel.timings);
1215 hdmi.code = cm.code;
1216 hdmi.mode = cm.mode;
1217 omapdss_hdmi_display_enable(dssdev);
1218 hdmi.custom_set = 0;
1219}
1220
1221int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
1222{
1223 int r = 0;
1224
1225 DSSDBG("ENTER hdmi_display_enable\n");
1226
1227 mutex_lock(&hdmi.lock);
1228
1229 r = omap_dss_start_device(dssdev);
1230 if (r) {
1231 DSSERR("failed to start device\n");
1232 goto err0;
1233 }
1234
1235 if (dssdev->platform_enable) {
1236 r = dssdev->platform_enable(dssdev);
1237 if (r) {
1238 DSSERR("failed to enable GPIO's\n");
1239 goto err1;
1240 }
1241 }
1242
1243 r = hdmi_power_on(dssdev);
1244 if (r) {
1245 DSSERR("failed to power on device\n");
1246 goto err2;
1247 }
1248
1249 mutex_unlock(&hdmi.lock);
1250 return 0;
1251
1252err2:
1253 if (dssdev->platform_disable)
1254 dssdev->platform_disable(dssdev);
1255err1:
1256 omap_dss_stop_device(dssdev);
1257err0:
1258 mutex_unlock(&hdmi.lock);
1259 return r;
1260}
1261
1262void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1263{
1264 DSSDBG("Enter hdmi_display_disable\n");
1265
1266 mutex_lock(&hdmi.lock);
1267
1268 hdmi_power_off(dssdev);
1269
1270 if (dssdev->platform_disable)
1271 dssdev->platform_disable(dssdev);
1272
1273 omap_dss_stop_device(dssdev);
1274
1275 mutex_unlock(&hdmi.lock);
1276}
1277
1278/* HDMI HW IP initialisation */
1279static int omapdss_hdmihw_probe(struct platform_device *pdev)
1280{
1281 struct resource *hdmi_mem;
1282
1283 hdmi.pdata = pdev->dev.platform_data;
1284 hdmi.pdev = pdev;
1285
1286 mutex_init(&hdmi.lock);
1287
1288 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1289 if (!hdmi_mem) {
1290 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1291 return -EINVAL;
1292 }
1293
1294 /* Base address taken from platform */
1295 hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
1296 if (!hdmi.base_wp) {
1297 DSSERR("can't ioremap WP\n");
1298 return -ENOMEM;
1299 }
1300
1301 hdmi_panel_init();
1302
1303 return 0;
1304}
1305
1306static int omapdss_hdmihw_remove(struct platform_device *pdev)
1307{
1308 hdmi_panel_exit();
1309
1310 iounmap(hdmi.base_wp);
1311
1312 return 0;
1313}
1314
1315static struct platform_driver omapdss_hdmihw_driver = {
1316 .probe = omapdss_hdmihw_probe,
1317 .remove = omapdss_hdmihw_remove,
1318 .driver = {
1319 .name = "omapdss_hdmi",
1320 .owner = THIS_MODULE,
1321 },
1322};
1323
1324int hdmi_init_platform_driver(void)
1325{
1326 return platform_driver_register(&omapdss_hdmihw_driver);
1327}
1328
1329void hdmi_uninit_platform_driver(void)
1330{
1331 return platform_driver_unregister(&omapdss_hdmihw_driver);
1332}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
new file mode 100644
index 000000000000..9887ab96da3c
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -0,0 +1,415 @@
1/*
2 * hdmi.h
3 *
4 * HDMI driver definition for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef _OMAP4_DSS_HDMI_H_
22#define _OMAP4_DSS_HDMI_H_
23
24#include <linux/string.h>
25#include <plat/display.h>
26
27#define HDMI_WP 0x0
28#define HDMI_CORE_SYS 0x400
29#define HDMI_CORE_AV 0x900
30#define HDMI_PLLCTRL 0x200
31#define HDMI_PHY 0x300
32
33struct hdmi_reg { u16 idx; };
34
35#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
36
37/* HDMI Wrapper */
38#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
39
40#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
41#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
42#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
43#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
44#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
45#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
46#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
47#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
51
52/* HDMI IP Core System */
53#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
54
55#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
56#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
57#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
58#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
59#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
60#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
61#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
62#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
63#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
64#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
65#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
66#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
67#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
68#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
69#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
70#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
71#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
72#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
73#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
74#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
75#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
76#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
77#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
78#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
79#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
80#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
81#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
82
83/* HDMI DDC E-DID */
84#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
85#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
86#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
87#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
88#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
89#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
90#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
91#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
92
93/* HDMI IP Core Audio Video */
94#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
95
96#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
97#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
98#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
99#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
100#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
101#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
102#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
103#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
104#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
105#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
106#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
107#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
108#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
109#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
110#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
111#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
112#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
113#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
114#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
115#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
116#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
117#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
118#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
119#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
120#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
121#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
122#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
123#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
124#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
125#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
126#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
127#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
128#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
129#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
130#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
131#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
132#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
133#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
134#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
135#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
136#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
137#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
138#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
139#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
140#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
141#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
142#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
143#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
144#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
145#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
146#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
147#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
148#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
149#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
150#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
151#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
152#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
153#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
154#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
155#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
156#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
157#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
158#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
159#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
160#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
161#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
162#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
163#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
164#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
165#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
166
167/* PLL */
168#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
169
170#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
171#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
172#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
173#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
174#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
175#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
176#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
177
178/* HDMI PHY */
179#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
180
181#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
182#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
183#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
184#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
185
186/* HDMI EDID Length */
187#define HDMI_EDID_MAX_LENGTH 256
188#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
189#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
190#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
191#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
192#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
193
194#define OMAP_HDMI_TIMINGS_NB 34
195
196#define REG_FLD_MOD(idx, val, start, end) \
197 hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
198#define REG_GET(idx, start, end) \
199 FLD_GET(hdmi_read_reg(idx), start, end)
200
201/* HDMI timing structure */
202struct hdmi_timings {
203 struct omap_video_timings timings;
204 int vsync_pol;
205 int hsync_pol;
206};
207
208enum hdmi_phy_pwr {
209 HDMI_PHYPWRCMD_OFF = 0,
210 HDMI_PHYPWRCMD_LDOON = 1,
211 HDMI_PHYPWRCMD_TXON = 2
212};
213
214enum hdmi_pll_pwr {
215 HDMI_PLLPWRCMD_ALLOFF = 0,
216 HDMI_PLLPWRCMD_PLLONLY = 1,
217 HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
218 HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
219};
220
221enum hdmi_clk_refsel {
222 HDMI_REFSEL_PCLK = 0,
223 HDMI_REFSEL_REF1 = 1,
224 HDMI_REFSEL_REF2 = 2,
225 HDMI_REFSEL_SYSCLK = 3
226};
227
228enum hdmi_core_inputbus_width {
229 HDMI_INPUT_8BIT = 0,
230 HDMI_INPUT_10BIT = 1,
231 HDMI_INPUT_12BIT = 2
232};
233
234enum hdmi_core_dither_trunc {
235 HDMI_OUTPUTTRUNCATION_8BIT = 0,
236 HDMI_OUTPUTTRUNCATION_10BIT = 1,
237 HDMI_OUTPUTTRUNCATION_12BIT = 2,
238 HDMI_OUTPUTDITHER_8BIT = 3,
239 HDMI_OUTPUTDITHER_10BIT = 4,
240 HDMI_OUTPUTDITHER_12BIT = 5
241};
242
243enum hdmi_core_deepcolor_ed {
244 HDMI_DEEPCOLORPACKECTDISABLE = 0,
245 HDMI_DEEPCOLORPACKECTENABLE = 1
246};
247
248enum hdmi_core_packet_mode {
249 HDMI_PACKETMODERESERVEDVALUE = 0,
250 HDMI_PACKETMODE24BITPERPIXEL = 4,
251 HDMI_PACKETMODE30BITPERPIXEL = 5,
252 HDMI_PACKETMODE36BITPERPIXEL = 6,
253 HDMI_PACKETMODE48BITPERPIXEL = 7
254};
255
256enum hdmi_core_hdmi_dvi {
257 HDMI_DVI = 0,
258 HDMI_HDMI = 1
259};
260
261enum hdmi_core_tclkselclkmult {
262 HDMI_FPLL05IDCK = 0,
263 HDMI_FPLL10IDCK = 1,
264 HDMI_FPLL20IDCK = 2,
265 HDMI_FPLL40IDCK = 3
266};
267
268enum hdmi_core_packet_ctrl {
269 HDMI_PACKETENABLE = 1,
270 HDMI_PACKETDISABLE = 0,
271 HDMI_PACKETREPEATON = 1,
272 HDMI_PACKETREPEATOFF = 0
273};
274
275/* INFOFRAME_AVI_ definitions */
276enum hdmi_core_infoframe {
277 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
278 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
279 HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
280 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
281 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
282 HDMI_INFOFRAME_AVI_DB1B_NO = 0,
283 HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
284 HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
285 HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
286 HDMI_INFOFRAME_AVI_DB1S_0 = 0,
287 HDMI_INFOFRAME_AVI_DB1S_1 = 1,
288 HDMI_INFOFRAME_AVI_DB1S_2 = 2,
289 HDMI_INFOFRAME_AVI_DB2C_NO = 0,
290 HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
291 HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
292 HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
293 HDMI_INFOFRAME_AVI_DB2M_NO = 0,
294 HDMI_INFOFRAME_AVI_DB2M_43 = 1,
295 HDMI_INFOFRAME_AVI_DB2M_169 = 2,
296 HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
297 HDMI_INFOFRAME_AVI_DB2R_43 = 9,
298 HDMI_INFOFRAME_AVI_DB2R_169 = 10,
299 HDMI_INFOFRAME_AVI_DB2R_149 = 11,
300 HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
301 HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
302 HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
303 HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
304 HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
305 HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
306 HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
307 HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
308 HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
309 HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
310 HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
311 HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
312 HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
313 HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
314 HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
315 HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
316 HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
317 HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
318 HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
319 HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
320 HDMI_INFOFRAME_AVI_DB5PR_10 = 9
321};
322
323enum hdmi_packing_mode {
324 HDMI_PACK_10b_RGB_YUV444 = 0,
325 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
326 HDMI_PACK_20b_YUV422 = 2,
327 HDMI_PACK_ALREADYPACKED = 7
328};
329
330struct hdmi_core_video_config {
331 enum hdmi_core_inputbus_width ip_bus_width;
332 enum hdmi_core_dither_trunc op_dither_truc;
333 enum hdmi_core_deepcolor_ed deep_color_pkt;
334 enum hdmi_core_packet_mode pkt_mode;
335 enum hdmi_core_hdmi_dvi hdmi_dvi;
336 enum hdmi_core_tclkselclkmult tclk_sel_clkmult;
337};
338
339/*
340 * Refer to section 8.2 in HDMI 1.3 specification for
341 * details about infoframe databytes
342 */
343struct hdmi_core_infoframe_avi {
344 u8 db1_format;
345 /* Y0, Y1 rgb,yCbCr */
346 u8 db1_active_info;
347 /* A0 Active information Present */
348 u8 db1_bar_info_dv;
349 /* B0, B1 Bar info data valid */
350 u8 db1_scan_info;
351 /* S0, S1 scan information */
352 u8 db2_colorimetry;
353 /* C0, C1 colorimetry */
354 u8 db2_aspect_ratio;
355 /* M0, M1 Aspect ratio (4:3, 16:9) */
356 u8 db2_active_fmt_ar;
357 /* R0...R3 Active format aspect ratio */
358 u8 db3_itc;
359 /* ITC IT content. */
360 u8 db3_ec;
361 /* EC0, EC1, EC2 Extended colorimetry */
362 u8 db3_q_range;
363 /* Q1, Q0 Quantization range */
364 u8 db3_nup_scaling;
365 /* SC1, SC0 Non-uniform picture scaling */
366 u8 db4_videocode;
367 /* VIC0..6 Video format identification */
368 u8 db5_pixel_repeat;
369 /* PR0..PR3 Pixel repetition factor */
370 u16 db6_7_line_eoftop;
371 /* Line number end of top bar */
372 u16 db8_9_line_sofbottom;
373 /* Line number start of bottom bar */
374 u16 db10_11_pixel_eofleft;
375 /* Pixel number end of left bar */
376 u16 db12_13_pixel_sofright;
377 /* Pixel number start of right bar */
378};
379
380struct hdmi_core_packet_enable_repeat {
381 u32 audio_pkt;
382 u32 audio_pkt_repeat;
383 u32 avi_infoframe;
384 u32 avi_infoframe_repeat;
385 u32 gen_cntrl_pkt;
386 u32 gen_cntrl_pkt_repeat;
387 u32 generic_pkt;
388 u32 generic_pkt_repeat;
389};
390
391struct hdmi_video_format {
392 enum hdmi_packing_mode packing_mode;
393 u32 y_res; /* Line per panel */
394 u32 x_res; /* pixel per line */
395};
396
397struct hdmi_video_interface {
398 int vsp; /* Vsync polarity */
399 int hsp; /* Hsync polarity */
400 int interlacing;
401 int tm; /* Timing mode */
402};
403
404struct hdmi_cm {
405 int code;
406 int mode;
407};
408
409struct hdmi_config {
410 struct hdmi_timings timings;
411 u16 interlace;
412 struct hdmi_cm cm;
413};
414
415#endif
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
new file mode 100644
index 000000000000..ffb5de94131f
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
@@ -0,0 +1,222 @@
1/*
2 * hdmi_omap4_panel.c
3 *
4 * HDMI library support functions for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 * Authors: Mythri P k <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/mutex.h>
26#include <linux/module.h>
27#include <plat/display.h>
28
29#include "dss.h"
30
31static struct {
32 struct mutex hdmi_lock;
33} hdmi;
34
35
36static int hdmi_panel_probe(struct omap_dss_device *dssdev)
37{
38 DSSDBG("ENTER hdmi_panel_probe\n");
39
40 dssdev->panel.config = OMAP_DSS_LCD_TFT |
41 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
42
43 /*
44 * Initialize the timings to 640 * 480
45 * This is only for framebuffer update not for TV timing setting
46 * Setting TV timing will be done only on enable
47 */
48 dssdev->panel.timings.x_res = 640;
49 dssdev->panel.timings.y_res = 480;
50
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res,
53 dssdev->panel.timings.y_res);
54 return 0;
55}
56
57static void hdmi_panel_remove(struct omap_dss_device *dssdev)
58{
59
60}
61
62static int hdmi_panel_enable(struct omap_dss_device *dssdev)
63{
64 int r = 0;
65 DSSDBG("ENTER hdmi_panel_enable\n");
66
67 mutex_lock(&hdmi.hdmi_lock);
68
69 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
70 r = -EINVAL;
71 goto err;
72 }
73
74 r = omapdss_hdmi_display_enable(dssdev);
75 if (r) {
76 DSSERR("failed to power on\n");
77 goto err;
78 }
79
80 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
81
82err:
83 mutex_unlock(&hdmi.hdmi_lock);
84
85 return r;
86}
87
88static void hdmi_panel_disable(struct omap_dss_device *dssdev)
89{
90 mutex_lock(&hdmi.hdmi_lock);
91
92 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
93 omapdss_hdmi_display_disable(dssdev);
94
95 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
96
97 mutex_unlock(&hdmi.hdmi_lock);
98}
99
100static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
101{
102 int r = 0;
103
104 mutex_lock(&hdmi.hdmi_lock);
105
106 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
107 r = -EINVAL;
108 goto err;
109 }
110
111 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
112
113 omapdss_hdmi_display_disable(dssdev);
114
115err:
116 mutex_unlock(&hdmi.hdmi_lock);
117
118 return r;
119}
120
121static int hdmi_panel_resume(struct omap_dss_device *dssdev)
122{
123 int r = 0;
124
125 mutex_lock(&hdmi.hdmi_lock);
126
127 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
128 r = -EINVAL;
129 goto err;
130 }
131
132 r = omapdss_hdmi_display_enable(dssdev);
133 if (r) {
134 DSSERR("failed to power on\n");
135 goto err;
136 }
137
138 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
139
140err:
141 mutex_unlock(&hdmi.hdmi_lock);
142
143 return r;
144}
145
146static void hdmi_get_timings(struct omap_dss_device *dssdev,
147 struct omap_video_timings *timings)
148{
149 mutex_lock(&hdmi.hdmi_lock);
150
151 *timings = dssdev->panel.timings;
152
153 mutex_unlock(&hdmi.hdmi_lock);
154}
155
156static void hdmi_set_timings(struct omap_dss_device *dssdev,
157 struct omap_video_timings *timings)
158{
159 DSSDBG("hdmi_set_timings\n");
160
161 mutex_lock(&hdmi.hdmi_lock);
162
163 dssdev->panel.timings = *timings;
164
165 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
166 /* turn the hdmi off and on to get new timings to use */
167 omapdss_hdmi_display_disable(dssdev);
168 omapdss_hdmi_display_set_timing(dssdev);
169 }
170
171 mutex_unlock(&hdmi.hdmi_lock);
172}
173
174static int hdmi_check_timings(struct omap_dss_device *dssdev,
175 struct omap_video_timings *timings)
176{
177 int r = 0;
178
179 DSSDBG("hdmi_check_timings\n");
180
181 mutex_lock(&hdmi.hdmi_lock);
182
183 r = omapdss_hdmi_display_check_timing(dssdev, timings);
184 if (r) {
185 DSSERR("Timing cannot be applied\n");
186 goto err;
187 }
188err:
189 mutex_unlock(&hdmi.hdmi_lock);
190 return r;
191}
192
193static struct omap_dss_driver hdmi_driver = {
194 .probe = hdmi_panel_probe,
195 .remove = hdmi_panel_remove,
196 .enable = hdmi_panel_enable,
197 .disable = hdmi_panel_disable,
198 .suspend = hdmi_panel_suspend,
199 .resume = hdmi_panel_resume,
200 .get_timings = hdmi_get_timings,
201 .set_timings = hdmi_set_timings,
202 .check_timings = hdmi_check_timings,
203 .driver = {
204 .name = "hdmi_panel",
205 .owner = THIS_MODULE,
206 },
207};
208
209int hdmi_panel_init(void)
210{
211 mutex_init(&hdmi.hdmi_lock);
212
213 omap_dss_register_driver(&hdmi_driver);
214
215 return 0;
216}
217
218void hdmi_panel_exit(void)
219{
220 omap_dss_unregister_driver(&hdmi_driver);
221
222}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 172d4e697309..bcd37ec86952 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -515,6 +515,8 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
515 515
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD; 517 irq = DISPC_IRQ_EVSYNC_ODD;
518 } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) {
519 irq = DISPC_IRQ_EVSYNC_EVEN;
518 } else { 520 } else {
519 if (mgr->id == OMAP_DSS_CHANNEL_LCD) 521 if (mgr->id == OMAP_DSS_CHANNEL_LCD)
520 irq = DISPC_IRQ_VSYNC; 522 irq = DISPC_IRQ_VSYNC;
@@ -536,7 +538,8 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
536 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 538 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
537 return 0; 539 return 0;
538 540
539 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 541 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
542 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
540 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 543 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
541 } else { 544 } else {
542 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 545 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -613,7 +616,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
613 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 616 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
614 return 0; 617 return 0;
615 618
616 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 619 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
620 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
617 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 621 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
618 } else { 622 } else {
619 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 623 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -1377,6 +1381,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1377 case OMAP_DISPLAY_TYPE_DBI: 1381 case OMAP_DISPLAY_TYPE_DBI:
1378 case OMAP_DISPLAY_TYPE_SDI: 1382 case OMAP_DISPLAY_TYPE_SDI:
1379 case OMAP_DISPLAY_TYPE_VENC: 1383 case OMAP_DISPLAY_TYPE_VENC:
1384 case OMAP_DISPLAY_TYPE_HDMI:
1380 default_get_overlay_fifo_thresholds(ovl->id, size, 1385 default_get_overlay_fifo_thresholds(ovl->id, size,
1381 &oc->burst_size, &oc->fifo_low, 1386 &oc->burst_size, &oc->fifo_low,
1382 &oc->fifo_high); 1387 &oc->fifo_high);
@@ -1394,7 +1399,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1394 } 1399 }
1395 1400
1396 r = 0; 1401 r = 0;
1397 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1402 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1398 if (!dss_cache.irq_enabled) { 1403 if (!dss_cache.irq_enabled) {
1399 u32 mask; 1404 u32 mask;
1400 1405
@@ -1407,7 +1412,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1407 dss_cache.irq_enabled = true; 1412 dss_cache.irq_enabled = true;
1408 } 1413 }
1409 configure_dispc(); 1414 configure_dispc();
1410 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1415 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1411 1416
1412 spin_unlock_irqrestore(&dss_cache.lock, flags); 1417 spin_unlock_irqrestore(&dss_cache.lock, flags);
1413 1418
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 456efef03c20..f1aca6d04011 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -490,7 +490,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
490 490
491 ovl->manager = mgr; 491 ovl->manager = mgr;
492 492
493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
494 /* XXX: on manual update display, in auto update mode, a bug happens 494 /* XXX: on manual update display, in auto update mode, a bug happens
495 * here. When an overlay is first enabled on LCD, then it's disabled, 495 * here. When an overlay is first enabled on LCD, then it's disabled,
496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT 496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
@@ -499,7 +499,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
499 * but I don't understand how or why. */ 499 * but I don't understand how or why. */
500 msleep(40); 500 msleep(40);
501 dispc_set_channel_out(ovl->id, mgr->id); 501 dispc_set_channel_out(ovl->id, mgr->id);
502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
503 503
504 return 0; 504 return 0;
505} 505}
@@ -679,7 +679,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
679 lcd2_mgr->set_device(lcd2_mgr, dssdev); 679 lcd2_mgr->set_device(lcd2_mgr, dssdev);
680 mgr = lcd2_mgr; 680 mgr = lcd2_mgr;
681 } 681 }
682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
683 && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
683 if (!lcd_mgr->device || force) { 684 if (!lcd_mgr->device || force) {
684 if (lcd_mgr->device) 685 if (lcd_mgr->device)
685 lcd_mgr->unset_device(lcd_mgr); 686 lcd_mgr->unset_device(lcd_mgr);
@@ -688,7 +689,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
688 } 689 }
689 } 690 }
690 691
691 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 692 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
693 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
692 if (!tv_mgr->device || force) { 694 if (!tv_mgr->device || force) {
693 if (tv_mgr->device) 695 if (tv_mgr->device)
694 tv_mgr->unset_device(tv_mgr); 696 tv_mgr->unset_device(tv_mgr);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 10a2ffe02882..5ea17f49c611 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
36#include <plat/display.h> 36#include <plat/display.h>
37#include "dss.h" 37#include "dss.h"
38 38
39#define RFBI_BASE 0x48050800
40
41struct rfbi_reg { u16 idx; }; 39struct rfbi_reg { u16 idx; };
42 40
43#define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) 41#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
@@ -100,6 +98,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t);
100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 98static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
101 99
102static struct { 100static struct {
101 struct platform_device *pdev;
103 void __iomem *base; 102 void __iomem *base;
104 103
105 unsigned long l4_khz; 104 unsigned long l4_khz;
@@ -142,9 +141,9 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
142static void rfbi_enable_clocks(bool enable) 141static void rfbi_enable_clocks(bool enable)
143{ 142{
144 if (enable) 143 if (enable)
145 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 144 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
146 else 145 else
147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 146 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
148} 147}
149 148
150void omap_rfbi_write_command(const void *buf, u32 len) 149void omap_rfbi_write_command(const void *buf, u32 len)
@@ -497,7 +496,7 @@ unsigned long rfbi_get_max_tx_rate(void)
497 }; 496 };
498 497
499 l4_rate = rfbi.l4_khz / 1000; 498 l4_rate = rfbi.l4_khz / 1000;
500 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000; 499 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
501 500
502 for (i = 0; i < ARRAY_SIZE(ftab); i++) { 501 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
503 /* Use a window instead of an exact match, to account 502 /* Use a window instead of an exact match, to account
@@ -922,7 +921,7 @@ void rfbi_dump_regs(struct seq_file *s)
922{ 921{
923#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 922#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
924 923
925 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 924 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
926 925
927 DUMPREG(RFBI_REVISION); 926 DUMPREG(RFBI_REVISION);
928 DUMPREG(RFBI_SYSCONFIG); 927 DUMPREG(RFBI_SYSCONFIG);
@@ -953,54 +952,10 @@ void rfbi_dump_regs(struct seq_file *s)
953 DUMPREG(RFBI_VSYNC_WIDTH); 952 DUMPREG(RFBI_VSYNC_WIDTH);
954 DUMPREG(RFBI_HSYNC_WIDTH); 953 DUMPREG(RFBI_HSYNC_WIDTH);
955 954
956 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 955 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
957#undef DUMPREG 956#undef DUMPREG
958} 957}
959 958
960int rfbi_init(void)
961{
962 u32 rev;
963 u32 l;
964
965 spin_lock_init(&rfbi.cmd_lock);
966
967 init_completion(&rfbi.cmd_done);
968 atomic_set(&rfbi.cmd_fifo_full, 0);
969 atomic_set(&rfbi.cmd_pending, 0);
970
971 rfbi.base = ioremap(RFBI_BASE, SZ_256);
972 if (!rfbi.base) {
973 DSSERR("can't ioremap RFBI\n");
974 return -ENOMEM;
975 }
976
977 rfbi_enable_clocks(1);
978
979 msleep(10);
980
981 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
982
983 /* Enable autoidle and smart-idle */
984 l = rfbi_read_reg(RFBI_SYSCONFIG);
985 l |= (1 << 0) | (2 << 3);
986 rfbi_write_reg(RFBI_SYSCONFIG, l);
987
988 rev = rfbi_read_reg(RFBI_REVISION);
989 printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
990 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
991
992 rfbi_enable_clocks(0);
993
994 return 0;
995}
996
997void rfbi_exit(void)
998{
999 DSSDBG("rfbi_exit\n");
1000
1001 iounmap(rfbi.base);
1002}
1003
1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 959int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1005{ 960{
1006 int r; 961 int r;
@@ -1056,3 +1011,74 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
1056 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1011 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1057 return 0; 1012 return 0;
1058} 1013}
1014
1015/* RFBI HW IP initialisation */
1016static int omap_rfbihw_probe(struct platform_device *pdev)
1017{
1018 u32 rev;
1019 u32 l;
1020 struct resource *rfbi_mem;
1021
1022 rfbi.pdev = pdev;
1023
1024 spin_lock_init(&rfbi.cmd_lock);
1025
1026 init_completion(&rfbi.cmd_done);
1027 atomic_set(&rfbi.cmd_fifo_full, 0);
1028 atomic_set(&rfbi.cmd_pending, 0);
1029
1030 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
1031 if (!rfbi_mem) {
1032 DSSERR("can't get IORESOURCE_MEM RFBI\n");
1033 return -EINVAL;
1034 }
1035 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
1036 if (!rfbi.base) {
1037 DSSERR("can't ioremap RFBI\n");
1038 return -ENOMEM;
1039 }
1040
1041 rfbi_enable_clocks(1);
1042
1043 msleep(10);
1044
1045 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
1046
1047 /* Enable autoidle and smart-idle */
1048 l = rfbi_read_reg(RFBI_SYSCONFIG);
1049 l |= (1 << 0) | (2 << 3);
1050 rfbi_write_reg(RFBI_SYSCONFIG, l);
1051
1052 rev = rfbi_read_reg(RFBI_REVISION);
1053 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
1054 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1055
1056 rfbi_enable_clocks(0);
1057
1058 return 0;
1059}
1060
1061static int omap_rfbihw_remove(struct platform_device *pdev)
1062{
1063 iounmap(rfbi.base);
1064 return 0;
1065}
1066
1067static struct platform_driver omap_rfbihw_driver = {
1068 .probe = omap_rfbihw_probe,
1069 .remove = omap_rfbihw_remove,
1070 .driver = {
1071 .name = "omapdss_rfbi",
1072 .owner = THIS_MODULE,
1073 },
1074};
1075
1076int rfbi_init_platform_driver(void)
1077{
1078 return platform_driver_register(&omap_rfbihw_driver);
1079}
1080
1081void rfbi_uninit_platform_driver(void)
1082{
1083 return platform_driver_unregister(&omap_rfbihw_driver);
1084}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index b64adf7dfc88..54a53e648180 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -30,7 +30,6 @@
30#include "dss.h" 30#include "dss.h"
31 31
32static struct { 32static struct {
33 bool skip_init;
34 bool update_enabled; 33 bool update_enabled;
35 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
36} sdi; 35} sdi;
@@ -68,9 +67,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
68 if (r) 67 if (r)
69 goto err1; 68 goto err1;
70 69
71 /* In case of skip_init sdi_init has already enabled the clocks */ 70 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
72 if (!sdi.skip_init)
73 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
74 71
75 sdi_basic_init(dssdev); 72 sdi_basic_init(dssdev);
76 73
@@ -80,14 +77,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
80 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 77 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
81 dssdev->panel.acbi, dssdev->panel.acb); 78 dssdev->panel.acbi, dssdev->panel.acb);
82 79
83 if (!sdi.skip_init) { 80 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
84 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 81 &dss_cinfo, &dispc_cinfo);
85 &dss_cinfo, &dispc_cinfo);
86 } else {
87 r = dss_get_clock_div(&dss_cinfo);
88 r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo);
89 }
90
91 if (r) 82 if (r)
92 goto err2; 83 goto err2;
93 84
@@ -116,21 +107,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
116 if (r) 107 if (r)
117 goto err2; 108 goto err2;
118 109
119 if (!sdi.skip_init) { 110 dss_sdi_init(dssdev->phy.sdi.datapairs);
120 dss_sdi_init(dssdev->phy.sdi.datapairs); 111 r = dss_sdi_enable();
121 r = dss_sdi_enable(); 112 if (r)
122 if (r) 113 goto err1;
123 goto err1; 114 mdelay(2);
124 mdelay(2);
125 }
126 115
127 dssdev->manager->enable(dssdev->manager); 116 dssdev->manager->enable(dssdev->manager);
128 117
129 sdi.skip_init = 0;
130
131 return 0; 118 return 0;
132err2: 119err2:
133 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 120 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
134 regulator_disable(sdi.vdds_sdi_reg); 121 regulator_disable(sdi.vdds_sdi_reg);
135err1: 122err1:
136 omap_dss_stop_device(dssdev); 123 omap_dss_stop_device(dssdev);
@@ -145,7 +132,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
145 132
146 dss_sdi_disable(); 133 dss_sdi_disable();
147 134
148 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 135 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
149 136
150 regulator_disable(sdi.vdds_sdi_reg); 137 regulator_disable(sdi.vdds_sdi_reg);
151 138
@@ -157,25 +144,24 @@ int sdi_init_display(struct omap_dss_device *dssdev)
157{ 144{
158 DSSDBG("SDI init\n"); 145 DSSDBG("SDI init\n");
159 146
147 if (sdi.vdds_sdi_reg == NULL) {
148 struct regulator *vdds_sdi;
149
150 vdds_sdi = dss_get_vdds_sdi();
151
152 if (IS_ERR(vdds_sdi)) {
153 DSSERR("can't get VDDS_SDI regulator\n");
154 return PTR_ERR(vdds_sdi);
155 }
156
157 sdi.vdds_sdi_reg = vdds_sdi;
158 }
159
160 return 0; 160 return 0;
161} 161}
162 162
163int sdi_init(bool skip_init) 163int sdi_init(void)
164{ 164{
165 /* we store this for first display enable, then clear it */
166 sdi.skip_init = skip_init;
167
168 sdi.vdds_sdi_reg = dss_get_vdds_sdi();
169 if (IS_ERR(sdi.vdds_sdi_reg)) {
170 DSSERR("can't get VDDS_SDI regulator\n");
171 return PTR_ERR(sdi.vdds_sdi_reg);
172 }
173 /*
174 * Enable clocks already here, otherwise there would be a toggle
175 * of them until sdi_display_enable is called.
176 */
177 if (skip_init)
178 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
179 return 0; 165 return 0;
180} 166}
181 167
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index eff35050e28a..8e35a5bae429 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -39,8 +39,6 @@
39 39
40#include "dss.h" 40#include "dss.h"
41 41
42#define VENC_BASE 0x48050C00
43
44/* Venc registers */ 42/* Venc registers */
45#define VENC_REV_ID 0x00 43#define VENC_REV_ID 0x00
46#define VENC_STATUS 0x04 44#define VENC_STATUS 0x04
@@ -289,6 +287,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
289EXPORT_SYMBOL(omap_dss_ntsc_timings); 287EXPORT_SYMBOL(omap_dss_ntsc_timings);
290 288
291static struct { 289static struct {
290 struct platform_device *pdev;
292 void __iomem *base; 291 void __iomem *base;
293 struct mutex venc_lock; 292 struct mutex venc_lock;
294 u32 wss_data; 293 u32 wss_data;
@@ -381,11 +380,11 @@ static void venc_reset(void)
381static void venc_enable_clocks(int enable) 380static void venc_enable_clocks(int enable)
382{ 381{
383 if (enable) 382 if (enable)
384 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 383 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
385 DSS_CLK_96M); 384 DSS_CLK_VIDFCK);
386 else 385 else
387 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 386 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
388 DSS_CLK_96M); 387 DSS_CLK_VIDFCK);
389} 388}
390 389
391static const struct venc_config *venc_timings_to_config( 390static const struct venc_config *venc_timings_to_config(
@@ -641,50 +640,23 @@ static struct omap_dss_driver venc_driver = {
641}; 640};
642/* driver end */ 641/* driver end */
643 642
644 643int venc_init_display(struct omap_dss_device *dssdev)
645
646int venc_init(struct platform_device *pdev)
647{ 644{
648 u8 rev_id; 645 DSSDBG("init_display\n");
649 646
650 mutex_init(&venc.venc_lock); 647 if (venc.vdda_dac_reg == NULL) {
648 struct regulator *vdda_dac;
651 649
652 venc.wss_data = 0; 650 vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac");
653 651
654 venc.base = ioremap(VENC_BASE, SZ_1K); 652 if (IS_ERR(vdda_dac)) {
655 if (!venc.base) { 653 DSSERR("can't get VDDA_DAC regulator\n");
656 DSSERR("can't ioremap VENC\n"); 654 return PTR_ERR(vdda_dac);
657 return -ENOMEM; 655 }
658 }
659 656
660 venc.vdda_dac_reg = dss_get_vdda_dac(); 657 venc.vdda_dac_reg = vdda_dac;
661 if (IS_ERR(venc.vdda_dac_reg)) {
662 iounmap(venc.base);
663 DSSERR("can't get VDDA_DAC regulator\n");
664 return PTR_ERR(venc.vdda_dac_reg);
665 } 658 }
666 659
667 venc_enable_clocks(1);
668
669 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
670 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
671
672 venc_enable_clocks(0);
673
674 return omap_dss_register_driver(&venc_driver);
675}
676
677void venc_exit(void)
678{
679 omap_dss_unregister_driver(&venc_driver);
680
681 iounmap(venc.base);
682}
683
684int venc_init_display(struct omap_dss_device *dssdev)
685{
686 DSSDBG("init_display\n");
687
688 return 0; 660 return 0;
689} 661}
690 662
@@ -740,3 +712,73 @@ void venc_dump_regs(struct seq_file *s)
740 712
741#undef DUMPREG 713#undef DUMPREG
742} 714}
715
716/* VENC HW IP initialisation */
717static int omap_venchw_probe(struct platform_device *pdev)
718{
719 u8 rev_id;
720 struct resource *venc_mem;
721
722 venc.pdev = pdev;
723
724 mutex_init(&venc.venc_lock);
725
726 venc.wss_data = 0;
727
728 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
729 if (!venc_mem) {
730 DSSERR("can't get IORESOURCE_MEM VENC\n");
731 return -EINVAL;
732 }
733 venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
734 if (!venc.base) {
735 DSSERR("can't ioremap VENC\n");
736 return -ENOMEM;
737 }
738
739 venc_enable_clocks(1);
740
741 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
742 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
743
744 venc_enable_clocks(0);
745
746 return omap_dss_register_driver(&venc_driver);
747}
748
749static int omap_venchw_remove(struct platform_device *pdev)
750{
751 if (venc.vdda_dac_reg != NULL) {
752 regulator_put(venc.vdda_dac_reg);
753 venc.vdda_dac_reg = NULL;
754 }
755 omap_dss_unregister_driver(&venc_driver);
756
757 iounmap(venc.base);
758 return 0;
759}
760
761static struct platform_driver omap_venchw_driver = {
762 .probe = omap_venchw_probe,
763 .remove = omap_venchw_remove,
764 .driver = {
765 .name = "omapdss_venc",
766 .owner = THIS_MODULE,
767 },
768};
769
770int venc_init_platform_driver(void)
771{
772 if (cpu_is_omap44xx())
773 return 0;
774
775 return platform_driver_register(&omap_venchw_driver);
776}
777
778void venc_uninit_platform_driver(void)
779{
780 if (cpu_is_omap44xx())
781 return;
782
783 return platform_driver_unregister(&omap_venchw_driver);
784}
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 65149b22cf37..aa33386c81ff 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -1,5 +1,5 @@
1menuconfig FB_OMAP2 1menuconfig FB_OMAP2
2 tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)" 2 tristate "OMAP2+ frame buffer support (EXPERIMENTAL)"
3 depends on FB && OMAP2_DSS 3 depends on FB && OMAP2_DSS
4 4
5 select OMAP2_VRAM 5 select OMAP2_VRAM
@@ -8,10 +8,10 @@ menuconfig FB_OMAP2
8 select FB_CFB_COPYAREA 8 select FB_CFB_COPYAREA
9 select FB_CFB_IMAGEBLIT 9 select FB_CFB_IMAGEBLIT
10 help 10 help
11 Frame buffer driver for OMAP2/3 based boards. 11 Frame buffer driver for OMAP2+ based boards.
12 12
13config FB_OMAP2_DEBUG_SUPPORT 13config FB_OMAP2_DEBUG_SUPPORT
14 bool "Debug support for OMAP2/3 FB" 14 bool "Debug support for OMAP2+ FB"
15 default y 15 default y
16 depends on FB_OMAP2 16 depends on FB_OMAP2
17 help 17 help
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4fdab8e9c496..505ec6672049 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2090,7 +2090,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2090{ 2090{
2091 int r; 2091 int r;
2092 u8 bpp; 2092 u8 bpp;
2093 struct omap_video_timings timings; 2093 struct omap_video_timings timings, temp_timings;
2094 2094
2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
2096 if (r) 2096 if (r)
@@ -2100,14 +2100,23 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; 2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
2101 ++fbdev->num_bpp_overrides; 2101 ++fbdev->num_bpp_overrides;
2102 2102
2103 if (!display->driver->check_timings || !display->driver->set_timings) 2103 if (display->driver->check_timings) {
2104 return -EINVAL; 2104 r = display->driver->check_timings(display, &timings);
2105 if (r)
2106 return r;
2107 } else {
2108 /* If check_timings is not present compare xres and yres */
2109 if (display->driver->get_timings) {
2110 display->driver->get_timings(display, &temp_timings);
2105 2111
2106 r = display->driver->check_timings(display, &timings); 2112 if (temp_timings.x_res != timings.x_res ||
2107 if (r) 2113 temp_timings.y_res != timings.y_res)
2108 return r; 2114 return -EINVAL;
2115 }
2116 }
2109 2117
2110 display->driver->set_timings(display, &timings); 2118 if (display->driver->set_timings)
2119 display->driver->set_timings(display, &timings);
2111 2120
2112 return 0; 2121 return 0;
2113} 2122}
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
index cf4beb9dc9bb..0283c7021090 100644
--- a/drivers/video/pxa3xx-gcu.c
+++ b/drivers/video/pxa3xx-gcu.c
@@ -25,7 +25,7 @@
25 25
26/* 26/*
27 * WARNING: This controller is attached to System Bus 2 of the PXA which 27 * WARNING: This controller is attached to System Bus 2 of the PXA which
28 * needs its arbiter to be enabled explictly (CKENB & 1<<9). 28 * needs its arbiter to be enabled explicitly (CKENB & 1<<9).
29 * There is currently no way to do this from Linux, so you need to teach 29 * There is currently no way to do this from Linux, so you need to teach
30 * your bootloader for now. 30 * your bootloader for now.
31 */ 31 */
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 825b665245bb..0f4e8c942f9e 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb)
627 627
628static void overlay1fb_disable(struct pxafb_layer *ofb) 628static void overlay1fb_disable(struct pxafb_layer *ofb)
629{ 629{
630 uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); 630 uint32_t lccr5;
631
632 if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
633 return;
634
635 lccr5 = lcd_readl(ofb->fbi, LCCR5);
631 636
632 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN); 637 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
633 638
@@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb)
685 690
686static void overlay2fb_disable(struct pxafb_layer *ofb) 691static void overlay2fb_disable(struct pxafb_layer *ofb)
687{ 692{
688 uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); 693 uint32_t lccr5;
694
695 if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
696 return;
697
698 lccr5 = lcd_readl(ofb->fbi, LCCR5);
689 699
690 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN); 700 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
691 701
@@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user)
720 if (user == 0) 730 if (user == 0)
721 return -ENODEV; 731 return -ENODEV;
722 732
723 /* allow only one user at a time */ 733 if (ofb->usage++ == 0)
724 if (atomic_inc_and_test(&ofb->usage)) 734 /* unblank the base framebuffer */
725 return -EBUSY; 735 fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
726 736
727 /* unblank the base framebuffer */
728 fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
729 return 0; 737 return 0;
730} 738}
731 739
@@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user)
733{ 741{
734 struct pxafb_layer *ofb = (struct pxafb_layer*) info; 742 struct pxafb_layer *ofb = (struct pxafb_layer*) info;
735 743
736 atomic_dec(&ofb->usage); 744 if (ofb->usage == 1) {
737 ofb->ops->disable(ofb); 745 ofb->ops->disable(ofb);
746 ofb->fb.var.height = -1;
747 ofb->fb.var.width = -1;
748 ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
749 ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
738 750
739 free_pages_exact(ofb->video_mem, ofb->video_mem_size); 751 ofb->usage--;
740 ofb->video_mem = NULL; 752 }
741 ofb->video_mem_size = 0;
742 return 0; 753 return 0;
743} 754}
744 755
@@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
750 int xpos, ypos, pfor, bpp; 761 int xpos, ypos, pfor, bpp;
751 762
752 xpos = NONSTD_TO_XPOS(var->nonstd); 763 xpos = NONSTD_TO_XPOS(var->nonstd);
753 ypos = NONSTD_TO_XPOS(var->nonstd); 764 ypos = NONSTD_TO_YPOS(var->nonstd);
754 pfor = NONSTD_TO_PFOR(var->nonstd); 765 pfor = NONSTD_TO_PFOR(var->nonstd);
755 766
756 bpp = pxafb_var_to_bpp(var); 767 bpp = pxafb_var_to_bpp(var);
@@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
794 return 0; 805 return 0;
795} 806}
796 807
797static int overlayfb_map_video_memory(struct pxafb_layer *ofb) 808static int overlayfb_check_video_memory(struct pxafb_layer *ofb)
798{ 809{
799 struct fb_var_screeninfo *var = &ofb->fb.var; 810 struct fb_var_screeninfo *var = &ofb->fb.var;
800 int pfor = NONSTD_TO_PFOR(var->nonstd); 811 int pfor = NONSTD_TO_PFOR(var->nonstd);
@@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
812 823
813 size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual); 824 size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
814 825
815 /* don't re-allocate if the original video memory is enough */
816 if (ofb->video_mem) { 826 if (ofb->video_mem) {
817 if (ofb->video_mem_size >= size) 827 if (ofb->video_mem_size >= size)
818 return 0; 828 return 0;
819
820 free_pages_exact(ofb->video_mem, ofb->video_mem_size);
821 } 829 }
822 830 return -EINVAL;
823 ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
824 if (ofb->video_mem == NULL)
825 return -ENOMEM;
826
827 ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
828 ofb->video_mem_size = size;
829
830 mutex_lock(&ofb->fb.mm_lock);
831 ofb->fb.fix.smem_start = ofb->video_mem_phys;
832 ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual;
833 mutex_unlock(&ofb->fb.mm_lock);
834 ofb->fb.screen_base = ofb->video_mem;
835 return 0;
836} 831}
837 832
838static int overlayfb_set_par(struct fb_info *info) 833static int overlayfb_set_par(struct fb_info *info)
@@ -841,13 +836,13 @@ static int overlayfb_set_par(struct fb_info *info)
841 struct fb_var_screeninfo *var = &info->var; 836 struct fb_var_screeninfo *var = &info->var;
842 int xpos, ypos, pfor, bpp, ret; 837 int xpos, ypos, pfor, bpp, ret;
843 838
844 ret = overlayfb_map_video_memory(ofb); 839 ret = overlayfb_check_video_memory(ofb);
845 if (ret) 840 if (ret)
846 return ret; 841 return ret;
847 842
848 bpp = pxafb_var_to_bpp(var); 843 bpp = pxafb_var_to_bpp(var);
849 xpos = NONSTD_TO_XPOS(var->nonstd); 844 xpos = NONSTD_TO_XPOS(var->nonstd);
850 ypos = NONSTD_TO_XPOS(var->nonstd); 845 ypos = NONSTD_TO_YPOS(var->nonstd);
851 pfor = NONSTD_TO_PFOR(var->nonstd); 846 pfor = NONSTD_TO_PFOR(var->nonstd);
852 847
853 ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) | 848 ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
@@ -891,7 +886,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
891 886
892 ofb->id = id; 887 ofb->id = id;
893 ofb->ops = &ofb_ops[id]; 888 ofb->ops = &ofb_ops[id];
894 atomic_set(&ofb->usage, 0); 889 ofb->usage = 0;
895 ofb->fbi = fbi; 890 ofb->fbi = fbi;
896 init_completion(&ofb->branch_done); 891 init_completion(&ofb->branch_done);
897} 892}
@@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void)
904 return 0; 899 return 0;
905} 900}
906 901
907static int __devinit pxafb_overlay_init(struct pxafb_info *fbi) 902static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
903 struct pxafb_layer *ofb)
904{
905 /* We assume that user will use at most video_mem_size for overlay fb,
906 * anyway, it's useless to use 16bpp main plane and 24bpp overlay
907 */
908 ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size),
909 GFP_KERNEL | __GFP_ZERO);
910 if (ofb->video_mem == NULL)
911 return -ENOMEM;
912
913 ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
914 ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size);
915
916 mutex_lock(&ofb->fb.mm_lock);
917 ofb->fb.fix.smem_start = ofb->video_mem_phys;
918 ofb->fb.fix.smem_len = pxafb->video_mem_size;
919 mutex_unlock(&ofb->fb.mm_lock);
920
921 ofb->fb.screen_base = ofb->video_mem;
922
923 return 0;
924}
925
926static void __devinit pxafb_overlay_init(struct pxafb_info *fbi)
908{ 927{
909 int i, ret; 928 int i, ret;
910 929
911 if (!pxafb_overlay_supported()) 930 if (!pxafb_overlay_supported())
912 return 0; 931 return;
913 932
914 for (i = 0; i < 2; i++) { 933 for (i = 0; i < 2; i++) {
915 init_pxafb_overlay(fbi, &fbi->overlay[i], i); 934 struct pxafb_layer *ofb = &fbi->overlay[i];
916 ret = register_framebuffer(&fbi->overlay[i].fb); 935 init_pxafb_overlay(fbi, ofb, i);
936 ret = register_framebuffer(&ofb->fb);
917 if (ret) { 937 if (ret) {
918 dev_err(fbi->dev, "failed to register overlay %d\n", i); 938 dev_err(fbi->dev, "failed to register overlay %d\n", i);
919 return ret; 939 continue;
920 } 940 }
941 ret = pxafb_overlay_map_video_memory(fbi, ofb);
942 if (ret) {
943 dev_err(fbi->dev,
944 "failed to map video memory for overlay %d\n",
945 i);
946 unregister_framebuffer(&ofb->fb);
947 continue;
948 }
949 ofb->registered = 1;
921 } 950 }
922 951
923 /* mask all IU/BS/EOF/SOF interrupts */ 952 /* mask all IU/BS/EOF/SOF interrupts */
924 lcd_writel(fbi, LCCR5, ~0); 953 lcd_writel(fbi, LCCR5, ~0);
925 954
926 /* place overlay(s) on top of base */
927 fbi->lccr0 |= LCCR0_OUC;
928 pr_info("PXA Overlay driver loaded successfully!\n"); 955 pr_info("PXA Overlay driver loaded successfully!\n");
929 return 0;
930} 956}
931 957
932static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) 958static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
@@ -936,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
936 if (!pxafb_overlay_supported()) 962 if (!pxafb_overlay_supported())
937 return; 963 return;
938 964
939 for (i = 0; i < 2; i++) 965 for (i = 0; i < 2; i++) {
940 unregister_framebuffer(&fbi->overlay[i].fb); 966 struct pxafb_layer *ofb = &fbi->overlay[i];
967 if (ofb->registered) {
968 if (ofb->video_mem)
969 free_pages_exact(ofb->video_mem,
970 ofb->video_mem_size);
971 unregister_framebuffer(&ofb->fb);
972 }
973 }
941} 974}
942#else 975#else
943static inline void pxafb_overlay_init(struct pxafb_info *fbi) {} 976static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}
@@ -1368,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
1368 (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || 1401 (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
1369 (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || 1402 (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
1370 (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || 1403 (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
1371 (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])) 1404 ((fbi->lccr0 & LCCR0_SDS) &&
1405 (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
1372 pxafb_schedule_work(fbi, C_REENABLE); 1406 pxafb_schedule_work(fbi, C_REENABLE);
1373 1407
1374 return 0; 1408 return 0;
@@ -1420,7 +1454,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
1420 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); 1454 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1421 1455
1422 lcd_writel(fbi, FDADR0, fbi->fdadr[0]); 1456 lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
1423 lcd_writel(fbi, FDADR1, fbi->fdadr[1]); 1457 if (fbi->lccr0 & LCCR0_SDS)
1458 lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
1424 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); 1459 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
1425} 1460}
1426 1461
@@ -1613,7 +1648,10 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
1613 1648
1614 switch (val) { 1649 switch (val) {
1615 case CPUFREQ_PRECHANGE: 1650 case CPUFREQ_PRECHANGE:
1616 set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); 1651#ifdef CONFIG_FB_PXA_OVERLAY
1652 if (!(fbi->overlay[0].usage || fbi->overlay[1].usage))
1653#endif
1654 set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
1617 break; 1655 break;
1618 1656
1619 case CPUFREQ_POSTCHANGE: 1657 case CPUFREQ_POSTCHANGE:
@@ -1806,6 +1844,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
1806 1844
1807 pxafb_decode_mach_info(fbi, inf); 1845 pxafb_decode_mach_info(fbi, inf);
1808 1846
1847#ifdef CONFIG_FB_PXA_OVERLAY
1848 /* place overlay(s) on top of base */
1849 if (pxafb_overlay_supported())
1850 fbi->lccr0 |= LCCR0_OUC;
1851#endif
1852
1809 init_waitqueue_head(&fbi->ctrlr_wait); 1853 init_waitqueue_head(&fbi->ctrlr_wait);
1810 INIT_WORK(&fbi->task, pxafb_task); 1854 INIT_WORK(&fbi->task, pxafb_task);
1811 mutex_init(&fbi->ctrlr_lock); 1855 mutex_init(&fbi->ctrlr_lock);
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 2353521c5c8c..26ba9fa3f737 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -92,7 +92,8 @@ struct pxafb_layer_ops {
92struct pxafb_layer { 92struct pxafb_layer {
93 struct fb_info fb; 93 struct fb_info fb;
94 int id; 94 int id;
95 atomic_t usage; 95 int registered;
96 uint32_t usage;
96 uint32_t control[2]; 97 uint32_t control[2];
97 98
98 struct pxafb_layer_ops *ops; 99 struct pxafb_layer_ops *ops;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index da388186d617..d8ab7be4fd6b 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -355,6 +355,7 @@ static void riva_bl_init(struct riva_par *par)
355 snprintf(name, sizeof(name), "rivabl%d", info->node); 355 snprintf(name, sizeof(name), "rivabl%d", info->node);
356 356
357 memset(&props, 0, sizeof(struct backlight_properties)); 357 memset(&props, 0, sizeof(struct backlight_properties));
358 props.type = BACKLIGHT_RAW;
358 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 359 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
359 bd = backlight_device_register(name, info->dev, par, &riva_bl_ops, 360 bd = backlight_device_register(name, info->dev, par, &riva_bl_ops,
360 &props); 361 &props);
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 83ce9a04d872..3b6cdcac8f1a 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -48,7 +48,7 @@
48#undef writel 48#undef writel
49#define writel(v, r) do { \ 49#define writel(v, r) do { \
50 printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \ 50 printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
51 __raw_writel(v, r); } while(0) 51 __raw_writel(v, r); } while (0)
52#endif /* FB_S3C_DEBUG_REGWRITE */ 52#endif /* FB_S3C_DEBUG_REGWRITE */
53 53
54/* irq_flags bits */ 54/* irq_flags bits */
@@ -518,7 +518,7 @@ static int s3c_fb_set_par(struct fb_info *info)
518 518
519 data = VIDTCON2_LINEVAL(var->yres - 1) | 519 data = VIDTCON2_LINEVAL(var->yres - 1) |
520 VIDTCON2_HOZVAL(var->xres - 1); 520 VIDTCON2_HOZVAL(var->xres - 1);
521 writel(data, regs +sfb->variant.vidtcon + 8 ); 521 writel(data, regs + sfb->variant.vidtcon + 8);
522 } 522 }
523 523
524 /* write the buffer address */ 524 /* write the buffer address */
@@ -1304,6 +1304,7 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
1304 1304
1305static int __devinit s3c_fb_probe(struct platform_device *pdev) 1305static int __devinit s3c_fb_probe(struct platform_device *pdev)
1306{ 1306{
1307 const struct platform_device_id *platid;
1307 struct s3c_fb_driverdata *fbdrv; 1308 struct s3c_fb_driverdata *fbdrv;
1308 struct device *dev = &pdev->dev; 1309 struct device *dev = &pdev->dev;
1309 struct s3c_fb_platdata *pd; 1310 struct s3c_fb_platdata *pd;
@@ -1312,7 +1313,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1312 int win; 1313 int win;
1313 int ret = 0; 1314 int ret = 0;
1314 1315
1315 fbdrv = (struct s3c_fb_driverdata *)platform_get_device_id(pdev)->driver_data; 1316 platid = platform_get_device_id(pdev);
1317 fbdrv = (struct s3c_fb_driverdata *)platid->driver_data;
1316 1318
1317 if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) { 1319 if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) {
1318 dev_err(dev, "too many windows, cannot attach\n"); 1320 dev_err(dev, "too many windows, cannot attach\n");
@@ -1340,6 +1342,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1340 sfb->bus_clk = clk_get(dev, "lcd"); 1342 sfb->bus_clk = clk_get(dev, "lcd");
1341 if (IS_ERR(sfb->bus_clk)) { 1343 if (IS_ERR(sfb->bus_clk)) {
1342 dev_err(dev, "failed to get bus clock\n"); 1344 dev_err(dev, "failed to get bus clock\n");
1345 ret = PTR_ERR(sfb->bus_clk);
1343 goto err_sfb; 1346 goto err_sfb;
1344 } 1347 }
1345 1348
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 75738a928610..c4482f2e5799 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -64,15 +64,18 @@ static const struct svga_fb_format s3fb_formats[] = {
64 64
65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, 65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
66 35000, 240000, 14318}; 66 35000, 240000, 14318};
67static const struct svga_pll s3_trio3d_pll = {3, 129, 3, 31, 0, 4,
68 230000, 460000, 14318};
67 69
68static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; 70static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
69 71
70static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+", 72static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+",
71 "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX", 73 "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX",
72 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", 74 "S3 Plato/PX", "S3 Aurora64V+", "S3 Virge",
73 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
74 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P", 76 "S3 Virge/GX2", "S3 Virge/GX2+", "",
75 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X"}; 77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
78 "S3 Trio3D"};
76 79
77#define CHIP_UNKNOWN 0x00 80#define CHIP_UNKNOWN 0x00
78#define CHIP_732_TRIO32 0x01 81#define CHIP_732_TRIO32 0x01
@@ -87,12 +90,12 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
87#define CHIP_988_VIRGE_VX 0x0A 90#define CHIP_988_VIRGE_VX 0x0A
88#define CHIP_375_VIRGE_DX 0x0B 91#define CHIP_375_VIRGE_DX 0x0B
89#define CHIP_385_VIRGE_GX 0x0C 92#define CHIP_385_VIRGE_GX 0x0C
90#define CHIP_356_VIRGE_GX2 0x0D 93#define CHIP_357_VIRGE_GX2 0x0D
91#define CHIP_357_VIRGE_GX2P 0x0E 94#define CHIP_359_VIRGE_GX2P 0x0E
92#define CHIP_359_VIRGE_GX2P 0x0F
93#define CHIP_360_TRIO3D_1X 0x10 95#define CHIP_360_TRIO3D_1X 0x10
94#define CHIP_362_TRIO3D_2X 0x11 96#define CHIP_362_TRIO3D_2X 0x11
95#define CHIP_368_TRIO3D_2X 0x12 97#define CHIP_368_TRIO3D_2X 0x12
98#define CHIP_365_TRIO3D 0x13
96 99
97#define CHIP_XXX_TRIO 0x80 100#define CHIP_XXX_TRIO 0x80
98#define CHIP_XXX_TRIO64V2_DXGX 0x81 101#define CHIP_XXX_TRIO64V2_DXGX 0x81
@@ -119,9 +122,11 @@ static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07,
119static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; 122static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END};
120 123
121static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END}; 124static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END};
122static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; 125static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x69, 0, 4}, VGA_REGSET_END};
123static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ 126static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */
124 127
128static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END};
129
125static const struct svga_timing_regs s3_timing_regs = { 130static const struct svga_timing_regs s3_timing_regs = {
126 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs, 131 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs,
127 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs, 132 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs,
@@ -188,12 +193,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
188 } 193 }
189} 194}
190 195
196static void s3fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
197{
198 struct s3fb_info *par = info->par;
199
200 svga_tilecursor(par->state.vgabase, info, cursor);
201}
202
191static struct fb_tile_ops s3fb_tile_ops = { 203static struct fb_tile_ops s3fb_tile_ops = {
192 .fb_settile = svga_settile, 204 .fb_settile = svga_settile,
193 .fb_tilecopy = svga_tilecopy, 205 .fb_tilecopy = svga_tilecopy,
194 .fb_tilefill = svga_tilefill, 206 .fb_tilefill = svga_tilefill,
195 .fb_tileblit = svga_tileblit, 207 .fb_tileblit = svga_tileblit,
196 .fb_tilecursor = svga_tilecursor, 208 .fb_tilecursor = s3fb_tilecursor,
197 .fb_get_tilemax = svga_get_tilemax, 209 .fb_get_tilemax = svga_get_tilemax,
198}; 210};
199 211
@@ -202,7 +214,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = {
202 .fb_tilecopy = svga_tilecopy, 214 .fb_tilecopy = svga_tilecopy,
203 .fb_tilefill = svga_tilefill, 215 .fb_tilefill = svga_tilefill,
204 .fb_tileblit = svga_tileblit, 216 .fb_tileblit = svga_tileblit,
205 .fb_tilecursor = svga_tilecursor, 217 .fb_tilecursor = s3fb_tilecursor,
206 .fb_get_tilemax = svga_get_tilemax, 218 .fb_get_tilemax = svga_get_tilemax,
207}; 219};
208 220
@@ -334,33 +346,36 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
334 u8 regval; 346 u8 regval;
335 int rv; 347 int rv;
336 348
337 rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); 349 rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll,
350 1000000000 / pixclock, &m, &n, &r, info->node);
338 if (rv < 0) { 351 if (rv < 0) {
339 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); 352 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
340 return; 353 return;
341 } 354 }
342 355
343 /* Set VGA misc register */ 356 /* Set VGA misc register */
344 regval = vga_r(NULL, VGA_MIS_R); 357 regval = vga_r(par->state.vgabase, VGA_MIS_R);
345 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 358 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
346 359
347 /* Set S3 clock registers */ 360 /* Set S3 clock registers */
348 if (par->chip == CHIP_360_TRIO3D_1X || 361 if (par->chip == CHIP_357_VIRGE_GX2 ||
362 par->chip == CHIP_359_VIRGE_GX2P ||
363 par->chip == CHIP_360_TRIO3D_1X ||
349 par->chip == CHIP_362_TRIO3D_2X || 364 par->chip == CHIP_362_TRIO3D_2X ||
350 par->chip == CHIP_368_TRIO3D_2X) { 365 par->chip == CHIP_368_TRIO3D_2X) {
351 vga_wseq(NULL, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 366 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
352 vga_wseq(NULL, 0x29, r >> 2); /* remaining highest bit of r */ 367 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */
353 } else 368 } else
354 vga_wseq(NULL, 0x12, (n - 2) | (r << 5)); 369 vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5));
355 vga_wseq(NULL, 0x13, m - 2); 370 vga_wseq(par->state.vgabase, 0x13, m - 2);
356 371
357 udelay(1000); 372 udelay(1000);
358 373
359 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ 374 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */
360 regval = vga_rseq (NULL, 0x15); /* | 0x80; */ 375 regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */
361 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 376 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
362 vga_wseq(NULL, 0x15, regval | (1<<5)); 377 vga_wseq(par->state.vgabase, 0x15, regval | (1<<5));
363 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 378 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
364} 379}
365 380
366 381
@@ -372,7 +387,10 @@ static int s3fb_open(struct fb_info *info, int user)
372 387
373 mutex_lock(&(par->open_lock)); 388 mutex_lock(&(par->open_lock));
374 if (par->ref_count == 0) { 389 if (par->ref_count == 0) {
390 void __iomem *vgabase = par->state.vgabase;
391
375 memset(&(par->state), 0, sizeof(struct vgastate)); 392 memset(&(par->state), 0, sizeof(struct vgastate));
393 par->state.vgabase = vgabase;
376 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 394 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
377 par->state.num_crtc = 0x70; 395 par->state.num_crtc = 0x70;
378 par->state.num_seq = 0x20; 396 par->state.num_seq = 0x20;
@@ -470,6 +488,7 @@ static int s3fb_set_par(struct fb_info *info)
470 struct s3fb_info *par = info->par; 488 struct s3fb_info *par = info->par;
471 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; 489 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes;
472 u32 bpp = info->var.bits_per_pixel; 490 u32 bpp = info->var.bits_per_pixel;
491 u32 htotal, hsstart;
473 492
474 if (bpp != 0) { 493 if (bpp != 0) {
475 info->fix.ypanstep = 1; 494 info->fix.ypanstep = 1;
@@ -504,99 +523,115 @@ static int s3fb_set_par(struct fb_info *info)
504 info->var.activate = FB_ACTIVATE_NOW; 523 info->var.activate = FB_ACTIVATE_NOW;
505 524
506 /* Unlock registers */ 525 /* Unlock registers */
507 vga_wcrt(NULL, 0x38, 0x48); 526 vga_wcrt(par->state.vgabase, 0x38, 0x48);
508 vga_wcrt(NULL, 0x39, 0xA5); 527 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
509 vga_wseq(NULL, 0x08, 0x06); 528 vga_wseq(par->state.vgabase, 0x08, 0x06);
510 svga_wcrt_mask(0x11, 0x00, 0x80); 529 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
511 530
512 /* Blank screen and turn off sync */ 531 /* Blank screen and turn off sync */
513 svga_wseq_mask(0x01, 0x20, 0x20); 532 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
514 svga_wcrt_mask(0x17, 0x00, 0x80); 533 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
515 534
516 /* Set default values */ 535 /* Set default values */
517 svga_set_default_gfx_regs(); 536 svga_set_default_gfx_regs(par->state.vgabase);
518 svga_set_default_atc_regs(); 537 svga_set_default_atc_regs(par->state.vgabase);
519 svga_set_default_seq_regs(); 538 svga_set_default_seq_regs(par->state.vgabase);
520 svga_set_default_crt_regs(); 539 svga_set_default_crt_regs(par->state.vgabase);
521 svga_wcrt_multi(s3_line_compare_regs, 0xFFFFFFFF); 540 svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF);
522 svga_wcrt_multi(s3_start_address_regs, 0); 541 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0);
523 542
524 /* S3 specific initialization */ 543 /* S3 specific initialization */
525 svga_wcrt_mask(0x58, 0x10, 0x10); /* enable linear framebuffer */ 544 svga_wcrt_mask(par->state.vgabase, 0x58, 0x10, 0x10); /* enable linear framebuffer */
526 svga_wcrt_mask(0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */ 545 svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */
527 546
528/* svga_wcrt_mask(0x33, 0x08, 0x08); */ /* DDR ? */ 547/* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */
529/* svga_wcrt_mask(0x43, 0x01, 0x01); */ /* DDR ? */ 548/* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */
530 svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */ 549 svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */
531 svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */ 550 svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */
532 551
533 svga_wcrt_mask(0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ 552 svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */
534 553
535/* svga_wcrt_mask(0x58, 0x03, 0x03); */ 554/* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */
536 555
537/* svga_wcrt_mask(0x53, 0x12, 0x13); */ /* enable MMIO */ 556/* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */
538/* svga_wcrt_mask(0x40, 0x08, 0x08); */ /* enable write buffer */ 557/* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */
539 558
540 559
541 /* Set the offset register */ 560 /* Set the offset register */
542 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 561 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
543 svga_wcrt_multi(s3_offset_regs, offset_value); 562 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);
544 563
545 if (par->chip != CHIP_360_TRIO3D_1X && 564 if (par->chip != CHIP_357_VIRGE_GX2 &&
565 par->chip != CHIP_359_VIRGE_GX2P &&
566 par->chip != CHIP_360_TRIO3D_1X &&
546 par->chip != CHIP_362_TRIO3D_2X && 567 par->chip != CHIP_362_TRIO3D_2X &&
547 par->chip != CHIP_368_TRIO3D_2X) { 568 par->chip != CHIP_368_TRIO3D_2X) {
548 vga_wcrt(NULL, 0x54, 0x18); /* M parameter */ 569 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
549 vga_wcrt(NULL, 0x60, 0xff); /* N parameter */ 570 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */
550 vga_wcrt(NULL, 0x61, 0xff); /* L parameter */ 571 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */
551 vga_wcrt(NULL, 0x62, 0xff); /* L parameter */ 572 vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */
552 } 573 }
553 574
554 vga_wcrt(NULL, 0x3A, 0x35); 575 vga_wcrt(par->state.vgabase, 0x3A, 0x35);
555 svga_wattr(0x33, 0x00); 576 svga_wattr(par->state.vgabase, 0x33, 0x00);
556 577
557 if (info->var.vmode & FB_VMODE_DOUBLE) 578 if (info->var.vmode & FB_VMODE_DOUBLE)
558 svga_wcrt_mask(0x09, 0x80, 0x80); 579 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
559 else 580 else
560 svga_wcrt_mask(0x09, 0x00, 0x80); 581 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
561 582
562 if (info->var.vmode & FB_VMODE_INTERLACED) 583 if (info->var.vmode & FB_VMODE_INTERLACED)
563 svga_wcrt_mask(0x42, 0x20, 0x20); 584 svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20);
564 else 585 else
565 svga_wcrt_mask(0x42, 0x00, 0x20); 586 svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20);
566 587
567 /* Disable hardware graphics cursor */ 588 /* Disable hardware graphics cursor */
568 svga_wcrt_mask(0x45, 0x00, 0x01); 589 svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01);
569 /* Disable Streams engine */ 590 /* Disable Streams engine */
570 svga_wcrt_mask(0x67, 0x00, 0x0C); 591 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C);
571 592
572 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); 593 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix));
573 594
574 /* S3 virge DX hack */ 595 /* S3 virge DX hack */
575 if (par->chip == CHIP_375_VIRGE_DX) { 596 if (par->chip == CHIP_375_VIRGE_DX) {
576 vga_wcrt(NULL, 0x86, 0x80); 597 vga_wcrt(par->state.vgabase, 0x86, 0x80);
577 vga_wcrt(NULL, 0x90, 0x00); 598 vga_wcrt(par->state.vgabase, 0x90, 0x00);
578 } 599 }
579 600
580 /* S3 virge VX hack */ 601 /* S3 virge VX hack */
581 if (par->chip == CHIP_988_VIRGE_VX) { 602 if (par->chip == CHIP_988_VIRGE_VX) {
582 vga_wcrt(NULL, 0x50, 0x00); 603 vga_wcrt(par->state.vgabase, 0x50, 0x00);
583 vga_wcrt(NULL, 0x67, 0x50); 604 vga_wcrt(par->state.vgabase, 0x67, 0x50);
584 605
585 vga_wcrt(NULL, 0x63, (mode <= 2) ? 0x90 : 0x09); 606 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
586 vga_wcrt(NULL, 0x66, 0x90); 607 vga_wcrt(par->state.vgabase, 0x66, 0x90);
587 } 608 }
588 609
589 if (par->chip == CHIP_360_TRIO3D_1X || 610 if (par->chip == CHIP_357_VIRGE_GX2 ||
611 par->chip == CHIP_359_VIRGE_GX2P ||
612 par->chip == CHIP_360_TRIO3D_1X ||
590 par->chip == CHIP_362_TRIO3D_2X || 613 par->chip == CHIP_362_TRIO3D_2X ||
591 par->chip == CHIP_368_TRIO3D_2X) { 614 par->chip == CHIP_368_TRIO3D_2X ||
615 par->chip == CHIP_365_TRIO3D ||
616 par->chip == CHIP_375_VIRGE_DX ||
617 par->chip == CHIP_385_VIRGE_GX) {
592 dbytes = info->var.xres * ((bpp+7)/8); 618 dbytes = info->var.xres * ((bpp+7)/8);
593 vga_wcrt(NULL, 0x91, (dbytes + 7) / 8); 619 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8);
594 vga_wcrt(NULL, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); 620 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
595 621
596 vga_wcrt(NULL, 0x66, 0x81); 622 vga_wcrt(par->state.vgabase, 0x66, 0x81);
597 } 623 }
598 624
599 svga_wcrt_mask(0x31, 0x00, 0x40); 625 if (par->chip == CHIP_357_VIRGE_GX2 ||
626 par->chip == CHIP_359_VIRGE_GX2P ||
627 par->chip == CHIP_360_TRIO3D_1X ||
628 par->chip == CHIP_362_TRIO3D_2X ||
629 par->chip == CHIP_368_TRIO3D_2X)
630 vga_wcrt(par->state.vgabase, 0x34, 0x00);
631 else /* enable Data Transfer Position Control (DTPC) */
632 vga_wcrt(par->state.vgabase, 0x34, 0x10);
633
634 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40);
600 multiplex = 0; 635 multiplex = 0;
601 hmul = 1; 636 hmul = 1;
602 637
@@ -604,51 +639,53 @@ static int s3fb_set_par(struct fb_info *info)
604 switch (mode) { 639 switch (mode) {
605 case 0: 640 case 0:
606 pr_debug("fb%d: text mode\n", info->node); 641 pr_debug("fb%d: text mode\n", info->node);
607 svga_set_textmode_vga_regs(); 642 svga_set_textmode_vga_regs(par->state.vgabase);
608 643
609 /* Set additional registers like in 8-bit mode */ 644 /* Set additional registers like in 8-bit mode */
610 svga_wcrt_mask(0x50, 0x00, 0x30); 645 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
611 svga_wcrt_mask(0x67, 0x00, 0xF0); 646 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
612 647
613 /* Disable enhanced mode */ 648 /* Disable enhanced mode */
614 svga_wcrt_mask(0x3A, 0x00, 0x30); 649 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
615 650
616 if (fasttext) { 651 if (fasttext) {
617 pr_debug("fb%d: high speed text mode set\n", info->node); 652 pr_debug("fb%d: high speed text mode set\n", info->node);
618 svga_wcrt_mask(0x31, 0x40, 0x40); 653 svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40);
619 } 654 }
620 break; 655 break;
621 case 1: 656 case 1:
622 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 657 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
623 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 658 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
624 659
625 /* Set additional registers like in 8-bit mode */ 660 /* Set additional registers like in 8-bit mode */
626 svga_wcrt_mask(0x50, 0x00, 0x30); 661 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
627 svga_wcrt_mask(0x67, 0x00, 0xF0); 662 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
628 663
629 /* disable enhanced mode */ 664 /* disable enhanced mode */
630 svga_wcrt_mask(0x3A, 0x00, 0x30); 665 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
631 break; 666 break;
632 case 2: 667 case 2:
633 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 668 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
634 669
635 /* Set additional registers like in 8-bit mode */ 670 /* Set additional registers like in 8-bit mode */
636 svga_wcrt_mask(0x50, 0x00, 0x30); 671 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
637 svga_wcrt_mask(0x67, 0x00, 0xF0); 672 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
638 673
639 /* disable enhanced mode */ 674 /* disable enhanced mode */
640 svga_wcrt_mask(0x3A, 0x00, 0x30); 675 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
641 break; 676 break;
642 case 3: 677 case 3:
643 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 678 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
644 svga_wcrt_mask(0x50, 0x00, 0x30); 679 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
645 if (info->var.pixclock > 20000 || 680 if (info->var.pixclock > 20000 ||
681 par->chip == CHIP_357_VIRGE_GX2 ||
682 par->chip == CHIP_359_VIRGE_GX2P ||
646 par->chip == CHIP_360_TRIO3D_1X || 683 par->chip == CHIP_360_TRIO3D_1X ||
647 par->chip == CHIP_362_TRIO3D_2X || 684 par->chip == CHIP_362_TRIO3D_2X ||
648 par->chip == CHIP_368_TRIO3D_2X) 685 par->chip == CHIP_368_TRIO3D_2X)
649 svga_wcrt_mask(0x67, 0x00, 0xF0); 686 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
650 else { 687 else {
651 svga_wcrt_mask(0x67, 0x10, 0xF0); 688 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0);
652 multiplex = 1; 689 multiplex = 1;
653 } 690 }
654 break; 691 break;
@@ -656,13 +693,24 @@ static int s3fb_set_par(struct fb_info *info)
656 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 693 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
657 if (par->chip == CHIP_988_VIRGE_VX) { 694 if (par->chip == CHIP_988_VIRGE_VX) {
658 if (info->var.pixclock > 20000) 695 if (info->var.pixclock > 20000)
659 svga_wcrt_mask(0x67, 0x20, 0xF0); 696 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
660 else 697 else
661 svga_wcrt_mask(0x67, 0x30, 0xF0); 698 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
699 } else if (par->chip == CHIP_365_TRIO3D) {
700 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
701 if (info->var.pixclock > 8695) {
702 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
703 hmul = 2;
704 } else {
705 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
706 multiplex = 1;
707 }
662 } else { 708 } else {
663 svga_wcrt_mask(0x50, 0x10, 0x30); 709 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
664 svga_wcrt_mask(0x67, 0x30, 0xF0); 710 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
665 if (par->chip != CHIP_360_TRIO3D_1X && 711 if (par->chip != CHIP_357_VIRGE_GX2 &&
712 par->chip != CHIP_359_VIRGE_GX2P &&
713 par->chip != CHIP_360_TRIO3D_1X &&
666 par->chip != CHIP_362_TRIO3D_2X && 714 par->chip != CHIP_362_TRIO3D_2X &&
667 par->chip != CHIP_368_TRIO3D_2X) 715 par->chip != CHIP_368_TRIO3D_2X)
668 hmul = 2; 716 hmul = 2;
@@ -672,13 +720,24 @@ static int s3fb_set_par(struct fb_info *info)
672 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 720 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
673 if (par->chip == CHIP_988_VIRGE_VX) { 721 if (par->chip == CHIP_988_VIRGE_VX) {
674 if (info->var.pixclock > 20000) 722 if (info->var.pixclock > 20000)
675 svga_wcrt_mask(0x67, 0x40, 0xF0); 723 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
676 else 724 else
677 svga_wcrt_mask(0x67, 0x50, 0xF0); 725 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
726 } else if (par->chip == CHIP_365_TRIO3D) {
727 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
728 if (info->var.pixclock > 8695) {
729 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
730 hmul = 2;
731 } else {
732 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
733 multiplex = 1;
734 }
678 } else { 735 } else {
679 svga_wcrt_mask(0x50, 0x10, 0x30); 736 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
680 svga_wcrt_mask(0x67, 0x50, 0xF0); 737 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
681 if (par->chip != CHIP_360_TRIO3D_1X && 738 if (par->chip != CHIP_357_VIRGE_GX2 &&
739 par->chip != CHIP_359_VIRGE_GX2P &&
740 par->chip != CHIP_360_TRIO3D_1X &&
682 par->chip != CHIP_362_TRIO3D_2X && 741 par->chip != CHIP_362_TRIO3D_2X &&
683 par->chip != CHIP_368_TRIO3D_2X) 742 par->chip != CHIP_368_TRIO3D_2X)
684 hmul = 2; 743 hmul = 2;
@@ -687,12 +746,12 @@ static int s3fb_set_par(struct fb_info *info)
687 case 6: 746 case 6:
688 /* VIRGE VX case */ 747 /* VIRGE VX case */
689 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 748 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
690 svga_wcrt_mask(0x67, 0xD0, 0xF0); 749 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
691 break; 750 break;
692 case 7: 751 case 7:
693 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 752 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
694 svga_wcrt_mask(0x50, 0x30, 0x30); 753 svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30);
695 svga_wcrt_mask(0x67, 0xD0, 0xF0); 754 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
696 break; 755 break;
697 default: 756 default:
698 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); 757 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node);
@@ -700,25 +759,30 @@ static int s3fb_set_par(struct fb_info *info)
700 } 759 }
701 760
702 if (par->chip != CHIP_988_VIRGE_VX) { 761 if (par->chip != CHIP_988_VIRGE_VX) {
703 svga_wseq_mask(0x15, multiplex ? 0x10 : 0x00, 0x10); 762 svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10);
704 svga_wseq_mask(0x18, multiplex ? 0x80 : 0x00, 0x80); 763 svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80);
705 } 764 }
706 765
707 s3_set_pixclock(info, info->var.pixclock); 766 s3_set_pixclock(info, info->var.pixclock);
708 svga_set_timings(&s3_timing_regs, &(info->var), hmul, 1, 767 svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1,
709 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 768 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
710 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 769 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
711 hmul, info->node); 770 hmul, info->node);
712 771
713 /* Set interlaced mode start/end register */ 772 /* Set interlaced mode start/end register */
714 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 773 htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
715 value = ((value * hmul) / 8) - 5; 774 htotal = ((htotal * hmul) / 8) - 5;
716 vga_wcrt(NULL, 0x3C, (value + 1) / 2); 775 vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2);
776
777 /* Set Data Transfer Position */
778 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
779 value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
780 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
717 781
718 memset_io(info->screen_base, 0x00, screen_size); 782 memset_io(info->screen_base, 0x00, screen_size);
719 /* Device and screen back on */ 783 /* Device and screen back on */
720 svga_wcrt_mask(0x17, 0x80, 0x80); 784 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
721 svga_wseq_mask(0x01, 0x00, 0x20); 785 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
722 786
723 return 0; 787 return 0;
724} 788}
@@ -788,31 +852,33 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
788 852
789static int s3fb_blank(int blank_mode, struct fb_info *info) 853static int s3fb_blank(int blank_mode, struct fb_info *info)
790{ 854{
855 struct s3fb_info *par = info->par;
856
791 switch (blank_mode) { 857 switch (blank_mode) {
792 case FB_BLANK_UNBLANK: 858 case FB_BLANK_UNBLANK:
793 pr_debug("fb%d: unblank\n", info->node); 859 pr_debug("fb%d: unblank\n", info->node);
794 svga_wcrt_mask(0x56, 0x00, 0x06); 860 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
795 svga_wseq_mask(0x01, 0x00, 0x20); 861 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
796 break; 862 break;
797 case FB_BLANK_NORMAL: 863 case FB_BLANK_NORMAL:
798 pr_debug("fb%d: blank\n", info->node); 864 pr_debug("fb%d: blank\n", info->node);
799 svga_wcrt_mask(0x56, 0x00, 0x06); 865 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
800 svga_wseq_mask(0x01, 0x20, 0x20); 866 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
801 break; 867 break;
802 case FB_BLANK_HSYNC_SUSPEND: 868 case FB_BLANK_HSYNC_SUSPEND:
803 pr_debug("fb%d: hsync\n", info->node); 869 pr_debug("fb%d: hsync\n", info->node);
804 svga_wcrt_mask(0x56, 0x02, 0x06); 870 svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);
805 svga_wseq_mask(0x01, 0x20, 0x20); 871 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
806 break; 872 break;
807 case FB_BLANK_VSYNC_SUSPEND: 873 case FB_BLANK_VSYNC_SUSPEND:
808 pr_debug("fb%d: vsync\n", info->node); 874 pr_debug("fb%d: vsync\n", info->node);
809 svga_wcrt_mask(0x56, 0x04, 0x06); 875 svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);
810 svga_wseq_mask(0x01, 0x20, 0x20); 876 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
811 break; 877 break;
812 case FB_BLANK_POWERDOWN: 878 case FB_BLANK_POWERDOWN:
813 pr_debug("fb%d: sync down\n", info->node); 879 pr_debug("fb%d: sync down\n", info->node);
814 svga_wcrt_mask(0x56, 0x06, 0x06); 880 svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);
815 svga_wseq_mask(0x01, 0x20, 0x20); 881 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
816 break; 882 break;
817 } 883 }
818 884
@@ -822,8 +888,9 @@ static int s3fb_blank(int blank_mode, struct fb_info *info)
822 888
823/* Pan the display */ 889/* Pan the display */
824 890
825static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { 891static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
826 892{
893 struct s3fb_info *par = info->par;
827 unsigned int offset; 894 unsigned int offset;
828 895
829 /* Calculate the offset */ 896 /* Calculate the offset */
@@ -837,7 +904,7 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
837 } 904 }
838 905
839 /* Set the offset */ 906 /* Set the offset */
840 svga_wcrt_multi(s3_start_address_regs, offset); 907 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset);
841 908
842 return 0; 909 return 0;
843} 910}
@@ -863,12 +930,14 @@ static struct fb_ops s3fb_ops = {
863 930
864/* ------------------------------------------------------------------------- */ 931/* ------------------------------------------------------------------------- */
865 932
866static int __devinit s3_identification(int chip) 933static int __devinit s3_identification(struct s3fb_info *par)
867{ 934{
935 int chip = par->chip;
936
868 if (chip == CHIP_XXX_TRIO) { 937 if (chip == CHIP_XXX_TRIO) {
869 u8 cr30 = vga_rcrt(NULL, 0x30); 938 u8 cr30 = vga_rcrt(par->state.vgabase, 0x30);
870 u8 cr2e = vga_rcrt(NULL, 0x2e); 939 u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e);
871 u8 cr2f = vga_rcrt(NULL, 0x2f); 940 u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f);
872 941
873 if ((cr30 == 0xE0) || (cr30 == 0xE1)) { 942 if ((cr30 == 0xE0) || (cr30 == 0xE1)) {
874 if (cr2e == 0x10) 943 if (cr2e == 0x10)
@@ -883,7 +952,7 @@ static int __devinit s3_identification(int chip)
883 } 952 }
884 953
885 if (chip == CHIP_XXX_TRIO64V2_DXGX) { 954 if (chip == CHIP_XXX_TRIO64V2_DXGX) {
886 u8 cr6f = vga_rcrt(NULL, 0x6f); 955 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
887 956
888 if (! (cr6f & 0x01)) 957 if (! (cr6f & 0x01))
889 return CHIP_775_TRIO64V2_DX; 958 return CHIP_775_TRIO64V2_DX;
@@ -892,7 +961,7 @@ static int __devinit s3_identification(int chip)
892 } 961 }
893 962
894 if (chip == CHIP_XXX_VIRGE_DXGX) { 963 if (chip == CHIP_XXX_VIRGE_DXGX) {
895 u8 cr6f = vga_rcrt(NULL, 0x6f); 964 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
896 965
897 if (! (cr6f & 0x01)) 966 if (! (cr6f & 0x01))
898 return CHIP_375_VIRGE_DX; 967 return CHIP_375_VIRGE_DX;
@@ -901,7 +970,7 @@ static int __devinit s3_identification(int chip)
901 } 970 }
902 971
903 if (chip == CHIP_36X_TRIO3D_1X_2X) { 972 if (chip == CHIP_36X_TRIO3D_1X_2X) {
904 switch (vga_rcrt(NULL, 0x2f)) { 973 switch (vga_rcrt(par->state.vgabase, 0x2f)) {
905 case 0x00: 974 case 0x00:
906 return CHIP_360_TRIO3D_1X; 975 return CHIP_360_TRIO3D_1X;
907 case 0x01: 976 case 0x01:
@@ -919,6 +988,8 @@ static int __devinit s3_identification(int chip)
919 988
920static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 989static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
921{ 990{
991 struct pci_bus_region bus_reg;
992 struct resource vga_res;
922 struct fb_info *info; 993 struct fb_info *info;
923 struct s3fb_info *par; 994 struct s3fb_info *par;
924 int rc; 995 int rc;
@@ -968,47 +1039,68 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
968 goto err_iomap; 1039 goto err_iomap;
969 } 1040 }
970 1041
1042 bus_reg.start = 0;
1043 bus_reg.end = 64 * 1024;
1044
1045 vga_res.flags = IORESOURCE_IO;
1046
1047 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1048
1049 par->state.vgabase = (void __iomem *) vga_res.start;
1050
971 /* Unlock regs */ 1051 /* Unlock regs */
972 cr38 = vga_rcrt(NULL, 0x38); 1052 cr38 = vga_rcrt(par->state.vgabase, 0x38);
973 cr39 = vga_rcrt(NULL, 0x39); 1053 cr39 = vga_rcrt(par->state.vgabase, 0x39);
974 vga_wseq(NULL, 0x08, 0x06); 1054 vga_wseq(par->state.vgabase, 0x08, 0x06);
975 vga_wcrt(NULL, 0x38, 0x48); 1055 vga_wcrt(par->state.vgabase, 0x38, 0x48);
976 vga_wcrt(NULL, 0x39, 0xA5); 1056 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
977 1057
978 /* Identify chip type */ 1058 /* Identify chip type */
979 par->chip = id->driver_data & CHIP_MASK; 1059 par->chip = id->driver_data & CHIP_MASK;
980 par->rev = vga_rcrt(NULL, 0x2f); 1060 par->rev = vga_rcrt(par->state.vgabase, 0x2f);
981 if (par->chip & CHIP_UNDECIDED_FLAG) 1061 if (par->chip & CHIP_UNDECIDED_FLAG)
982 par->chip = s3_identification(par->chip); 1062 par->chip = s3_identification(par);
983 1063
984 /* Find how many physical memory there is on card */ 1064 /* Find how many physical memory there is on card */
985 /* 0x36 register is accessible even if other registers are locked */ 1065 /* 0x36 register is accessible even if other registers are locked */
986 regval = vga_rcrt(NULL, 0x36); 1066 regval = vga_rcrt(par->state.vgabase, 0x36);
987 if (par->chip == CHIP_360_TRIO3D_1X || 1067 if (par->chip == CHIP_360_TRIO3D_1X ||
988 par->chip == CHIP_362_TRIO3D_2X || 1068 par->chip == CHIP_362_TRIO3D_2X ||
989 par->chip == CHIP_368_TRIO3D_2X) { 1069 par->chip == CHIP_368_TRIO3D_2X ||
1070 par->chip == CHIP_365_TRIO3D) {
990 switch ((regval & 0xE0) >> 5) { 1071 switch ((regval & 0xE0) >> 5) {
991 case 0: /* 8MB -- only 4MB usable for display */ 1072 case 0: /* 8MB -- only 4MB usable for display */
992 case 1: /* 4MB with 32-bit bus */ 1073 case 1: /* 4MB with 32-bit bus */
993 case 2: /* 4MB */ 1074 case 2: /* 4MB */
994 info->screen_size = 4 << 20; 1075 info->screen_size = 4 << 20;
995 break; 1076 break;
1077 case 4: /* 2MB on 365 Trio3D */
996 case 6: /* 2MB */ 1078 case 6: /* 2MB */
997 info->screen_size = 2 << 20; 1079 info->screen_size = 2 << 20;
998 break; 1080 break;
999 } 1081 }
1082 } else if (par->chip == CHIP_357_VIRGE_GX2 ||
1083 par->chip == CHIP_359_VIRGE_GX2P) {
1084 switch ((regval & 0xC0) >> 6) {
1085 case 1: /* 4MB */
1086 info->screen_size = 4 << 20;
1087 break;
1088 case 3: /* 2MB */
1089 info->screen_size = 2 << 20;
1090 break;
1091 }
1000 } else 1092 } else
1001 info->screen_size = s3_memsizes[regval >> 5] << 10; 1093 info->screen_size = s3_memsizes[regval >> 5] << 10;
1002 info->fix.smem_len = info->screen_size; 1094 info->fix.smem_len = info->screen_size;
1003 1095
1004 /* Find MCLK frequency */ 1096 /* Find MCLK frequency */
1005 regval = vga_rseq(NULL, 0x10); 1097 regval = vga_rseq(par->state.vgabase, 0x10);
1006 par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); 1098 par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2);
1007 par->mclk_freq = par->mclk_freq >> (regval >> 5); 1099 par->mclk_freq = par->mclk_freq >> (regval >> 5);
1008 1100
1009 /* Restore locks */ 1101 /* Restore locks */
1010 vga_wcrt(NULL, 0x38, cr38); 1102 vga_wcrt(par->state.vgabase, 0x38, cr38);
1011 vga_wcrt(NULL, 0x39, cr39); 1103 vga_wcrt(par->state.vgabase, 0x39, cr39);
1012 1104
1013 strcpy(info->fix.id, s3_names [par->chip]); 1105 strcpy(info->fix.id, s3_names [par->chip]);
1014 info->fix.mmio_start = 0; 1106 info->fix.mmio_start = 0;
@@ -1027,6 +1119,14 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1027 goto err_find_mode; 1119 goto err_find_mode;
1028 } 1120 }
1029 1121
1122 /* maximize virtual vertical size for fast scrolling */
1123 info->var.yres_virtual = info->fix.smem_len * 8 /
1124 (info->var.bits_per_pixel * info->var.xres_virtual);
1125 if (info->var.yres_virtual < info->var.yres) {
1126 dev_err(info->device, "virtual vertical size smaller than real\n");
1127 goto err_find_mode;
1128 }
1129
1030 rc = fb_alloc_cmap(&info->cmap, 256, 0); 1130 rc = fb_alloc_cmap(&info->cmap, 256, 0);
1031 if (rc < 0) { 1131 if (rc < 0) {
1032 dev_err(info->device, "cannot allocate colormap\n"); 1132 dev_err(info->device, "cannot allocate colormap\n");
@@ -1044,8 +1144,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1044 1144
1045 if (par->chip == CHIP_UNKNOWN) 1145 if (par->chip == CHIP_UNKNOWN)
1046 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", 1146 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n",
1047 info->node, vga_rcrt(NULL, 0x2d), vga_rcrt(NULL, 0x2e), 1147 info->node, vga_rcrt(par->state.vgabase, 0x2d), vga_rcrt(par->state.vgabase, 0x2e),
1048 vga_rcrt(NULL, 0x2f), vga_rcrt(NULL, 0x30)); 1148 vga_rcrt(par->state.vgabase, 0x2f), vga_rcrt(par->state.vgabase, 0x30));
1049 1149
1050 /* Record a reference to the driver data */ 1150 /* Record a reference to the driver data */
1051 pci_set_drvdata(dev, info); 1151 pci_set_drvdata(dev, info);
@@ -1188,10 +1288,11 @@ static struct pci_device_id s3_devices[] __devinitdata = {
1188 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE}, 1288 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE},
1189 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX}, 1289 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX},
1190 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX}, 1290 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX},
1191 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_356_VIRGE_GX2}, 1291 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_357_VIRGE_GX2},
1192 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, 1292 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_359_VIRGE_GX2P},
1193 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1293 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
1194 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1294 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
1295 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
1195 1296
1196 {0, 0, 0, 0, 0, 0, 0} 1297 {0, 0, 0, 0, 0, 0, 0}
1197}; 1298};
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index b16e6138fdd4..bb71fea07284 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -159,8 +159,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
159 else 159 else
160 dev_warn(&chan->par->pcidev->dev, 160 dev_warn(&chan->par->pcidev->dev,
161 "Failed to register I2C bus %s.\n", name); 161 "Failed to register I2C bus %s.\n", name);
162 } else 162 }
163 chan->par = NULL;
164 163
165 return rc; 164 return rc;
166} 165}
@@ -170,9 +169,8 @@ void savagefb_create_i2c_busses(struct fb_info *info)
170 struct savagefb_par *par = info->par; 169 struct savagefb_par *par = info->par;
171 par->chan.par = par; 170 par->chan.par = par;
172 171
173 switch(info->fix.accel) { 172 switch (par->chip) {
174 case FB_ACCEL_PROSAVAGE_DDRK: 173 case S3_PROSAVAGE:
175 case FB_ACCEL_PROSAVAGE_PM:
176 par->chan.reg = CR_SERIAL2; 174 par->chan.reg = CR_SERIAL2;
177 par->chan.ioaddr = par->mmio.vbase; 175 par->chan.ioaddr = par->mmio.vbase;
178 par->chan.algo.setsda = prosavage_gpio_setsda; 176 par->chan.algo.setsda = prosavage_gpio_setsda;
@@ -180,7 +178,7 @@ void savagefb_create_i2c_busses(struct fb_info *info)
180 par->chan.algo.getsda = prosavage_gpio_getsda; 178 par->chan.algo.getsda = prosavage_gpio_getsda;
181 par->chan.algo.getscl = prosavage_gpio_getscl; 179 par->chan.algo.getscl = prosavage_gpio_getscl;
182 break; 180 break;
183 case FB_ACCEL_SAVAGE4: 181 case S3_SAVAGE4:
184 par->chan.reg = CR_SERIAL1; 182 par->chan.reg = CR_SERIAL1;
185 if (par->pcidev->revision > 1 && !(VGArCR(0xa6, par) & 0x40)) 183 if (par->pcidev->revision > 1 && !(VGArCR(0xa6, par) & 0x40))
186 par->chan.reg = CR_SERIAL2; 184 par->chan.reg = CR_SERIAL2;
@@ -190,8 +188,8 @@ void savagefb_create_i2c_busses(struct fb_info *info)
190 par->chan.algo.getsda = prosavage_gpio_getsda; 188 par->chan.algo.getsda = prosavage_gpio_getsda;
191 par->chan.algo.getscl = prosavage_gpio_getscl; 189 par->chan.algo.getscl = prosavage_gpio_getscl;
192 break; 190 break;
193 case FB_ACCEL_SAVAGE2000: 191 case S3_SAVAGE2000:
194 par->chan.reg = 0xff20; 192 par->chan.reg = MM_SERIAL1;
195 par->chan.ioaddr = par->mmio.vbase; 193 par->chan.ioaddr = par->mmio.vbase;
196 par->chan.algo.setsda = savage4_gpio_setsda; 194 par->chan.algo.setsda = savage4_gpio_setsda;
197 par->chan.algo.setscl = savage4_gpio_setscl; 195 par->chan.algo.setscl = savage4_gpio_setscl;
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index e4c3f214eb8e..4e9490c19d7d 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -153,7 +153,7 @@ struct savage_reg {
153 unsigned char CRTC[25]; /* Crtc Controller */ 153 unsigned char CRTC[25]; /* Crtc Controller */
154 unsigned char Sequencer[5]; /* Video Sequencer */ 154 unsigned char Sequencer[5]; /* Video Sequencer */
155 unsigned char Graphics[9]; /* Video Graphics */ 155 unsigned char Graphics[9]; /* Video Graphics */
156 unsigned char Attribute[21]; /* Video Atribute */ 156 unsigned char Attribute[21]; /* Video Attribute */
157 157
158 unsigned int mode, refresh; 158 unsigned int mode, refresh;
159 unsigned char SR08, SR0E, SR0F; 159 unsigned char SR08, SR0E, SR0F;
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 487911e2926c..a2dc1a7ec758 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -385,7 +385,7 @@ SavageSetup2DEngine(struct savagefb_par *par)
385 BCI_SEND(GlobalBitmapDescriptor); 385 BCI_SEND(GlobalBitmapDescriptor);
386 386
387 /* 387 /*
388 * I don't know why, sending this twice fixes the intial black screen, 388 * I don't know why, sending this twice fixes the initial black screen,
389 * prevents X from crashing at least in Toshiba laptops with SavageIX. 389 * prevents X from crashing at least in Toshiba laptops with SavageIX.
390 * --Tony 390 * --Tony
391 */ 391 */
@@ -2211,7 +2211,7 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
2211 goto failed_mmio; 2211 goto failed_mmio;
2212 2212
2213 video_len = savage_init_hw(par); 2213 video_len = savage_init_hw(par);
2214 /* FIXME: cant be negative */ 2214 /* FIXME: can't be negative */
2215 if (video_len < 0) { 2215 if (video_len < 0) {
2216 err = video_len; 2216 err = video_len;
2217 goto failed_mmio; 2217 goto failed_mmio;
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index bea38fce2470..8fe19582c460 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -459,14 +459,14 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev)
459 } 459 }
460 460
461 par->ioarea = request_mem_region(res->start, 461 par->ioarea = request_mem_region(res->start,
462 (res->end - res->start), pdev->name); 462 resource_size(res), pdev->name);
463 if (!par->ioarea) { 463 if (!par->ioarea) {
464 dev_err(&pdev->dev, "mmio area busy\n"); 464 dev_err(&pdev->dev, "mmio area busy\n");
465 ret = -EBUSY; 465 ret = -EBUSY;
466 goto out_fb; 466 goto out_fb;
467 } 467 }
468 468
469 par->base = ioremap_nocache(res->start, res->end - res->start + 1); 469 par->base = ioremap_nocache(res->start, resource_size(res));
470 if (!par->base) { 470 if (!par->base) {
471 dev_err(&pdev->dev, "cannot remap\n"); 471 dev_err(&pdev->dev, "cannot remap\n");
472 ret = -ENODEV; 472 ret = -ENODEV;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index bf2629f83f40..9bcc61b4ef14 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -643,7 +643,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
643 continue; 643 continue;
644 644
645 board_cfg = &ch->cfg.board_cfg; 645 board_cfg = &ch->cfg.board_cfg;
646 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 646 if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
647 board_cfg->display_on(board_cfg->board_data, ch->info); 647 board_cfg->display_on(board_cfg->board_data, ch->info);
648 module_put(board_cfg->owner); 648 module_put(board_cfg->owner);
649 } 649 }
@@ -688,7 +688,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
688 } 688 }
689 689
690 board_cfg = &ch->cfg.board_cfg; 690 board_cfg = &ch->cfg.board_cfg;
691 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 691 if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
692 board_cfg->display_off(board_cfg->board_data); 692 board_cfg->display_off(board_cfg->board_data);
693 module_put(board_cfg->owner); 693 module_put(board_cfg->owner);
694 } 694 }
@@ -1032,6 +1032,49 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1032 return 0; 1032 return 0;
1033} 1033}
1034 1034
1035/*
1036 * Screen blanking. Behavior is as follows:
1037 * FB_BLANK_UNBLANK: screen unblanked, clocks enabled
1038 * FB_BLANK_NORMAL: screen blanked, clocks enabled
1039 * FB_BLANK_VSYNC,
1040 * FB_BLANK_HSYNC,
1041 * FB_BLANK_POWEROFF: screen blanked, clocks disabled
1042 */
1043static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
1044{
1045 struct sh_mobile_lcdc_chan *ch = info->par;
1046 struct sh_mobile_lcdc_priv *p = ch->lcdc;
1047
1048 /* blank the screen? */
1049 if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) {
1050 struct fb_fillrect rect = {
1051 .width = info->var.xres,
1052 .height = info->var.yres,
1053 };
1054 sh_mobile_lcdc_fillrect(info, &rect);
1055 }
1056 /* turn clocks on? */
1057 if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) {
1058 sh_mobile_lcdc_clk_on(p);
1059 }
1060 /* turn clocks off? */
1061 if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) {
1062 /* make sure the screen is updated with the black fill before
1063 * switching the clocks off. one vsync is not enough since
1064 * blanking may occur in the middle of a refresh. deferred io
1065 * mode will reenable the clocks and update the screen in time,
1066 * so it does not need this. */
1067 if (!info->fbdefio) {
1068 sh_mobile_wait_for_vsync(info);
1069 sh_mobile_wait_for_vsync(info);
1070 }
1071 sh_mobile_lcdc_clk_off(p);
1072 }
1073
1074 ch->blank_status = blank;
1075 return 0;
1076}
1077
1035static struct fb_ops sh_mobile_lcdc_ops = { 1078static struct fb_ops sh_mobile_lcdc_ops = {
1036 .owner = THIS_MODULE, 1079 .owner = THIS_MODULE,
1037 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 1080 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -1040,6 +1083,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
1040 .fb_fillrect = sh_mobile_lcdc_fillrect, 1083 .fb_fillrect = sh_mobile_lcdc_fillrect,
1041 .fb_copyarea = sh_mobile_lcdc_copyarea, 1084 .fb_copyarea = sh_mobile_lcdc_copyarea,
1042 .fb_imageblit = sh_mobile_lcdc_imageblit, 1085 .fb_imageblit = sh_mobile_lcdc_imageblit,
1086 .fb_blank = sh_mobile_lcdc_blank,
1043 .fb_pan_display = sh_mobile_fb_pan_display, 1087 .fb_pan_display = sh_mobile_fb_pan_display,
1044 .fb_ioctl = sh_mobile_ioctl, 1088 .fb_ioctl = sh_mobile_ioctl,
1045 .fb_open = sh_mobile_open, 1089 .fb_open = sh_mobile_open,
@@ -1088,8 +1132,9 @@ static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1088 1132
1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch, 1133 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
1090 &sh_mobile_lcdc_bl_ops, NULL); 1134 &sh_mobile_lcdc_bl_ops, NULL);
1091 if (!bl) { 1135 if (IS_ERR(bl)) {
1092 dev_err(parent, "unable to register backlight device\n"); 1136 dev_err(parent, "unable to register backlight device: %ld\n",
1137 PTR_ERR(bl));
1093 return NULL; 1138 return NULL;
1094 } 1139 }
1095 1140
@@ -1253,7 +1298,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1253 1298
1254 switch(action) { 1299 switch(action) {
1255 case FB_EVENT_SUSPEND: 1300 case FB_EVENT_SUSPEND:
1256 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 1301 if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
1257 board_cfg->display_off(board_cfg->board_data); 1302 board_cfg->display_off(board_cfg->board_data);
1258 module_put(board_cfg->owner); 1303 module_put(board_cfg->owner);
1259 } 1304 }
@@ -1266,7 +1311,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1266 mutex_unlock(&ch->open_lock); 1311 mutex_unlock(&ch->open_lock);
1267 1312
1268 /* HDMI must be enabled before LCDC configuration */ 1313 /* HDMI must be enabled before LCDC configuration */
1269 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 1314 if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
1270 board_cfg->display_on(board_cfg->board_data, info); 1315 board_cfg->display_on(board_cfg->board_data, info);
1271 module_put(board_cfg->owner); 1316 module_put(board_cfg->owner);
1272 } 1317 }
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 4635eed63eee..f16cb5645a13 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -37,6 +37,7 @@ struct sh_mobile_lcdc_chan {
37 struct completion vsync_completion; 37 struct completion vsync_completion;
38 struct fb_var_screeninfo display_var; 38 struct fb_var_screeninfo display_var;
39 int use_count; 39 int use_count;
40 int blank_status;
40 struct mutex open_lock; /* protects the use counter */ 41 struct mutex open_lock; /* protects the use counter */
41}; 42};
42 43
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index eac7a01925f3..1987f1b7212f 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -495,6 +495,7 @@ struct sis_video_info {
495 unsigned int refresh_rate; 495 unsigned int refresh_rate;
496 496
497 unsigned int chip; 497 unsigned int chip;
498 unsigned int chip_real_id;
498 u8 revision_id; 499 u8 revision_id;
499 int sisvga_enabled; /* PCI device was enabled */ 500 int sisvga_enabled; /* PCI device was enabled */
500 501
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a660fb..75259845933d 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4563,6 +4563,11 @@ sisfb_post_sis315330(struct pci_dev *pdev)
4563} 4563}
4564#endif 4564#endif
4565 4565
4566static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
4567{
4568 return ivideo->chip_real_id == XGI_21;
4569}
4570
4566static void __devinit 4571static void __devinit
4567sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) 4572sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
4568{ 4573{
@@ -4627,11 +4632,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
4627 return 1; 4632 return 1;
4628} 4633}
4629 4634
4630static void __devinit 4635static int __devinit
4631sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) 4636sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4632{ 4637{
4633 unsigned int buswidth, ranksize, channelab, mapsize; 4638 unsigned int buswidth, ranksize, channelab, mapsize;
4634 int i, j, k, l; 4639 int i, j, k, l, status;
4635 u8 reg, sr14; 4640 u8 reg, sr14;
4636 static const u8 dramsr13[12 * 5] = { 4641 static const u8 dramsr13[12 * 5] = {
4637 0x02, 0x0e, 0x0b, 0x80, 0x5d, 4642 0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4678,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4673 SiS_SetReg(SISSR, 0x13, 0x35); 4678 SiS_SetReg(SISSR, 0x13, 0x35);
4674 SiS_SetReg(SISSR, 0x14, 0x41); 4679 SiS_SetReg(SISSR, 0x14, 0x41);
4675 /* TODO */ 4680 /* TODO */
4676 return; 4681 return -ENOMEM;
4677 } 4682 }
4678 4683
4679 /* Non-interleaving */ 4684 /* Non-interleaving */
@@ -4835,6 +4840,7 @@ bail_out:
4835 4840
4836 j = (ivideo->chip == XGI_20) ? 5 : 9; 4841 j = (ivideo->chip == XGI_20) ? 5 : 9;
4837 k = (ivideo->chip == XGI_20) ? 12 : 4; 4842 k = (ivideo->chip == XGI_20) ? 12 : 4;
4843 status = -EIO;
4838 4844
4839 for(i = 0; i < k; i++) { 4845 for(i = 0; i < k; i++) {
4840 4846
@@ -4868,11 +4874,15 @@ bail_out:
4868 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0)); 4874 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
4869 sisfb_post_xgi_delay(ivideo, 1); 4875 sisfb_post_xgi_delay(ivideo, 1);
4870 4876
4871 if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) 4877 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
4878 status = 0;
4872 break; 4879 break;
4880 }
4873 } 4881 }
4874 4882
4875 iounmap(ivideo->video_vbase); 4883 iounmap(ivideo->video_vbase);
4884
4885 return status;
4876} 4886}
4877 4887
4878static void __devinit 4888static void __devinit
@@ -4931,6 +4941,175 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
4931 sisfb_post_xgi_delay(ivideo, 0x43); 4941 sisfb_post_xgi_delay(ivideo, 0x43);
4932} 4942}
4933 4943
4944static void __devinit
4945sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
4946{
4947 unsigned char *bios = ivideo->bios_abase;
4948 u8 v1;
4949
4950 SiS_SetReg(SISSR, 0x28, 0x64);
4951 SiS_SetReg(SISSR, 0x29, 0x63);
4952 sisfb_post_xgi_delay(ivideo, 15);
4953 SiS_SetReg(SISSR, 0x18, 0x00);
4954 SiS_SetReg(SISSR, 0x19, 0x20);
4955 SiS_SetReg(SISSR, 0x16, 0x00);
4956 SiS_SetReg(SISSR, 0x16, 0x80);
4957 SiS_SetReg(SISSR, 0x18, 0xc5);
4958 SiS_SetReg(SISSR, 0x19, 0x23);
4959 SiS_SetReg(SISSR, 0x16, 0x00);
4960 SiS_SetReg(SISSR, 0x16, 0x80);
4961 sisfb_post_xgi_delay(ivideo, 1);
4962 SiS_SetReg(SISCR, 0x97, 0x11);
4963 sisfb_post_xgi_setclocks(ivideo, regb);
4964 sisfb_post_xgi_delay(ivideo, 0x46);
4965 SiS_SetReg(SISSR, 0x18, 0xc5);
4966 SiS_SetReg(SISSR, 0x19, 0x23);
4967 SiS_SetReg(SISSR, 0x16, 0x00);
4968 SiS_SetReg(SISSR, 0x16, 0x80);
4969 sisfb_post_xgi_delay(ivideo, 1);
4970 SiS_SetReg(SISSR, 0x1b, 0x04);
4971 sisfb_post_xgi_delay(ivideo, 1);
4972 SiS_SetReg(SISSR, 0x1b, 0x00);
4973 sisfb_post_xgi_delay(ivideo, 1);
4974 v1 = 0x31;
4975 if (ivideo->haveXGIROM) {
4976 v1 = bios[0xf0];
4977 }
4978 SiS_SetReg(SISSR, 0x18, v1);
4979 SiS_SetReg(SISSR, 0x19, 0x06);
4980 SiS_SetReg(SISSR, 0x16, 0x04);
4981 SiS_SetReg(SISSR, 0x16, 0x84);
4982 sisfb_post_xgi_delay(ivideo, 1);
4983}
4984
4985static void __devinit
4986sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
4987{
4988 sisfb_post_xgi_setclocks(ivideo, 1);
4989
4990 SiS_SetReg(SISCR, 0x97, 0x11);
4991 sisfb_post_xgi_delay(ivideo, 0x46);
4992
4993 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */
4994 SiS_SetReg(SISSR, 0x19, 0x80);
4995 SiS_SetReg(SISSR, 0x16, 0x05);
4996 SiS_SetReg(SISSR, 0x16, 0x85);
4997
4998 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */
4999 SiS_SetReg(SISSR, 0x19, 0xc0);
5000 SiS_SetReg(SISSR, 0x16, 0x05);
5001 SiS_SetReg(SISSR, 0x16, 0x85);
5002
5003 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */
5004 SiS_SetReg(SISSR, 0x19, 0x40);
5005 SiS_SetReg(SISSR, 0x16, 0x05);
5006 SiS_SetReg(SISSR, 0x16, 0x85);
5007
5008 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5009 SiS_SetReg(SISSR, 0x19, 0x02);
5010 SiS_SetReg(SISSR, 0x16, 0x05);
5011 SiS_SetReg(SISSR, 0x16, 0x85);
5012 sisfb_post_xgi_delay(ivideo, 1);
5013
5014 SiS_SetReg(SISSR, 0x1b, 0x04);
5015 sisfb_post_xgi_delay(ivideo, 1);
5016
5017 SiS_SetReg(SISSR, 0x1b, 0x00);
5018 sisfb_post_xgi_delay(ivideo, 1);
5019
5020 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5021 SiS_SetReg(SISSR, 0x19, 0x00);
5022 SiS_SetReg(SISSR, 0x16, 0x05);
5023 SiS_SetReg(SISSR, 0x16, 0x85);
5024 sisfb_post_xgi_delay(ivideo, 1);
5025}
5026
5027static void __devinit
5028sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
5029{
5030 unsigned char *bios = ivideo->bios_abase;
5031 static const u8 cs158[8] = {
5032 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5033 };
5034 static const u8 cs160[8] = {
5035 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5036 };
5037 static const u8 cs168[8] = {
5038 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5039 };
5040 u8 reg;
5041 u8 v1;
5042 u8 v2;
5043 u8 v3;
5044
5045 SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
5046 SiS_SetReg(SISCR, 0x82, 0x77);
5047 SiS_SetReg(SISCR, 0x86, 0x00);
5048 reg = SiS_GetReg(SISCR, 0x86);
5049 SiS_SetReg(SISCR, 0x86, 0x88);
5050 reg = SiS_GetReg(SISCR, 0x86);
5051 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5052 if (ivideo->haveXGIROM) {
5053 v1 = bios[regb + 0x168];
5054 v2 = bios[regb + 0x160];
5055 v3 = bios[regb + 0x158];
5056 }
5057 SiS_SetReg(SISCR, 0x86, v1);
5058 SiS_SetReg(SISCR, 0x82, 0x77);
5059 SiS_SetReg(SISCR, 0x85, 0x00);
5060 reg = SiS_GetReg(SISCR, 0x85);
5061 SiS_SetReg(SISCR, 0x85, 0x88);
5062 reg = SiS_GetReg(SISCR, 0x85);
5063 SiS_SetReg(SISCR, 0x85, v2);
5064 SiS_SetReg(SISCR, 0x82, v3);
5065 SiS_SetReg(SISCR, 0x98, 0x01);
5066 SiS_SetReg(SISCR, 0x9a, 0x02);
5067 if (sisfb_xgi_is21(ivideo))
5068 sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
5069 else
5070 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
5071}
5072
5073static u8 __devinit
5074sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
5075{
5076 unsigned char *bios = ivideo->bios_abase;
5077 u8 ramtype;
5078 u8 reg;
5079 u8 v1;
5080
5081 ramtype = 0x00; v1 = 0x10;
5082 if (ivideo->haveXGIROM) {
5083 ramtype = bios[0x62];
5084 v1 = bios[0x1d2];
5085 }
5086 if (!(ramtype & 0x80)) {
5087 if (sisfb_xgi_is21(ivideo)) {
5088 SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
5089 SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */
5090 reg = SiS_GetReg(SISCR, 0x48);
5091 SiS_SetRegOR(SISCR, 0xb4, 0x02);
5092 ramtype = reg & 0x01; /* GPIOH */
5093 } else if (ivideo->chip == XGI_20) {
5094 SiS_SetReg(SISCR, 0x97, v1);
5095 reg = SiS_GetReg(SISCR, 0x97);
5096 if (reg & 0x10) {
5097 ramtype = (reg & 0x01) << 1;
5098 }
5099 } else {
5100 reg = SiS_GetReg(SISSR, 0x39);
5101 ramtype = reg & 0x02;
5102 if (!(ramtype)) {
5103 reg = SiS_GetReg(SISSR, 0x3a);
5104 ramtype = (reg >> 1) & 0x01;
5105 }
5106 }
5107 }
5108 ramtype &= 0x07;
5109
5110 return ramtype;
5111}
5112
4934static int __devinit 5113static int __devinit
4935sisfb_post_xgi(struct pci_dev *pdev) 5114sisfb_post_xgi(struct pci_dev *pdev)
4936{ 5115{
@@ -5213,9 +5392,23 @@ sisfb_post_xgi(struct pci_dev *pdev)
5213 SiS_SetReg(SISCR, 0x77, v1); 5392 SiS_SetReg(SISCR, 0x77, v1);
5214 } 5393 }
5215 5394
5216 /* RAM type */ 5395 /* RAM type:
5217 5396 *
5218 regb = 0; /* ! */ 5397 * 0 == DDR1, 1 == DDR2, 2..7 == reserved?
5398 *
5399 * The code seems to written so that regb should equal ramtype,
5400 * however, so far it has been hardcoded to 0. Enable other values only
5401 * on XGI Z9, as it passes the POST, and add a warning for others.
5402 */
5403 ramtype = sisfb_post_xgi_ramtype(ivideo);
5404 if (!sisfb_xgi_is21(ivideo) && ramtype) {
5405 dev_warn(&pdev->dev,
5406 "RAM type something else than expected: %d\n",
5407 ramtype);
5408 regb = 0;
5409 } else {
5410 regb = ramtype;
5411 }
5219 5412
5220 v1 = 0xff; 5413 v1 = 0xff;
5221 if(ivideo->haveXGIROM) { 5414 if(ivideo->haveXGIROM) {
@@ -5367,7 +5560,10 @@ sisfb_post_xgi(struct pci_dev *pdev)
5367 } 5560 }
5368 } 5561 }
5369 5562
5370 SiS_SetReg(SISSR, 0x17, 0x00); 5563 if (regb == 1)
5564 SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */
5565 else
5566 SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */
5371 SiS_SetReg(SISSR, 0x1a, 0x87); 5567 SiS_SetReg(SISSR, 0x1a, 0x87);
5372 5568
5373 if(ivideo->chip == XGI_20) { 5569 if(ivideo->chip == XGI_20) {
@@ -5375,31 +5571,6 @@ sisfb_post_xgi(struct pci_dev *pdev)
5375 SiS_SetReg(SISSR, 0x1c, 0x00); 5571 SiS_SetReg(SISSR, 0x1c, 0x00);
5376 } 5572 }
5377 5573
5378 ramtype = 0x00; v1 = 0x10;
5379 if(ivideo->haveXGIROM) {
5380 ramtype = bios[0x62];
5381 v1 = bios[0x1d2];
5382 }
5383 if(!(ramtype & 0x80)) {
5384 if(ivideo->chip == XGI_20) {
5385 SiS_SetReg(SISCR, 0x97, v1);
5386 reg = SiS_GetReg(SISCR, 0x97);
5387 if(reg & 0x10) {
5388 ramtype = (reg & 0x01) << 1;
5389 }
5390 } else {
5391 reg = SiS_GetReg(SISSR, 0x39);
5392 ramtype = reg & 0x02;
5393 if(!(ramtype)) {
5394 reg = SiS_GetReg(SISSR, 0x3a);
5395 ramtype = (reg >> 1) & 0x01;
5396 }
5397 }
5398 }
5399 ramtype &= 0x07;
5400
5401 regb = 0; /* ! */
5402
5403 switch(ramtype) { 5574 switch(ramtype) {
5404 case 0: 5575 case 0:
5405 sisfb_post_xgi_setclocks(ivideo, regb); 5576 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5485,61 +5656,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5485 SiS_SetReg(SISSR, 0x1b, 0x00); 5656 SiS_SetReg(SISSR, 0x1b, 0x00);
5486 break; 5657 break;
5487 case 1: 5658 case 1:
5488 SiS_SetReg(SISCR, 0x82, 0x77); 5659 sisfb_post_xgi_ddr2(ivideo, regb);
5489 SiS_SetReg(SISCR, 0x86, 0x00);
5490 reg = SiS_GetReg(SISCR, 0x86);
5491 SiS_SetReg(SISCR, 0x86, 0x88);
5492 reg = SiS_GetReg(SISCR, 0x86);
5493 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5494 if(ivideo->haveXGIROM) {
5495 v1 = bios[regb + 0x168];
5496 v2 = bios[regb + 0x160];
5497 v3 = bios[regb + 0x158];
5498 }
5499 SiS_SetReg(SISCR, 0x86, v1);
5500 SiS_SetReg(SISCR, 0x82, 0x77);
5501 SiS_SetReg(SISCR, 0x85, 0x00);
5502 reg = SiS_GetReg(SISCR, 0x85);
5503 SiS_SetReg(SISCR, 0x85, 0x88);
5504 reg = SiS_GetReg(SISCR, 0x85);
5505 SiS_SetReg(SISCR, 0x85, v2);
5506 SiS_SetReg(SISCR, 0x82, v3);
5507 SiS_SetReg(SISCR, 0x98, 0x01);
5508 SiS_SetReg(SISCR, 0x9a, 0x02);
5509
5510 SiS_SetReg(SISSR, 0x28, 0x64);
5511 SiS_SetReg(SISSR, 0x29, 0x63);
5512 sisfb_post_xgi_delay(ivideo, 15);
5513 SiS_SetReg(SISSR, 0x18, 0x00);
5514 SiS_SetReg(SISSR, 0x19, 0x20);
5515 SiS_SetReg(SISSR, 0x16, 0x00);
5516 SiS_SetReg(SISSR, 0x16, 0x80);
5517 SiS_SetReg(SISSR, 0x18, 0xc5);
5518 SiS_SetReg(SISSR, 0x19, 0x23);
5519 SiS_SetReg(SISSR, 0x16, 0x00);
5520 SiS_SetReg(SISSR, 0x16, 0x80);
5521 sisfb_post_xgi_delay(ivideo, 1);
5522 SiS_SetReg(SISCR, 0x97, 0x11);
5523 sisfb_post_xgi_setclocks(ivideo, regb);
5524 sisfb_post_xgi_delay(ivideo, 0x46);
5525 SiS_SetReg(SISSR, 0x18, 0xc5);
5526 SiS_SetReg(SISSR, 0x19, 0x23);
5527 SiS_SetReg(SISSR, 0x16, 0x00);
5528 SiS_SetReg(SISSR, 0x16, 0x80);
5529 sisfb_post_xgi_delay(ivideo, 1);
5530 SiS_SetReg(SISSR, 0x1b, 0x04);
5531 sisfb_post_xgi_delay(ivideo, 1);
5532 SiS_SetReg(SISSR, 0x1b, 0x00);
5533 sisfb_post_xgi_delay(ivideo, 1);
5534 v1 = 0x31;
5535 if(ivideo->haveXGIROM) {
5536 v1 = bios[0xf0];
5537 }
5538 SiS_SetReg(SISSR, 0x18, v1);
5539 SiS_SetReg(SISSR, 0x19, 0x06);
5540 SiS_SetReg(SISSR, 0x16, 0x04);
5541 SiS_SetReg(SISSR, 0x16, 0x84);
5542 sisfb_post_xgi_delay(ivideo, 1);
5543 break; 5660 break;
5544 default: 5661 default:
5545 sisfb_post_xgi_setclocks(ivideo, regb); 5662 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5648,6 +5765,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5648 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]); 5765 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
5649 5766
5650 } else { 5767 } else {
5768 int err;
5651 5769
5652 /* Set default mode, don't clear screen */ 5770 /* Set default mode, don't clear screen */
5653 ivideo->SiS_Pr.SiS_UseOEM = false; 5771 ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5779,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
5661 5779
5662 /* Disable read-cache */ 5780 /* Disable read-cache */
5663 SiS_SetRegAND(SISSR, 0x21, 0xdf); 5781 SiS_SetRegAND(SISSR, 0x21, 0xdf);
5664 sisfb_post_xgi_ramsize(ivideo); 5782 err = sisfb_post_xgi_ramsize(ivideo);
5665 /* Enable read-cache */ 5783 /* Enable read-cache */
5666 SiS_SetRegOR(SISSR, 0x21, 0x20); 5784 SiS_SetRegOR(SISSR, 0x21, 0x20);
5667 5785
5786 if (err) {
5787 dev_err(&pdev->dev,
5788 "%s: RAM size detection failed: %d\n",
5789 __func__, err);
5790 return 0;
5791 }
5668 } 5792 }
5669 5793
5670#if 0 5794#if 0
@@ -5777,6 +5901,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5777#endif 5901#endif
5778 5902
5779 ivideo->chip = chipinfo->chip; 5903 ivideo->chip = chipinfo->chip;
5904 ivideo->chip_real_id = chipinfo->chip;
5780 ivideo->sisvga_engine = chipinfo->vgaengine; 5905 ivideo->sisvga_engine = chipinfo->vgaengine;
5781 ivideo->hwcursor_size = chipinfo->hwcursor_size; 5906 ivideo->hwcursor_size = chipinfo->hwcursor_size;
5782 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable; 5907 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
@@ -6010,6 +6135,18 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
6010 sisfb_detect_custom_timing(ivideo); 6135 sisfb_detect_custom_timing(ivideo);
6011 } 6136 }
6012 6137
6138#ifdef CONFIG_FB_SIS_315
6139 if (ivideo->chip == XGI_20) {
6140 /* Check if our Z7 chip is actually Z9 */
6141 SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */
6142 reg = SiS_GetReg(SISCR, 0x48);
6143 if (reg & 0x02) { /* GPIOG */
6144 ivideo->chip_real_id = XGI_21;
6145 dev_info(&pdev->dev, "Z9 detected\n");
6146 }
6147 }
6148#endif
6149
6013 /* POST card in case this has not been done by the BIOS */ 6150 /* POST card in case this has not been done by the BIOS */
6014 if( (!ivideo->sisvga_enabled) 6151 if( (!ivideo->sisvga_enabled)
6015#if !defined(__i386__) && !defined(__x86_64__) 6152#if !defined(__i386__) && !defined(__x86_64__)
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 12c0dfaf2518..e3f9976cfef0 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -87,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
87 SIS_341, 87 SIS_341,
88 SIS_342, 88 SIS_342,
89 XGI_20 = 75, 89 XGI_20 = 75,
90 XGI_21,
90 XGI_40, 91 XGI_40,
91 MAX_SIS_CHIP 92 MAX_SIS_CHIP
92} SIS_CHIP_TYPE; 93} SIS_CHIP_TYPE;
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index bcb44a594ebc..56ef6b3a9851 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -41,6 +41,26 @@
41#include <linux/sm501.h> 41#include <linux/sm501.h>
42#include <linux/sm501-regs.h> 42#include <linux/sm501-regs.h>
43 43
44#include "edid.h"
45
46static char *fb_mode = "640x480-16@60";
47static unsigned long default_bpp = 16;
48
49static struct fb_videomode __devinitdata sm501_default_mode = {
50 .refresh = 60,
51 .xres = 640,
52 .yres = 480,
53 .pixclock = 20833,
54 .left_margin = 142,
55 .right_margin = 13,
56 .upper_margin = 21,
57 .lower_margin = 1,
58 .hsync_len = 69,
59 .vsync_len = 3,
60 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
61 .vmode = FB_VMODE_NONINTERLACED
62};
63
44#define NR_PALETTE 256 64#define NR_PALETTE 256
45 65
46enum sm501_controller { 66enum sm501_controller {
@@ -77,6 +97,7 @@ struct sm501fb_info {
77 void __iomem *regs2d; /* 2d remapped registers */ 97 void __iomem *regs2d; /* 2d remapped registers */
78 void __iomem *fbmem; /* remapped framebuffer */ 98 void __iomem *fbmem; /* remapped framebuffer */
79 size_t fbmem_len; /* length of remapped region */ 99 size_t fbmem_len; /* length of remapped region */
100 u8 *edid_data;
80}; 101};
81 102
82/* per-framebuffer private data */ 103/* per-framebuffer private data */
@@ -117,7 +138,7 @@ static inline int v_total(struct fb_var_screeninfo *var)
117 138
118static inline void sm501fb_sync_regs(struct sm501fb_info *info) 139static inline void sm501fb_sync_regs(struct sm501fb_info *info)
119{ 140{
120 readl(info->regs); 141 smc501_readl(info->regs);
121} 142}
122 143
123/* sm501_alloc_mem 144/* sm501_alloc_mem
@@ -244,7 +265,7 @@ static unsigned long sm501fb_ps_to_hz(unsigned long psvalue)
244 return (unsigned long)numerator; 265 return (unsigned long)numerator;
245} 266}
246 267
247/* sm501fb_hz_to_ps is identical to the oposite transform */ 268/* sm501fb_hz_to_ps is identical to the opposite transform */
248 269
249#define sm501fb_hz_to_ps(x) sm501fb_ps_to_hz(x) 270#define sm501fb_hz_to_ps(x) sm501fb_ps_to_hz(x)
250 271
@@ -262,7 +283,7 @@ static void sm501fb_setup_gamma(struct sm501fb_info *fbi,
262 283
263 /* set gamma values */ 284 /* set gamma values */
264 for (offset = 0; offset < 256 * 4; offset += 4) { 285 for (offset = 0; offset < 256 * 4; offset += 4) {
265 writel(value, fbi->regs + palette + offset); 286 smc501_writel(value, fbi->regs + palette + offset);
266 value += 0x010101; /* Advance RGB by 1,1,1.*/ 287 value += 0x010101; /* Advance RGB by 1,1,1.*/
267 } 288 }
268} 289}
@@ -476,7 +497,8 @@ static int sm501fb_set_par_common(struct fb_info *info,
476 497
477 /* set start of framebuffer to the screen */ 498 /* set start of framebuffer to the screen */
478 499
479 writel(par->screen.sm_addr | SM501_ADDR_FLIP, fbi->regs + head_addr); 500 smc501_writel(par->screen.sm_addr | SM501_ADDR_FLIP,
501 fbi->regs + head_addr);
480 502
481 /* program CRT clock */ 503 /* program CRT clock */
482 504
@@ -519,7 +541,7 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
519 reg = info->fix.line_length; 541 reg = info->fix.line_length;
520 reg |= ((var->xres * var->bits_per_pixel)/8) << 16; 542 reg |= ((var->xres * var->bits_per_pixel)/8) << 16;
521 543
522 writel(reg, fbi->regs + (par->head == HEAD_CRT ? 544 smc501_writel(reg, fbi->regs + (par->head == HEAD_CRT ?
523 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET)); 545 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET));
524 546
525 /* program horizontal total */ 547 /* program horizontal total */
@@ -527,27 +549,27 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
527 reg = (h_total(var) - 1) << 16; 549 reg = (h_total(var) - 1) << 16;
528 reg |= (var->xres - 1); 550 reg |= (var->xres - 1);
529 551
530 writel(reg, base + SM501_OFF_DC_H_TOT); 552 smc501_writel(reg, base + SM501_OFF_DC_H_TOT);
531 553
532 /* program horizontal sync */ 554 /* program horizontal sync */
533 555
534 reg = var->hsync_len << 16; 556 reg = var->hsync_len << 16;
535 reg |= var->xres + var->right_margin - 1; 557 reg |= var->xres + var->right_margin - 1;
536 558
537 writel(reg, base + SM501_OFF_DC_H_SYNC); 559 smc501_writel(reg, base + SM501_OFF_DC_H_SYNC);
538 560
539 /* program vertical total */ 561 /* program vertical total */
540 562
541 reg = (v_total(var) - 1) << 16; 563 reg = (v_total(var) - 1) << 16;
542 reg |= (var->yres - 1); 564 reg |= (var->yres - 1);
543 565
544 writel(reg, base + SM501_OFF_DC_V_TOT); 566 smc501_writel(reg, base + SM501_OFF_DC_V_TOT);
545 567
546 /* program vertical sync */ 568 /* program vertical sync */
547 reg = var->vsync_len << 16; 569 reg = var->vsync_len << 16;
548 reg |= var->yres + var->lower_margin - 1; 570 reg |= var->yres + var->lower_margin - 1;
549 571
550 writel(reg, base + SM501_OFF_DC_V_SYNC); 572 smc501_writel(reg, base + SM501_OFF_DC_V_SYNC);
551} 573}
552 574
553/* sm501fb_pan_crt 575/* sm501fb_pan_crt
@@ -566,15 +588,15 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
566 588
567 xoffs = var->xoffset * bytes_pixel; 589 xoffs = var->xoffset * bytes_pixel;
568 590
569 reg = readl(fbi->regs + SM501_DC_CRT_CONTROL); 591 reg = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
570 592
571 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK; 593 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK;
572 reg |= ((xoffs & 15) / bytes_pixel) << 4; 594 reg |= ((xoffs & 15) / bytes_pixel) << 4;
573 writel(reg, fbi->regs + SM501_DC_CRT_CONTROL); 595 smc501_writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
574 596
575 reg = (par->screen.sm_addr + xoffs + 597 reg = (par->screen.sm_addr + xoffs +
576 var->yoffset * info->fix.line_length); 598 var->yoffset * info->fix.line_length);
577 writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR); 599 smc501_writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
578 600
579 sm501fb_sync_regs(fbi); 601 sm501fb_sync_regs(fbi);
580 return 0; 602 return 0;
@@ -593,10 +615,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
593 unsigned long reg; 615 unsigned long reg;
594 616
595 reg = var->xoffset | (var->xres_virtual << 16); 617 reg = var->xoffset | (var->xres_virtual << 16);
596 writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH); 618 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
597 619
598 reg = var->yoffset | (var->yres_virtual << 16); 620 reg = var->yoffset | (var->yres_virtual << 16);
599 writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT); 621 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
600 622
601 sm501fb_sync_regs(fbi); 623 sm501fb_sync_regs(fbi);
602 return 0; 624 return 0;
@@ -622,7 +644,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
622 /* enable CRT DAC - note 0 is on!*/ 644 /* enable CRT DAC - note 0 is on!*/
623 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER); 645 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER);
624 646
625 control = readl(fbi->regs + SM501_DC_CRT_CONTROL); 647 control = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
626 648
627 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK | 649 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK |
628 SM501_DC_CRT_CONTROL_GAMMA | 650 SM501_DC_CRT_CONTROL_GAMMA |
@@ -684,7 +706,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
684 out_update: 706 out_update:
685 dev_dbg(fbi->dev, "new control is %08lx\n", control); 707 dev_dbg(fbi->dev, "new control is %08lx\n", control);
686 708
687 writel(control, fbi->regs + SM501_DC_CRT_CONTROL); 709 smc501_writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
688 sm501fb_sync_regs(fbi); 710 sm501fb_sync_regs(fbi);
689 711
690 return 0; 712 return 0;
@@ -696,18 +718,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
696 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; 718 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
697 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl; 719 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
698 720
699 control = readl(ctrl_reg); 721 control = smc501_readl(ctrl_reg);
700 722
701 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) { 723 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) {
702 /* enable panel power */ 724 /* enable panel power */
703 725
704 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */ 726 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */
705 writel(control, ctrl_reg); 727 smc501_writel(control, ctrl_reg);
706 sm501fb_sync_regs(fbi); 728 sm501fb_sync_regs(fbi);
707 mdelay(10); 729 mdelay(10);
708 730
709 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */ 731 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */
710 writel(control, ctrl_reg); 732 smc501_writel(control, ctrl_reg);
711 sm501fb_sync_regs(fbi); 733 sm501fb_sync_regs(fbi);
712 mdelay(10); 734 mdelay(10);
713 735
@@ -719,7 +741,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
719 else 741 else
720 control |= SM501_DC_PANEL_CONTROL_BIAS; 742 control |= SM501_DC_PANEL_CONTROL_BIAS;
721 743
722 writel(control, ctrl_reg); 744 smc501_writel(control, ctrl_reg);
723 sm501fb_sync_regs(fbi); 745 sm501fb_sync_regs(fbi);
724 mdelay(10); 746 mdelay(10);
725 } 747 }
@@ -730,7 +752,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
730 else 752 else
731 control |= SM501_DC_PANEL_CONTROL_FPEN; 753 control |= SM501_DC_PANEL_CONTROL_FPEN;
732 754
733 writel(control, ctrl_reg); 755 smc501_writel(control, ctrl_reg);
734 sm501fb_sync_regs(fbi); 756 sm501fb_sync_regs(fbi);
735 mdelay(10); 757 mdelay(10);
736 } 758 }
@@ -742,7 +764,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
742 else 764 else
743 control &= ~SM501_DC_PANEL_CONTROL_FPEN; 765 control &= ~SM501_DC_PANEL_CONTROL_FPEN;
744 766
745 writel(control, ctrl_reg); 767 smc501_writel(control, ctrl_reg);
746 sm501fb_sync_regs(fbi); 768 sm501fb_sync_regs(fbi);
747 mdelay(10); 769 mdelay(10);
748 } 770 }
@@ -753,18 +775,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
753 else 775 else
754 control &= ~SM501_DC_PANEL_CONTROL_BIAS; 776 control &= ~SM501_DC_PANEL_CONTROL_BIAS;
755 777
756 writel(control, ctrl_reg); 778 smc501_writel(control, ctrl_reg);
757 sm501fb_sync_regs(fbi); 779 sm501fb_sync_regs(fbi);
758 mdelay(10); 780 mdelay(10);
759 } 781 }
760 782
761 control &= ~SM501_DC_PANEL_CONTROL_DATA; 783 control &= ~SM501_DC_PANEL_CONTROL_DATA;
762 writel(control, ctrl_reg); 784 smc501_writel(control, ctrl_reg);
763 sm501fb_sync_regs(fbi); 785 sm501fb_sync_regs(fbi);
764 mdelay(10); 786 mdelay(10);
765 787
766 control &= ~SM501_DC_PANEL_CONTROL_VDD; 788 control &= ~SM501_DC_PANEL_CONTROL_VDD;
767 writel(control, ctrl_reg); 789 smc501_writel(control, ctrl_reg);
768 sm501fb_sync_regs(fbi); 790 sm501fb_sync_regs(fbi);
769 mdelay(10); 791 mdelay(10);
770 } 792 }
@@ -799,7 +821,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
799 821
800 /* update control register */ 822 /* update control register */
801 823
802 control = readl(fbi->regs + SM501_DC_PANEL_CONTROL); 824 control = smc501_readl(fbi->regs + SM501_DC_PANEL_CONTROL);
803 control &= (SM501_DC_PANEL_CONTROL_GAMMA | 825 control &= (SM501_DC_PANEL_CONTROL_GAMMA |
804 SM501_DC_PANEL_CONTROL_VDD | 826 SM501_DC_PANEL_CONTROL_VDD |
805 SM501_DC_PANEL_CONTROL_DATA | 827 SM501_DC_PANEL_CONTROL_DATA |
@@ -833,16 +855,16 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
833 BUG(); 855 BUG();
834 } 856 }
835 857
836 writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL); 858 smc501_writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
837 859
838 /* panel plane top left and bottom right location */ 860 /* panel plane top left and bottom right location */
839 861
840 writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC); 862 smc501_writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
841 863
842 reg = var->xres - 1; 864 reg = var->xres - 1;
843 reg |= (var->yres - 1) << 16; 865 reg |= (var->yres - 1) << 16;
844 866
845 writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC); 867 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
846 868
847 /* program panel control register */ 869 /* program panel control register */
848 870
@@ -855,7 +877,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
855 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0) 877 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
856 control |= SM501_DC_PANEL_CONTROL_VSP; 878 control |= SM501_DC_PANEL_CONTROL_VSP;
857 879
858 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL); 880 smc501_writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
859 sm501fb_sync_regs(fbi); 881 sm501fb_sync_regs(fbi);
860 882
861 /* ensure the panel interface is not tristated at this point */ 883 /* ensure the panel interface is not tristated at this point */
@@ -924,7 +946,7 @@ static int sm501fb_setcolreg(unsigned regno,
924 val |= (green >> 8) << 8; 946 val |= (green >> 8) << 8;
925 val |= blue >> 8; 947 val |= blue >> 8;
926 948
927 writel(val, base + (regno * 4)); 949 smc501_writel(val, base + (regno * 4));
928 } 950 }
929 951
930 break; 952 break;
@@ -980,7 +1002,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
980 1002
981 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info); 1003 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info);
982 1004
983 ctrl = readl(fbi->regs + SM501_DC_CRT_CONTROL); 1005 ctrl = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
984 1006
985 switch (blank_mode) { 1007 switch (blank_mode) {
986 case FB_BLANK_POWERDOWN: 1008 case FB_BLANK_POWERDOWN:
@@ -1004,7 +1026,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
1004 1026
1005 } 1027 }
1006 1028
1007 writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL); 1029 smc501_writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
1008 sm501fb_sync_regs(fbi); 1030 sm501fb_sync_regs(fbi);
1009 1031
1010 return 0; 1032 return 0;
@@ -1041,12 +1063,14 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1041 if (cursor->image.depth > 1) 1063 if (cursor->image.depth > 1)
1042 return -EINVAL; 1064 return -EINVAL;
1043 1065
1044 hwc_addr = readl(base + SM501_OFF_HWC_ADDR); 1066 hwc_addr = smc501_readl(base + SM501_OFF_HWC_ADDR);
1045 1067
1046 if (cursor->enable) 1068 if (cursor->enable)
1047 writel(hwc_addr | SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1069 smc501_writel(hwc_addr | SM501_HWC_EN,
1070 base + SM501_OFF_HWC_ADDR);
1048 else 1071 else
1049 writel(hwc_addr & ~SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1072 smc501_writel(hwc_addr & ~SM501_HWC_EN,
1073 base + SM501_OFF_HWC_ADDR);
1050 1074
1051 /* set data */ 1075 /* set data */
1052 if (cursor->set & FB_CUR_SETPOS) { 1076 if (cursor->set & FB_CUR_SETPOS) {
@@ -1060,7 +1084,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1060 1084
1061 //y += cursor->image.height; 1085 //y += cursor->image.height;
1062 1086
1063 writel(x | (y << 16), base + SM501_OFF_HWC_LOC); 1087 smc501_writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
1064 } 1088 }
1065 1089
1066 if (cursor->set & FB_CUR_SETCMAP) { 1090 if (cursor->set & FB_CUR_SETCMAP) {
@@ -1080,8 +1104,8 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1080 1104
1081 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg); 1105 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
1082 1106
1083 writel(bg, base + SM501_OFF_HWC_COLOR_1_2); 1107 smc501_writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
1084 writel(fg, base + SM501_OFF_HWC_COLOR_3); 1108 smc501_writel(fg, base + SM501_OFF_HWC_COLOR_3);
1085 } 1109 }
1086 1110
1087 if (cursor->set & FB_CUR_SETSIZE || 1111 if (cursor->set & FB_CUR_SETSIZE ||
@@ -1102,7 +1126,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1102 __func__, cursor->image.width, cursor->image.height); 1126 __func__, cursor->image.width, cursor->image.height);
1103 1127
1104 for (op = 0; op < (64*64*2)/8; op+=4) 1128 for (op = 0; op < (64*64*2)/8; op+=4)
1105 writel(0x0, dst + op); 1129 smc501_writel(0x0, dst + op);
1106 1130
1107 for (y = 0; y < cursor->image.height; y++) { 1131 for (y = 0; y < cursor->image.height; y++) {
1108 for (x = 0; x < cursor->image.width; x++) { 1132 for (x = 0; x < cursor->image.width; x++) {
@@ -1141,7 +1165,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
1141 struct sm501fb_info *info = dev_get_drvdata(dev); 1165 struct sm501fb_info *info = dev_get_drvdata(dev);
1142 unsigned long ctrl; 1166 unsigned long ctrl;
1143 1167
1144 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1168 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1145 ctrl &= SM501_DC_CRT_CONTROL_SEL; 1169 ctrl &= SM501_DC_CRT_CONTROL_SEL;
1146 1170
1147 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel"); 1171 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
@@ -1172,7 +1196,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1172 1196
1173 dev_info(dev, "setting crt source to head %d\n", head); 1197 dev_info(dev, "setting crt source to head %d\n", head);
1174 1198
1175 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1199 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1176 1200
1177 if (head == HEAD_CRT) { 1201 if (head == HEAD_CRT) {
1178 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1202 ctrl |= SM501_DC_CRT_CONTROL_SEL;
@@ -1184,7 +1208,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1184 ctrl &= ~SM501_DC_CRT_CONTROL_TE; 1208 ctrl &= ~SM501_DC_CRT_CONTROL_TE;
1185 } 1209 }
1186 1210
1187 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1211 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1188 sm501fb_sync_regs(info); 1212 sm501fb_sync_regs(info);
1189 1213
1190 return len; 1214 return len;
@@ -1205,7 +1229,8 @@ static int sm501fb_show_regs(struct sm501fb_info *info, char *ptr,
1205 unsigned int reg; 1229 unsigned int reg;
1206 1230
1207 for (reg = start; reg < (len + start); reg += 4) 1231 for (reg = start; reg < (len + start); reg += 4)
1208 ptr += sprintf(ptr, "%08x = %08x\n", reg, readl(mem + reg)); 1232 ptr += sprintf(ptr, "%08x = %08x\n", reg,
1233 smc501_readl(mem + reg));
1209 1234
1210 return ptr - buf; 1235 return ptr - buf;
1211} 1236}
@@ -1257,7 +1282,7 @@ static int sm501fb_sync(struct fb_info *info)
1257 1282
1258 /* wait for the 2d engine to be ready */ 1283 /* wait for the 2d engine to be ready */
1259 while ((count > 0) && 1284 while ((count > 0) &&
1260 (readl(fbi->regs + SM501_SYSTEM_CONTROL) & 1285 (smc501_readl(fbi->regs + SM501_SYSTEM_CONTROL) &
1261 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0) 1286 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0)
1262 count--; 1287 count--;
1263 1288
@@ -1312,45 +1337,46 @@ static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
1312 return; 1337 return;
1313 1338
1314 /* set the base addresses */ 1339 /* set the base addresses */
1315 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1340 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1316 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1341 smc501_writel(par->screen.sm_addr,
1342 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1317 1343
1318 /* set the window width */ 1344 /* set the window width */
1319 writel((info->var.xres << 16) | info->var.xres, 1345 smc501_writel((info->var.xres << 16) | info->var.xres,
1320 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1346 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1321 1347
1322 /* set window stride */ 1348 /* set window stride */
1323 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1349 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1324 fbi->regs2d + SM501_2D_PITCH); 1350 fbi->regs2d + SM501_2D_PITCH);
1325 1351
1326 /* set data format */ 1352 /* set data format */
1327 switch (info->var.bits_per_pixel) { 1353 switch (info->var.bits_per_pixel) {
1328 case 8: 1354 case 8:
1329 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1355 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1330 break; 1356 break;
1331 case 16: 1357 case 16:
1332 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1358 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1333 break; 1359 break;
1334 case 32: 1360 case 32:
1335 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1361 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1336 break; 1362 break;
1337 } 1363 }
1338 1364
1339 /* 2d compare mask */ 1365 /* 2d compare mask */
1340 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1366 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1341 1367
1342 /* 2d mask */ 1368 /* 2d mask */
1343 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1369 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1344 1370
1345 /* source and destination x y */ 1371 /* source and destination x y */
1346 writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE); 1372 smc501_writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
1347 writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION); 1373 smc501_writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
1348 1374
1349 /* w/h */ 1375 /* w/h */
1350 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1376 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1351 1377
1352 /* do area move */ 1378 /* do area move */
1353 writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL); 1379 smc501_writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
1354} 1380}
1355 1381
1356static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 1382static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
@@ -1372,47 +1398,49 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
1372 return; 1398 return;
1373 1399
1374 /* set the base addresses */ 1400 /* set the base addresses */
1375 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1401 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1376 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1402 smc501_writel(par->screen.sm_addr,
1403 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1377 1404
1378 /* set the window width */ 1405 /* set the window width */
1379 writel((info->var.xres << 16) | info->var.xres, 1406 smc501_writel((info->var.xres << 16) | info->var.xres,
1380 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1407 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1381 1408
1382 /* set window stride */ 1409 /* set window stride */
1383 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1410 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1384 fbi->regs2d + SM501_2D_PITCH); 1411 fbi->regs2d + SM501_2D_PITCH);
1385 1412
1386 /* set data format */ 1413 /* set data format */
1387 switch (info->var.bits_per_pixel) { 1414 switch (info->var.bits_per_pixel) {
1388 case 8: 1415 case 8:
1389 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1416 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1390 break; 1417 break;
1391 case 16: 1418 case 16:
1392 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1419 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1393 break; 1420 break;
1394 case 32: 1421 case 32:
1395 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1422 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1396 break; 1423 break;
1397 } 1424 }
1398 1425
1399 /* 2d compare mask */ 1426 /* 2d compare mask */
1400 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1427 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1401 1428
1402 /* 2d mask */ 1429 /* 2d mask */
1403 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1430 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1404 1431
1405 /* colour */ 1432 /* colour */
1406 writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND); 1433 smc501_writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
1407 1434
1408 /* x y */ 1435 /* x y */
1409 writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION); 1436 smc501_writel((rect->dx << 16) | rect->dy,
1437 fbi->regs2d + SM501_2D_DESTINATION);
1410 1438
1411 /* w/h */ 1439 /* w/h */
1412 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1440 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1413 1441
1414 /* do rectangle fill */ 1442 /* do rectangle fill */
1415 writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL); 1443 smc501_writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
1416} 1444}
1417 1445
1418 1446
@@ -1470,11 +1498,12 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
1470 1498
1471 /* initialise the colour registers */ 1499 /* initialise the colour registers */
1472 1500
1473 writel(par->cursor.sm_addr, par->cursor_regs + SM501_OFF_HWC_ADDR); 1501 smc501_writel(par->cursor.sm_addr,
1502 par->cursor_regs + SM501_OFF_HWC_ADDR);
1474 1503
1475 writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC); 1504 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
1476 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2); 1505 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
1477 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3); 1506 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
1478 sm501fb_sync_regs(info); 1507 sm501fb_sync_regs(info);
1479 1508
1480 return 0; 1509 return 0;
@@ -1581,7 +1610,7 @@ static int sm501fb_start(struct sm501fb_info *info,
1581 1610
1582 /* clear palette ram - undefined at power on */ 1611 /* clear palette ram - undefined at power on */
1583 for (k = 0; k < (256 * 3); k++) 1612 for (k = 0; k < (256 * 3); k++)
1584 writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4)); 1613 smc501_writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
1585 1614
1586 /* enable display controller */ 1615 /* enable display controller */
1587 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); 1616 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
@@ -1649,20 +1678,20 @@ static int sm501fb_init_fb(struct fb_info *fb,
1649 switch (head) { 1678 switch (head) {
1650 case HEAD_CRT: 1679 case HEAD_CRT:
1651 pd = info->pdata->fb_crt; 1680 pd = info->pdata->fb_crt;
1652 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1681 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1653 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0; 1682 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0;
1654 1683
1655 /* ensure we set the correct source register */ 1684 /* ensure we set the correct source register */
1656 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) { 1685 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) {
1657 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1686 ctrl |= SM501_DC_CRT_CONTROL_SEL;
1658 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1687 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1659 } 1688 }
1660 1689
1661 break; 1690 break;
1662 1691
1663 case HEAD_PANEL: 1692 case HEAD_PANEL:
1664 pd = info->pdata->fb_pnl; 1693 pd = info->pdata->fb_pnl;
1665 ctrl = readl(info->regs + SM501_DC_PANEL_CONTROL); 1694 ctrl = smc501_readl(info->regs + SM501_DC_PANEL_CONTROL);
1666 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0; 1695 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0;
1667 break; 1696 break;
1668 1697
@@ -1680,7 +1709,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
1680 1709
1681 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) { 1710 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) {
1682 ctrl &= ~SM501_DC_CRT_CONTROL_SEL; 1711 ctrl &= ~SM501_DC_CRT_CONTROL_SEL;
1683 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1712 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1684 enable = 0; 1713 enable = 0;
1685 } 1714 }
1686 1715
@@ -1690,7 +1719,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
1690 (head == HEAD_CRT) ? &sm501fb_ops_crt : &sm501fb_ops_pnl, 1719 (head == HEAD_CRT) ? &sm501fb_ops_crt : &sm501fb_ops_pnl,
1691 sizeof(struct fb_ops)); 1720 sizeof(struct fb_ops));
1692 1721
1693 /* update ops dependant on what we've been passed */ 1722 /* update ops dependent on what we've been passed */
1694 1723
1695 if ((pd->flags & SM501FB_FLAG_USE_HWCURSOR) == 0) 1724 if ((pd->flags & SM501FB_FLAG_USE_HWCURSOR) == 0)
1696 par->ops.fb_cursor = NULL; 1725 par->ops.fb_cursor = NULL;
@@ -1700,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
1700 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1729 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1701 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; 1730 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
1702 1731
1732#if defined(CONFIG_OF)
1733#ifdef __BIG_ENDIAN
1734 if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
1735 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1736#else
1737 if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
1738 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1739#endif
1740#endif
1703 /* fixed data */ 1741 /* fixed data */
1704 1742
1705 fb->fix.type = FB_TYPE_PACKED_PIXELS; 1743 fb->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1717,9 +1755,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
1717 fb->var.vmode = FB_VMODE_NONINTERLACED; 1755 fb->var.vmode = FB_VMODE_NONINTERLACED;
1718 fb->var.bits_per_pixel = 16; 1756 fb->var.bits_per_pixel = 16;
1719 1757
1758 if (info->edid_data) {
1759 /* Now build modedb from EDID */
1760 fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
1761 fb_videomode_to_modelist(fb->monspecs.modedb,
1762 fb->monspecs.modedb_len,
1763 &fb->modelist);
1764 }
1765
1720 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { 1766 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
1721 /* TODO read the mode from the current display */ 1767 /* TODO read the mode from the current display */
1722
1723 } else { 1768 } else {
1724 if (pd->def_mode) { 1769 if (pd->def_mode) {
1725 dev_info(info->dev, "using supplied mode\n"); 1770 dev_info(info->dev, "using supplied mode\n");
@@ -1729,12 +1774,37 @@ static int sm501fb_init_fb(struct fb_info *fb,
1729 fb->var.xres_virtual = fb->var.xres; 1774 fb->var.xres_virtual = fb->var.xres;
1730 fb->var.yres_virtual = fb->var.yres; 1775 fb->var.yres_virtual = fb->var.yres;
1731 } else { 1776 } else {
1732 ret = fb_find_mode(&fb->var, fb, 1777 if (info->edid_data) {
1778 ret = fb_find_mode(&fb->var, fb, fb_mode,
1779 fb->monspecs.modedb,
1780 fb->monspecs.modedb_len,
1781 &sm501_default_mode, default_bpp);
1782 /* edid_data is no longer needed, free it */
1783 kfree(info->edid_data);
1784 } else {
1785 ret = fb_find_mode(&fb->var, fb,
1733 NULL, NULL, 0, NULL, 8); 1786 NULL, NULL, 0, NULL, 8);
1787 }
1734 1788
1735 if (ret == 0 || ret == 4) { 1789 switch (ret) {
1736 dev_err(info->dev, 1790 case 1:
1737 "failed to get initial mode\n"); 1791 dev_info(info->dev, "using mode specified in "
1792 "@mode\n");
1793 break;
1794 case 2:
1795 dev_info(info->dev, "using mode specified in "
1796 "@mode with ignored refresh rate\n");
1797 break;
1798 case 3:
1799 dev_info(info->dev, "using mode default "
1800 "mode\n");
1801 break;
1802 case 4:
1803 dev_info(info->dev, "using mode from list\n");
1804 break;
1805 default:
1806 dev_info(info->dev, "ret = %d\n", ret);
1807 dev_info(info->dev, "failed to find mode\n");
1738 return -EINVAL; 1808 return -EINVAL;
1739 } 1809 }
1740 } 1810 }
@@ -1875,8 +1945,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
1875 } 1945 }
1876 1946
1877 if (info->pdata == NULL) { 1947 if (info->pdata == NULL) {
1878 dev_info(dev, "using default configuration data\n"); 1948 int found = 0;
1949#if defined(CONFIG_OF)
1950 struct device_node *np = pdev->dev.parent->of_node;
1951 const u8 *prop;
1952 const char *cp;
1953 int len;
1954
1879 info->pdata = &sm501fb_def_pdata; 1955 info->pdata = &sm501fb_def_pdata;
1956 if (np) {
1957 /* Get EDID */
1958 cp = of_get_property(np, "mode", &len);
1959 if (cp)
1960 strcpy(fb_mode, cp);
1961 prop = of_get_property(np, "edid", &len);
1962 if (prop && len == EDID_LENGTH) {
1963 info->edid_data = kmemdup(prop, EDID_LENGTH,
1964 GFP_KERNEL);
1965 if (info->edid_data)
1966 found = 1;
1967 }
1968 }
1969#endif
1970 if (!found) {
1971 dev_info(dev, "using default configuration data\n");
1972 info->pdata = &sm501fb_def_pdata;
1973 }
1880 } 1974 }
1881 1975
1882 /* probe for the presence of each panel */ 1976 /* probe for the presence of each panel */
@@ -2085,7 +2179,7 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
2085 struct sm501fb_info *info = platform_get_drvdata(pdev); 2179 struct sm501fb_info *info = platform_get_drvdata(pdev);
2086 2180
2087 /* store crt control to resume with */ 2181 /* store crt control to resume with */
2088 info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2182 info->pm_crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2089 2183
2090 sm501fb_suspend_fb(info, HEAD_CRT); 2184 sm501fb_suspend_fb(info, HEAD_CRT);
2091 sm501fb_suspend_fb(info, HEAD_PANEL); 2185 sm501fb_suspend_fb(info, HEAD_PANEL);
@@ -2109,10 +2203,10 @@ static int sm501fb_resume(struct platform_device *pdev)
2109 2203
2110 /* restore the items we want to be saved for crt control */ 2204 /* restore the items we want to be saved for crt control */
2111 2205
2112 crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2206 crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2113 crt_ctrl &= ~SM501_CRT_CTRL_SAVE; 2207 crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
2114 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE; 2208 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
2115 writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL); 2209 smc501_writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
2116 2210
2117 sm501fb_resume_fb(info, HEAD_CRT); 2211 sm501fb_resume_fb(info, HEAD_CRT);
2118 sm501fb_resume_fb(info, HEAD_PANEL); 2212 sm501fb_resume_fb(info, HEAD_PANEL);
@@ -2149,6 +2243,11 @@ static void __exit sm501fb_cleanup(void)
2149module_init(sm501fb_init); 2243module_init(sm501fb_init);
2150module_exit(sm501fb_cleanup); 2244module_exit(sm501fb_cleanup);
2151 2245
2246module_param_named(mode, fb_mode, charp, 0);
2247MODULE_PARM_DESC(mode,
2248 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
2249module_param_named(bpp, default_bpp, ulong, 0);
2250MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
2152MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); 2251MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
2153MODULE_DESCRIPTION("SM501 Framebuffer driver"); 2252MODULE_DESCRIPTION("SM501 Framebuffer driver");
2154MODULE_LICENSE("GPL v2"); 2253MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 2ab704118c44..2301c275d63a 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -221,7 +221,7 @@ static int __sst_wait_idle(u8 __iomem *vbase)
221 while(1) { 221 while(1) {
222 if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) { 222 if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) {
223 f_dddprintk("status: busy\n"); 223 f_dddprintk("status: busy\n");
224/* FIXME basicaly, this is a busy wait. maybe not that good. oh well; 224/* FIXME basically, this is a busy wait. maybe not that good. oh well;
225 * this is a small loop after all. 225 * this is a small loop after all.
226 * Or maybe we should use mdelay() or udelay() here instead ? */ 226 * Or maybe we should use mdelay() or udelay() here instead ? */
227 count = 0; 227 count = 0;
@@ -501,7 +501,7 @@ static int sstfb_set_par(struct fb_info *info)
501 } 501 }
502 502
503 if (IS_VOODOO2(par)) { 503 if (IS_VOODOO2(par)) {
504 /* voodoo2 has 32 pixel wide tiles , BUT stange things 504 /* voodoo2 has 32 pixel wide tiles , BUT strange things
505 happen with odd number of tiles */ 505 happen with odd number of tiles */
506 par->tiles_in_X = (info->var.xres + 63 ) / 64 * 2; 506 par->tiles_in_X = (info->var.xres + 63 ) / 64 * 2;
507 } else { 507 } else {
@@ -920,11 +920,11 @@ static int __devinit sst_detect_ti(struct fb_info *info)
920 * we get the 1st byte (M value) of preset f1,f7 and fB 920 * we get the 1st byte (M value) of preset f1,f7 and fB
921 * why those 3 ? mmmh... for now, i'll do it the glide way... 921 * why those 3 ? mmmh... for now, i'll do it the glide way...
922 * and ask questions later. anyway, it seems that all the freq registers are 922 * and ask questions later. anyway, it seems that all the freq registers are
923 * realy at their default state (cf specs) so i ask again, why those 3 regs ? 923 * really at their default state (cf specs) so i ask again, why those 3 regs ?
924 * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for 924 * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for
925 * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be 925 * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be
926 * touched... 926 * touched...
927 * is it realy safe ? how can i reset this ramdac ? geee... 927 * is it really safe ? how can i reset this ramdac ? geee...
928 */ 928 */
929static int __devinit sst_detect_ics(struct fb_info *info) 929static int __devinit sst_detect_ics(struct fb_info *info)
930{ 930{
diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h
index 7fe5be4bc70e..addf7b615ef8 100644
--- a/drivers/video/sticore.h
+++ b/drivers/video/sticore.h
@@ -79,7 +79,7 @@ struct sti_glob_cfg_ext {
79 u8 curr_mon; /* current monitor configured */ 79 u8 curr_mon; /* current monitor configured */
80 u8 friendly_boot; /* in friendly boot mode */ 80 u8 friendly_boot; /* in friendly boot mode */
81 s16 power; /* power calculation (in Watts) */ 81 s16 power; /* power calculation (in Watts) */
82 s32 freq_ref; /* frequency refrence */ 82 s32 freq_ref; /* frequency reference */
83 u32 sti_mem_addr; /* pointer to global sti memory (size=sti_mem_request) */ 83 u32 sti_mem_addr; /* pointer to global sti memory (size=sti_mem_request) */
84 u32 future_ptr; /* pointer to future data */ 84 u32 future_ptr; /* pointer to future data */
85}; 85};
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index fdb45674e2f6..33df9ec91795 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -20,12 +20,12 @@
20 20
21 21
22/* Write a CRT register value spread across multiple registers */ 22/* Write a CRT register value spread across multiple registers */
23void svga_wcrt_multi(const struct vga_regset *regset, u32 value) { 23void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
24 24{
25 u8 regval, bitval, bitnum; 25 u8 regval, bitval, bitnum;
26 26
27 while (regset->regnum != VGA_REGSET_END_VAL) { 27 while (regset->regnum != VGA_REGSET_END_VAL) {
28 regval = vga_rcrt(NULL, regset->regnum); 28 regval = vga_rcrt(regbase, regset->regnum);
29 bitnum = regset->lowbit; 29 bitnum = regset->lowbit;
30 while (bitnum <= regset->highbit) { 30 while (bitnum <= regset->highbit) {
31 bitval = 1 << bitnum; 31 bitval = 1 << bitnum;
@@ -34,18 +34,18 @@ void svga_wcrt_multi(const struct vga_regset *regset, u32 value) {
34 bitnum ++; 34 bitnum ++;
35 value = value >> 1; 35 value = value >> 1;
36 } 36 }
37 vga_wcrt(NULL, regset->regnum, regval); 37 vga_wcrt(regbase, regset->regnum, regval);
38 regset ++; 38 regset ++;
39 } 39 }
40} 40}
41 41
42/* Write a sequencer register value spread across multiple registers */ 42/* Write a sequencer register value spread across multiple registers */
43void svga_wseq_multi(const struct vga_regset *regset, u32 value) { 43void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
44 44{
45 u8 regval, bitval, bitnum; 45 u8 regval, bitval, bitnum;
46 46
47 while (regset->regnum != VGA_REGSET_END_VAL) { 47 while (regset->regnum != VGA_REGSET_END_VAL) {
48 regval = vga_rseq(NULL, regset->regnum); 48 regval = vga_rseq(regbase, regset->regnum);
49 bitnum = regset->lowbit; 49 bitnum = regset->lowbit;
50 while (bitnum <= regset->highbit) { 50 while (bitnum <= regset->highbit) {
51 bitval = 1 << bitnum; 51 bitval = 1 << bitnum;
@@ -54,7 +54,7 @@ void svga_wseq_multi(const struct vga_regset *regset, u32 value) {
54 bitnum ++; 54 bitnum ++;
55 value = value >> 1; 55 value = value >> 1;
56 } 56 }
57 vga_wseq(NULL, regset->regnum, regval); 57 vga_wseq(regbase, regset->regnum, regval);
58 regset ++; 58 regset ++;
59 } 59 }
60} 60}
@@ -75,95 +75,95 @@ static unsigned int svga_regset_size(const struct vga_regset *regset)
75 75
76 76
77/* Set graphics controller registers to sane values */ 77/* Set graphics controller registers to sane values */
78void svga_set_default_gfx_regs(void) 78void svga_set_default_gfx_regs(void __iomem *regbase)
79{ 79{
80 /* All standard GFX registers (GR00 - GR08) */ 80 /* All standard GFX registers (GR00 - GR08) */
81 vga_wgfx(NULL, VGA_GFX_SR_VALUE, 0x00); 81 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0x00);
82 vga_wgfx(NULL, VGA_GFX_SR_ENABLE, 0x00); 82 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0x00);
83 vga_wgfx(NULL, VGA_GFX_COMPARE_VALUE, 0x00); 83 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0x00);
84 vga_wgfx(NULL, VGA_GFX_DATA_ROTATE, 0x00); 84 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0x00);
85 vga_wgfx(NULL, VGA_GFX_PLANE_READ, 0x00); 85 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0x00);
86 vga_wgfx(NULL, VGA_GFX_MODE, 0x00); 86 vga_wgfx(regbase, VGA_GFX_MODE, 0x00);
87/* vga_wgfx(NULL, VGA_GFX_MODE, 0x20); */ 87/* vga_wgfx(regbase, VGA_GFX_MODE, 0x20); */
88/* vga_wgfx(NULL, VGA_GFX_MODE, 0x40); */ 88/* vga_wgfx(regbase, VGA_GFX_MODE, 0x40); */
89 vga_wgfx(NULL, VGA_GFX_MISC, 0x05); 89 vga_wgfx(regbase, VGA_GFX_MISC, 0x05);
90/* vga_wgfx(NULL, VGA_GFX_MISC, 0x01); */ 90/* vga_wgfx(regbase, VGA_GFX_MISC, 0x01); */
91 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x0F); 91 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x0F);
92 vga_wgfx(NULL, VGA_GFX_BIT_MASK, 0xFF); 92 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 0xFF);
93} 93}
94 94
95/* Set attribute controller registers to sane values */ 95/* Set attribute controller registers to sane values */
96void svga_set_default_atc_regs(void) 96void svga_set_default_atc_regs(void __iomem *regbase)
97{ 97{
98 u8 count; 98 u8 count;
99 99
100 vga_r(NULL, 0x3DA); 100 vga_r(regbase, 0x3DA);
101 vga_w(NULL, VGA_ATT_W, 0x00); 101 vga_w(regbase, VGA_ATT_W, 0x00);
102 102
103 /* All standard ATC registers (AR00 - AR14) */ 103 /* All standard ATC registers (AR00 - AR14) */
104 for (count = 0; count <= 0xF; count ++) 104 for (count = 0; count <= 0xF; count ++)
105 svga_wattr(count, count); 105 svga_wattr(regbase, count, count);
106 106
107 svga_wattr(VGA_ATC_MODE, 0x01); 107 svga_wattr(regbase, VGA_ATC_MODE, 0x01);
108/* svga_wattr(VGA_ATC_MODE, 0x41); */ 108/* svga_wattr(regbase, VGA_ATC_MODE, 0x41); */
109 svga_wattr(VGA_ATC_OVERSCAN, 0x00); 109 svga_wattr(regbase, VGA_ATC_OVERSCAN, 0x00);
110 svga_wattr(VGA_ATC_PLANE_ENABLE, 0x0F); 110 svga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 0x0F);
111 svga_wattr(VGA_ATC_PEL, 0x00); 111 svga_wattr(regbase, VGA_ATC_PEL, 0x00);
112 svga_wattr(VGA_ATC_COLOR_PAGE, 0x00); 112 svga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0x00);
113 113
114 vga_r(NULL, 0x3DA); 114 vga_r(regbase, 0x3DA);
115 vga_w(NULL, VGA_ATT_W, 0x20); 115 vga_w(regbase, VGA_ATT_W, 0x20);
116} 116}
117 117
118/* Set sequencer registers to sane values */ 118/* Set sequencer registers to sane values */
119void svga_set_default_seq_regs(void) 119void svga_set_default_seq_regs(void __iomem *regbase)
120{ 120{
121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */ 121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */
122 vga_wseq(NULL, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS); 122 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
123 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES); 123 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
124 vga_wseq(NULL, VGA_SEQ_CHARACTER_MAP, 0x00); 124 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
125/* vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */ 125/* vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
126 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE); 126 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
127} 127}
128 128
129/* Set CRTC registers to sane values */ 129/* Set CRTC registers to sane values */
130void svga_set_default_crt_regs(void) 130void svga_set_default_crt_regs(void __iomem *regbase)
131{ 131{
132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */ 132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */
133 svga_wcrt_mask(0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */ 133 svga_wcrt_mask(regbase, 0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
134 vga_wcrt(NULL, VGA_CRTC_PRESET_ROW, 0); 134 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
135 svga_wcrt_mask(VGA_CRTC_MAX_SCAN, 0, 0x1F); 135 svga_wcrt_mask(regbase, VGA_CRTC_MAX_SCAN, 0, 0x1F);
136 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0); 136 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
137 vga_wcrt(NULL, VGA_CRTC_MODE, 0xE3); 137 vga_wcrt(regbase, VGA_CRTC_MODE, 0xE3);
138} 138}
139 139
140void svga_set_textmode_vga_regs(void) 140void svga_set_textmode_vga_regs(void __iomem *regbase)
141{ 141{
142 /* svga_wseq_mask(0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */ 142 /* svga_wseq_mask(regbase, 0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
143 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM); 143 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
144 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, 0x03); 144 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x03);
145 145
146 vga_wcrt(NULL, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */ 146 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
147 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0x1f); 147 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0x1f);
148 svga_wcrt_mask(VGA_CRTC_MODE, 0x23, 0x7f); 148 svga_wcrt_mask(regbase, VGA_CRTC_MODE, 0x23, 0x7f);
149 149
150 vga_wcrt(NULL, VGA_CRTC_CURSOR_START, 0x0d); 150 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0x0d);
151 vga_wcrt(NULL, VGA_CRTC_CURSOR_END, 0x0e); 151 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 0x0e);
152 vga_wcrt(NULL, VGA_CRTC_CURSOR_HI, 0x00); 152 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0x00);
153 vga_wcrt(NULL, VGA_CRTC_CURSOR_LO, 0x00); 153 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0x00);
154 154
155 vga_wgfx(NULL, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */ 155 vga_wgfx(regbase, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
156 vga_wgfx(NULL, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */ 156 vga_wgfx(regbase, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
157 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x00); 157 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x00);
158 158
159 vga_r(NULL, 0x3DA); 159 vga_r(regbase, 0x3DA);
160 vga_w(NULL, VGA_ATT_W, 0x00); 160 vga_w(regbase, VGA_ATT_W, 0x00);
161 161
162 svga_wattr(0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */ 162 svga_wattr(regbase, 0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
163 svga_wattr(0x13, 0x08); /* Horizontal Pixel Panning Register */ 163 svga_wattr(regbase, 0x13, 0x08); /* Horizontal Pixel Panning Register */
164 164
165 vga_r(NULL, 0x3DA); 165 vga_r(regbase, 0x3DA);
166 vga_w(NULL, VGA_ATT_W, 0x20); 166 vga_w(regbase, VGA_ATT_W, 0x20);
167} 167}
168 168
169#if 0 169#if 0
@@ -299,7 +299,7 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
299} 299}
300 300
301/* Set cursor in text (tileblit) mode */ 301/* Set cursor in text (tileblit) mode */
302void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) 302void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor)
303{ 303{
304 u8 cs = 0x0d; 304 u8 cs = 0x0d;
305 u8 ce = 0x0e; 305 u8 ce = 0x0e;
@@ -310,7 +310,7 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
310 if (! cursor -> mode) 310 if (! cursor -> mode)
311 return; 311 return;
312 312
313 svga_wcrt_mask(0x0A, 0x20, 0x20); /* disable cursor */ 313 svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20); /* disable cursor */
314 314
315 if (cursor -> shape == FB_TILE_CURSOR_NONE) 315 if (cursor -> shape == FB_TILE_CURSOR_NONE)
316 return; 316 return;
@@ -334,11 +334,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
334 } 334 }
335 335
336 /* set cursor position */ 336 /* set cursor position */
337 vga_wcrt(NULL, 0x0E, pos >> 8); 337 vga_wcrt(regbase, 0x0E, pos >> 8);
338 vga_wcrt(NULL, 0x0F, pos & 0xFF); 338 vga_wcrt(regbase, 0x0F, pos & 0xFF);
339 339
340 vga_wcrt(NULL, 0x0B, ce); /* set cursor end */ 340 vga_wcrt(regbase, 0x0B, ce); /* set cursor end */
341 vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */ 341 vga_wcrt(regbase, 0x0A, cs); /* set cursor start and enable it */
342} 342}
343 343
344int svga_get_tilemax(struct fb_info *info) 344int svga_get_tilemax(struct fb_info *info)
@@ -507,8 +507,9 @@ int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screenin
507} 507}
508 508
509/* Set CRT timing registers */ 509/* Set CRT timing registers */
510void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, 510void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
511 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node) 511 struct fb_var_screeninfo *var,
512 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
512{ 513{
513 u8 regval; 514 u8 regval;
514 u32 value; 515 u32 value;
@@ -516,66 +517,66 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
516 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 517 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
517 value = (value * hmul) / hdiv; 518 value = (value * hmul) / hdiv;
518 pr_debug("fb%d: horizontal total : %d\n", node, value); 519 pr_debug("fb%d: horizontal total : %d\n", node, value);
519 svga_wcrt_multi(tm->h_total_regs, (value / 8) - 5); 520 svga_wcrt_multi(regbase, tm->h_total_regs, (value / 8) - 5);
520 521
521 value = var->xres; 522 value = var->xres;
522 value = (value * hmul) / hdiv; 523 value = (value * hmul) / hdiv;
523 pr_debug("fb%d: horizontal display : %d\n", node, value); 524 pr_debug("fb%d: horizontal display : %d\n", node, value);
524 svga_wcrt_multi(tm->h_display_regs, (value / 8) - 1); 525 svga_wcrt_multi(regbase, tm->h_display_regs, (value / 8) - 1);
525 526
526 value = var->xres; 527 value = var->xres;
527 value = (value * hmul) / hdiv; 528 value = (value * hmul) / hdiv;
528 pr_debug("fb%d: horizontal blank start: %d\n", node, value); 529 pr_debug("fb%d: horizontal blank start: %d\n", node, value);
529 svga_wcrt_multi(tm->h_blank_start_regs, (value / 8) - 1 + hborder); 530 svga_wcrt_multi(regbase, tm->h_blank_start_regs, (value / 8) - 1 + hborder);
530 531
531 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 532 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
532 value = (value * hmul) / hdiv; 533 value = (value * hmul) / hdiv;
533 pr_debug("fb%d: horizontal blank end : %d\n", node, value); 534 pr_debug("fb%d: horizontal blank end : %d\n", node, value);
534 svga_wcrt_multi(tm->h_blank_end_regs, (value / 8) - 1 - hborder); 535 svga_wcrt_multi(regbase, tm->h_blank_end_regs, (value / 8) - 1 - hborder);
535 536
536 value = var->xres + var->right_margin; 537 value = var->xres + var->right_margin;
537 value = (value * hmul) / hdiv; 538 value = (value * hmul) / hdiv;
538 pr_debug("fb%d: horizontal sync start : %d\n", node, value); 539 pr_debug("fb%d: horizontal sync start : %d\n", node, value);
539 svga_wcrt_multi(tm->h_sync_start_regs, (value / 8)); 540 svga_wcrt_multi(regbase, tm->h_sync_start_regs, (value / 8));
540 541
541 value = var->xres + var->right_margin + var->hsync_len; 542 value = var->xres + var->right_margin + var->hsync_len;
542 value = (value * hmul) / hdiv; 543 value = (value * hmul) / hdiv;
543 pr_debug("fb%d: horizontal sync end : %d\n", node, value); 544 pr_debug("fb%d: horizontal sync end : %d\n", node, value);
544 svga_wcrt_multi(tm->h_sync_end_regs, (value / 8)); 545 svga_wcrt_multi(regbase, tm->h_sync_end_regs, (value / 8));
545 546
546 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 547 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
547 value = (value * vmul) / vdiv; 548 value = (value * vmul) / vdiv;
548 pr_debug("fb%d: vertical total : %d\n", node, value); 549 pr_debug("fb%d: vertical total : %d\n", node, value);
549 svga_wcrt_multi(tm->v_total_regs, value - 2); 550 svga_wcrt_multi(regbase, tm->v_total_regs, value - 2);
550 551
551 value = var->yres; 552 value = var->yres;
552 value = (value * vmul) / vdiv; 553 value = (value * vmul) / vdiv;
553 pr_debug("fb%d: vertical display : %d\n", node, value); 554 pr_debug("fb%d: vertical display : %d\n", node, value);
554 svga_wcrt_multi(tm->v_display_regs, value - 1); 555 svga_wcrt_multi(regbase, tm->v_display_regs, value - 1);
555 556
556 value = var->yres; 557 value = var->yres;
557 value = (value * vmul) / vdiv; 558 value = (value * vmul) / vdiv;
558 pr_debug("fb%d: vertical blank start : %d\n", node, value); 559 pr_debug("fb%d: vertical blank start : %d\n", node, value);
559 svga_wcrt_multi(tm->v_blank_start_regs, value); 560 svga_wcrt_multi(regbase, tm->v_blank_start_regs, value);
560 561
561 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 562 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
562 value = (value * vmul) / vdiv; 563 value = (value * vmul) / vdiv;
563 pr_debug("fb%d: vertical blank end : %d\n", node, value); 564 pr_debug("fb%d: vertical blank end : %d\n", node, value);
564 svga_wcrt_multi(tm->v_blank_end_regs, value - 2); 565 svga_wcrt_multi(regbase, tm->v_blank_end_regs, value - 2);
565 566
566 value = var->yres + var->lower_margin; 567 value = var->yres + var->lower_margin;
567 value = (value * vmul) / vdiv; 568 value = (value * vmul) / vdiv;
568 pr_debug("fb%d: vertical sync start : %d\n", node, value); 569 pr_debug("fb%d: vertical sync start : %d\n", node, value);
569 svga_wcrt_multi(tm->v_sync_start_regs, value); 570 svga_wcrt_multi(regbase, tm->v_sync_start_regs, value);
570 571
571 value = var->yres + var->lower_margin + var->vsync_len; 572 value = var->yres + var->lower_margin + var->vsync_len;
572 value = (value * vmul) / vdiv; 573 value = (value * vmul) / vdiv;
573 pr_debug("fb%d: vertical sync end : %d\n", node, value); 574 pr_debug("fb%d: vertical sync end : %d\n", node, value);
574 svga_wcrt_multi(tm->v_sync_end_regs, value); 575 svga_wcrt_multi(regbase, tm->v_sync_end_regs, value);
575 576
576 /* Set horizontal and vertical sync pulse polarity in misc register */ 577 /* Set horizontal and vertical sync pulse polarity in misc register */
577 578
578 regval = vga_r(NULL, VGA_MIS_R); 579 regval = vga_r(regbase, VGA_MIS_R);
579 if (var->sync & FB_SYNC_HOR_HIGH_ACT) { 580 if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
580 pr_debug("fb%d: positive horizontal sync\n", node); 581 pr_debug("fb%d: positive horizontal sync\n", node);
581 regval = regval & ~0x80; 582 regval = regval & ~0x80;
@@ -590,7 +591,7 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
590 pr_debug("fb%d: negative vertical sync\n\n", node); 591 pr_debug("fb%d: negative vertical sync\n\n", node);
591 regval = regval | 0x40; 592 regval = regval | 0x40;
592 } 593 }
593 vga_w(NULL, VGA_MIS_W, regval); 594 vga_w(regbase, VGA_MIS_W, regval);
594} 595}
595 596
596 597
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 855b71993f61..07c66e946634 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -480,6 +480,7 @@ out_dealloc_cmap:
480 480
481out_unmap_regs: 481out_unmap_regs:
482 tcx_unmap_regs(op, info, par); 482 tcx_unmap_regs(op, info, par);
483 framebuffer_release(info);
483 484
484out_err: 485out_err:
485 return err; 486 return err;
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 3ee5e63cfa4f..a99b994c9b6b 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -877,12 +877,12 @@ static void tdfxfb_fillrect(struct fb_info *info,
877 else 877 else
878 tdfx_rop = TDFX_ROP_XOR; 878 tdfx_rop = TDFX_ROP_XOR;
879 879
880 /* asume always rect->height < 4096 */ 880 /* assume always rect->height < 4096 */
881 if (dy + rect->height > 4095) { 881 if (dy + rect->height > 4095) {
882 dstbase = stride * dy; 882 dstbase = stride * dy;
883 dy = 0; 883 dy = 0;
884 } 884 }
885 /* asume always rect->width < 4096 */ 885 /* assume always rect->width < 4096 */
886 if (dx + rect->width > 4095) { 886 if (dx + rect->width > 4095) {
887 dstbase += dx * bpp >> 3; 887 dstbase += dx * bpp >> 3;
888 dx = 0; 888 dx = 0;
@@ -915,22 +915,22 @@ static void tdfxfb_copyarea(struct fb_info *info,
915 u32 dstbase = 0; 915 u32 dstbase = 0;
916 u32 srcbase = 0; 916 u32 srcbase = 0;
917 917
918 /* asume always area->height < 4096 */ 918 /* assume always area->height < 4096 */
919 if (sy + area->height > 4095) { 919 if (sy + area->height > 4095) {
920 srcbase = stride * sy; 920 srcbase = stride * sy;
921 sy = 0; 921 sy = 0;
922 } 922 }
923 /* asume always area->width < 4096 */ 923 /* assume always area->width < 4096 */
924 if (sx + area->width > 4095) { 924 if (sx + area->width > 4095) {
925 srcbase += sx * bpp >> 3; 925 srcbase += sx * bpp >> 3;
926 sx = 0; 926 sx = 0;
927 } 927 }
928 /* asume always area->height < 4096 */ 928 /* assume always area->height < 4096 */
929 if (dy + area->height > 4095) { 929 if (dy + area->height > 4095) {
930 dstbase = stride * dy; 930 dstbase = stride * dy;
931 dy = 0; 931 dy = 0;
932 } 932 }
933 /* asume always area->width < 4096 */ 933 /* assume always area->width < 4096 */
934 if (dx + area->width > 4095) { 934 if (dx + area->width > 4095) {
935 dstbase += dx * bpp >> 3; 935 dstbase += dx * bpp >> 3;
936 dx = 0; 936 dx = 0;
@@ -1003,12 +1003,12 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
1003#else 1003#else
1004 srcfmt = 0x400000; 1004 srcfmt = 0x400000;
1005#endif 1005#endif
1006 /* asume always image->height < 4096 */ 1006 /* assume always image->height < 4096 */
1007 if (dy + image->height > 4095) { 1007 if (dy + image->height > 4095) {
1008 dstbase = stride * dy; 1008 dstbase = stride * dy;
1009 dy = 0; 1009 dy = 0;
1010 } 1010 }
1011 /* asume always image->width < 4096 */ 1011 /* assume always image->width < 4096 */
1012 if (dx + image->width > 4095) { 1012 if (dx + image->width > 4095) {
1013 dstbase += dx * bpp >> 3; 1013 dstbase += dx * bpp >> 3;
1014 dx = 0; 1014 dx = 0;
@@ -1124,7 +1124,7 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1124 * lower half (least significant 64 bits) of a 128 bit word 1124 * lower half (least significant 64 bits) of a 128 bit word
1125 * and pattern 1 the upper half. If you examine the data of 1125 * and pattern 1 the upper half. If you examine the data of
1126 * the cursor image the graphics card uses then from the 1126 * the cursor image the graphics card uses then from the
1127 * begining you see line one of pattern 0, line one of 1127 * beginning you see line one of pattern 0, line one of
1128 * pattern 1, line two of pattern 0, line two of pattern 1, 1128 * pattern 1, line two of pattern 0, line two of pattern 1,
1129 * etc etc. The linear stride for the cursor is always 16 bytes 1129 * etc etc. The linear stride for the cursor is always 16 bytes
1130 * (128 bits) which is the maximum cursor width times two for 1130 * (128 bits) which is the maximum cursor width times two for
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index dfef88c803d4..0c341d739604 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -250,8 +250,7 @@ static irqreturn_t tmiofb_irq(int irq, void *__info)
250 */ 250 */
251static int tmiofb_hw_stop(struct platform_device *dev) 251static int tmiofb_hw_stop(struct platform_device *dev)
252{ 252{
253 struct mfd_cell *cell = dev->dev.platform_data; 253 struct tmio_fb_data *data = mfd_get_data(dev);
254 struct tmio_fb_data *data = cell->driver_data;
255 struct fb_info *info = platform_get_drvdata(dev); 254 struct fb_info *info = platform_get_drvdata(dev);
256 struct tmiofb_par *par = info->par; 255 struct tmiofb_par *par = info->par;
257 256
@@ -268,7 +267,7 @@ static int tmiofb_hw_stop(struct platform_device *dev)
268 */ 267 */
269static int tmiofb_hw_init(struct platform_device *dev) 268static int tmiofb_hw_init(struct platform_device *dev)
270{ 269{
271 struct mfd_cell *cell = dev->dev.platform_data; 270 const struct mfd_cell *cell = mfd_get_cell(dev);
272 struct fb_info *info = platform_get_drvdata(dev); 271 struct fb_info *info = platform_get_drvdata(dev);
273 struct tmiofb_par *par = info->par; 272 struct tmiofb_par *par = info->par;
274 const struct resource *nlcr = &cell->resources[0]; 273 const struct resource *nlcr = &cell->resources[0];
@@ -312,8 +311,7 @@ static int tmiofb_hw_init(struct platform_device *dev)
312 */ 311 */
313static void tmiofb_hw_mode(struct platform_device *dev) 312static void tmiofb_hw_mode(struct platform_device *dev)
314{ 313{
315 struct mfd_cell *cell = dev->dev.platform_data; 314 struct tmio_fb_data *data = mfd_get_data(dev);
316 struct tmio_fb_data *data = cell->driver_data;
317 struct fb_info *info = platform_get_drvdata(dev); 315 struct fb_info *info = platform_get_drvdata(dev);
318 struct fb_videomode *mode = info->mode; 316 struct fb_videomode *mode = info->mode;
319 struct tmiofb_par *par = info->par; 317 struct tmiofb_par *par = info->par;
@@ -361,7 +359,7 @@ tmiofb_acc_wait(struct fb_info *info, unsigned int ccs)
361{ 359{
362 struct tmiofb_par *par = info->par; 360 struct tmiofb_par *par = info->par;
363 /* 361 /*
364 * This code can be called whith interrupts disabled. 362 * This code can be called with interrupts disabled.
365 * So instead of relaying on irq to trigger the event, 363 * So instead of relaying on irq to trigger the event,
366 * poll the state till the necessary command is executed. 364 * poll the state till the necessary command is executed.
367 */ 365 */
@@ -559,9 +557,8 @@ static int tmiofb_ioctl(struct fb_info *fbi,
559static struct fb_videomode * 557static struct fb_videomode *
560tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) 558tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
561{ 559{
562 struct mfd_cell *cell = 560 struct tmio_fb_data *data =
563 info->device->platform_data; 561 mfd_get_data(to_platform_device(info->device));
564 struct tmio_fb_data *data = cell->driver_data;
565 struct fb_videomode *best = NULL; 562 struct fb_videomode *best = NULL;
566 int i; 563 int i;
567 564
@@ -581,9 +578,8 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
581{ 578{
582 579
583 struct fb_videomode *mode; 580 struct fb_videomode *mode;
584 struct mfd_cell *cell = 581 struct tmio_fb_data *data =
585 info->device->platform_data; 582 mfd_get_data(to_platform_device(info->device));
586 struct tmio_fb_data *data = cell->driver_data;
587 583
588 mode = tmiofb_find_mode(info, var); 584 mode = tmiofb_find_mode(info, var);
589 if (!mode || var->bits_per_pixel > 16) 585 if (!mode || var->bits_per_pixel > 16)
@@ -683,8 +679,8 @@ static struct fb_ops tmiofb_ops = {
683 679
684static int __devinit tmiofb_probe(struct platform_device *dev) 680static int __devinit tmiofb_probe(struct platform_device *dev)
685{ 681{
686 struct mfd_cell *cell = dev->dev.platform_data; 682 const struct mfd_cell *cell = mfd_get_cell(dev);
687 struct tmio_fb_data *data = cell->driver_data; 683 struct tmio_fb_data *data = mfd_get_data(dev);
688 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); 684 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
689 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); 685 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
690 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); 686 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
@@ -811,7 +807,7 @@ err_ioremap_ccr:
811 807
812static int __devexit tmiofb_remove(struct platform_device *dev) 808static int __devexit tmiofb_remove(struct platform_device *dev)
813{ 809{
814 struct mfd_cell *cell = dev->dev.platform_data; 810 const struct mfd_cell *cell = mfd_get_cell(dev);
815 struct fb_info *info = platform_get_drvdata(dev); 811 struct fb_info *info = platform_get_drvdata(dev);
816 int irq = platform_get_irq(dev, 0); 812 int irq = platform_get_irq(dev, 0);
817 struct tmiofb_par *par; 813 struct tmiofb_par *par;
@@ -941,7 +937,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
941#ifdef CONFIG_FB_TMIO_ACCELL 937#ifdef CONFIG_FB_TMIO_ACCELL
942 struct tmiofb_par *par = info->par; 938 struct tmiofb_par *par = info->par;
943#endif 939#endif
944 struct mfd_cell *cell = dev->dev.platform_data; 940 const struct mfd_cell *cell = mfd_get_cell(dev);
945 int retval = 0; 941 int retval = 0;
946 942
947 console_lock(); 943 console_lock();
@@ -973,7 +969,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
973static int tmiofb_resume(struct platform_device *dev) 969static int tmiofb_resume(struct platform_device *dev)
974{ 970{
975 struct fb_info *info = platform_get_drvdata(dev); 971 struct fb_info *info = platform_get_drvdata(dev);
976 struct mfd_cell *cell = dev->dev.platform_data; 972 const struct mfd_cell *cell = mfd_get_cell(dev);
977 int retval = 0; 973 int retval = 0;
978 974
979 console_lock(); 975 console_lock();
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 2c8364e9b632..68041d9dc260 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -769,7 +769,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
769 769
770 /* 770 /*
771 * If we have a damage-aware client, turn fb_defio "off" 771 * If we have a damage-aware client, turn fb_defio "off"
772 * To avoid perf imact of unecessary page fault handling. 772 * To avoid perf imact of unnecessary page fault handling.
773 * Done by resetting the delay for this fb_info to a very 773 * Done by resetting the delay for this fb_info to a very
774 * long period. Pages will become writable and stay that way. 774 * long period. Pages will become writable and stay that way.
775 * Reset to normal value when all clients have closed this fb. 775 * Reset to normal value when all clients have closed this fb.
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 5180a215d781..7f8472cc993b 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -1552,8 +1552,7 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1552 int rc; 1552 int rc;
1553 1553
1554 /* Find the largest power-of-two */ 1554 /* Find the largest power-of-two */
1555 while (temp_size & (temp_size - 1)) 1555 temp_size = roundup_pow_of_two(temp_size);
1556 temp_size &= (temp_size - 1);
1557 1556
1558 /* Try and find a power of two to add */ 1557 /* Try and find a power of two to add */
1559 do { 1558 do {
@@ -1566,6 +1565,28 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1566#endif /* CONFIG_MTRR */ 1565#endif /* CONFIG_MTRR */
1567} 1566}
1568 1567
1568static void __devinit uvesafb_ioremap(struct fb_info *info)
1569{
1570#ifdef CONFIG_X86
1571 switch (mtrr) {
1572 case 1: /* uncachable */
1573 info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
1574 break;
1575 case 2: /* write-back */
1576 info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
1577 break;
1578 case 3: /* write-combining */
1579 info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
1580 break;
1581 case 4: /* write-through */
1582 default:
1583 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1584 break;
1585 }
1586#else
1587 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1588#endif /* CONFIG_X86 */
1589}
1569 1590
1570static ssize_t uvesafb_show_vbe_ver(struct device *dev, 1591static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1571 struct device_attribute *attr, char *buf) 1592 struct device_attribute *attr, char *buf)
@@ -1736,15 +1757,22 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1736 1757
1737 uvesafb_init_info(info, mode); 1758 uvesafb_init_info(info, mode);
1738 1759
1760 if (!request_region(0x3c0, 32, "uvesafb")) {
1761 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1762 err = -EIO;
1763 goto out_mode;
1764 }
1765
1739 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len, 1766 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
1740 "uvesafb")) { 1767 "uvesafb")) {
1741 printk(KERN_ERR "uvesafb: cannot reserve video memory at " 1768 printk(KERN_ERR "uvesafb: cannot reserve video memory at "
1742 "0x%lx\n", info->fix.smem_start); 1769 "0x%lx\n", info->fix.smem_start);
1743 err = -EIO; 1770 err = -EIO;
1744 goto out_mode; 1771 goto out_reg;
1745 } 1772 }
1746 1773
1747 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 1774 uvesafb_init_mtrr(info);
1775 uvesafb_ioremap(info);
1748 1776
1749 if (!info->screen_base) { 1777 if (!info->screen_base) {
1750 printk(KERN_ERR 1778 printk(KERN_ERR
@@ -1755,20 +1783,13 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1755 goto out_mem; 1783 goto out_mem;
1756 } 1784 }
1757 1785
1758 if (!request_region(0x3c0, 32, "uvesafb")) {
1759 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1760 err = -EIO;
1761 goto out_unmap;
1762 }
1763
1764 uvesafb_init_mtrr(info);
1765 platform_set_drvdata(dev, info); 1786 platform_set_drvdata(dev, info);
1766 1787
1767 if (register_framebuffer(info) < 0) { 1788 if (register_framebuffer(info) < 0) {
1768 printk(KERN_ERR 1789 printk(KERN_ERR
1769 "uvesafb: failed to register framebuffer device\n"); 1790 "uvesafb: failed to register framebuffer device\n");
1770 err = -EINVAL; 1791 err = -EINVAL;
1771 goto out_reg; 1792 goto out_unmap;
1772 } 1793 }
1773 1794
1774 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, " 1795 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -1785,12 +1806,12 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1785 1806
1786 return 0; 1807 return 0;
1787 1808
1788out_reg:
1789 release_region(0x3c0, 32);
1790out_unmap: 1809out_unmap:
1791 iounmap(info->screen_base); 1810 iounmap(info->screen_base);
1792out_mem: 1811out_mem:
1793 release_mem_region(info->fix.smem_start, info->fix.smem_len); 1812 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1813out_reg:
1814 release_region(0x3c0, 32);
1794out_mode: 1815out_mode:
1795 if (!list_empty(&info->modelist)) 1816 if (!list_empty(&info->modelist))
1796 fb_destroy_modelist(&info->modelist); 1817 fb_destroy_modelist(&info->modelist);
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 931a567f9aff..970e43d13f52 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -891,8 +891,7 @@ static int vmlfb_set_par(struct fb_info *info)
891 int ret; 891 int ret;
892 892
893 mutex_lock(&vml_mutex); 893 mutex_lock(&vml_mutex);
894 list_del(&vinfo->head); 894 list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
895 list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
896 ret = vmlfb_set_par_locked(vinfo); 895 ret = vmlfb_set_par_locked(vinfo);
897 896
898 mutex_unlock(&vml_mutex); 897 mutex_unlock(&vml_mutex);
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 6a069d047914..a99bbe86db13 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -303,19 +303,6 @@ static int __init vesafb_probe(struct platform_device *dev)
303 info->apertures->ranges[0].base = screen_info.lfb_base; 303 info->apertures->ranges[0].base = screen_info.lfb_base;
304 info->apertures->ranges[0].size = size_total; 304 info->apertures->ranges[0].size = size_total;
305 305
306 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
307 if (!info->screen_base) {
308 printk(KERN_ERR
309 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
310 vesafb_fix.smem_len, vesafb_fix.smem_start);
311 err = -EIO;
312 goto err;
313 }
314
315 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
316 "using %dk, total %dk\n",
317 vesafb_fix.smem_start, info->screen_base,
318 size_remap/1024, size_total/1024);
319 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", 306 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
320 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); 307 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
321 308
@@ -438,8 +425,7 @@ static int __init vesafb_probe(struct platform_device *dev)
438 int rc; 425 int rc;
439 426
440 /* Find the largest power-of-two */ 427 /* Find the largest power-of-two */
441 while (temp_size & (temp_size - 1)) 428 temp_size = roundup_pow_of_two(temp_size);
442 temp_size &= (temp_size - 1);
443 429
444 /* Try and find a power of two to add */ 430 /* Try and find a power of two to add */
445 do { 431 do {
@@ -451,6 +437,34 @@ static int __init vesafb_probe(struct platform_device *dev)
451 } 437 }
452#endif 438#endif
453 439
440 switch (mtrr) {
441 case 1: /* uncachable */
442 info->screen_base = ioremap_nocache(vesafb_fix.smem_start, vesafb_fix.smem_len);
443 break;
444 case 2: /* write-back */
445 info->screen_base = ioremap_cache(vesafb_fix.smem_start, vesafb_fix.smem_len);
446 break;
447 case 3: /* write-combining */
448 info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
449 break;
450 case 4: /* write-through */
451 default:
452 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
453 break;
454 }
455 if (!info->screen_base) {
456 printk(KERN_ERR
457 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
458 vesafb_fix.smem_len, vesafb_fix.smem_start);
459 err = -EIO;
460 goto err;
461 }
462
463 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
464 "using %dk, total %dk\n",
465 vesafb_fix.smem_start, info->screen_base,
466 size_remap/1024, size_total/1024);
467
454 info->fbops = &vesafb_ops; 468 info->fbops = &vesafb_ops;
455 info->var = vesafb_defined; 469 info->var = vesafb_defined;
456 info->fix = vesafb_fix; 470 info->fix = vesafb_fix;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 28ccab44a391..53b2c5aae067 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -152,7 +152,7 @@ static inline int setop(int op)
152} 152}
153 153
154/* Set the Enable Set/Reset Register and return its old value. 154/* Set the Enable Set/Reset Register and return its old value.
155 The code here always uses value 0xf for thsi register. */ 155 The code here always uses value 0xf for this register. */
156static inline int setsr(int sr) 156static inline int setsr(int sr)
157{ 157{
158 int oldsr; 158 int oldsr;
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index 781f3aa66b42..29d70244a21f 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -139,7 +139,6 @@ struct chip_information {
139 139
140struct crt_setting_information { 140struct crt_setting_information {
141 int iga_path; 141 int iga_path;
142 int refresh_rate;
143}; 142};
144 143
145struct tmds_setting_information { 144struct tmds_setting_information {
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 5728fd76bc11..dc4c778877ce 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -2002,13 +2002,15 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2002 int i; 2002 int i;
2003 int index = 0; 2003 int index = 0;
2004 int h_addr, v_addr; 2004 int h_addr, v_addr;
2005 u32 pll_D_N, clock; 2005 u32 pll_D_N, clock, refresh = viafb_refresh;
2006
2007 if (viafb_SAMM_ON && set_iga == IGA2)
2008 refresh = viafb_refresh1;
2006 2009
2007 for (i = 0; i < video_mode->mode_array; i++) { 2010 for (i = 0; i < video_mode->mode_array; i++) {
2008 index = i; 2011 index = i;
2009 2012
2010 if (crt_table[i].refresh_rate == viaparinfo-> 2013 if (crt_table[i].refresh_rate == refresh)
2011 crt_setting_info->refresh_rate)
2012 break; 2014 break;
2013 } 2015 }
2014 2016
@@ -2019,7 +2021,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2019 if ((viafb_LCD_ON | viafb_DVI_ON) 2021 if ((viafb_LCD_ON | viafb_DVI_ON)
2020 && video_mode->crtc[0].crtc.hor_addr == 640 2022 && video_mode->crtc[0].crtc.hor_addr == 640
2021 && video_mode->crtc[0].crtc.ver_addr == 480 2023 && video_mode->crtc[0].crtc.ver_addr == 480
2022 && viaparinfo->crt_setting_info->refresh_rate == 60) { 2024 && refresh == 60) {
2023 /* The border is 8 pixels. */ 2025 /* The border is 8 pixels. */
2024 crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8; 2026 crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
2025 2027
@@ -2070,7 +2072,6 @@ void __devinit viafb_init_chip_info(int chip_type)
2070 init_lvds_chip_info(); 2072 init_lvds_chip_info();
2071 2073
2072 viaparinfo->crt_setting_info->iga_path = IGA1; 2074 viaparinfo->crt_setting_info->iga_path = IGA1;
2073 viaparinfo->crt_setting_info->refresh_rate = viafb_refresh;
2074 2075
2075 /*Set IGA path for each device */ 2076 /*Set IGA path for each device */
2076 viafb_set_iga_path(); 2077 viafb_set_iga_path();
@@ -2083,13 +2084,9 @@ void __devinit viafb_init_chip_info(int chip_type)
2083 viaparinfo->lvds_setting_info->lcd_mode; 2084 viaparinfo->lvds_setting_info->lcd_mode;
2084} 2085}
2085 2086
2086void viafb_update_device_setting(int hres, int vres, 2087void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
2087 int bpp, int vmode_refresh, int flag)
2088{ 2088{
2089 if (flag == 0) { 2089 if (flag == 0) {
2090 viaparinfo->crt_setting_info->refresh_rate =
2091 vmode_refresh;
2092
2093 viaparinfo->tmds_setting_info->h_active = hres; 2090 viaparinfo->tmds_setting_info->h_active = hres;
2094 viaparinfo->tmds_setting_info->v_active = vres; 2091 viaparinfo->tmds_setting_info->v_active = vres;
2095 2092
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 7295263299f7..8858593405aa 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -949,8 +949,7 @@ void __devinit viafb_init_chip_info(int chip_type);
949void __devinit viafb_init_dac(int set_iga); 949void __devinit viafb_init_dac(int set_iga);
950int viafb_get_pixclock(int hres, int vres, int vmode_refresh); 950int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
951int viafb_get_refresh(int hres, int vres, u32 float_refresh); 951int viafb_get_refresh(int hres, int vres, u32 float_refresh);
952void viafb_update_device_setting(int hres, int vres, int bpp, 952void viafb_update_device_setting(int hres, int vres, int bpp, int flag);
953 int vmode_refresh, int flag);
954 953
955void viafb_set_iga_path(void); 954void viafb_set_iga_path(void);
956void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue); 955void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue);
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c
index d05ccb62b55f..35458a5eadc8 100644
--- a/drivers/video/via/via_utility.c
+++ b/drivers/video/via/via_utility.c
@@ -174,7 +174,7 @@ void viafb_set_gamma_table(int bpp, unsigned int *gamma_table)
174 } 174 }
175 175
176 /* If adjust Gamma value in SAMM, fill IGA1, 176 /* If adjust Gamma value in SAMM, fill IGA1,
177 IGA2 Gamma table simultanous. */ 177 IGA2 Gamma table simultaneous. */
178 /* Switch to IGA2 Gamma Table */ 178 /* Switch to IGA2 Gamma Table */
179 if ((active_device_amount > 1) && 179 if ((active_device_amount > 1) &&
180 !((viaparinfo->chip_info->gfx_chip_name == 180 !((viaparinfo->chip_info->gfx_chip_name ==
diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h
index 1670ba82143f..f23be1708c14 100644
--- a/drivers/video/via/via_utility.h
+++ b/drivers/video/via/via_utility.h
@@ -21,7 +21,7 @@
21#ifndef __VIAUTILITY_H__ 21#ifndef __VIAUTILITY_H__
22#define __VIAUTILITY_H__ 22#define __VIAUTILITY_H__
23 23
24/* These functions are used to get infomation about device's state */ 24/* These functions are used to get information about device's state */
25void viafb_get_device_support_state(u32 *support_state); 25void viafb_get_device_support_state(u32 *support_state);
26void viafb_get_device_connect_state(u32 *connect_state); 26void viafb_get_device_connect_state(u32 *connect_state);
27bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres); 27bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres);
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index f555b891cc72..a542bed086e2 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -182,13 +182,24 @@ static int viafb_release(struct fb_info *info, int user)
182 return 0; 182 return 0;
183} 183}
184 184
185static inline int get_var_refresh(struct fb_var_screeninfo *var)
186{
187 u32 htotal, vtotal;
188
189 htotal = var->left_margin + var->xres + var->right_margin
190 + var->hsync_len;
191 vtotal = var->upper_margin + var->yres + var->lower_margin
192 + var->vsync_len;
193 return PICOS2KHZ(var->pixclock) * 1000 / (htotal * vtotal);
194}
195
185static int viafb_check_var(struct fb_var_screeninfo *var, 196static int viafb_check_var(struct fb_var_screeninfo *var,
186 struct fb_info *info) 197 struct fb_info *info)
187{ 198{
188 int htotal, vtotal, depth; 199 int depth, refresh;
189 struct VideoModeTable *vmode_entry; 200 struct VideoModeTable *vmode_entry;
190 struct viafb_par *ppar = info->par; 201 struct viafb_par *ppar = info->par;
191 u32 long_refresh, line; 202 u32 line;
192 203
193 DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); 204 DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
194 /* Sanity check */ 205 /* Sanity check */
@@ -231,17 +242,11 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
231 /* Based on var passed in to calculate the refresh, 242 /* Based on var passed in to calculate the refresh,
232 * because our driver use some modes special. 243 * because our driver use some modes special.
233 */ 244 */
234 htotal = var->xres + var->left_margin + 245 refresh = viafb_get_refresh(var->xres, var->yres,
235 var->right_margin + var->hsync_len; 246 get_var_refresh(var));
236 vtotal = var->yres + var->upper_margin +
237 var->lower_margin + var->vsync_len;
238 long_refresh = 1000000000UL / var->pixclock * 1000;
239 long_refresh /= (htotal * vtotal);
240
241 viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);
242 247
243 /* Adjust var according to our driver's own table */ 248 /* Adjust var according to our driver's own table */
244 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); 249 viafb_fill_var_timing_info(var, refresh, vmode_entry);
245 if (var->accel_flags & FB_ACCELF_TEXT && 250 if (var->accel_flags & FB_ACCELF_TEXT &&
246 !ppar->shared->vdev->engine_mmio) 251 !ppar->shared->vdev->engine_mmio)
247 var->accel_flags = 0; 252 var->accel_flags = 0;
@@ -253,12 +258,13 @@ static int viafb_set_par(struct fb_info *info)
253{ 258{
254 struct viafb_par *viapar = info->par; 259 struct viafb_par *viapar = info->par;
255 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL; 260 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
261 int refresh;
256 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 262 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
257 263
258 viafb_update_fix(info); 264 viafb_update_fix(info);
259 viapar->depth = fb_get_color_depth(&info->var, &info->fix); 265 viapar->depth = fb_get_color_depth(&info->var, &info->fix);
260 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, 266 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
261 viafbinfo->var.bits_per_pixel, viafb_refresh, 0); 267 viafbinfo->var.bits_per_pixel, 0);
262 268
263 vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres); 269 vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres);
264 if (viafb_dual_fb) { 270 if (viafb_dual_fb) {
@@ -266,7 +272,7 @@ static int viafb_set_par(struct fb_info *info)
266 viafbinfo1->var.yres); 272 viafbinfo1->var.yres);
267 viafb_update_device_setting(viafbinfo1->var.xres, 273 viafb_update_device_setting(viafbinfo1->var.xres,
268 viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel, 274 viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel,
269 viafb_refresh1, 1); 275 1);
270 } else if (viafb_SAMM_ON == 1) { 276 } else if (viafb_SAMM_ON == 1) {
271 DEBUG_MSG(KERN_INFO 277 DEBUG_MSG(KERN_INFO
272 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", 278 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
@@ -275,14 +281,19 @@ static int viafb_set_par(struct fb_info *info)
275 viafb_second_yres); 281 viafb_second_yres);
276 282
277 viafb_update_device_setting(viafb_second_xres, 283 viafb_update_device_setting(viafb_second_xres,
278 viafb_second_yres, viafb_bpp1, viafb_refresh1, 1); 284 viafb_second_yres, viafb_bpp1, 1);
279 } 285 }
280 286
287 refresh = viafb_get_refresh(info->var.xres, info->var.yres,
288 get_var_refresh(&info->var));
281 if (vmode_entry) { 289 if (vmode_entry) {
282 if (viafb_dual_fb && viapar->iga_path == IGA2) 290 if (viafb_dual_fb && viapar->iga_path == IGA2) {
283 viafb_bpp1 = info->var.bits_per_pixel; 291 viafb_bpp1 = info->var.bits_per_pixel;
284 else 292 viafb_refresh1 = refresh;
293 } else {
285 viafb_bpp = info->var.bits_per_pixel; 294 viafb_bpp = info->var.bits_per_pixel;
295 viafb_refresh = refresh;
296 }
286 297
287 if (info->var.accel_flags & FB_ACCELF_TEXT) 298 if (info->var.accel_flags & FB_ACCELF_TEXT)
288 info->flags &= ~FBINFO_HWACCEL_DISABLED; 299 info->flags &= ~FBINFO_HWACCEL_DISABLED;
@@ -1795,14 +1806,9 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1795 default_var.xres_virtual = default_xres; 1806 default_var.xres_virtual = default_xres;
1796 default_var.yres_virtual = default_yres; 1807 default_var.yres_virtual = default_yres;
1797 default_var.bits_per_pixel = viafb_bpp; 1808 default_var.bits_per_pixel = viafb_bpp;
1798 default_var.pixclock = 1809 viafb_fill_var_timing_info(&default_var, viafb_get_refresh(
1799 viafb_get_pixclock(default_xres, default_yres, viafb_refresh); 1810 default_var.xres, default_var.yres, viafb_refresh),
1800 default_var.left_margin = (default_xres >> 3) & 0xf8; 1811 viafb_get_mode(default_var.xres, default_var.yres));
1801 default_var.right_margin = 32;
1802 default_var.upper_margin = 16;
1803 default_var.lower_margin = 4;
1804 default_var.hsync_len = default_var.left_margin;
1805 default_var.vsync_len = 4;
1806 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); 1812 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
1807 viafbinfo->var = default_var; 1813 viafbinfo->var = default_var;
1808 1814
@@ -1841,15 +1847,9 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1841 default_var.xres_virtual = viafb_second_virtual_xres; 1847 default_var.xres_virtual = viafb_second_virtual_xres;
1842 default_var.yres_virtual = viafb_second_virtual_yres; 1848 default_var.yres_virtual = viafb_second_virtual_yres;
1843 default_var.bits_per_pixel = viafb_bpp1; 1849 default_var.bits_per_pixel = viafb_bpp1;
1844 default_var.pixclock = 1850 viafb_fill_var_timing_info(&default_var, viafb_get_refresh(
1845 viafb_get_pixclock(viafb_second_xres, viafb_second_yres, 1851 default_var.xres, default_var.yres, viafb_refresh1),
1846 viafb_refresh); 1852 viafb_get_mode(default_var.xres, default_var.yres));
1847 default_var.left_margin = (viafb_second_xres >> 3) & 0xf8;
1848 default_var.right_margin = 32;
1849 default_var.upper_margin = 16;
1850 default_var.lower_margin = 4;
1851 default_var.hsync_len = default_var.left_margin;
1852 default_var.vsync_len = 4;
1853 1853
1854 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); 1854 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
1855 viafb_check_var(&default_var, viafbinfo1); 1855 viafb_check_var(&default_var, viafbinfo1);
@@ -2004,22 +2004,24 @@ static int __init viafb_setup(char *options)
2004 */ 2004 */
2005int __init viafb_init(void) 2005int __init viafb_init(void)
2006{ 2006{
2007 u32 dummy; 2007 u32 dummy_x, dummy_y;
2008#ifndef MODULE 2008#ifndef MODULE
2009 char *option = NULL; 2009 char *option = NULL;
2010 if (fb_get_options("viafb", &option)) 2010 if (fb_get_options("viafb", &option))
2011 return -ENODEV; 2011 return -ENODEV;
2012 viafb_setup(option); 2012 viafb_setup(option);
2013#endif 2013#endif
2014 if (parse_mode(viafb_mode, &dummy, &dummy) 2014 if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
2015 || parse_mode(viafb_mode1, &dummy, &dummy) 2015 || !viafb_get_mode(dummy_x, dummy_y)
2016 || parse_mode(viafb_mode1, &dummy_x, &dummy_y)
2017 || !viafb_get_mode(dummy_x, dummy_y)
2016 || viafb_bpp < 0 || viafb_bpp > 32 2018 || viafb_bpp < 0 || viafb_bpp > 32
2017 || viafb_bpp1 < 0 || viafb_bpp1 > 32 2019 || viafb_bpp1 < 0 || viafb_bpp1 > 32
2018 || parse_active_dev()) 2020 || parse_active_dev())
2019 return -EINVAL; 2021 return -EINVAL;
2020 2022
2021 printk(KERN_INFO 2023 printk(KERN_INFO
2022 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", 2024 "VIA Graphics Integration Chipset framebuffer %d.%d initializing\n",
2023 VERSION_MAJOR, VERSION_MINOR); 2025 VERSION_MAJOR, VERSION_MINOR);
2024 return 0; 2026 return 0;
2025} 2027}
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index d66f963e930e..137996dc547e 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -94,9 +94,6 @@ extern int viafb_LCD_ON;
94extern int viafb_DVI_ON; 94extern int viafb_DVI_ON;
95extern int viafb_hotplug; 95extern int viafb_hotplug;
96 96
97extern int strict_strtoul(const char *cp, unsigned int base,
98 unsigned long *res);
99
100u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information 97u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
101 *plvds_setting_info, struct lvds_chip_information 98 *plvds_setting_info, struct lvds_chip_information
102 *plvds_chip_info, u8 index); 99 *plvds_chip_info, u8 index);
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index a2965ab92cfb..f9b3e3dc2421 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -121,13 +121,19 @@ MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, d
121 121
122/* ------------------------------------------------------------------------- */ 122/* ------------------------------------------------------------------------- */
123 123
124static void vt8623fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
125{
126 struct vt8623fb_info *par = info->par;
127
128 svga_tilecursor(par->state.vgabase, info, cursor);
129}
124 130
125static struct fb_tile_ops vt8623fb_tile_ops = { 131static struct fb_tile_ops vt8623fb_tile_ops = {
126 .fb_settile = svga_settile, 132 .fb_settile = svga_settile,
127 .fb_tilecopy = svga_tilecopy, 133 .fb_tilecopy = svga_tilecopy,
128 .fb_tilefill = svga_tilefill, 134 .fb_tilefill = svga_tilefill,
129 .fb_tileblit = svga_tileblit, 135 .fb_tileblit = svga_tileblit,
130 .fb_tilecursor = svga_tilecursor, 136 .fb_tilecursor = vt8623fb_tilecursor,
131 .fb_get_tilemax = svga_get_tilemax, 137 .fb_get_tilemax = svga_get_tilemax,
132}; 138};
133 139
@@ -253,6 +259,7 @@ static void vt8623fb_fillrect(struct fb_info *info, const struct fb_fillrect *re
253 259
254static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock) 260static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
255{ 261{
262 struct vt8623fb_info *par = info->par;
256 u16 m, n, r; 263 u16 m, n, r;
257 u8 regval; 264 u8 regval;
258 int rv; 265 int rv;
@@ -264,18 +271,18 @@ static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
264 } 271 }
265 272
266 /* Set VGA misc register */ 273 /* Set VGA misc register */
267 regval = vga_r(NULL, VGA_MIS_R); 274 regval = vga_r(par->state.vgabase, VGA_MIS_R);
268 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 275 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
269 276
270 /* Set clock registers */ 277 /* Set clock registers */
271 vga_wseq(NULL, 0x46, (n | (r << 6))); 278 vga_wseq(par->state.vgabase, 0x46, (n | (r << 6)));
272 vga_wseq(NULL, 0x47, m); 279 vga_wseq(par->state.vgabase, 0x47, m);
273 280
274 udelay(1000); 281 udelay(1000);
275 282
276 /* PLL reset */ 283 /* PLL reset */
277 svga_wseq_mask(0x40, 0x02, 0x02); 284 svga_wseq_mask(par->state.vgabase, 0x40, 0x02, 0x02);
278 svga_wseq_mask(0x40, 0x00, 0x02); 285 svga_wseq_mask(par->state.vgabase, 0x40, 0x00, 0x02);
279} 286}
280 287
281 288
@@ -285,7 +292,10 @@ static int vt8623fb_open(struct fb_info *info, int user)
285 292
286 mutex_lock(&(par->open_lock)); 293 mutex_lock(&(par->open_lock));
287 if (par->ref_count == 0) { 294 if (par->ref_count == 0) {
295 void __iomem *vgabase = par->state.vgabase;
296
288 memset(&(par->state), 0, sizeof(struct vgastate)); 297 memset(&(par->state), 0, sizeof(struct vgastate));
298 par->state.vgabase = vgabase;
289 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 299 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
290 par->state.num_crtc = 0xA2; 300 par->state.num_crtc = 0xA2;
291 par->state.num_seq = 0x50; 301 par->state.num_seq = 0x50;
@@ -373,6 +383,7 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
373static int vt8623fb_set_par(struct fb_info *info) 383static int vt8623fb_set_par(struct fb_info *info)
374{ 384{
375 u32 mode, offset_value, fetch_value, screen_size; 385 u32 mode, offset_value, fetch_value, screen_size;
386 struct vt8623fb_info *par = info->par;
376 u32 bpp = info->var.bits_per_pixel; 387 u32 bpp = info->var.bits_per_pixel;
377 388
378 if (bpp != 0) { 389 if (bpp != 0) {
@@ -414,82 +425,82 @@ static int vt8623fb_set_par(struct fb_info *info)
414 info->var.activate = FB_ACTIVATE_NOW; 425 info->var.activate = FB_ACTIVATE_NOW;
415 426
416 /* Unlock registers */ 427 /* Unlock registers */
417 svga_wseq_mask(0x10, 0x01, 0x01); 428 svga_wseq_mask(par->state.vgabase, 0x10, 0x01, 0x01);
418 svga_wcrt_mask(0x11, 0x00, 0x80); 429 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
419 svga_wcrt_mask(0x47, 0x00, 0x01); 430 svga_wcrt_mask(par->state.vgabase, 0x47, 0x00, 0x01);
420 431
421 /* Device, screen and sync off */ 432 /* Device, screen and sync off */
422 svga_wseq_mask(0x01, 0x20, 0x20); 433 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
423 svga_wcrt_mask(0x36, 0x30, 0x30); 434 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
424 svga_wcrt_mask(0x17, 0x00, 0x80); 435 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
425 436
426 /* Set default values */ 437 /* Set default values */
427 svga_set_default_gfx_regs(); 438 svga_set_default_gfx_regs(par->state.vgabase);
428 svga_set_default_atc_regs(); 439 svga_set_default_atc_regs(par->state.vgabase);
429 svga_set_default_seq_regs(); 440 svga_set_default_seq_regs(par->state.vgabase);
430 svga_set_default_crt_regs(); 441 svga_set_default_crt_regs(par->state.vgabase);
431 svga_wcrt_multi(vt8623_line_compare_regs, 0xFFFFFFFF); 442 svga_wcrt_multi(par->state.vgabase, vt8623_line_compare_regs, 0xFFFFFFFF);
432 svga_wcrt_multi(vt8623_start_address_regs, 0); 443 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, 0);
433 444
434 svga_wcrt_multi(vt8623_offset_regs, offset_value); 445 svga_wcrt_multi(par->state.vgabase, vt8623_offset_regs, offset_value);
435 svga_wseq_multi(vt8623_fetch_count_regs, fetch_value); 446 svga_wseq_multi(par->state.vgabase, vt8623_fetch_count_regs, fetch_value);
436 447
437 /* Clear H/V Skew */ 448 /* Clear H/V Skew */
438 svga_wcrt_mask(0x03, 0x00, 0x60); 449 svga_wcrt_mask(par->state.vgabase, 0x03, 0x00, 0x60);
439 svga_wcrt_mask(0x05, 0x00, 0x60); 450 svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60);
440 451
441 if (info->var.vmode & FB_VMODE_DOUBLE) 452 if (info->var.vmode & FB_VMODE_DOUBLE)
442 svga_wcrt_mask(0x09, 0x80, 0x80); 453 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
443 else 454 else
444 svga_wcrt_mask(0x09, 0x00, 0x80); 455 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
445 456
446 svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus 457 svga_wseq_mask(par->state.vgabase, 0x1E, 0xF0, 0xF0); // DI/DVP bus
447 svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus 458 svga_wseq_mask(par->state.vgabase, 0x2A, 0x0F, 0x0F); // DI/DVP bus
448 svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold 459 svga_wseq_mask(par->state.vgabase, 0x16, 0x08, 0xBF); // FIFO read threshold
449 vga_wseq(NULL, 0x17, 0x1F); // FIFO depth 460 vga_wseq(par->state.vgabase, 0x17, 0x1F); // FIFO depth
450 vga_wseq(NULL, 0x18, 0x4E); 461 vga_wseq(par->state.vgabase, 0x18, 0x4E);
451 svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ? 462 svga_wseq_mask(par->state.vgabase, 0x1A, 0x08, 0x08); // enable MMIO ?
452 463
453 vga_wcrt(NULL, 0x32, 0x00); 464 vga_wcrt(par->state.vgabase, 0x32, 0x00);
454 vga_wcrt(NULL, 0x34, 0x00); 465 vga_wcrt(par->state.vgabase, 0x34, 0x00);
455 vga_wcrt(NULL, 0x6A, 0x80); 466 vga_wcrt(par->state.vgabase, 0x6A, 0x80);
456 vga_wcrt(NULL, 0x6A, 0xC0); 467 vga_wcrt(par->state.vgabase, 0x6A, 0xC0);
457 468
458 vga_wgfx(NULL, 0x20, 0x00); 469 vga_wgfx(par->state.vgabase, 0x20, 0x00);
459 vga_wgfx(NULL, 0x21, 0x00); 470 vga_wgfx(par->state.vgabase, 0x21, 0x00);
460 vga_wgfx(NULL, 0x22, 0x00); 471 vga_wgfx(par->state.vgabase, 0x22, 0x00);
461 472
462 /* Set SR15 according to number of bits per pixel */ 473 /* Set SR15 according to number of bits per pixel */
463 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix)); 474 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix));
464 switch (mode) { 475 switch (mode) {
465 case 0: 476 case 0:
466 pr_debug("fb%d: text mode\n", info->node); 477 pr_debug("fb%d: text mode\n", info->node);
467 svga_set_textmode_vga_regs(); 478 svga_set_textmode_vga_regs(par->state.vgabase);
468 svga_wseq_mask(0x15, 0x00, 0xFE); 479 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
469 svga_wcrt_mask(0x11, 0x60, 0x70); 480 svga_wcrt_mask(par->state.vgabase, 0x11, 0x60, 0x70);
470 break; 481 break;
471 case 1: 482 case 1:
472 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 483 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
473 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 484 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
474 svga_wseq_mask(0x15, 0x20, 0xFE); 485 svga_wseq_mask(par->state.vgabase, 0x15, 0x20, 0xFE);
475 svga_wcrt_mask(0x11, 0x00, 0x70); 486 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
476 break; 487 break;
477 case 2: 488 case 2:
478 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 489 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
479 svga_wseq_mask(0x15, 0x00, 0xFE); 490 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
480 svga_wcrt_mask(0x11, 0x00, 0x70); 491 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
481 break; 492 break;
482 case 3: 493 case 3:
483 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 494 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
484 svga_wseq_mask(0x15, 0x22, 0xFE); 495 svga_wseq_mask(par->state.vgabase, 0x15, 0x22, 0xFE);
485 break; 496 break;
486 case 4: 497 case 4:
487 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 498 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
488 svga_wseq_mask(0x15, 0xB6, 0xFE); 499 svga_wseq_mask(par->state.vgabase, 0x15, 0xB6, 0xFE);
489 break; 500 break;
490 case 5: 501 case 5:
491 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 502 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
492 svga_wseq_mask(0x15, 0xAE, 0xFE); 503 svga_wseq_mask(par->state.vgabase, 0x15, 0xAE, 0xFE);
493 break; 504 break;
494 default: 505 default:
495 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n"); 506 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n");
@@ -497,16 +508,16 @@ static int vt8623fb_set_par(struct fb_info *info)
497 } 508 }
498 509
499 vt8623_set_pixclock(info, info->var.pixclock); 510 vt8623_set_pixclock(info, info->var.pixclock);
500 svga_set_timings(&vt8623_timing_regs, &(info->var), 1, 1, 511 svga_set_timings(par->state.vgabase, &vt8623_timing_regs, &(info->var), 1, 1,
501 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1, 512 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
502 1, info->node); 513 1, info->node);
503 514
504 memset_io(info->screen_base, 0x00, screen_size); 515 memset_io(info->screen_base, 0x00, screen_size);
505 516
506 /* Device and screen back on */ 517 /* Device and screen back on */
507 svga_wcrt_mask(0x17, 0x80, 0x80); 518 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
508 svga_wcrt_mask(0x36, 0x00, 0x30); 519 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
509 svga_wseq_mask(0x01, 0x00, 0x20); 520 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
510 521
511 return 0; 522 return 0;
512} 523}
@@ -569,31 +580,33 @@ static int vt8623fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
569 580
570static int vt8623fb_blank(int blank_mode, struct fb_info *info) 581static int vt8623fb_blank(int blank_mode, struct fb_info *info)
571{ 582{
583 struct vt8623fb_info *par = info->par;
584
572 switch (blank_mode) { 585 switch (blank_mode) {
573 case FB_BLANK_UNBLANK: 586 case FB_BLANK_UNBLANK:
574 pr_debug("fb%d: unblank\n", info->node); 587 pr_debug("fb%d: unblank\n", info->node);
575 svga_wcrt_mask(0x36, 0x00, 0x30); 588 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
576 svga_wseq_mask(0x01, 0x00, 0x20); 589 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
577 break; 590 break;
578 case FB_BLANK_NORMAL: 591 case FB_BLANK_NORMAL:
579 pr_debug("fb%d: blank\n", info->node); 592 pr_debug("fb%d: blank\n", info->node);
580 svga_wcrt_mask(0x36, 0x00, 0x30); 593 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
581 svga_wseq_mask(0x01, 0x20, 0x20); 594 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
582 break; 595 break;
583 case FB_BLANK_HSYNC_SUSPEND: 596 case FB_BLANK_HSYNC_SUSPEND:
584 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node); 597 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node);
585 svga_wcrt_mask(0x36, 0x10, 0x30); 598 svga_wcrt_mask(par->state.vgabase, 0x36, 0x10, 0x30);
586 svga_wseq_mask(0x01, 0x20, 0x20); 599 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
587 break; 600 break;
588 case FB_BLANK_VSYNC_SUSPEND: 601 case FB_BLANK_VSYNC_SUSPEND:
589 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node); 602 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node);
590 svga_wcrt_mask(0x36, 0x20, 0x30); 603 svga_wcrt_mask(par->state.vgabase, 0x36, 0x20, 0x30);
591 svga_wseq_mask(0x01, 0x20, 0x20); 604 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
592 break; 605 break;
593 case FB_BLANK_POWERDOWN: 606 case FB_BLANK_POWERDOWN:
594 pr_debug("fb%d: DPMS off (no sync)\n", info->node); 607 pr_debug("fb%d: DPMS off (no sync)\n", info->node);
595 svga_wcrt_mask(0x36, 0x30, 0x30); 608 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
596 svga_wseq_mask(0x01, 0x20, 0x20); 609 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
597 break; 610 break;
598 } 611 }
599 612
@@ -603,6 +616,7 @@ static int vt8623fb_blank(int blank_mode, struct fb_info *info)
603 616
604static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 617static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
605{ 618{
619 struct vt8623fb_info *par = info->par;
606 unsigned int offset; 620 unsigned int offset;
607 621
608 /* Calculate the offset */ 622 /* Calculate the offset */
@@ -616,7 +630,7 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
616 } 630 }
617 631
618 /* Set the offset */ 632 /* Set the offset */
619 svga_wcrt_multi(vt8623_start_address_regs, offset); 633 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, offset);
620 634
621 return 0; 635 return 0;
622} 636}
@@ -647,6 +661,8 @@ static struct fb_ops vt8623fb_ops = {
647 661
648static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 662static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
649{ 663{
664 struct pci_bus_region bus_reg;
665 struct resource vga_res;
650 struct fb_info *info; 666 struct fb_info *info;
651 struct vt8623fb_info *par; 667 struct vt8623fb_info *par;
652 unsigned int memsize1, memsize2; 668 unsigned int memsize1, memsize2;
@@ -705,9 +721,18 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
705 goto err_iomap_2; 721 goto err_iomap_2;
706 } 722 }
707 723
724 bus_reg.start = 0;
725 bus_reg.end = 64 * 1024;
726
727 vga_res.flags = IORESOURCE_IO;
728
729 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
730
731 par->state.vgabase = (void __iomem *) vga_res.start;
732
708 /* Find how many physical memory there is on card */ 733 /* Find how many physical memory there is on card */
709 memsize1 = (vga_rseq(NULL, 0x34) + 1) >> 1; 734 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;
710 memsize2 = vga_rseq(NULL, 0x39) << 2; 735 memsize2 = vga_rseq(par->state.vgabase, 0x39) << 2;
711 736
712 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2)) 737 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2))
713 info->screen_size = memsize1 << 20; 738 info->screen_size = memsize1 << 20;
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index d8b12c32e3ef..c8be8af0cc6d 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -1306,7 +1306,7 @@ static void w100_init_lcd(struct w100fb_par *par)
1306 union graphic_v_disp_u graphic_v_disp; 1306 union graphic_v_disp_u graphic_v_disp;
1307 union crtc_total_u crtc_total; 1307 union crtc_total_u crtc_total;
1308 1308
1309 /* w3200 doesnt like undefined bits being set so zero register values first */ 1309 /* w3200 doesn't like undefined bits being set so zero register values first */
1310 1310
1311 active_h_disp.val = 0; 1311 active_h_disp.val = 0;
1312 active_h_disp.f.active_h_start=mode->left_margin; 1312 active_h_disp.f.active_h_start=mode->left_margin;