diff options
Diffstat (limited to 'drivers/video')
133 files changed, 9900 insertions, 3536 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6bafb51bb437..e6a8d8c0101d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -322,69 +322,6 @@ config FB_ARMCLCD | |||
322 | here and read <file:Documentation/kbuild/modules.txt>. The module | 322 | here and read <file:Documentation/kbuild/modules.txt>. The module |
323 | will be called amba-clcd. | 323 | will be called amba-clcd. |
324 | 324 | ||
325 | choice | ||
326 | |||
327 | depends on FB_ARMCLCD && (ARCH_LH7A40X || ARCH_LH7952X) | ||
328 | prompt "LCD Panel" | ||
329 | default FB_ARMCLCD_SHARP_LQ035Q7DB02 | ||
330 | |||
331 | config FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT | ||
332 | bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC" | ||
333 | help | ||
334 | This is an implementation of the Sharp LQ035Q7DB02, a 3.5" | ||
335 | color QVGA, HRTFT panel. The LogicPD device includes | ||
336 | an integrated HRTFT controller IC. | ||
337 | The native resolution is 240x320. | ||
338 | |||
339 | config FB_ARMCLCD_SHARP_LQ057Q3DC02 | ||
340 | bool "LogicPD LCD 5.7\" QVGA" | ||
341 | help | ||
342 | This is an implementation of the Sharp LQ057Q3DC02, a 5.7" | ||
343 | color QVGA, TFT panel. The LogicPD device includes an | ||
344 | The native resolution is 320x240. | ||
345 | |||
346 | config FB_ARMCLCD_SHARP_LQ64D343 | ||
347 | bool "LogicPD LCD 6.4\" VGA" | ||
348 | help | ||
349 | This is an implementation of the Sharp LQ64D343, a 6.4" | ||
350 | color VGA, TFT panel. The LogicPD device includes an | ||
351 | The native resolution is 640x480. | ||
352 | |||
353 | config FB_ARMCLCD_SHARP_LQ10D368 | ||
354 | bool "LogicPD LCD 10.4\" VGA" | ||
355 | help | ||
356 | This is an implementation of the Sharp LQ10D368, a 10.4" | ||
357 | color VGA, TFT panel. The LogicPD device includes an | ||
358 | The native resolution is 640x480. | ||
359 | |||
360 | |||
361 | config FB_ARMCLCD_SHARP_LQ121S1DG41 | ||
362 | bool "LogicPD LCD 12.1\" SVGA" | ||
363 | help | ||
364 | This is an implementation of the Sharp LQ121S1DG41, a 12.1" | ||
365 | color SVGA, TFT panel. The LogicPD device includes an | ||
366 | The native resolution is 800x600. | ||
367 | |||
368 | This panel requires a clock rate may be an integer fraction | ||
369 | of the base LCDCLK frequency. The driver will select the | ||
370 | highest frequency available that is lower than the maximum | ||
371 | allowed. The panel may flicker if the clock rate is | ||
372 | slower than the recommended minimum. | ||
373 | |||
374 | config FB_ARMCLCD_AUO_A070VW01_WIDE | ||
375 | bool "AU Optronics A070VW01 LCD 7.0\" WIDE" | ||
376 | help | ||
377 | This is an implementation of the AU Optronics, a 7.0" | ||
378 | WIDE Color. The native resolution is 234x480. | ||
379 | |||
380 | config FB_ARMCLCD_HITACHI | ||
381 | bool "Hitachi Wide Screen 800x480" | ||
382 | help | ||
383 | This is an implementation of the Hitachi 800x480. | ||
384 | |||
385 | endchoice | ||
386 | |||
387 | |||
388 | config FB_ACORN | 325 | config FB_ACORN |
389 | bool "Acorn VIDC support" | 326 | bool "Acorn VIDC support" |
390 | depends on (FB = y) && ARM && ARCH_ACORN | 327 | depends on (FB = y) && ARM && ARCH_ACORN |
@@ -439,6 +376,24 @@ config FB_CYBER2000 | |||
439 | Say Y if you have a NetWinder or a graphics card containing this | 376 | Say Y if you have a NetWinder or a graphics card containing this |
440 | device, otherwise say N. | 377 | device, otherwise say N. |
441 | 378 | ||
379 | config FB_CYBER2000_DDC | ||
380 | bool "DDC for CyberPro support" | ||
381 | depends on FB_CYBER2000 | ||
382 | select FB_DDC | ||
383 | default y | ||
384 | help | ||
385 | Say Y here if you want DDC support for your CyberPro graphics | ||
386 | card. This is only I2C bus support, driver does not use EDID. | ||
387 | |||
388 | config FB_CYBER2000_I2C | ||
389 | bool "CyberPro 2000/2010/5000 I2C support" | ||
390 | depends on FB_CYBER2000 && I2C && ARCH_NETWINDER | ||
391 | select I2C_ALGOBIT | ||
392 | help | ||
393 | Enable support for the I2C video decoder interface on the | ||
394 | Integraphics CyberPro 20x0 and 5000 VGA chips. This is used | ||
395 | on the Netwinder machines for the SAA7111 video capture. | ||
396 | |||
442 | config FB_APOLLO | 397 | config FB_APOLLO |
443 | bool | 398 | bool |
444 | depends on (FB = y) && APOLLO | 399 | depends on (FB = y) && APOLLO |
@@ -2005,6 +1960,7 @@ config FB_SH_MOBILE_LCDC | |||
2005 | select FB_SYS_IMAGEBLIT | 1960 | select FB_SYS_IMAGEBLIT |
2006 | select FB_SYS_FOPS | 1961 | select FB_SYS_FOPS |
2007 | select FB_DEFERRED_IO | 1962 | select FB_DEFERRED_IO |
1963 | select FB_BACKLIGHT | ||
2008 | select SH_MIPI_DSI if SH_LCD_MIPI_DSI | 1964 | select SH_MIPI_DSI if SH_LCD_MIPI_DSI |
2009 | ---help--- | 1965 | ---help--- |
2010 | Frame buffer driver for the on-chip SH-Mobile LCD controller. | 1966 | Frame buffer driver for the on-chip SH-Mobile LCD controller. |
@@ -2365,6 +2321,26 @@ config FB_JZ4740 | |||
2365 | help | 2321 | help |
2366 | Framebuffer support for the JZ4740 SoC. | 2322 | Framebuffer support for the JZ4740 SoC. |
2367 | 2323 | ||
2324 | config FB_MXS | ||
2325 | tristate "MXS LCD framebuffer support" | ||
2326 | depends on FB && ARCH_MXS | ||
2327 | select FB_CFB_FILLRECT | ||
2328 | select FB_CFB_COPYAREA | ||
2329 | select FB_CFB_IMAGEBLIT | ||
2330 | help | ||
2331 | Framebuffer support for the MXS SoC. | ||
2332 | |||
2333 | config FB_PUV3_UNIGFX | ||
2334 | tristate "PKUnity v3 Unigfx framebuffer support" | ||
2335 | depends on FB && UNICORE32 && ARCH_PUV3 | ||
2336 | select FB_SYS_FILLRECT | ||
2337 | select FB_SYS_COPYAREA | ||
2338 | select FB_SYS_IMAGEBLIT | ||
2339 | select FB_SYS_FOPS | ||
2340 | help | ||
2341 | Choose this option if you want to use the Unigfx device as a | ||
2342 | framebuffer device. Without the support of PCI & AGP. | ||
2343 | |||
2368 | source "drivers/video/omap/Kconfig" | 2344 | source "drivers/video/omap/Kconfig" |
2369 | source "drivers/video/omap2/Kconfig" | 2345 | source "drivers/video/omap2/Kconfig" |
2370 | 2346 | ||
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 8c8fabdff9d0..2ea44b6625fe 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -139,6 +139,7 @@ obj-$(CONFIG_FB_MB862XX) += mb862xx/ | |||
139 | obj-$(CONFIG_FB_MSM) += msm/ | 139 | obj-$(CONFIG_FB_MSM) += msm/ |
140 | obj-$(CONFIG_FB_NUC900) += nuc900fb.o | 140 | obj-$(CONFIG_FB_NUC900) += nuc900fb.o |
141 | obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o | 141 | obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o |
142 | obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o | ||
142 | 143 | ||
143 | # Platform or fallback drivers go here | 144 | # Platform or fallback drivers go here |
144 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | 145 | obj-$(CONFIG_FB_UVESA) += uvesafb.o |
@@ -153,6 +154,7 @@ obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o | |||
153 | obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o | 154 | obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o |
154 | obj-$(CONFIG_FB_MX3) += mx3fb.o | 155 | obj-$(CONFIG_FB_MX3) += mx3fb.o |
155 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o | 156 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o |
157 | obj-$(CONFIG_FB_MXS) += mxsfb.o | ||
156 | 158 | ||
157 | # the test framebuffer is last | 159 | # the test framebuffer is last |
158 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o | 160 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index 1c2c68356ea7..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) | |||
120 | static int | 120 | static int |
121 | clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) | 121 | clcdfb_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) |
@@ -461,7 +534,7 @@ static int clcdfb_register(struct clcd_fb *fb) | |||
461 | return ret; | 534 | return ret; |
462 | } | 535 | } |
463 | 536 | ||
464 | static int clcdfb_probe(struct amba_device *dev, struct amba_id *id) | 537 | static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) |
465 | { | 538 | { |
466 | struct clcd_board *board = dev->dev.platform_data; | 539 | struct clcd_board *board = dev->dev.platform_data; |
467 | struct clcd_fb *fb; | 540 | struct clcd_fb *fb; |
@@ -486,6 +559,10 @@ static int clcdfb_probe(struct amba_device *dev, 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 | ||
161 | static 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 | |||
161 | static struct fb_tile_ops arkfb_tile_ops = { | 168 | static 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 | ||
467 | static void ark_dac_read_regs(void *data, u8 *code, int count) | 474 | static 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 | ||
482 | static void ark_dac_write_regs(void *data, u8 *code, int count) | 493 | static 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 | ||
858 | static int arkfb_blank(int blank_mode, struct fb_info *info) | 876 | static 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 | ||
885 | static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 905 | static 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 */ |
931 | static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | 952 | static 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..ccecf9974587 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 | ||
71 | static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 | 71 | static 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 | ||
164 | static void init_contrast(struct atmel_lcdfb_info *sinfo) | 165 | static 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); |
@@ -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 | ||
718 | static 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 | |||
713 | static struct fb_ops atmel_lcdfb_ops = { | 741 | static 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..d437b3daf1f5 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); |
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/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 | ||
164 | static 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 | |||
183 | static int pm860x_backlight_probe(struct platform_device *pdev) | 165 | static 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 | ||
112 | config 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 | |||
112 | endif # LCD_CLASS_DEVICE | 120 | endif # 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 | ||
239 | config BACKLIGHT_MBP_NVIDIA | 247 | config 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 | ||
246 | config BACKLIGHT_TOSA | 254 | config 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 | |||
12 | obj-$(CONFIG_LCD_TDO24M) += tdo24m.o | 12 | obj-$(CONFIG_LCD_TDO24M) += tdo24m.o |
13 | obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o | 13 | obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o |
14 | obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o | 14 | obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o |
15 | obj-$(CONFIG_LCD_LD9040) += ld9040.o | ||
15 | 16 | ||
16 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o | 17 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o |
17 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o | 18 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o |
@@ -26,7 +27,7 @@ obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o | |||
26 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o | 27 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o |
27 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o | 28 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o |
28 | obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o | 29 | obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o |
29 | obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o | 30 | obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o |
30 | obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o | 31 | obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o |
31 | obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o | 32 | obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o |
32 | obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o | 33 | obj-$(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 | |||
28 | static struct backlight_device *apple_backlight_device; | ||
29 | |||
30 | struct 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 | |||
39 | static const struct hw_data *hw_data; | ||
40 | |||
41 | #define DRIVER "apple_backlight: " | ||
42 | |||
43 | /* Module parameters. */ | ||
44 | static int debug; | ||
45 | module_param_named(debug, debug, int, 0644); | ||
46 | MODULE_PARM_DESC(debug, "Set to one to enable debugging messages."); | ||
47 | |||
48 | /* | ||
49 | * Implementation for machines with Intel chipset. | ||
50 | */ | ||
51 | static void intel_chipset_set_brightness(int intensity) | ||
52 | { | ||
53 | outb(0x04 | (intensity << 4), 0xb3); | ||
54 | outb(0xbf, 0xb2); | ||
55 | } | ||
56 | |||
57 | static 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 | |||
69 | static 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 | |||
84 | static 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 | */ | ||
98 | static void nvidia_chipset_set_brightness(int intensity) | ||
99 | { | ||
100 | outb(0x04 | (intensity << 4), 0x52f); | ||
101 | outb(0xbf, 0x52e); | ||
102 | } | ||
103 | |||
104 | static 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 | |||
116 | static 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 | |||
131 | static 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 | |||
142 | static 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 | |||
201 | static 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 | |||
210 | static const struct acpi_device_id apple_bl_ids[] = { | ||
211 | {"APP0002", 0}, | ||
212 | {"", 0}, | ||
213 | }; | ||
214 | |||
215 | static 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 | |||
224 | static int __init apple_bl_init(void) | ||
225 | { | ||
226 | return acpi_bus_register_driver(&apple_bl_driver); | ||
227 | } | ||
228 | |||
229 | static void __exit apple_bl_exit(void) | ||
230 | { | ||
231 | acpi_bus_unregister_driver(&apple_bl_driver); | ||
232 | } | ||
233 | |||
234 | module_init(apple_bl_init); | ||
235 | module_exit(apple_bl_exit); | ||
236 | |||
237 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | ||
238 | MODULE_DESCRIPTION("Apple Backlight Driver"); | ||
239 | MODULE_LICENSE("GPL"); | ||
240 | MODULE_DEVICE_TABLE(acpi, apple_bl_ids); | ||
241 | MODULE_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 | ||
22 | static 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 | ||
178 | static 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 | |||
172 | static ssize_t backlight_show_max_brightness(struct device *dev, | 186 | static 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..af6098396fe6 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c | |||
@@ -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 | ||
149 | int __init jornada_bl_init(void) | 150 | static 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 | ||
154 | void __exit jornada_bl_exit(void) | 155 | static 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 | ||
138 | int __init jornada_lcd_init(void) | 138 | static 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 | ||
143 | void __exit jornada_lcd_exit(void) | 143 | static 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 | |||
46 | struct 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 | |||
57 | static const unsigned short seq_swreset[] = { | ||
58 | 0x01, COMMAND_ONLY, | ||
59 | ENDDEF, 0x00 | ||
60 | }; | ||
61 | |||
62 | static const unsigned short seq_user_setting[] = { | ||
63 | 0xF0, 0x5A, | ||
64 | |||
65 | DATA_ONLY, 0x5A, | ||
66 | ENDDEF, 0x00 | ||
67 | }; | ||
68 | |||
69 | static const unsigned short seq_elvss_on[] = { | ||
70 | 0xB1, 0x0D, | ||
71 | |||
72 | DATA_ONLY, 0x00, | ||
73 | DATA_ONLY, 0x16, | ||
74 | ENDDEF, 0x00 | ||
75 | }; | ||
76 | |||
77 | static const unsigned short seq_gtcon[] = { | ||
78 | 0xF7, 0x09, | ||
79 | |||
80 | DATA_ONLY, 0x00, | ||
81 | DATA_ONLY, 0x00, | ||
82 | ENDDEF, 0x00 | ||
83 | }; | ||
84 | |||
85 | static 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 | |||
113 | static 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 | |||
139 | static const unsigned short seq_gamma_ctrl[] = { | ||
140 | 0xFB, 0x02, | ||
141 | |||
142 | DATA_ONLY, 0x5A, | ||
143 | ENDDEF, 0x00 | ||
144 | }; | ||
145 | |||
146 | static const unsigned short seq_gamma_start[] = { | ||
147 | 0xF9, COMMAND_ONLY, | ||
148 | |||
149 | ENDDEF, 0x00 | ||
150 | }; | ||
151 | |||
152 | static 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 | |||
162 | static 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 | |||
172 | static const unsigned short seq_manual_pwr[] = { | ||
173 | 0xB0, 0x04, | ||
174 | ENDDEF, 0x00 | ||
175 | }; | ||
176 | |||
177 | static 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 | |||
189 | static const unsigned short seq_sleep_out[] = { | ||
190 | 0x11, COMMAND_ONLY, | ||
191 | ENDDEF, 0x00 | ||
192 | }; | ||
193 | |||
194 | static const unsigned short seq_sleep_in[] = { | ||
195 | 0x10, COMMAND_ONLY, | ||
196 | ENDDEF, 0x00 | ||
197 | }; | ||
198 | |||
199 | static const unsigned short seq_display_on[] = { | ||
200 | 0x29, COMMAND_ONLY, | ||
201 | ENDDEF, 0x00 | ||
202 | }; | ||
203 | |||
204 | static const unsigned short seq_display_off[] = { | ||
205 | 0x28, COMMAND_ONLY, | ||
206 | ENDDEF, 0x00 | ||
207 | }; | ||
208 | |||
209 | static 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 | |||
219 | static 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 | |||
229 | static 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 | |||
239 | static 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 | |||
249 | static 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 | |||
259 | static 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 | |||
269 | static 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 | |||
279 | static 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 | |||
289 | static 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 | |||
299 | static 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 | |||
311 | static 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 | |||
321 | static 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 | |||
331 | static 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 | |||
343 | static 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 | |||
355 | static 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 | |||
367 | static 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 | |||
379 | static 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 | |||
391 | static 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 | |||
409 | static 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 | |||
422 | static 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 | |||
440 | static 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 | |||
465 | gamma_err: | ||
466 | return ret; | ||
467 | } | ||
468 | |||
469 | static 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 | |||
479 | static 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 | |||
505 | static 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 | |||
514 | static 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 | |||
524 | static 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 | |||
565 | static 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 | |||
593 | static 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 | |||
608 | static 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 | |||
621 | static int ld9040_get_power(struct lcd_device *ld) | ||
622 | { | ||
623 | struct ld9040 *lcd = lcd_get_data(ld); | ||
624 | |||
625 | return lcd->power; | ||
626 | } | ||
627 | |||
628 | static int ld9040_get_brightness(struct backlight_device *bd) | ||
629 | { | ||
630 | return bd->props.brightness; | ||
631 | } | ||
632 | |||
633 | static 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 | |||
654 | static struct lcd_ops ld9040_lcd_ops = { | ||
655 | .set_power = ld9040_set_power, | ||
656 | .get_power = ld9040_get_power, | ||
657 | }; | ||
658 | |||
659 | static const struct backlight_ops ld9040_backlight_ops = { | ||
660 | .get_brightness = ld9040_get_brightness, | ||
661 | .update_status = ld9040_set_brightness, | ||
662 | }; | ||
663 | |||
664 | |||
665 | static 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 | |||
734 | out_free_lcd: | ||
735 | kfree(lcd); | ||
736 | return ret; | ||
737 | } | ||
738 | |||
739 | static 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) | ||
751 | static 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 | |||
767 | static 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. */ | ||
784 | static 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 | |||
791 | static 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 | |||
804 | static int __init ld9040_init(void) | ||
805 | { | ||
806 | return spi_register_driver(&ld9040_driver); | ||
807 | } | ||
808 | |||
809 | static void __exit ld9040_exit(void) | ||
810 | { | ||
811 | spi_unregister_driver(&ld9040_driver); | ||
812 | } | ||
813 | |||
814 | module_init(ld9040_init); | ||
815 | module_exit(ld9040_exit); | ||
816 | |||
817 | MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>"); | ||
818 | MODULE_DESCRIPTION("ld9040 LCD Driver"); | ||
819 | MODULE_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 */ | ||
20 | static 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 | |||
26 | static 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 | |||
32 | static 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 | |||
38 | static 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 | }; | ||
44 | static 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 | |||
50 | static 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 | |||
56 | static 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 | |||
62 | static 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 | |||
68 | static 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 | |||
74 | static 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 | |||
80 | static 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 | |||
86 | static 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 | |||
92 | static 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 | |||
98 | static 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 | |||
104 | static 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 | |||
110 | static 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 | |||
116 | static 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 | |||
122 | static 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 | |||
128 | static 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 | |||
134 | static 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 | |||
140 | static 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 | |||
146 | static 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 | |||
152 | static 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 | |||
158 | static 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 | |||
164 | static 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 | |||
170 | struct 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..bbca3127071e 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c | |||
@@ -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 | |||
28 | static struct backlight_device *mbp_backlight_device; | ||
29 | |||
30 | /* Structure to be passed to the DMI_MATCH function. */ | ||
31 | struct 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. */ | ||
40 | static int debug; | ||
41 | module_param_named(debug, debug, int, 0644); | ||
42 | MODULE_PARM_DESC(debug, "Set to one to enable debugging messages."); | ||
43 | |||
44 | /* | ||
45 | * Implementation for MacBooks with Intel chipset. | ||
46 | */ | ||
47 | static 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 | |||
60 | static 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 | |||
75 | static 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 | */ | ||
88 | static 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 | |||
101 | static 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 | |||
116 | static 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 | */ | ||
129 | static /* const */ struct dmi_match_data *driver_data; | ||
130 | |||
131 | static 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 | |||
139 | static 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 | |||
359 | static 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 | |||
387 | static 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 | |||
394 | module_init(mbp_init); | ||
395 | module_exit(mbp_exit); | ||
396 | |||
397 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | ||
398 | MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver"); | ||
399 | MODULE_LICENSE("GPL"); | ||
400 | MODULE_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 | ||
33 | static int pwm_backlight_update_status(struct backlight_device *bl) | 34 | static 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 | ||
66 | static 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 | |||
65 | static const struct backlight_ops pwm_backlight_ops = { | 74 | static 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 | ||
70 | static int pwm_backlight_probe(struct platform_device *pdev) | 80 | static 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-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/bw2.c b/drivers/video/bw2.c index 4dc13467281d..7ba74cd4be61 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c | |||
@@ -273,7 +273,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par, | |||
273 | return 0; | 273 | return 0; |
274 | } | 274 | } |
275 | 275 | ||
276 | static int __devinit bw2_probe(struct platform_device *op, const struct of_device_id *match) | 276 | static int __devinit bw2_probe(struct platform_device *op) |
277 | { | 277 | { |
278 | struct device_node *dp = op->dev.of_node; | 278 | struct device_node *dp = op->dev.of_node; |
279 | struct fb_info *info; | 279 | struct fb_info *info; |
@@ -375,7 +375,7 @@ static const struct of_device_id bw2_match[] = { | |||
375 | }; | 375 | }; |
376 | MODULE_DEVICE_TABLE(of, bw2_match); | 376 | MODULE_DEVICE_TABLE(of, bw2_match); |
377 | 377 | ||
378 | static struct of_platform_driver bw2_driver = { | 378 | static struct platform_driver bw2_driver = { |
379 | .driver = { | 379 | .driver = { |
380 | .name = "bw2", | 380 | .name = "bw2", |
381 | .owner = THIS_MODULE, | 381 | .owner = THIS_MODULE, |
@@ -390,12 +390,12 @@ static int __init bw2_init(void) | |||
390 | if (fb_get_options("bw2fb", NULL)) | 390 | if (fb_get_options("bw2fb", NULL)) |
391 | return -ENODEV; | 391 | return -ENODEV; |
392 | 392 | ||
393 | return of_register_platform_driver(&bw2_driver); | 393 | return platform_driver_register(&bw2_driver); |
394 | } | 394 | } |
395 | 395 | ||
396 | static void __exit bw2_exit(void) | 396 | static void __exit bw2_exit(void) |
397 | { | 397 | { |
398 | of_unregister_platform_driver(&bw2_driver); | 398 | platform_driver_unregister(&bw2_driver); |
399 | } | 399 | } |
400 | 400 | ||
401 | module_init(bw2_init); | 401 | module_init(bw2_init); |
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 24249535ac86..f18895006627 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c | |||
@@ -463,7 +463,7 @@ static void cg14_unmap_regs(struct platform_device *op, struct fb_info *info, | |||
463 | info->screen_base, info->fix.smem_len); | 463 | info->screen_base, info->fix.smem_len); |
464 | } | 464 | } |
465 | 465 | ||
466 | static int __devinit cg14_probe(struct platform_device *op, const struct of_device_id *match) | 466 | static int __devinit cg14_probe(struct platform_device *op) |
467 | { | 467 | { |
468 | struct device_node *dp = op->dev.of_node; | 468 | struct device_node *dp = op->dev.of_node; |
469 | struct fb_info *info; | 469 | struct fb_info *info; |
@@ -565,6 +565,7 @@ out_dealloc_cmap: | |||
565 | 565 | ||
566 | out_unmap_regs: | 566 | out_unmap_regs: |
567 | cg14_unmap_regs(op, info, par); | 567 | cg14_unmap_regs(op, info, par); |
568 | framebuffer_release(info); | ||
568 | 569 | ||
569 | out_err: | 570 | out_err: |
570 | return err; | 571 | return err; |
@@ -595,7 +596,7 @@ static const struct of_device_id cg14_match[] = { | |||
595 | }; | 596 | }; |
596 | MODULE_DEVICE_TABLE(of, cg14_match); | 597 | MODULE_DEVICE_TABLE(of, cg14_match); |
597 | 598 | ||
598 | static struct of_platform_driver cg14_driver = { | 599 | static struct platform_driver cg14_driver = { |
599 | .driver = { | 600 | .driver = { |
600 | .name = "cg14", | 601 | .name = "cg14", |
601 | .owner = THIS_MODULE, | 602 | .owner = THIS_MODULE, |
@@ -610,12 +611,12 @@ static int __init cg14_init(void) | |||
610 | if (fb_get_options("cg14fb", NULL)) | 611 | if (fb_get_options("cg14fb", NULL)) |
611 | return -ENODEV; | 612 | return -ENODEV; |
612 | 613 | ||
613 | return of_register_platform_driver(&cg14_driver); | 614 | return platform_driver_register(&cg14_driver); |
614 | } | 615 | } |
615 | 616 | ||
616 | static void __exit cg14_exit(void) | 617 | static void __exit cg14_exit(void) |
617 | { | 618 | { |
618 | of_unregister_platform_driver(&cg14_driver); | 619 | platform_driver_unregister(&cg14_driver); |
619 | } | 620 | } |
620 | 621 | ||
621 | module_init(cg14_init); | 622 | module_init(cg14_init); |
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 09c0c3c42482..f927a7b1a8d4 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c | |||
@@ -346,8 +346,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par) | |||
346 | return 0; | 346 | return 0; |
347 | } | 347 | } |
348 | 348 | ||
349 | static int __devinit cg3_probe(struct platform_device *op, | 349 | static int __devinit cg3_probe(struct platform_device *op) |
350 | const struct of_device_id *match) | ||
351 | { | 350 | { |
352 | struct device_node *dp = op->dev.of_node; | 351 | struct device_node *dp = op->dev.of_node; |
353 | struct fb_info *info; | 352 | struct fb_info *info; |
@@ -462,7 +461,7 @@ static const struct of_device_id cg3_match[] = { | |||
462 | }; | 461 | }; |
463 | MODULE_DEVICE_TABLE(of, cg3_match); | 462 | MODULE_DEVICE_TABLE(of, cg3_match); |
464 | 463 | ||
465 | static struct of_platform_driver cg3_driver = { | 464 | static struct platform_driver cg3_driver = { |
466 | .driver = { | 465 | .driver = { |
467 | .name = "cg3", | 466 | .name = "cg3", |
468 | .owner = THIS_MODULE, | 467 | .owner = THIS_MODULE, |
@@ -477,12 +476,12 @@ static int __init cg3_init(void) | |||
477 | if (fb_get_options("cg3fb", NULL)) | 476 | if (fb_get_options("cg3fb", NULL)) |
478 | return -ENODEV; | 477 | return -ENODEV; |
479 | 478 | ||
480 | return of_register_platform_driver(&cg3_driver); | 479 | return platform_driver_register(&cg3_driver); |
481 | } | 480 | } |
482 | 481 | ||
483 | static void __exit cg3_exit(void) | 482 | static void __exit cg3_exit(void) |
484 | { | 483 | { |
485 | of_unregister_platform_driver(&cg3_driver); | 484 | platform_driver_unregister(&cg3_driver); |
486 | } | 485 | } |
487 | 486 | ||
488 | module_init(cg3_init); | 487 | module_init(cg3_init); |
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 2b5a97058b08..179e96cdb323 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c | |||
@@ -737,8 +737,7 @@ static void cg6_unmap_regs(struct platform_device *op, struct fb_info *info, | |||
737 | info->fix.smem_len); | 737 | info->fix.smem_len); |
738 | } | 738 | } |
739 | 739 | ||
740 | static int __devinit cg6_probe(struct platform_device *op, | 740 | static int __devinit cg6_probe(struct platform_device *op) |
741 | const struct of_device_id *match) | ||
742 | { | 741 | { |
743 | struct device_node *dp = op->dev.of_node; | 742 | struct device_node *dp = op->dev.of_node; |
744 | struct fb_info *info; | 743 | struct fb_info *info; |
@@ -822,6 +821,7 @@ out_dealloc_cmap: | |||
822 | 821 | ||
823 | out_unmap_regs: | 822 | out_unmap_regs: |
824 | cg6_unmap_regs(op, info, par); | 823 | cg6_unmap_regs(op, info, par); |
824 | framebuffer_release(info); | ||
825 | 825 | ||
826 | out_err: | 826 | out_err: |
827 | return err; | 827 | return err; |
@@ -855,7 +855,7 @@ static const struct of_device_id cg6_match[] = { | |||
855 | }; | 855 | }; |
856 | MODULE_DEVICE_TABLE(of, cg6_match); | 856 | MODULE_DEVICE_TABLE(of, cg6_match); |
857 | 857 | ||
858 | static struct of_platform_driver cg6_driver = { | 858 | static struct platform_driver cg6_driver = { |
859 | .driver = { | 859 | .driver = { |
860 | .name = "cg6", | 860 | .name = "cg6", |
861 | .owner = THIS_MODULE, | 861 | .owner = THIS_MODULE, |
@@ -870,12 +870,12 @@ static int __init cg6_init(void) | |||
870 | if (fb_get_options("cg6fb", NULL)) | 870 | if (fb_get_options("cg6fb", NULL)) |
871 | return -ENODEV; | 871 | return -ENODEV; |
872 | 872 | ||
873 | return of_register_platform_driver(&cg6_driver); | 873 | return platform_driver_register(&cg6_driver); |
874 | } | 874 | } |
875 | 875 | ||
876 | static void __exit cg6_exit(void) | 876 | static void __exit cg6_exit(void) |
877 | { | 877 | { |
878 | of_unregister_platform_driver(&cg6_driver); | 878 | platform_driver_unregister(&cg6_driver); |
879 | } | 879 | } |
880 | 880 | ||
881 | module_init(cg6_init); | 881 | module_init(cg6_init); |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 9c092b8d64e6..c58393402da2 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -823,10 +823,10 @@ static int set_con2fb_map(int unit, int newidx, int user) | |||
823 | if (oldidx == newidx) | 823 | if (oldidx == newidx) |
824 | return 0; | 824 | return 0; |
825 | 825 | ||
826 | if (!info || fbcon_has_exited) | 826 | if (!info) |
827 | return -EINVAL; | 827 | return -EINVAL; |
828 | 828 | ||
829 | if (!err && !search_for_mapped_con()) { | 829 | if (!search_for_mapped_con() || !con_is_bound(&fb_con)) { |
830 | info_idx = newidx; | 830 | info_idx = newidx; |
831 | return fbcon_takeover(0); | 831 | return fbcon_takeover(0); |
832 | } | 832 | } |
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/cyber2000fb.c b/drivers/video/cyber2000fb.c index 0c1afd13ddd3..850380795b05 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/init.h> | 48 | #include <linux/init.h> |
49 | #include <linux/io.h> | 49 | #include <linux/io.h> |
50 | #include <linux/i2c.h> | ||
51 | #include <linux/i2c-algo-bit.h> | ||
50 | 52 | ||
51 | #include <asm/pgtable.h> | 53 | #include <asm/pgtable.h> |
52 | #include <asm/system.h> | 54 | #include <asm/system.h> |
@@ -61,10 +63,10 @@ struct cfb_info { | |||
61 | struct fb_info fb; | 63 | struct fb_info fb; |
62 | struct display_switch *dispsw; | 64 | struct display_switch *dispsw; |
63 | struct display *display; | 65 | struct display *display; |
64 | struct pci_dev *dev; | ||
65 | unsigned char __iomem *region; | 66 | unsigned char __iomem *region; |
66 | unsigned char __iomem *regs; | 67 | unsigned char __iomem *regs; |
67 | u_int id; | 68 | u_int id; |
69 | u_int irq; | ||
68 | int func_use_count; | 70 | int func_use_count; |
69 | u_long ref_ps; | 71 | u_long ref_ps; |
70 | 72 | ||
@@ -88,6 +90,19 @@ struct cfb_info { | |||
88 | u_char ramdac_powerdown; | 90 | u_char ramdac_powerdown; |
89 | 91 | ||
90 | u32 pseudo_palette[16]; | 92 | u32 pseudo_palette[16]; |
93 | |||
94 | spinlock_t reg_b0_lock; | ||
95 | |||
96 | #ifdef CONFIG_FB_CYBER2000_DDC | ||
97 | bool ddc_registered; | ||
98 | struct i2c_adapter ddc_adapter; | ||
99 | struct i2c_algo_bit_data ddc_algo; | ||
100 | #endif | ||
101 | |||
102 | #ifdef CONFIG_FB_CYBER2000_I2C | ||
103 | struct i2c_adapter i2c_adapter; | ||
104 | struct i2c_algo_bit_data i2c_algo; | ||
105 | #endif | ||
91 | }; | 106 | }; |
92 | 107 | ||
93 | static char *default_font = "Acorn8x8"; | 108 | static char *default_font = "Acorn8x8"; |
@@ -494,6 +509,7 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw) | |||
494 | cyber2000_attrw(0x14, 0x00, cfb); | 509 | cyber2000_attrw(0x14, 0x00, cfb); |
495 | 510 | ||
496 | /* PLL registers */ | 511 | /* PLL registers */ |
512 | spin_lock(&cfb->reg_b0_lock); | ||
497 | cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb); | 513 | cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb); |
498 | cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb); | 514 | cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb); |
499 | cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb); | 515 | cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb); |
@@ -501,6 +517,7 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw) | |||
501 | cyber2000_grphw(0x90, 0x01, cfb); | 517 | cyber2000_grphw(0x90, 0x01, cfb); |
502 | cyber2000_grphw(0xb9, 0x80, cfb); | 518 | cyber2000_grphw(0xb9, 0x80, cfb); |
503 | cyber2000_grphw(0xb9, 0x00, cfb); | 519 | cyber2000_grphw(0xb9, 0x00, cfb); |
520 | spin_unlock(&cfb->reg_b0_lock); | ||
504 | 521 | ||
505 | cfb->ramdac_ctrl = hw->ramdac; | 522 | cfb->ramdac_ctrl = hw->ramdac; |
506 | cyber2000fb_write_ramdac_ctrl(cfb); | 523 | cyber2000fb_write_ramdac_ctrl(cfb); |
@@ -681,9 +698,9 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb, | |||
681 | * pll_ps_calc = best_div1 / (ref_ps * best_mult) | 698 | * pll_ps_calc = best_div1 / (ref_ps * best_mult) |
682 | */ | 699 | */ |
683 | best_diff = 0x7fffffff; | 700 | best_diff = 0x7fffffff; |
684 | best_mult = 32; | 701 | best_mult = 2; |
685 | best_div1 = 255; | 702 | best_div1 = 32; |
686 | for (t_div1 = 32; t_div1 > 1; t_div1 -= 1) { | 703 | for (t_div1 = 2; t_div1 < 32; t_div1 += 1) { |
687 | u_int rr, t_mult, t_pll_ps; | 704 | u_int rr, t_mult, t_pll_ps; |
688 | int diff; | 705 | int diff; |
689 | 706 | ||
@@ -1105,24 +1122,22 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb) | |||
1105 | } | 1122 | } |
1106 | EXPORT_SYMBOL(cyber2000fb_disable_extregs); | 1123 | EXPORT_SYMBOL(cyber2000fb_disable_extregs); |
1107 | 1124 | ||
1108 | void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var) | ||
1109 | { | ||
1110 | memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo)); | ||
1111 | } | ||
1112 | EXPORT_SYMBOL(cyber2000fb_get_fb_var); | ||
1113 | |||
1114 | /* | 1125 | /* |
1115 | * Attach a capture/tv driver to the core CyberX0X0 driver. | 1126 | * Attach a capture/tv driver to the core CyberX0X0 driver. |
1116 | */ | 1127 | */ |
1117 | int cyber2000fb_attach(struct cyberpro_info *info, int idx) | 1128 | int cyber2000fb_attach(struct cyberpro_info *info, int idx) |
1118 | { | 1129 | { |
1119 | if (int_cfb_info != NULL) { | 1130 | if (int_cfb_info != NULL) { |
1120 | info->dev = int_cfb_info->dev; | 1131 | info->dev = int_cfb_info->fb.device; |
1132 | #ifdef CONFIG_FB_CYBER2000_I2C | ||
1133 | info->i2c = &int_cfb_info->i2c_adapter; | ||
1134 | #else | ||
1135 | info->i2c = NULL; | ||
1136 | #endif | ||
1121 | info->regs = int_cfb_info->regs; | 1137 | info->regs = int_cfb_info->regs; |
1138 | info->irq = int_cfb_info->irq; | ||
1122 | info->fb = int_cfb_info->fb.screen_base; | 1139 | info->fb = int_cfb_info->fb.screen_base; |
1123 | info->fb_size = int_cfb_info->fb.fix.smem_len; | 1140 | info->fb_size = int_cfb_info->fb.fix.smem_len; |
1124 | info->enable_extregs = cyber2000fb_enable_extregs; | ||
1125 | info->disable_extregs = cyber2000fb_disable_extregs; | ||
1126 | info->info = int_cfb_info; | 1141 | info->info = int_cfb_info; |
1127 | 1142 | ||
1128 | strlcpy(info->dev_name, int_cfb_info->fb.fix.id, | 1143 | strlcpy(info->dev_name, int_cfb_info->fb.fix.id, |
@@ -1141,6 +1156,183 @@ void cyber2000fb_detach(int idx) | |||
1141 | } | 1156 | } |
1142 | EXPORT_SYMBOL(cyber2000fb_detach); | 1157 | EXPORT_SYMBOL(cyber2000fb_detach); |
1143 | 1158 | ||
1159 | #ifdef CONFIG_FB_CYBER2000_DDC | ||
1160 | |||
1161 | #define DDC_REG 0xb0 | ||
1162 | #define DDC_SCL_OUT (1 << 0) | ||
1163 | #define DDC_SDA_OUT (1 << 4) | ||
1164 | #define DDC_SCL_IN (1 << 2) | ||
1165 | #define DDC_SDA_IN (1 << 6) | ||
1166 | |||
1167 | static void cyber2000fb_enable_ddc(struct cfb_info *cfb) | ||
1168 | { | ||
1169 | spin_lock(&cfb->reg_b0_lock); | ||
1170 | cyber2000fb_writew(0x1bf, 0x3ce, cfb); | ||
1171 | } | ||
1172 | |||
1173 | static void cyber2000fb_disable_ddc(struct cfb_info *cfb) | ||
1174 | { | ||
1175 | cyber2000fb_writew(0x0bf, 0x3ce, cfb); | ||
1176 | spin_unlock(&cfb->reg_b0_lock); | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | static void cyber2000fb_ddc_setscl(void *data, int val) | ||
1181 | { | ||
1182 | struct cfb_info *cfb = data; | ||
1183 | unsigned char reg; | ||
1184 | |||
1185 | cyber2000fb_enable_ddc(cfb); | ||
1186 | reg = cyber2000_grphr(DDC_REG, cfb); | ||
1187 | if (!val) /* bit is inverted */ | ||
1188 | reg |= DDC_SCL_OUT; | ||
1189 | else | ||
1190 | reg &= ~DDC_SCL_OUT; | ||
1191 | cyber2000_grphw(DDC_REG, reg, cfb); | ||
1192 | cyber2000fb_disable_ddc(cfb); | ||
1193 | } | ||
1194 | |||
1195 | static void cyber2000fb_ddc_setsda(void *data, int val) | ||
1196 | { | ||
1197 | struct cfb_info *cfb = data; | ||
1198 | unsigned char reg; | ||
1199 | |||
1200 | cyber2000fb_enable_ddc(cfb); | ||
1201 | reg = cyber2000_grphr(DDC_REG, cfb); | ||
1202 | if (!val) /* bit is inverted */ | ||
1203 | reg |= DDC_SDA_OUT; | ||
1204 | else | ||
1205 | reg &= ~DDC_SDA_OUT; | ||
1206 | cyber2000_grphw(DDC_REG, reg, cfb); | ||
1207 | cyber2000fb_disable_ddc(cfb); | ||
1208 | } | ||
1209 | |||
1210 | static int cyber2000fb_ddc_getscl(void *data) | ||
1211 | { | ||
1212 | struct cfb_info *cfb = data; | ||
1213 | int retval; | ||
1214 | |||
1215 | cyber2000fb_enable_ddc(cfb); | ||
1216 | retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SCL_IN); | ||
1217 | cyber2000fb_disable_ddc(cfb); | ||
1218 | |||
1219 | return retval; | ||
1220 | } | ||
1221 | |||
1222 | static int cyber2000fb_ddc_getsda(void *data) | ||
1223 | { | ||
1224 | struct cfb_info *cfb = data; | ||
1225 | int retval; | ||
1226 | |||
1227 | cyber2000fb_enable_ddc(cfb); | ||
1228 | retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SDA_IN); | ||
1229 | cyber2000fb_disable_ddc(cfb); | ||
1230 | |||
1231 | return retval; | ||
1232 | } | ||
1233 | |||
1234 | static int __devinit cyber2000fb_setup_ddc_bus(struct cfb_info *cfb) | ||
1235 | { | ||
1236 | strlcpy(cfb->ddc_adapter.name, cfb->fb.fix.id, | ||
1237 | sizeof(cfb->ddc_adapter.name)); | ||
1238 | cfb->ddc_adapter.owner = THIS_MODULE; | ||
1239 | cfb->ddc_adapter.class = I2C_CLASS_DDC; | ||
1240 | cfb->ddc_adapter.algo_data = &cfb->ddc_algo; | ||
1241 | cfb->ddc_adapter.dev.parent = cfb->fb.device; | ||
1242 | cfb->ddc_algo.setsda = cyber2000fb_ddc_setsda; | ||
1243 | cfb->ddc_algo.setscl = cyber2000fb_ddc_setscl; | ||
1244 | cfb->ddc_algo.getsda = cyber2000fb_ddc_getsda; | ||
1245 | cfb->ddc_algo.getscl = cyber2000fb_ddc_getscl; | ||
1246 | cfb->ddc_algo.udelay = 10; | ||
1247 | cfb->ddc_algo.timeout = 20; | ||
1248 | cfb->ddc_algo.data = cfb; | ||
1249 | |||
1250 | i2c_set_adapdata(&cfb->ddc_adapter, cfb); | ||
1251 | |||
1252 | return i2c_bit_add_bus(&cfb->ddc_adapter); | ||
1253 | } | ||
1254 | #endif /* CONFIG_FB_CYBER2000_DDC */ | ||
1255 | |||
1256 | #ifdef CONFIG_FB_CYBER2000_I2C | ||
1257 | static void cyber2000fb_i2c_setsda(void *data, int state) | ||
1258 | { | ||
1259 | struct cfb_info *cfb = data; | ||
1260 | unsigned int latch2; | ||
1261 | |||
1262 | spin_lock(&cfb->reg_b0_lock); | ||
1263 | latch2 = cyber2000_grphr(EXT_LATCH2, cfb); | ||
1264 | latch2 &= EXT_LATCH2_I2C_CLKEN; | ||
1265 | if (state) | ||
1266 | latch2 |= EXT_LATCH2_I2C_DATEN; | ||
1267 | cyber2000_grphw(EXT_LATCH2, latch2, cfb); | ||
1268 | spin_unlock(&cfb->reg_b0_lock); | ||
1269 | } | ||
1270 | |||
1271 | static void cyber2000fb_i2c_setscl(void *data, int state) | ||
1272 | { | ||
1273 | struct cfb_info *cfb = data; | ||
1274 | unsigned int latch2; | ||
1275 | |||
1276 | spin_lock(&cfb->reg_b0_lock); | ||
1277 | latch2 = cyber2000_grphr(EXT_LATCH2, cfb); | ||
1278 | latch2 &= EXT_LATCH2_I2C_DATEN; | ||
1279 | if (state) | ||
1280 | latch2 |= EXT_LATCH2_I2C_CLKEN; | ||
1281 | cyber2000_grphw(EXT_LATCH2, latch2, cfb); | ||
1282 | spin_unlock(&cfb->reg_b0_lock); | ||
1283 | } | ||
1284 | |||
1285 | static int cyber2000fb_i2c_getsda(void *data) | ||
1286 | { | ||
1287 | struct cfb_info *cfb = data; | ||
1288 | int ret; | ||
1289 | |||
1290 | spin_lock(&cfb->reg_b0_lock); | ||
1291 | ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_DAT); | ||
1292 | spin_unlock(&cfb->reg_b0_lock); | ||
1293 | |||
1294 | return ret; | ||
1295 | } | ||
1296 | |||
1297 | static int cyber2000fb_i2c_getscl(void *data) | ||
1298 | { | ||
1299 | struct cfb_info *cfb = data; | ||
1300 | int ret; | ||
1301 | |||
1302 | spin_lock(&cfb->reg_b0_lock); | ||
1303 | ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_CLK); | ||
1304 | spin_unlock(&cfb->reg_b0_lock); | ||
1305 | |||
1306 | return ret; | ||
1307 | } | ||
1308 | |||
1309 | static int __devinit cyber2000fb_i2c_register(struct cfb_info *cfb) | ||
1310 | { | ||
1311 | strlcpy(cfb->i2c_adapter.name, cfb->fb.fix.id, | ||
1312 | sizeof(cfb->i2c_adapter.name)); | ||
1313 | cfb->i2c_adapter.owner = THIS_MODULE; | ||
1314 | cfb->i2c_adapter.algo_data = &cfb->i2c_algo; | ||
1315 | cfb->i2c_adapter.dev.parent = cfb->fb.device; | ||
1316 | cfb->i2c_algo.setsda = cyber2000fb_i2c_setsda; | ||
1317 | cfb->i2c_algo.setscl = cyber2000fb_i2c_setscl; | ||
1318 | cfb->i2c_algo.getsda = cyber2000fb_i2c_getsda; | ||
1319 | cfb->i2c_algo.getscl = cyber2000fb_i2c_getscl; | ||
1320 | cfb->i2c_algo.udelay = 5; | ||
1321 | cfb->i2c_algo.timeout = msecs_to_jiffies(100); | ||
1322 | cfb->i2c_algo.data = cfb; | ||
1323 | |||
1324 | return i2c_bit_add_bus(&cfb->i2c_adapter); | ||
1325 | } | ||
1326 | |||
1327 | static void cyber2000fb_i2c_unregister(struct cfb_info *cfb) | ||
1328 | { | ||
1329 | i2c_del_adapter(&cfb->i2c_adapter); | ||
1330 | } | ||
1331 | #else | ||
1332 | #define cyber2000fb_i2c_register(cfb) (0) | ||
1333 | #define cyber2000fb_i2c_unregister(cfb) do { } while (0) | ||
1334 | #endif | ||
1335 | |||
1144 | /* | 1336 | /* |
1145 | * These parameters give | 1337 | * These parameters give |
1146 | * 640x480, hsync 31.5kHz, vsync 60Hz | 1338 | * 640x480, hsync 31.5kHz, vsync 60Hz |
@@ -1275,6 +1467,8 @@ static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id, | |||
1275 | cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 1467 | cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
1276 | cfb->fb.pseudo_palette = cfb->pseudo_palette; | 1468 | cfb->fb.pseudo_palette = cfb->pseudo_palette; |
1277 | 1469 | ||
1470 | spin_lock_init(&cfb->reg_b0_lock); | ||
1471 | |||
1278 | fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); | 1472 | fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); |
1279 | 1473 | ||
1280 | return cfb; | 1474 | return cfb; |
@@ -1369,6 +1563,11 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) | |||
1369 | cfb->fb.fix.mmio_len = MMIO_SIZE; | 1563 | cfb->fb.fix.mmio_len = MMIO_SIZE; |
1370 | cfb->fb.screen_base = cfb->region; | 1564 | cfb->fb.screen_base = cfb->region; |
1371 | 1565 | ||
1566 | #ifdef CONFIG_FB_CYBER2000_DDC | ||
1567 | if (cyber2000fb_setup_ddc_bus(cfb) == 0) | ||
1568 | cfb->ddc_registered = true; | ||
1569 | #endif | ||
1570 | |||
1372 | err = -EINVAL; | 1571 | err = -EINVAL; |
1373 | if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0, | 1572 | if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0, |
1374 | &cyber2000fb_default_mode, 8)) { | 1573 | &cyber2000fb_default_mode, 8)) { |
@@ -1401,14 +1600,32 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) | |||
1401 | cfb->fb.var.xres, cfb->fb.var.yres, | 1600 | cfb->fb.var.xres, cfb->fb.var.yres, |
1402 | h_sync / 1000, h_sync % 1000, v_sync); | 1601 | h_sync / 1000, h_sync % 1000, v_sync); |
1403 | 1602 | ||
1404 | if (cfb->dev) | 1603 | err = cyber2000fb_i2c_register(cfb); |
1405 | cfb->fb.device = &cfb->dev->dev; | 1604 | if (err) |
1605 | goto failed; | ||
1606 | |||
1406 | err = register_framebuffer(&cfb->fb); | 1607 | err = register_framebuffer(&cfb->fb); |
1608 | if (err) | ||
1609 | cyber2000fb_i2c_unregister(cfb); | ||
1407 | 1610 | ||
1408 | failed: | 1611 | failed: |
1612 | #ifdef CONFIG_FB_CYBER2000_DDC | ||
1613 | if (err && cfb->ddc_registered) | ||
1614 | i2c_del_adapter(&cfb->ddc_adapter); | ||
1615 | #endif | ||
1409 | return err; | 1616 | return err; |
1410 | } | 1617 | } |
1411 | 1618 | ||
1619 | static void __devexit cyberpro_common_remove(struct cfb_info *cfb) | ||
1620 | { | ||
1621 | unregister_framebuffer(&cfb->fb); | ||
1622 | #ifdef CONFIG_FB_CYBER2000_DDC | ||
1623 | if (cfb->ddc_registered) | ||
1624 | i2c_del_adapter(&cfb->ddc_adapter); | ||
1625 | #endif | ||
1626 | cyber2000fb_i2c_unregister(cfb); | ||
1627 | } | ||
1628 | |||
1412 | static void cyberpro_common_resume(struct cfb_info *cfb) | 1629 | static void cyberpro_common_resume(struct cfb_info *cfb) |
1413 | { | 1630 | { |
1414 | cyberpro_init_hw(cfb); | 1631 | cyberpro_init_hw(cfb); |
@@ -1442,12 +1659,13 @@ static int __devinit cyberpro_vl_probe(void) | |||
1442 | if (!cfb) | 1659 | if (!cfb) |
1443 | goto failed_release; | 1660 | goto failed_release; |
1444 | 1661 | ||
1445 | cfb->dev = NULL; | 1662 | cfb->irq = -1; |
1446 | cfb->region = ioremap(FB_START, FB_SIZE); | 1663 | cfb->region = ioremap(FB_START, FB_SIZE); |
1447 | if (!cfb->region) | 1664 | if (!cfb->region) |
1448 | goto failed_ioremap; | 1665 | goto failed_ioremap; |
1449 | 1666 | ||
1450 | cfb->regs = cfb->region + MMIO_OFFSET; | 1667 | cfb->regs = cfb->region + MMIO_OFFSET; |
1668 | cfb->fb.device = NULL; | ||
1451 | cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET; | 1669 | cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET; |
1452 | cfb->fb.fix.smem_start = FB_START; | 1670 | cfb->fb.fix.smem_start = FB_START; |
1453 | 1671 | ||
@@ -1585,12 +1803,13 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1585 | if (err) | 1803 | if (err) |
1586 | goto failed_regions; | 1804 | goto failed_regions; |
1587 | 1805 | ||
1588 | cfb->dev = dev; | 1806 | cfb->irq = dev->irq; |
1589 | cfb->region = pci_ioremap_bar(dev, 0); | 1807 | cfb->region = pci_ioremap_bar(dev, 0); |
1590 | if (!cfb->region) | 1808 | if (!cfb->region) |
1591 | goto failed_ioremap; | 1809 | goto failed_ioremap; |
1592 | 1810 | ||
1593 | cfb->regs = cfb->region + MMIO_OFFSET; | 1811 | cfb->regs = cfb->region + MMIO_OFFSET; |
1812 | cfb->fb.device = &dev->dev; | ||
1594 | cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET; | 1813 | cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET; |
1595 | cfb->fb.fix.smem_start = pci_resource_start(dev, 0); | 1814 | cfb->fb.fix.smem_start = pci_resource_start(dev, 0); |
1596 | 1815 | ||
@@ -1648,15 +1867,7 @@ static void __devexit cyberpro_pci_remove(struct pci_dev *dev) | |||
1648 | struct cfb_info *cfb = pci_get_drvdata(dev); | 1867 | struct cfb_info *cfb = pci_get_drvdata(dev); |
1649 | 1868 | ||
1650 | if (cfb) { | 1869 | if (cfb) { |
1651 | /* | 1870 | cyberpro_common_remove(cfb); |
1652 | * If unregister_framebuffer fails, then | ||
1653 | * we will be leaving hooks that could cause | ||
1654 | * oopsen laying around. | ||
1655 | */ | ||
1656 | if (unregister_framebuffer(&cfb->fb)) | ||
1657 | printk(KERN_WARNING "%s: danger Will Robinson, " | ||
1658 | "danger danger! Oopsen imminent!\n", | ||
1659 | cfb->fb.fix.id); | ||
1660 | iounmap(cfb->region); | 1871 | iounmap(cfb->region); |
1661 | cyberpro_free_fb_info(cfb); | 1872 | cyberpro_free_fb_info(cfb); |
1662 | 1873 | ||
diff --git a/drivers/video/cyber2000fb.h b/drivers/video/cyber2000fb.h index de4fc43e51c1..bad69102e774 100644 --- a/drivers/video/cyber2000fb.h +++ b/drivers/video/cyber2000fb.h | |||
@@ -464,12 +464,14 @@ static void debug_printf(char *fmt, ...) | |||
464 | struct cfb_info; | 464 | struct cfb_info; |
465 | 465 | ||
466 | struct cyberpro_info { | 466 | struct cyberpro_info { |
467 | struct pci_dev *dev; | 467 | struct device *dev; |
468 | struct i2c_adapter *i2c; | ||
468 | unsigned char __iomem *regs; | 469 | unsigned char __iomem *regs; |
469 | char __iomem *fb; | 470 | char __iomem *fb; |
470 | char dev_name[32]; | 471 | char dev_name[32]; |
471 | unsigned int fb_size; | 472 | unsigned int fb_size; |
472 | unsigned int chip_id; | 473 | unsigned int chip_id; |
474 | unsigned int irq; | ||
473 | 475 | ||
474 | /* | 476 | /* |
475 | * The following is a pointer to be passed into the | 477 | * The following is a pointer to be passed into the |
@@ -478,15 +480,6 @@ struct cyberpro_info { | |||
478 | * is within this structure. | 480 | * is within this structure. |
479 | */ | 481 | */ |
480 | struct cfb_info *info; | 482 | struct cfb_info *info; |
481 | |||
482 | /* | ||
483 | * Use these to enable the BM or TV registers. In an SMP | ||
484 | * environment, these two function pointers should only be | ||
485 | * called from the module_init() or module_exit() | ||
486 | * functions. | ||
487 | */ | ||
488 | void (*enable_extregs)(struct cfb_info *); | ||
489 | void (*disable_extregs)(struct cfb_info *); | ||
490 | }; | 483 | }; |
491 | 484 | ||
492 | #define ID_IGA_1682 0 | 485 | #define ID_IGA_1682 0 |
@@ -494,8 +487,6 @@ struct cyberpro_info { | |||
494 | #define ID_CYBERPRO_2010 2 | 487 | #define ID_CYBERPRO_2010 2 |
495 | #define ID_CYBERPRO_5000 3 | 488 | #define ID_CYBERPRO_5000 3 |
496 | 489 | ||
497 | struct fb_var_screeninfo; | ||
498 | |||
499 | /* | 490 | /* |
500 | * Note! Writing to the Cyber20x0 registers from an interrupt | 491 | * Note! Writing to the Cyber20x0 registers from an interrupt |
501 | * routine is definitely a bad idea atm. | 492 | * routine is definitely a bad idea atm. |
@@ -504,4 +495,3 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx); | |||
504 | void cyber2000fb_detach(int idx); | 495 | void cyber2000fb_detach(int idx); |
505 | void cyber2000fb_enable_extregs(struct cfb_info *cfb); | 496 | void cyber2000fb_enable_extregs(struct cfb_info *cfb); |
506 | void cyber2000fb_disable_extregs(struct cfb_info *cfb); | 497 | void cyber2000fb_disable_extregs(struct cfb_info *cfb); |
507 | void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var); | ||
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/fb-puv3.c b/drivers/video/fb-puv3.c new file mode 100644 index 000000000000..dbd2dc4745d1 --- /dev/null +++ b/drivers/video/fb-puv3.c | |||
@@ -0,0 +1,846 @@ | |||
1 | /* | ||
2 | * Frame Buffer Driver for PKUnity-v3 Unigfx | ||
3 | * Code specific to PKUnity SoC and UniCore ISA | ||
4 | * | ||
5 | * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> | ||
6 | * Copyright (C) 2001-2010 Guan Xuetao | ||
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 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/vmalloc.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/fb.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/console.h> | ||
22 | |||
23 | #include <asm/sizes.h> | ||
24 | #include <mach/hardware.h> | ||
25 | |||
26 | /* Platform_data reserved for unifb registers. */ | ||
27 | #define UNIFB_REGS_NUM 10 | ||
28 | /* RAM reserved for the frame buffer. */ | ||
29 | #define UNIFB_MEMSIZE (SZ_4M) /* 4 MB for 1024*768*32b */ | ||
30 | |||
31 | /* | ||
32 | * cause UNIGFX don not have EDID | ||
33 | * all the modes are organized as follow | ||
34 | */ | ||
35 | static const struct fb_videomode unifb_modes[] = { | ||
36 | /* 0 640x480-60 VESA */ | ||
37 | { "640x480@60", 60, 640, 480, 25175000, 48, 16, 34, 10, 96, 1, | ||
38 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
39 | /* 1 640x480-75 VESA */ | ||
40 | { "640x480@75", 75, 640, 480, 31500000, 120, 16, 18, 1, 64, 1, | ||
41 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
42 | /* 2 800x600-60 VESA */ | ||
43 | { "800x600@60", 60, 800, 600, 40000000, 88, 40, 26, 1, 128, 1, | ||
44 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
45 | /* 3 800x600-75 VESA */ | ||
46 | { "800x600@75", 75, 800, 600, 49500000, 160, 16, 23, 1, 80, 1, | ||
47 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
48 | /* 4 1024x768-60 VESA */ | ||
49 | { "1024x768@60", 60, 1024, 768, 65000000, 160, 24, 34, 3, 136, 1, | ||
50 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
51 | /* 5 1024x768-75 VESA */ | ||
52 | { "1024x768@75", 75, 1024, 768, 78750000, 176, 16, 30, 1, 96, 1, | ||
53 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
54 | /* 6 1280x960-60 VESA */ | ||
55 | { "1280x960@60", 60, 1280, 960, 108000000, 312, 96, 38, 1, 112, 1, | ||
56 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
57 | /* 7 1440x900-60 VESA */ | ||
58 | { "1440x900@60", 60, 1440, 900, 106500000, 232, 80, 30, 3, 152, 1, | ||
59 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
60 | /* 8 FIXME 9 1024x600-60 VESA UNTESTED */ | ||
61 | { "1024x600@60", 60, 1024, 600, 50650000, 160, 24, 26, 1, 136, 1, | ||
62 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
63 | /* 9 FIXME 10 1024x600-75 VESA UNTESTED */ | ||
64 | { "1024x600@75", 75, 1024, 600, 61500000, 176, 16, 23, 1, 96, 1, | ||
65 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
66 | /* 10 FIXME 11 1366x768-60 VESA UNTESTED */ | ||
67 | { "1366x768@60", 60, 1366, 768, 85500000, 256, 58, 18, 1, 112, 3, | ||
68 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
69 | }; | ||
70 | |||
71 | static struct fb_var_screeninfo unifb_default = { | ||
72 | .xres = 640, | ||
73 | .yres = 480, | ||
74 | .xres_virtual = 640, | ||
75 | .yres_virtual = 480, | ||
76 | .bits_per_pixel = 16, | ||
77 | .red = { 11, 5, 0 }, | ||
78 | .green = { 5, 6, 0 }, | ||
79 | .blue = { 0, 5, 0 }, | ||
80 | .activate = FB_ACTIVATE_NOW, | ||
81 | .height = -1, | ||
82 | .width = -1, | ||
83 | .pixclock = 25175000, | ||
84 | .left_margin = 48, | ||
85 | .right_margin = 16, | ||
86 | .upper_margin = 33, | ||
87 | .lower_margin = 10, | ||
88 | .hsync_len = 96, | ||
89 | .vsync_len = 2, | ||
90 | .vmode = FB_VMODE_NONINTERLACED, | ||
91 | }; | ||
92 | |||
93 | static struct fb_fix_screeninfo unifb_fix = { | ||
94 | .id = "UNIGFX FB", | ||
95 | .type = FB_TYPE_PACKED_PIXELS, | ||
96 | .visual = FB_VISUAL_TRUECOLOR, | ||
97 | .xpanstep = 1, | ||
98 | .ypanstep = 1, | ||
99 | .ywrapstep = 1, | ||
100 | .accel = FB_ACCEL_NONE, | ||
101 | }; | ||
102 | |||
103 | static void unifb_sync(struct fb_info *info) | ||
104 | { | ||
105 | /* TODO: may, this can be replaced by interrupt */ | ||
106 | int cnt; | ||
107 | |||
108 | for (cnt = 0; cnt < 0x10000000; cnt++) { | ||
109 | if (readl(UGE_COMMAND) & 0x1000000) | ||
110 | return; | ||
111 | } | ||
112 | |||
113 | if (cnt > 0x8000000) | ||
114 | dev_warn(info->device, "Warning: UniGFX GE time out ...\n"); | ||
115 | } | ||
116 | |||
117 | static void unifb_prim_fillrect(struct fb_info *info, | ||
118 | const struct fb_fillrect *region) | ||
119 | { | ||
120 | int awidth = region->width; | ||
121 | int aheight = region->height; | ||
122 | int m_iBpp = info->var.bits_per_pixel; | ||
123 | int screen_width = info->var.xres; | ||
124 | int src_sel = 1; /* from fg_color */ | ||
125 | int pat_sel = 1; | ||
126 | int src_x0 = 0; | ||
127 | int dst_x0 = region->dx; | ||
128 | int src_y0 = 0; | ||
129 | int dst_y0 = region->dy; | ||
130 | int rop_alpha_sel = 0; | ||
131 | int rop_alpha_code = 0xCC; | ||
132 | int x_dir = 1; | ||
133 | int y_dir = 1; | ||
134 | int alpha_r = 0; | ||
135 | int alpha_sel = 0; | ||
136 | int dst_pitch = screen_width * (m_iBpp / 8); | ||
137 | int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8); | ||
138 | int src_pitch = screen_width * (m_iBpp / 8); | ||
139 | int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8); | ||
140 | unsigned int command = 0; | ||
141 | int clip_region = 0; | ||
142 | int clip_en = 0; | ||
143 | int tp_en = 0; | ||
144 | int fg_color = 0; | ||
145 | int bottom = info->var.yres - 1; | ||
146 | int right = info->var.xres - 1; | ||
147 | int top = 0; | ||
148 | |||
149 | bottom = (bottom << 16) | right; | ||
150 | command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16) | ||
151 | | (x_dir << 20) | (y_dir << 21) | (command << 24) | ||
152 | | (clip_region << 23) | (clip_en << 22) | (tp_en << 27); | ||
153 | src_pitch = (dst_pitch << 16) | src_pitch; | ||
154 | awidth = awidth | (aheight << 16); | ||
155 | alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff) | ||
156 | | (alpha_sel << 16); | ||
157 | src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16); | ||
158 | dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16); | ||
159 | fg_color = region->color; | ||
160 | |||
161 | unifb_sync(info); | ||
162 | |||
163 | writel(((u32 *)(info->pseudo_palette))[fg_color], UGE_FCOLOR); | ||
164 | writel(0, UGE_BCOLOR); | ||
165 | writel(src_pitch, UGE_PITCH); | ||
166 | writel(src_offset, UGE_SRCSTART); | ||
167 | writel(dst_offset, UGE_DSTSTART); | ||
168 | writel(awidth, UGE_WIDHEIGHT); | ||
169 | writel(top, UGE_CLIP0); | ||
170 | writel(bottom, UGE_CLIP1); | ||
171 | writel(alpha_r, UGE_ROPALPHA); | ||
172 | writel(src_x0, UGE_SRCXY); | ||
173 | writel(dst_x0, UGE_DSTXY); | ||
174 | writel(command, UGE_COMMAND); | ||
175 | } | ||
176 | |||
177 | static void unifb_fillrect(struct fb_info *info, | ||
178 | const struct fb_fillrect *region) | ||
179 | { | ||
180 | struct fb_fillrect modded; | ||
181 | int vxres, vyres; | ||
182 | |||
183 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
184 | sys_fillrect(info, region); | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | vxres = info->var.xres_virtual; | ||
189 | vyres = info->var.yres_virtual; | ||
190 | |||
191 | memcpy(&modded, region, sizeof(struct fb_fillrect)); | ||
192 | |||
193 | if (!modded.width || !modded.height || | ||
194 | modded.dx >= vxres || modded.dy >= vyres) | ||
195 | return; | ||
196 | |||
197 | if (modded.dx + modded.width > vxres) | ||
198 | modded.width = vxres - modded.dx; | ||
199 | if (modded.dy + modded.height > vyres) | ||
200 | modded.height = vyres - modded.dy; | ||
201 | |||
202 | unifb_prim_fillrect(info, &modded); | ||
203 | } | ||
204 | |||
205 | static void unifb_prim_copyarea(struct fb_info *info, | ||
206 | const struct fb_copyarea *area) | ||
207 | { | ||
208 | int awidth = area->width; | ||
209 | int aheight = area->height; | ||
210 | int m_iBpp = info->var.bits_per_pixel; | ||
211 | int screen_width = info->var.xres; | ||
212 | int src_sel = 2; /* from mem */ | ||
213 | int pat_sel = 0; | ||
214 | int src_x0 = area->sx; | ||
215 | int dst_x0 = area->dx; | ||
216 | int src_y0 = area->sy; | ||
217 | int dst_y0 = area->dy; | ||
218 | |||
219 | int rop_alpha_sel = 0; | ||
220 | int rop_alpha_code = 0xCC; | ||
221 | int x_dir = 1; | ||
222 | int y_dir = 1; | ||
223 | |||
224 | int alpha_r = 0; | ||
225 | int alpha_sel = 0; | ||
226 | int dst_pitch = screen_width * (m_iBpp / 8); | ||
227 | int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8); | ||
228 | int src_pitch = screen_width * (m_iBpp / 8); | ||
229 | int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8); | ||
230 | unsigned int command = 0; | ||
231 | int clip_region = 0; | ||
232 | int clip_en = 1; | ||
233 | int tp_en = 0; | ||
234 | int top = 0; | ||
235 | int bottom = info->var.yres; | ||
236 | int right = info->var.xres; | ||
237 | int fg_color = 0; | ||
238 | int bg_color = 0; | ||
239 | |||
240 | if (src_x0 < 0) | ||
241 | src_x0 = 0; | ||
242 | if (src_y0 < 0) | ||
243 | src_y0 = 0; | ||
244 | |||
245 | if (src_y0 - dst_y0 > 0) { | ||
246 | y_dir = 1; | ||
247 | } else { | ||
248 | y_dir = 0; | ||
249 | src_offset = (src_y0 + aheight) * src_pitch + | ||
250 | src_x0 * (m_iBpp / 8); | ||
251 | dst_offset = (dst_y0 + aheight) * dst_pitch + | ||
252 | dst_x0 * (m_iBpp / 8); | ||
253 | src_y0 += aheight; | ||
254 | dst_y0 += aheight; | ||
255 | } | ||
256 | |||
257 | command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16) | | ||
258 | (x_dir << 20) | (y_dir << 21) | (command << 24) | | ||
259 | (clip_region << 23) | (clip_en << 22) | (tp_en << 27); | ||
260 | src_pitch = (dst_pitch << 16) | src_pitch; | ||
261 | awidth = awidth | (aheight << 16); | ||
262 | alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff) | | ||
263 | (alpha_sel << 16); | ||
264 | src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16); | ||
265 | dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16); | ||
266 | bottom = (bottom << 16) | right; | ||
267 | |||
268 | unifb_sync(info); | ||
269 | |||
270 | writel(src_pitch, UGE_PITCH); | ||
271 | writel(src_offset, UGE_SRCSTART); | ||
272 | writel(dst_offset, UGE_DSTSTART); | ||
273 | writel(awidth, UGE_WIDHEIGHT); | ||
274 | writel(top, UGE_CLIP0); | ||
275 | writel(bottom, UGE_CLIP1); | ||
276 | writel(bg_color, UGE_BCOLOR); | ||
277 | writel(fg_color, UGE_FCOLOR); | ||
278 | writel(alpha_r, UGE_ROPALPHA); | ||
279 | writel(src_x0, UGE_SRCXY); | ||
280 | writel(dst_x0, UGE_DSTXY); | ||
281 | writel(command, UGE_COMMAND); | ||
282 | } | ||
283 | |||
284 | static void unifb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
285 | { | ||
286 | struct fb_copyarea modded; | ||
287 | u32 vxres, vyres; | ||
288 | modded.sx = area->sx; | ||
289 | modded.sy = area->sy; | ||
290 | modded.dx = area->dx; | ||
291 | modded.dy = area->dy; | ||
292 | modded.width = area->width; | ||
293 | modded.height = area->height; | ||
294 | |||
295 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
296 | sys_copyarea(info, area); | ||
297 | return; | ||
298 | } | ||
299 | |||
300 | vxres = info->var.xres_virtual; | ||
301 | vyres = info->var.yres_virtual; | ||
302 | |||
303 | if (!modded.width || !modded.height || | ||
304 | modded.sx >= vxres || modded.sy >= vyres || | ||
305 | modded.dx >= vxres || modded.dy >= vyres) | ||
306 | return; | ||
307 | |||
308 | if (modded.sx + modded.width > vxres) | ||
309 | modded.width = vxres - modded.sx; | ||
310 | if (modded.dx + modded.width > vxres) | ||
311 | modded.width = vxres - modded.dx; | ||
312 | if (modded.sy + modded.height > vyres) | ||
313 | modded.height = vyres - modded.sy; | ||
314 | if (modded.dy + modded.height > vyres) | ||
315 | modded.height = vyres - modded.dy; | ||
316 | |||
317 | unifb_prim_copyarea(info, &modded); | ||
318 | } | ||
319 | |||
320 | static void unifb_imageblit(struct fb_info *info, const struct fb_image *image) | ||
321 | { | ||
322 | sys_imageblit(info, image); | ||
323 | } | ||
324 | |||
325 | static u_long get_line_length(int xres_virtual, int bpp) | ||
326 | { | ||
327 | u_long length; | ||
328 | |||
329 | length = xres_virtual * bpp; | ||
330 | length = (length + 31) & ~31; | ||
331 | length >>= 3; | ||
332 | return length; | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Setting the video mode has been split into two parts. | ||
337 | * First part, xxxfb_check_var, must not write anything | ||
338 | * to hardware, it should only verify and adjust var. | ||
339 | * This means it doesn't alter par but it does use hardware | ||
340 | * data from it to check this var. | ||
341 | */ | ||
342 | static int unifb_check_var(struct fb_var_screeninfo *var, | ||
343 | struct fb_info *info) | ||
344 | { | ||
345 | u_long line_length; | ||
346 | |||
347 | /* | ||
348 | * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! | ||
349 | * as FB_VMODE_SMOOTH_XPAN is only used internally | ||
350 | */ | ||
351 | |||
352 | if (var->vmode & FB_VMODE_CONUPDATE) { | ||
353 | var->vmode |= FB_VMODE_YWRAP; | ||
354 | var->xoffset = info->var.xoffset; | ||
355 | var->yoffset = info->var.yoffset; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * Some very basic checks | ||
360 | */ | ||
361 | if (!var->xres) | ||
362 | var->xres = 1; | ||
363 | if (!var->yres) | ||
364 | var->yres = 1; | ||
365 | if (var->xres > var->xres_virtual) | ||
366 | var->xres_virtual = var->xres; | ||
367 | if (var->yres > var->yres_virtual) | ||
368 | var->yres_virtual = var->yres; | ||
369 | if (var->bits_per_pixel <= 1) | ||
370 | var->bits_per_pixel = 1; | ||
371 | else if (var->bits_per_pixel <= 8) | ||
372 | var->bits_per_pixel = 8; | ||
373 | else if (var->bits_per_pixel <= 16) | ||
374 | var->bits_per_pixel = 16; | ||
375 | else if (var->bits_per_pixel <= 24) | ||
376 | var->bits_per_pixel = 24; | ||
377 | else if (var->bits_per_pixel <= 32) | ||
378 | var->bits_per_pixel = 32; | ||
379 | else | ||
380 | return -EINVAL; | ||
381 | |||
382 | if (var->xres_virtual < var->xoffset + var->xres) | ||
383 | var->xres_virtual = var->xoffset + var->xres; | ||
384 | if (var->yres_virtual < var->yoffset + var->yres) | ||
385 | var->yres_virtual = var->yoffset + var->yres; | ||
386 | |||
387 | /* | ||
388 | * Memory limit | ||
389 | */ | ||
390 | line_length = | ||
391 | get_line_length(var->xres_virtual, var->bits_per_pixel); | ||
392 | if (line_length * var->yres_virtual > UNIFB_MEMSIZE) | ||
393 | return -ENOMEM; | ||
394 | |||
395 | /* | ||
396 | * Now that we checked it we alter var. The reason being is that the | ||
397 | * video mode passed in might not work but slight changes to it might | ||
398 | * make it work. This way we let the user know what is acceptable. | ||
399 | */ | ||
400 | switch (var->bits_per_pixel) { | ||
401 | case 1: | ||
402 | case 8: | ||
403 | var->red.offset = 0; | ||
404 | var->red.length = 8; | ||
405 | var->green.offset = 0; | ||
406 | var->green.length = 8; | ||
407 | var->blue.offset = 0; | ||
408 | var->blue.length = 8; | ||
409 | var->transp.offset = 0; | ||
410 | var->transp.length = 0; | ||
411 | break; | ||
412 | case 16: /* RGBA 5551 */ | ||
413 | if (var->transp.length) { | ||
414 | var->red.offset = 0; | ||
415 | var->red.length = 5; | ||
416 | var->green.offset = 5; | ||
417 | var->green.length = 5; | ||
418 | var->blue.offset = 10; | ||
419 | var->blue.length = 5; | ||
420 | var->transp.offset = 15; | ||
421 | var->transp.length = 1; | ||
422 | } else { /* RGB 565 */ | ||
423 | var->red.offset = 11; | ||
424 | var->red.length = 5; | ||
425 | var->green.offset = 5; | ||
426 | var->green.length = 6; | ||
427 | var->blue.offset = 0; | ||
428 | var->blue.length = 5; | ||
429 | var->transp.offset = 0; | ||
430 | var->transp.length = 0; | ||
431 | } | ||
432 | break; | ||
433 | case 24: /* RGB 888 */ | ||
434 | var->red.offset = 0; | ||
435 | var->red.length = 8; | ||
436 | var->green.offset = 8; | ||
437 | var->green.length = 8; | ||
438 | var->blue.offset = 16; | ||
439 | var->blue.length = 8; | ||
440 | var->transp.offset = 0; | ||
441 | var->transp.length = 0; | ||
442 | break; | ||
443 | case 32: /* RGBA 8888 */ | ||
444 | var->red.offset = 16; | ||
445 | var->red.length = 8; | ||
446 | var->green.offset = 8; | ||
447 | var->green.length = 8; | ||
448 | var->blue.offset = 0; | ||
449 | var->blue.length = 8; | ||
450 | var->transp.offset = 24; | ||
451 | var->transp.length = 8; | ||
452 | break; | ||
453 | } | ||
454 | var->red.msb_right = 0; | ||
455 | var->green.msb_right = 0; | ||
456 | var->blue.msb_right = 0; | ||
457 | var->transp.msb_right = 0; | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | /* | ||
463 | * This routine actually sets the video mode. It's in here where we | ||
464 | * the hardware state info->par and fix which can be affected by the | ||
465 | * change in par. For this driver it doesn't do much. | ||
466 | */ | ||
467 | static int unifb_set_par(struct fb_info *info) | ||
468 | { | ||
469 | int hTotal, vTotal, hSyncStart, hSyncEnd, vSyncStart, vSyncEnd; | ||
470 | int format; | ||
471 | |||
472 | #ifdef CONFIG_PUV3_PM | ||
473 | struct clk *clk_vga; | ||
474 | u32 pixclk = 0; | ||
475 | int i; | ||
476 | |||
477 | for (i = 0; i <= 10; i++) { | ||
478 | if (info->var.xres == unifb_modes[i].xres | ||
479 | && info->var.yres == unifb_modes[i].yres | ||
480 | && info->var.upper_margin == unifb_modes[i].upper_margin | ||
481 | && info->var.lower_margin == unifb_modes[i].lower_margin | ||
482 | && info->var.left_margin == unifb_modes[i].left_margin | ||
483 | && info->var.right_margin == unifb_modes[i].right_margin | ||
484 | && info->var.hsync_len == unifb_modes[i].hsync_len | ||
485 | && info->var.vsync_len == unifb_modes[i].vsync_len) { | ||
486 | pixclk = unifb_modes[i].pixclock; | ||
487 | break; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | /* set clock rate */ | ||
492 | clk_vga = clk_get(info->device, "VGA_CLK"); | ||
493 | if (clk_vga == ERR_PTR(-ENOENT)) | ||
494 | return -ENOENT; | ||
495 | |||
496 | if (pixclk != 0) { | ||
497 | if (clk_set_rate(clk_vga, pixclk)) { /* set clock failed */ | ||
498 | info->fix = unifb_fix; | ||
499 | info->var = unifb_default; | ||
500 | if (clk_set_rate(clk_vga, unifb_default.pixclock)) | ||
501 | return -EINVAL; | ||
502 | } | ||
503 | } | ||
504 | #endif | ||
505 | |||
506 | info->fix.line_length = get_line_length(info->var.xres_virtual, | ||
507 | info->var.bits_per_pixel); | ||
508 | |||
509 | hSyncStart = info->var.xres + info->var.right_margin; | ||
510 | hSyncEnd = hSyncStart + info->var.hsync_len; | ||
511 | hTotal = hSyncEnd + info->var.left_margin; | ||
512 | |||
513 | vSyncStart = info->var.yres + info->var.lower_margin; | ||
514 | vSyncEnd = vSyncStart + info->var.vsync_len; | ||
515 | vTotal = vSyncEnd + info->var.upper_margin; | ||
516 | |||
517 | switch (info->var.bits_per_pixel) { | ||
518 | case 8: | ||
519 | format = UDE_CFG_DST8; | ||
520 | break; | ||
521 | case 16: | ||
522 | format = UDE_CFG_DST16; | ||
523 | break; | ||
524 | case 24: | ||
525 | format = UDE_CFG_DST24; | ||
526 | break; | ||
527 | case 32: | ||
528 | format = UDE_CFG_DST32; | ||
529 | break; | ||
530 | default: | ||
531 | return -EINVAL; | ||
532 | } | ||
533 | |||
534 | writel(PKUNITY_UNIGFX_MMAP_BASE, UDE_FSA); | ||
535 | writel(info->var.yres, UDE_LS); | ||
536 | writel(get_line_length(info->var.xres, | ||
537 | info->var.bits_per_pixel) >> 3, UDE_PS); | ||
538 | /* >> 3 for hardware required. */ | ||
539 | writel((hTotal << 16) | (info->var.xres), UDE_HAT); | ||
540 | writel(((hTotal - 1) << 16) | (info->var.xres - 1), UDE_HBT); | ||
541 | writel(((hSyncEnd - 1) << 16) | (hSyncStart - 1), UDE_HST); | ||
542 | writel((vTotal << 16) | (info->var.yres), UDE_VAT); | ||
543 | writel(((vTotal - 1) << 16) | (info->var.yres - 1), UDE_VBT); | ||
544 | writel(((vSyncEnd - 1) << 16) | (vSyncStart - 1), UDE_VST); | ||
545 | writel(UDE_CFG_GDEN_ENABLE | UDE_CFG_TIMEUP_ENABLE | ||
546 | | format | 0xC0000001, UDE_CFG); | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | /* | ||
552 | * Set a single color register. The values supplied are already | ||
553 | * rounded down to the hardware's capabilities (according to the | ||
554 | * entries in the var structure). Return != 0 for invalid regno. | ||
555 | */ | ||
556 | static int unifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
557 | u_int transp, struct fb_info *info) | ||
558 | { | ||
559 | if (regno >= 256) /* no. of hw registers */ | ||
560 | return 1; | ||
561 | |||
562 | /* grayscale works only partially under directcolor */ | ||
563 | if (info->var.grayscale) { | ||
564 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
565 | red = green = blue = | ||
566 | (red * 77 + green * 151 + blue * 28) >> 8; | ||
567 | } | ||
568 | |||
569 | #define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16) | ||
570 | switch (info->fix.visual) { | ||
571 | case FB_VISUAL_TRUECOLOR: | ||
572 | case FB_VISUAL_PSEUDOCOLOR: | ||
573 | red = CNVT_TOHW(red, info->var.red.length); | ||
574 | green = CNVT_TOHW(green, info->var.green.length); | ||
575 | blue = CNVT_TOHW(blue, info->var.blue.length); | ||
576 | transp = CNVT_TOHW(transp, info->var.transp.length); | ||
577 | break; | ||
578 | case FB_VISUAL_DIRECTCOLOR: | ||
579 | red = CNVT_TOHW(red, 8); /* expect 8 bit DAC */ | ||
580 | green = CNVT_TOHW(green, 8); | ||
581 | blue = CNVT_TOHW(blue, 8); | ||
582 | /* hey, there is bug in transp handling... */ | ||
583 | transp = CNVT_TOHW(transp, 8); | ||
584 | break; | ||
585 | } | ||
586 | #undef CNVT_TOHW | ||
587 | /* Truecolor has hardware independent palette */ | ||
588 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | ||
589 | u32 v; | ||
590 | |||
591 | if (regno >= 16) | ||
592 | return 1; | ||
593 | |||
594 | v = (red << info->var.red.offset) | | ||
595 | (green << info->var.green.offset) | | ||
596 | (blue << info->var.blue.offset) | | ||
597 | (transp << info->var.transp.offset); | ||
598 | switch (info->var.bits_per_pixel) { | ||
599 | case 8: | ||
600 | break; | ||
601 | case 16: | ||
602 | case 24: | ||
603 | case 32: | ||
604 | ((u32 *) (info->pseudo_palette))[regno] = v; | ||
605 | break; | ||
606 | default: | ||
607 | return 1; | ||
608 | } | ||
609 | return 0; | ||
610 | } | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | /* | ||
615 | * Pan or Wrap the Display | ||
616 | * | ||
617 | * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag | ||
618 | */ | ||
619 | static int unifb_pan_display(struct fb_var_screeninfo *var, | ||
620 | struct fb_info *info) | ||
621 | { | ||
622 | if (var->vmode & FB_VMODE_YWRAP) { | ||
623 | if (var->yoffset < 0 | ||
624 | || var->yoffset >= info->var.yres_virtual | ||
625 | || var->xoffset) | ||
626 | return -EINVAL; | ||
627 | } else { | ||
628 | if (var->xoffset + var->xres > info->var.xres_virtual || | ||
629 | var->yoffset + var->yres > info->var.yres_virtual) | ||
630 | return -EINVAL; | ||
631 | } | ||
632 | info->var.xoffset = var->xoffset; | ||
633 | info->var.yoffset = var->yoffset; | ||
634 | if (var->vmode & FB_VMODE_YWRAP) | ||
635 | info->var.vmode |= FB_VMODE_YWRAP; | ||
636 | else | ||
637 | info->var.vmode &= ~FB_VMODE_YWRAP; | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | int unifb_mmap(struct fb_info *info, | ||
642 | struct vm_area_struct *vma) | ||
643 | { | ||
644 | unsigned long size = vma->vm_end - vma->vm_start; | ||
645 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | ||
646 | unsigned long pos = info->fix.smem_start + offset; | ||
647 | |||
648 | if (offset + size > info->fix.smem_len) | ||
649 | return -EINVAL; | ||
650 | |||
651 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
652 | |||
653 | if (io_remap_pfn_range(vma, vma->vm_start, pos >> PAGE_SHIFT, size, | ||
654 | vma->vm_page_prot)) | ||
655 | return -EAGAIN; | ||
656 | |||
657 | vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ | ||
658 | return 0; | ||
659 | |||
660 | } | ||
661 | |||
662 | static struct fb_ops unifb_ops = { | ||
663 | .fb_read = fb_sys_read, | ||
664 | .fb_write = fb_sys_write, | ||
665 | .fb_check_var = unifb_check_var, | ||
666 | .fb_set_par = unifb_set_par, | ||
667 | .fb_setcolreg = unifb_setcolreg, | ||
668 | .fb_pan_display = unifb_pan_display, | ||
669 | .fb_fillrect = unifb_fillrect, | ||
670 | .fb_copyarea = unifb_copyarea, | ||
671 | .fb_imageblit = unifb_imageblit, | ||
672 | .fb_mmap = unifb_mmap, | ||
673 | }; | ||
674 | |||
675 | /* | ||
676 | * Initialisation | ||
677 | */ | ||
678 | static int unifb_probe(struct platform_device *dev) | ||
679 | { | ||
680 | struct fb_info *info; | ||
681 | u32 unifb_regs[UNIFB_REGS_NUM]; | ||
682 | int retval = -ENOMEM; | ||
683 | struct resource *iomem, *mapmem; | ||
684 | |||
685 | info = framebuffer_alloc(sizeof(u32)*256, &dev->dev); | ||
686 | if (!info) | ||
687 | goto err; | ||
688 | |||
689 | info->screen_base = (char __iomem *)KUSER_UNIGFX_BASE; | ||
690 | info->fbops = &unifb_ops; | ||
691 | |||
692 | retval = fb_find_mode(&info->var, info, NULL, | ||
693 | unifb_modes, 10, &unifb_modes[0], 16); | ||
694 | |||
695 | if (!retval || (retval == 4)) | ||
696 | info->var = unifb_default; | ||
697 | |||
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; | ||
706 | info->pseudo_palette = info->par; | ||
707 | info->par = NULL; | ||
708 | info->flags = FBINFO_FLAG_DEFAULT; | ||
709 | #ifdef FB_ACCEL_PUV3_UNIGFX | ||
710 | info->fix.accel = FB_ACCEL_PUV3_UNIGFX; | ||
711 | #endif | ||
712 | |||
713 | retval = fb_alloc_cmap(&info->cmap, 256, 0); | ||
714 | if (retval < 0) | ||
715 | goto err1; | ||
716 | |||
717 | retval = register_framebuffer(info); | ||
718 | if (retval < 0) | ||
719 | goto err2; | ||
720 | platform_set_drvdata(dev, info); | ||
721 | platform_device_add_data(dev, unifb_regs, sizeof(u32) * UNIFB_REGS_NUM); | ||
722 | |||
723 | printk(KERN_INFO | ||
724 | "fb%d: Virtual frame buffer device, using %dM of video memory\n", | ||
725 | info->node, UNIFB_MEMSIZE >> 20); | ||
726 | return 0; | ||
727 | err2: | ||
728 | fb_dealloc_cmap(&info->cmap); | ||
729 | err1: | ||
730 | framebuffer_release(info); | ||
731 | err: | ||
732 | return retval; | ||
733 | } | ||
734 | |||
735 | static int unifb_remove(struct platform_device *dev) | ||
736 | { | ||
737 | struct fb_info *info = platform_get_drvdata(dev); | ||
738 | |||
739 | if (info) { | ||
740 | unregister_framebuffer(info); | ||
741 | fb_dealloc_cmap(&info->cmap); | ||
742 | framebuffer_release(info); | ||
743 | } | ||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | #ifdef CONFIG_PM | ||
748 | static int unifb_resume(struct platform_device *dev) | ||
749 | { | ||
750 | int rc = 0; | ||
751 | u32 *unifb_regs = dev->dev.platform_data; | ||
752 | |||
753 | if (dev->dev.power.power_state.event == PM_EVENT_ON) | ||
754 | return 0; | ||
755 | |||
756 | console_lock(); | ||
757 | |||
758 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND) { | ||
759 | writel(unifb_regs[0], UDE_FSA); | ||
760 | writel(unifb_regs[1], UDE_LS); | ||
761 | writel(unifb_regs[2], UDE_PS); | ||
762 | writel(unifb_regs[3], UDE_HAT); | ||
763 | writel(unifb_regs[4], UDE_HBT); | ||
764 | writel(unifb_regs[5], UDE_HST); | ||
765 | writel(unifb_regs[6], UDE_VAT); | ||
766 | writel(unifb_regs[7], UDE_VBT); | ||
767 | writel(unifb_regs[8], UDE_VST); | ||
768 | writel(unifb_regs[9], UDE_CFG); | ||
769 | } | ||
770 | dev->dev.power.power_state = PMSG_ON; | ||
771 | |||
772 | console_unlock(); | ||
773 | |||
774 | return rc; | ||
775 | } | ||
776 | |||
777 | static int unifb_suspend(struct platform_device *dev, pm_message_t mesg) | ||
778 | { | ||
779 | u32 *unifb_regs = dev->dev.platform_data; | ||
780 | |||
781 | unifb_regs[0] = readl(UDE_FSA); | ||
782 | unifb_regs[1] = readl(UDE_LS); | ||
783 | unifb_regs[2] = readl(UDE_PS); | ||
784 | unifb_regs[3] = readl(UDE_HAT); | ||
785 | unifb_regs[4] = readl(UDE_HBT); | ||
786 | unifb_regs[5] = readl(UDE_HST); | ||
787 | unifb_regs[6] = readl(UDE_VAT); | ||
788 | unifb_regs[7] = readl(UDE_VBT); | ||
789 | unifb_regs[8] = readl(UDE_VST); | ||
790 | unifb_regs[9] = readl(UDE_CFG); | ||
791 | |||
792 | if (mesg.event == dev->dev.power.power_state.event) | ||
793 | return 0; | ||
794 | |||
795 | switch (mesg.event) { | ||
796 | case PM_EVENT_FREEZE: /* about to take snapshot */ | ||
797 | case PM_EVENT_PRETHAW: /* before restoring snapshot */ | ||
798 | goto done; | ||
799 | } | ||
800 | |||
801 | console_lock(); | ||
802 | |||
803 | /* do nothing... */ | ||
804 | |||
805 | console_unlock(); | ||
806 | |||
807 | done: | ||
808 | dev->dev.power.power_state = mesg; | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | #else | ||
813 | #define unifb_resume NULL | ||
814 | #define unifb_suspend NULL | ||
815 | #endif | ||
816 | |||
817 | static struct platform_driver unifb_driver = { | ||
818 | .probe = unifb_probe, | ||
819 | .remove = unifb_remove, | ||
820 | .resume = unifb_resume, | ||
821 | .suspend = unifb_suspend, | ||
822 | .driver = { | ||
823 | .name = "PKUnity-v3-UNIGFX", | ||
824 | }, | ||
825 | }; | ||
826 | |||
827 | static int __init unifb_init(void) | ||
828 | { | ||
829 | #ifndef MODULE | ||
830 | if (fb_get_options("unifb", NULL)) | ||
831 | return -ENODEV; | ||
832 | #endif | ||
833 | |||
834 | return platform_driver_register(&unifb_driver); | ||
835 | } | ||
836 | |||
837 | module_init(unifb_init); | ||
838 | |||
839 | static void __exit unifb_exit(void) | ||
840 | { | ||
841 | platform_driver_unregister(&unifb_driver); | ||
842 | } | ||
843 | |||
844 | module_exit(unifb_exit); | ||
845 | |||
846 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 6739b2af3bc0..14102a3f70f5 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c | |||
@@ -893,8 +893,7 @@ static void ffb_init_fix(struct fb_info *info) | |||
893 | info->fix.accel = FB_ACCEL_SUN_CREATOR; | 893 | info->fix.accel = FB_ACCEL_SUN_CREATOR; |
894 | } | 894 | } |
895 | 895 | ||
896 | static int __devinit ffb_probe(struct platform_device *op, | 896 | static int __devinit ffb_probe(struct platform_device *op) |
897 | const struct of_device_id *match) | ||
898 | { | 897 | { |
899 | struct device_node *dp = op->dev.of_node; | 898 | struct device_node *dp = op->dev.of_node; |
900 | struct ffb_fbc __iomem *fbc; | 899 | struct ffb_fbc __iomem *fbc; |
@@ -1011,7 +1010,7 @@ out_dealloc_cmap: | |||
1011 | fb_dealloc_cmap(&info->cmap); | 1010 | fb_dealloc_cmap(&info->cmap); |
1012 | 1011 | ||
1013 | out_unmap_dac: | 1012 | out_unmap_dac: |
1014 | of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); | 1013 | of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac)); |
1015 | 1014 | ||
1016 | out_unmap_fbc: | 1015 | out_unmap_fbc: |
1017 | of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); | 1016 | of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); |
@@ -1052,7 +1051,7 @@ static const struct of_device_id ffb_match[] = { | |||
1052 | }; | 1051 | }; |
1053 | MODULE_DEVICE_TABLE(of, ffb_match); | 1052 | MODULE_DEVICE_TABLE(of, ffb_match); |
1054 | 1053 | ||
1055 | static struct of_platform_driver ffb_driver = { | 1054 | static struct platform_driver ffb_driver = { |
1056 | .driver = { | 1055 | .driver = { |
1057 | .name = "ffb", | 1056 | .name = "ffb", |
1058 | .owner = THIS_MODULE, | 1057 | .owner = THIS_MODULE, |
@@ -1067,12 +1066,12 @@ static int __init ffb_init(void) | |||
1067 | if (fb_get_options("ffb", NULL)) | 1066 | if (fb_get_options("ffb", NULL)) |
1068 | return -ENODEV; | 1067 | return -ENODEV; |
1069 | 1068 | ||
1070 | return of_register_platform_driver(&ffb_driver); | 1069 | return platform_driver_register(&ffb_driver); |
1071 | } | 1070 | } |
1072 | 1071 | ||
1073 | static void __exit ffb_exit(void) | 1072 | static void __exit ffb_exit(void) |
1074 | { | 1073 | { |
1075 | of_unregister_platform_driver(&ffb_driver); | 1074 | platform_driver_unregister(&ffb_driver); |
1076 | } | 1075 | } |
1077 | 1076 | ||
1078 | module_init(ffb_init); | 1077 | module_init(ffb_init); |
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 8bbbf08fa3ce..9048f87fa8c1 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -1487,8 +1487,7 @@ static ssize_t show_monitor(struct device *device, | |||
1487 | return diu_ops.show_monitor_port(machine_data->monitor_port, buf); | 1487 | return diu_ops.show_monitor_port(machine_data->monitor_port, buf); |
1488 | } | 1488 | } |
1489 | 1489 | ||
1490 | static int __devinit fsl_diu_probe(struct platform_device *ofdev, | 1490 | static int __devinit fsl_diu_probe(struct platform_device *ofdev) |
1491 | const struct of_device_id *match) | ||
1492 | { | 1491 | { |
1493 | struct device_node *np = ofdev->dev.of_node; | 1492 | struct device_node *np = ofdev->dev.of_node; |
1494 | struct mfb_info *mfbi; | 1493 | struct mfb_info *mfbi; |
@@ -1735,7 +1734,7 @@ static struct of_device_id fsl_diu_match[] = { | |||
1735 | }; | 1734 | }; |
1736 | MODULE_DEVICE_TABLE(of, fsl_diu_match); | 1735 | MODULE_DEVICE_TABLE(of, fsl_diu_match); |
1737 | 1736 | ||
1738 | static struct of_platform_driver fsl_diu_driver = { | 1737 | static struct platform_driver fsl_diu_driver = { |
1739 | .driver = { | 1738 | .driver = { |
1740 | .name = "fsl_diu", | 1739 | .name = "fsl_diu", |
1741 | .owner = THIS_MODULE, | 1740 | .owner = THIS_MODULE, |
@@ -1797,7 +1796,7 @@ static int __init fsl_diu_init(void) | |||
1797 | if (!coherence_data) | 1796 | if (!coherence_data) |
1798 | return -ENOMEM; | 1797 | return -ENOMEM; |
1799 | #endif | 1798 | #endif |
1800 | ret = of_register_platform_driver(&fsl_diu_driver); | 1799 | ret = platform_driver_register(&fsl_diu_driver); |
1801 | if (ret) { | 1800 | if (ret) { |
1802 | printk(KERN_ERR | 1801 | printk(KERN_ERR |
1803 | "fsl-diu: failed to register platform driver\n"); | 1802 | "fsl-diu: failed to register platform driver\n"); |
@@ -1811,7 +1810,7 @@ static int __init fsl_diu_init(void) | |||
1811 | 1810 | ||
1812 | static void __exit fsl_diu_exit(void) | 1811 | static void __exit fsl_diu_exit(void) |
1813 | { | 1812 | { |
1814 | of_unregister_platform_driver(&fsl_diu_driver); | 1813 | platform_driver_unregister(&fsl_diu_driver); |
1815 | #if defined(CONFIG_NOT_COHERENT_CACHE) | 1814 | #if defined(CONFIG_NOT_COHERENT_CACHE) |
1816 | vfree(coherence_data); | 1815 | vfree(coherence_data); |
1817 | #endif | 1816 | #endif |
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 | ||
300 | static struct platform_driver hecubafb_driver = { | 300 | static 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 | ||
350 | static struct dio_device_id hpfb_dio_tbl[] = { | 350 | static struct dio_device_id hpfb_dio_tbl[] = { |
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 | |||
4 | intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o | 4 | intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o |
5 | intelfb-objs := $(intelfb-y) | 5 | intelfb-objs := $(intelfb-y) |
6 | 6 | ||
7 | ifdef CONFIG_FB_INTEL_DEBUG | 7 | ccflags-$(CONFIG_FB_INTEL_DEBUG) := -DDEBUG -DREGDUMP |
8 | #EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP | ||
9 | EXTRA_CFLAGS += -DDEBUG -DREGDUMP | ||
10 | endif | ||
diff --git a/drivers/video/leo.c b/drivers/video/leo.c index b599e5e36ced..9e946e2c1da9 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c | |||
@@ -547,8 +547,7 @@ static void leo_unmap_regs(struct platform_device *op, struct fb_info *info, | |||
547 | of_iounmap(&op->resource[0], info->screen_base, 0x800000); | 547 | of_iounmap(&op->resource[0], info->screen_base, 0x800000); |
548 | } | 548 | } |
549 | 549 | ||
550 | static int __devinit leo_probe(struct platform_device *op, | 550 | static int __devinit leo_probe(struct platform_device *op) |
551 | const struct of_device_id *match) | ||
552 | { | 551 | { |
553 | struct device_node *dp = op->dev.of_node; | 552 | struct device_node *dp = op->dev.of_node; |
554 | struct fb_info *info; | 553 | struct fb_info *info; |
@@ -662,7 +661,7 @@ static const struct of_device_id leo_match[] = { | |||
662 | }; | 661 | }; |
663 | MODULE_DEVICE_TABLE(of, leo_match); | 662 | MODULE_DEVICE_TABLE(of, leo_match); |
664 | 663 | ||
665 | static struct of_platform_driver leo_driver = { | 664 | static struct platform_driver leo_driver = { |
666 | .driver = { | 665 | .driver = { |
667 | .name = "leo", | 666 | .name = "leo", |
668 | .owner = THIS_MODULE, | 667 | .owner = THIS_MODULE, |
@@ -677,12 +676,12 @@ static int __init leo_init(void) | |||
677 | if (fb_get_options("leofb", NULL)) | 676 | if (fb_get_options("leofb", NULL)) |
678 | return -ENODEV; | 677 | return -ENODEV; |
679 | 678 | ||
680 | return of_register_platform_driver(&leo_driver); | 679 | return platform_driver_register(&leo_driver); |
681 | } | 680 | } |
682 | 681 | ||
683 | static void __exit leo_exit(void) | 682 | static void __exit leo_exit(void) |
684 | { | 683 | { |
685 | of_unregister_platform_driver(&leo_driver); | 684 | platform_driver_unregister(&leo_driver); |
686 | } | 685 | } |
687 | 686 | ||
688 | module_init(leo_init); | 687 | module_init(leo_init); |
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 8c9dbac9dc1b..5ce6fa6e59f0 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c | |||
@@ -1458,13 +1458,6 @@ static struct board { | |||
1458 | MGA_G100, | 1458 | MGA_G100, |
1459 | &vbG100, | 1459 | &vbG100, |
1460 | "MGA-G100 (AGP)"}, | 1460 | "MGA-G100 (AGP)"}, |
1461 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, 0xFF, | ||
1462 | 0, 0, | ||
1463 | DEVF_G200, | ||
1464 | 230000, | ||
1465 | MGA_G200, | ||
1466 | &vbG200, | ||
1467 | "MGA-G200eV (PCI)"}, | ||
1468 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, | 1461 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, |
1469 | 0, 0, | 1462 | 0, 0, |
1470 | DEVF_G200, | 1463 | DEVF_G200, |
@@ -2116,8 +2109,6 @@ static struct pci_device_id matroxfb_devices[] = { | |||
2116 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2109 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2117 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, | 2110 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, |
2118 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2111 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2119 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, | ||
2120 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
2121 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, | 2112 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, |
2122 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2113 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2123 | {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/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index b1c4374cf940..c76e663a6cd4 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c | |||
@@ -550,8 +550,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par) | |||
550 | return 0; | 550 | return 0; |
551 | } | 551 | } |
552 | 552 | ||
553 | static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev, | 553 | static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev) |
554 | const struct of_device_id *id) | ||
555 | { | 554 | { |
556 | struct device_node *np = ofdev->dev.of_node; | 555 | struct device_node *np = ofdev->dev.of_node; |
557 | struct device *dev = &ofdev->dev; | 556 | struct device *dev = &ofdev->dev; |
@@ -717,7 +716,7 @@ static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { | |||
717 | { /* end */ } | 716 | { /* end */ } |
718 | }; | 717 | }; |
719 | 718 | ||
720 | static struct of_platform_driver of_platform_mb862xxfb_driver = { | 719 | static struct platform_driver of_platform_mb862xxfb_driver = { |
721 | .driver = { | 720 | .driver = { |
722 | .name = DRV_NAME, | 721 | .name = DRV_NAME, |
723 | .owner = THIS_MODULE, | 722 | .owner = THIS_MODULE, |
@@ -1038,7 +1037,7 @@ static int __devinit mb862xxfb_init(void) | |||
1038 | int ret = -ENODEV; | 1037 | int ret = -ENODEV; |
1039 | 1038 | ||
1040 | #if defined(CONFIG_FB_MB862XX_LIME) | 1039 | #if defined(CONFIG_FB_MB862XX_LIME) |
1041 | ret = of_register_platform_driver(&of_platform_mb862xxfb_driver); | 1040 | ret = platform_driver_register(&of_platform_mb862xxfb_driver); |
1042 | #endif | 1041 | #endif |
1043 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | 1042 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) |
1044 | ret = pci_register_driver(&mb862xxfb_pci_driver); | 1043 | ret = pci_register_driver(&mb862xxfb_pci_driver); |
@@ -1049,7 +1048,7 @@ static int __devinit mb862xxfb_init(void) | |||
1049 | static void __exit mb862xxfb_exit(void) | 1048 | static void __exit mb862xxfb_exit(void) |
1050 | { | 1049 | { |
1051 | #if defined(CONFIG_FB_MB862XX_LIME) | 1050 | #if defined(CONFIG_FB_MB862XX_LIME) |
1052 | of_unregister_platform_driver(&of_platform_mb862xxfb_driver); | 1051 | platform_driver_unregister(&of_platform_mb862xxfb_driver); |
1053 | #endif | 1052 | #endif |
1054 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | 1053 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) |
1055 | pci_unregister_driver(&mb862xxfb_pci_driver); | 1054 | pci_unregister_driver(&mb862xxfb_pci_driver); |
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 | ||
766 | static struct platform_driver metronomefb_driver = { | 766 | static 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/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h index 4e3deb4e592b..d80477415caa 100644 --- a/drivers/video/msm/mdp_hw.h +++ b/drivers/video/msm/mdp_hw.h | |||
@@ -449,6 +449,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | |||
449 | #define PPP_CFG_MDP_XRGB_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) | 449 | #define PPP_CFG_MDP_XRGB_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) |
450 | #define PPP_CFG_MDP_RGBA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) | 450 | #define PPP_CFG_MDP_RGBA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) |
451 | #define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) | 451 | #define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) |
452 | #define PPP_CFG_MDP_RGBX_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) | ||
452 | 453 | ||
453 | #define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \ | 454 | #define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \ |
454 | PPP_##dir##_C0G_8BIT | \ | 455 | PPP_##dir##_C0G_8BIT | \ |
@@ -488,12 +489,14 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | |||
488 | MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8) | 489 | MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8) |
489 | #define PPP_PACK_PATTERN_MDP_RGB_888 PPP_PACK_PATTERN_MDP_RGB_565 | 490 | #define PPP_PACK_PATTERN_MDP_RGB_888 PPP_PACK_PATTERN_MDP_RGB_565 |
490 | #define PPP_PACK_PATTERN_MDP_XRGB_8888 \ | 491 | #define PPP_PACK_PATTERN_MDP_XRGB_8888 \ |
491 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8) | 492 | MDP_GET_PACK_PATTERN(CLR_B, CLR_G, CLR_R, CLR_ALPHA, 8) |
492 | #define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888 | 493 | #define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888 |
493 | #define PPP_PACK_PATTERN_MDP_RGBA_8888 \ | 494 | #define PPP_PACK_PATTERN_MDP_RGBA_8888 \ |
494 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8) | 495 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8) |
495 | #define PPP_PACK_PATTERN_MDP_BGRA_8888 \ | 496 | #define PPP_PACK_PATTERN_MDP_BGRA_8888 \ |
496 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8) | 497 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8) |
498 | #define PPP_PACK_PATTERN_MDP_RGBX_8888 \ | ||
499 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8) | ||
497 | #define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \ | 500 | #define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \ |
498 | MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8) | 501 | MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8) |
499 | #define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V2 PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 | 502 | #define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V2 PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 |
@@ -509,6 +512,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | |||
509 | #define PPP_CHROMA_SAMP_MDP_ARGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB | 512 | #define PPP_CHROMA_SAMP_MDP_ARGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB |
510 | #define PPP_CHROMA_SAMP_MDP_RGBA_8888(dir) PPP_OP_##dir##_CHROMA_RGB | 513 | #define PPP_CHROMA_SAMP_MDP_RGBA_8888(dir) PPP_OP_##dir##_CHROMA_RGB |
511 | #define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB | 514 | #define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB |
515 | #define PPP_CHROMA_SAMP_MDP_RGBX_8888(dir) PPP_OP_##dir##_CHROMA_RGB | ||
512 | #define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 | 516 | #define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 |
513 | #define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V2(dir) PPP_OP_##dir##_CHROMA_420 | 517 | #define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V2(dir) PPP_OP_##dir##_CHROMA_420 |
514 | #define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 | 518 | #define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 |
@@ -523,6 +527,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | |||
523 | [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\ | 527 | [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\ |
524 | [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\ | 528 | [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\ |
525 | [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\ | 529 | [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\ |
530 | [MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888,\ | ||
526 | [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\ | 531 | [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\ |
527 | [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\ | 532 | [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\ |
528 | [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\ | 533 | [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\ |
@@ -536,6 +541,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | |||
536 | [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\ | 541 | [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\ |
537 | [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\ | 542 | [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\ |
538 | [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\ | 543 | [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\ |
544 | [MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888(dir),\ | ||
539 | [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\ | 545 | [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\ |
540 | [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\ | 546 | [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\ |
541 | [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\ | 547 | [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\ |
@@ -547,7 +553,8 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | |||
547 | (img == MDP_YCRYCB_H2V1)) | 553 | (img == MDP_YCRYCB_H2V1)) |
548 | #define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \ | 554 | #define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \ |
549 | (img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ | 555 | (img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ |
550 | (img == MDP_XRGB_8888) | (img == MDP_BGRA_8888)) | 556 | (img == MDP_XRGB_8888) | (img == MDP_BGRA_8888) | \ |
557 | (img == MDP_RGBX_8888)) | ||
551 | #define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ | 558 | #define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ |
552 | (img == MDP_BGRA_8888)) | 559 | (img == MDP_BGRA_8888)) |
553 | 560 | ||
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c index 4ff001f4cbbd..2b6564e8bfea 100644 --- a/drivers/video/msm/mdp_ppp.c +++ b/drivers/video/msm/mdp_ppp.c | |||
@@ -69,6 +69,7 @@ static uint32_t bytes_per_pixel[] = { | |||
69 | [MDP_ARGB_8888] = 4, | 69 | [MDP_ARGB_8888] = 4, |
70 | [MDP_RGBA_8888] = 4, | 70 | [MDP_RGBA_8888] = 4, |
71 | [MDP_BGRA_8888] = 4, | 71 | [MDP_BGRA_8888] = 4, |
72 | [MDP_RGBX_8888] = 4, | ||
72 | [MDP_Y_CBCR_H2V1] = 1, | 73 | [MDP_Y_CBCR_H2V1] = 1, |
73 | [MDP_Y_CBCR_H2V2] = 1, | 74 | [MDP_Y_CBCR_H2V2] = 1, |
74 | [MDP_Y_CRCB_H2V1] = 1, | 75 | [MDP_Y_CRCB_H2V1] = 1, |
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c index debe5933fd2e..ec351309e607 100644 --- a/drivers/video/msm/msm_fb.c +++ b/drivers/video/msm/msm_fb.c | |||
@@ -81,7 +81,6 @@ struct msmfb_info { | |||
81 | spinlock_t update_lock; | 81 | spinlock_t update_lock; |
82 | struct mutex panel_init_lock; | 82 | struct mutex panel_init_lock; |
83 | wait_queue_head_t frame_wq; | 83 | wait_queue_head_t frame_wq; |
84 | struct workqueue_struct *resume_workqueue; | ||
85 | struct work_struct resume_work; | 84 | struct work_struct resume_work; |
86 | struct msmfb_callback dma_callback; | 85 | struct msmfb_callback dma_callback; |
87 | struct msmfb_callback vsync_callback; | 86 | struct msmfb_callback vsync_callback; |
@@ -111,7 +110,7 @@ static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback) | |||
111 | if (msmfb->sleeping == UPDATING && | 110 | if (msmfb->sleeping == UPDATING && |
112 | msmfb->frame_done == msmfb->update_frame) { | 111 | msmfb->frame_done == msmfb->update_frame) { |
113 | DLOG(SUSPEND_RESUME, "full update completed\n"); | 112 | DLOG(SUSPEND_RESUME, "full update completed\n"); |
114 | queue_work(msmfb->resume_workqueue, &msmfb->resume_work); | 113 | schedule_work(&msmfb->resume_work); |
115 | } | 114 | } |
116 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | 115 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); |
117 | wake_up(&msmfb->frame_wq); | 116 | wake_up(&msmfb->frame_wq); |
@@ -220,8 +219,8 @@ restart: | |||
220 | 219 | ||
221 | sleeping = msmfb->sleeping; | 220 | sleeping = msmfb->sleeping; |
222 | /* on a full update, if the last frame has not completed, wait for it */ | 221 | /* on a full update, if the last frame has not completed, wait for it */ |
223 | if (pan_display && (msmfb->frame_requested != msmfb->frame_done || | 222 | if ((pan_display && msmfb->frame_requested != msmfb->frame_done) || |
224 | sleeping == UPDATING)) { | 223 | sleeping == UPDATING) { |
225 | int ret; | 224 | int ret; |
226 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | 225 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); |
227 | ret = wait_event_interruptible_timeout(msmfb->frame_wq, | 226 | ret = wait_event_interruptible_timeout(msmfb->frame_wq, |
@@ -470,6 +469,18 @@ static void setup_fb_info(struct msmfb_info *msmfb) | |||
470 | fb_info->var.yoffset = 0; | 469 | fb_info->var.yoffset = 0; |
471 | 470 | ||
472 | if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) { | 471 | if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) { |
472 | /* | ||
473 | * Set the param in the fixed screen, so userspace can't | ||
474 | * change it. This will be used to check for the | ||
475 | * capability. | ||
476 | */ | ||
477 | fb_info->fix.reserved[0] = 0x5444; | ||
478 | fb_info->fix.reserved[1] = 0x5055; | ||
479 | |||
480 | /* | ||
481 | * This preloads the value so that if userspace doesn't | ||
482 | * change it, it will be a full update | ||
483 | */ | ||
473 | fb_info->var.reserved[0] = 0x54445055; | 484 | fb_info->var.reserved[0] = 0x54445055; |
474 | fb_info->var.reserved[1] = 0; | 485 | fb_info->var.reserved[1] = 0; |
475 | fb_info->var.reserved[2] = (uint16_t)msmfb->xres | | 486 | fb_info->var.reserved[2] = (uint16_t)msmfb->xres | |
@@ -559,12 +570,6 @@ static int msmfb_probe(struct platform_device *pdev) | |||
559 | spin_lock_init(&msmfb->update_lock); | 570 | spin_lock_init(&msmfb->update_lock); |
560 | mutex_init(&msmfb->panel_init_lock); | 571 | mutex_init(&msmfb->panel_init_lock); |
561 | init_waitqueue_head(&msmfb->frame_wq); | 572 | init_waitqueue_head(&msmfb->frame_wq); |
562 | msmfb->resume_workqueue = create_workqueue("panel_on"); | ||
563 | if (msmfb->resume_workqueue == NULL) { | ||
564 | printk(KERN_ERR "failed to create panel_on workqueue\n"); | ||
565 | ret = -ENOMEM; | ||
566 | goto error_create_workqueue; | ||
567 | } | ||
568 | INIT_WORK(&msmfb->resume_work, power_on_panel); | 573 | INIT_WORK(&msmfb->resume_work, power_on_panel); |
569 | msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres, | 574 | msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres, |
570 | GFP_KERNEL); | 575 | GFP_KERNEL); |
@@ -589,8 +594,6 @@ static int msmfb_probe(struct platform_device *pdev) | |||
589 | return 0; | 594 | return 0; |
590 | 595 | ||
591 | error_register_framebuffer: | 596 | error_register_framebuffer: |
592 | destroy_workqueue(msmfb->resume_workqueue); | ||
593 | error_create_workqueue: | ||
594 | iounmap(fb->screen_base); | 597 | iounmap(fb->screen_base); |
595 | error_setup_fbmem: | 598 | error_setup_fbmem: |
596 | framebuffer_release(msmfb->fb); | 599 | framebuffer_release(msmfb->fb); |
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c new file mode 100644 index 000000000000..7d0284882984 --- /dev/null +++ b/drivers/video/mxsfb.c | |||
@@ -0,0 +1,919 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Juergen Beisert, Pengutronix | ||
3 | * | ||
4 | * This code is based on: | ||
5 | * Author: Vitaly Wool <vital@embeddedalley.com> | ||
6 | * | ||
7 | * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. | ||
8 | * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #define DRIVER_NAME "mxsfb" | ||
21 | |||
22 | /** | ||
23 | * @file | ||
24 | * @brief LCDIF driver for i.MX23 and i.MX28 | ||
25 | * | ||
26 | * The LCDIF support four modes of operation | ||
27 | * - MPU interface (to drive smart displays) -> not supported yet | ||
28 | * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet | ||
29 | * - Dotclock interface (to drive LC displays with RGB data and sync signals) | ||
30 | * - DVI (to drive ITU-R BT656) -> not supported yet | ||
31 | * | ||
32 | * This driver depends on a correct setup of the pins used for this purpose | ||
33 | * (platform specific). | ||
34 | * | ||
35 | * For the developer: Don't forget to set the data bus width to the display | ||
36 | * in the imx_fb_videomode structure. You will else end up with ugly colours. | ||
37 | * If you fight against jitter you can vary the clock delay. This is a feature | ||
38 | * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give | ||
39 | * the required value in the imx_fb_videomode structure. | ||
40 | */ | ||
41 | |||
42 | #include <linux/kernel.h> | ||
43 | #include <linux/platform_device.h> | ||
44 | #include <linux/clk.h> | ||
45 | #include <linux/dma-mapping.h> | ||
46 | #include <linux/io.h> | ||
47 | #include <mach/mxsfb.h> | ||
48 | |||
49 | #define REG_SET 4 | ||
50 | #define REG_CLR 8 | ||
51 | |||
52 | #define LCDC_CTRL 0x00 | ||
53 | #define LCDC_CTRL1 0x10 | ||
54 | #define LCDC_V4_CTRL2 0x20 | ||
55 | #define LCDC_V3_TRANSFER_COUNT 0x20 | ||
56 | #define LCDC_V4_TRANSFER_COUNT 0x30 | ||
57 | #define LCDC_V4_CUR_BUF 0x40 | ||
58 | #define LCDC_V4_NEXT_BUF 0x50 | ||
59 | #define LCDC_V3_CUR_BUF 0x30 | ||
60 | #define LCDC_V3_NEXT_BUF 0x40 | ||
61 | #define LCDC_TIMING 0x60 | ||
62 | #define LCDC_VDCTRL0 0x70 | ||
63 | #define LCDC_VDCTRL1 0x80 | ||
64 | #define LCDC_VDCTRL2 0x90 | ||
65 | #define LCDC_VDCTRL3 0xa0 | ||
66 | #define LCDC_VDCTRL4 0xb0 | ||
67 | #define LCDC_DVICTRL0 0xc0 | ||
68 | #define LCDC_DVICTRL1 0xd0 | ||
69 | #define LCDC_DVICTRL2 0xe0 | ||
70 | #define LCDC_DVICTRL3 0xf0 | ||
71 | #define LCDC_DVICTRL4 0x100 | ||
72 | #define LCDC_V4_DATA 0x180 | ||
73 | #define LCDC_V3_DATA 0x1b0 | ||
74 | #define LCDC_V4_DEBUG0 0x1d0 | ||
75 | #define LCDC_V3_DEBUG0 0x1f0 | ||
76 | |||
77 | #define CTRL_SFTRST (1 << 31) | ||
78 | #define CTRL_CLKGATE (1 << 30) | ||
79 | #define CTRL_BYPASS_COUNT (1 << 19) | ||
80 | #define CTRL_VSYNC_MODE (1 << 18) | ||
81 | #define CTRL_DOTCLK_MODE (1 << 17) | ||
82 | #define CTRL_DATA_SELECT (1 << 16) | ||
83 | #define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10) | ||
84 | #define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3) | ||
85 | #define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8) | ||
86 | #define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3) | ||
87 | #define CTRL_MASTER (1 << 5) | ||
88 | #define CTRL_DF16 (1 << 3) | ||
89 | #define CTRL_DF18 (1 << 2) | ||
90 | #define CTRL_DF24 (1 << 1) | ||
91 | #define CTRL_RUN (1 << 0) | ||
92 | |||
93 | #define CTRL1_FIFO_CLEAR (1 << 21) | ||
94 | #define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16) | ||
95 | #define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf) | ||
96 | |||
97 | #define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16) | ||
98 | #define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff) | ||
99 | #define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff) | ||
100 | #define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff) | ||
101 | |||
102 | |||
103 | #define VDCTRL0_ENABLE_PRESENT (1 << 28) | ||
104 | #define VDCTRL0_VSYNC_ACT_HIGH (1 << 27) | ||
105 | #define VDCTRL0_HSYNC_ACT_HIGH (1 << 26) | ||
106 | #define VDCTRL0_DOTCLK_ACT_FAILING (1 << 25) | ||
107 | #define VDCTRL0_ENABLE_ACT_HIGH (1 << 24) | ||
108 | #define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21) | ||
109 | #define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20) | ||
110 | #define VDCTRL0_HALF_LINE (1 << 19) | ||
111 | #define VDCTRL0_HALF_LINE_MODE (1 << 18) | ||
112 | #define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff) | ||
113 | #define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff) | ||
114 | |||
115 | #define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff) | ||
116 | #define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff) | ||
117 | |||
118 | #define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29) | ||
119 | #define VDCTRL3_VSYNC_ONLY (1 << 28) | ||
120 | #define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16) | ||
121 | #define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff) | ||
122 | #define SET_VERT_WAIT_CNT(x) ((x) & 0xffff) | ||
123 | #define GET_VERT_WAIT_CNT(x) ((x) & 0xffff) | ||
124 | |||
125 | #define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */ | ||
126 | #define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */ | ||
127 | #define VDCTRL4_SYNC_SIGNALS_ON (1 << 18) | ||
128 | #define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff) | ||
129 | |||
130 | #define DEBUG0_HSYNC (1 < 26) | ||
131 | #define DEBUG0_VSYNC (1 < 25) | ||
132 | |||
133 | #define MIN_XRES 120 | ||
134 | #define MIN_YRES 120 | ||
135 | |||
136 | #define RED 0 | ||
137 | #define GREEN 1 | ||
138 | #define BLUE 2 | ||
139 | #define TRANSP 3 | ||
140 | |||
141 | enum mxsfb_devtype { | ||
142 | MXSFB_V3, | ||
143 | MXSFB_V4, | ||
144 | }; | ||
145 | |||
146 | /* CPU dependent register offsets */ | ||
147 | struct mxsfb_devdata { | ||
148 | unsigned transfer_count; | ||
149 | unsigned cur_buf; | ||
150 | unsigned next_buf; | ||
151 | unsigned debug0; | ||
152 | unsigned hs_wdth_mask; | ||
153 | unsigned hs_wdth_shift; | ||
154 | unsigned ipversion; | ||
155 | }; | ||
156 | |||
157 | struct mxsfb_info { | ||
158 | struct fb_info fb_info; | ||
159 | struct platform_device *pdev; | ||
160 | struct clk *clk; | ||
161 | void __iomem *base; /* registers */ | ||
162 | unsigned allocated_size; | ||
163 | int enabled; | ||
164 | unsigned ld_intf_width; | ||
165 | unsigned dotclk_delay; | ||
166 | const struct mxsfb_devdata *devdata; | ||
167 | int mapped; | ||
168 | }; | ||
169 | |||
170 | #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) | ||
171 | #define mxsfb_is_v4(host) (host->devdata->ipversion == 4) | ||
172 | |||
173 | static const struct mxsfb_devdata mxsfb_devdata[] = { | ||
174 | [MXSFB_V3] = { | ||
175 | .transfer_count = LCDC_V3_TRANSFER_COUNT, | ||
176 | .cur_buf = LCDC_V3_CUR_BUF, | ||
177 | .next_buf = LCDC_V3_NEXT_BUF, | ||
178 | .debug0 = LCDC_V3_DEBUG0, | ||
179 | .hs_wdth_mask = 0xff, | ||
180 | .hs_wdth_shift = 24, | ||
181 | .ipversion = 3, | ||
182 | }, | ||
183 | [MXSFB_V4] = { | ||
184 | .transfer_count = LCDC_V4_TRANSFER_COUNT, | ||
185 | .cur_buf = LCDC_V4_CUR_BUF, | ||
186 | .next_buf = LCDC_V4_NEXT_BUF, | ||
187 | .debug0 = LCDC_V4_DEBUG0, | ||
188 | .hs_wdth_mask = 0x3fff, | ||
189 | .hs_wdth_shift = 18, | ||
190 | .ipversion = 4, | ||
191 | }, | ||
192 | }; | ||
193 | |||
194 | #define to_imxfb_host(x) (container_of(x, struct mxsfb_info, fb_info)) | ||
195 | |||
196 | /* mask and shift depends on architecture */ | ||
197 | static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val) | ||
198 | { | ||
199 | return (val & host->devdata->hs_wdth_mask) << | ||
200 | host->devdata->hs_wdth_shift; | ||
201 | } | ||
202 | |||
203 | static inline u32 get_hsync_pulse_width(struct mxsfb_info *host, unsigned val) | ||
204 | { | ||
205 | return (val >> host->devdata->hs_wdth_shift) & | ||
206 | host->devdata->hs_wdth_mask; | ||
207 | } | ||
208 | |||
209 | static const struct fb_bitfield def_rgb565[] = { | ||
210 | [RED] = { | ||
211 | .offset = 11, | ||
212 | .length = 5, | ||
213 | }, | ||
214 | [GREEN] = { | ||
215 | .offset = 5, | ||
216 | .length = 6, | ||
217 | }, | ||
218 | [BLUE] = { | ||
219 | .offset = 0, | ||
220 | .length = 5, | ||
221 | }, | ||
222 | [TRANSP] = { /* no support for transparency */ | ||
223 | .length = 0, | ||
224 | } | ||
225 | }; | ||
226 | |||
227 | static const struct fb_bitfield def_rgb666[] = { | ||
228 | [RED] = { | ||
229 | .offset = 16, | ||
230 | .length = 6, | ||
231 | }, | ||
232 | [GREEN] = { | ||
233 | .offset = 8, | ||
234 | .length = 6, | ||
235 | }, | ||
236 | [BLUE] = { | ||
237 | .offset = 0, | ||
238 | .length = 6, | ||
239 | }, | ||
240 | [TRANSP] = { /* no support for transparency */ | ||
241 | .length = 0, | ||
242 | } | ||
243 | }; | ||
244 | |||
245 | static const struct fb_bitfield def_rgb888[] = { | ||
246 | [RED] = { | ||
247 | .offset = 16, | ||
248 | .length = 8, | ||
249 | }, | ||
250 | [GREEN] = { | ||
251 | .offset = 8, | ||
252 | .length = 8, | ||
253 | }, | ||
254 | [BLUE] = { | ||
255 | .offset = 0, | ||
256 | .length = 8, | ||
257 | }, | ||
258 | [TRANSP] = { /* no support for transparency */ | ||
259 | .length = 0, | ||
260 | } | ||
261 | }; | ||
262 | |||
263 | static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf) | ||
264 | { | ||
265 | chan &= 0xffff; | ||
266 | chan >>= 16 - bf->length; | ||
267 | return chan << bf->offset; | ||
268 | } | ||
269 | |||
270 | static int mxsfb_check_var(struct fb_var_screeninfo *var, | ||
271 | struct fb_info *fb_info) | ||
272 | { | ||
273 | struct mxsfb_info *host = to_imxfb_host(fb_info); | ||
274 | const struct fb_bitfield *rgb = NULL; | ||
275 | |||
276 | if (var->xres < MIN_XRES) | ||
277 | var->xres = MIN_XRES; | ||
278 | if (var->yres < MIN_YRES) | ||
279 | var->yres = MIN_YRES; | ||
280 | |||
281 | var->xres_virtual = var->xres; | ||
282 | |||
283 | var->yres_virtual = var->yres; | ||
284 | |||
285 | switch (var->bits_per_pixel) { | ||
286 | case 16: | ||
287 | /* always expect RGB 565 */ | ||
288 | rgb = def_rgb565; | ||
289 | break; | ||
290 | case 32: | ||
291 | switch (host->ld_intf_width) { | ||
292 | case STMLCDIF_8BIT: | ||
293 | pr_debug("Unsupported LCD bus width mapping\n"); | ||
294 | break; | ||
295 | case STMLCDIF_16BIT: | ||
296 | case STMLCDIF_18BIT: | ||
297 | /* 24 bit to 18 bit mapping */ | ||
298 | rgb = def_rgb666; | ||
299 | break; | ||
300 | case STMLCDIF_24BIT: | ||
301 | /* real 24 bit */ | ||
302 | rgb = def_rgb888; | ||
303 | break; | ||
304 | } | ||
305 | break; | ||
306 | default: | ||
307 | pr_debug("Unsupported colour depth: %u\n", var->bits_per_pixel); | ||
308 | return -EINVAL; | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * Copy the RGB parameters for this display | ||
313 | * from the machine specific parameters. | ||
314 | */ | ||
315 | var->red = rgb[RED]; | ||
316 | var->green = rgb[GREEN]; | ||
317 | var->blue = rgb[BLUE]; | ||
318 | var->transp = rgb[TRANSP]; | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static void mxsfb_enable_controller(struct fb_info *fb_info) | ||
324 | { | ||
325 | struct mxsfb_info *host = to_imxfb_host(fb_info); | ||
326 | u32 reg; | ||
327 | |||
328 | dev_dbg(&host->pdev->dev, "%s\n", __func__); | ||
329 | |||
330 | clk_enable(host->clk); | ||
331 | clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); | ||
332 | |||
333 | /* if it was disabled, re-enable the mode again */ | ||
334 | writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET); | ||
335 | |||
336 | /* enable the SYNC signals first, then the DMA engine */ | ||
337 | reg = readl(host->base + LCDC_VDCTRL4); | ||
338 | reg |= VDCTRL4_SYNC_SIGNALS_ON; | ||
339 | writel(reg, host->base + LCDC_VDCTRL4); | ||
340 | |||
341 | writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET); | ||
342 | |||
343 | host->enabled = 1; | ||
344 | } | ||
345 | |||
346 | static void mxsfb_disable_controller(struct fb_info *fb_info) | ||
347 | { | ||
348 | struct mxsfb_info *host = to_imxfb_host(fb_info); | ||
349 | unsigned loop; | ||
350 | u32 reg; | ||
351 | |||
352 | dev_dbg(&host->pdev->dev, "%s\n", __func__); | ||
353 | |||
354 | /* | ||
355 | * Even if we disable the controller here, it will still continue | ||
356 | * until its FIFOs are running out of data | ||
357 | */ | ||
358 | writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_CLR); | ||
359 | |||
360 | loop = 1000; | ||
361 | while (loop) { | ||
362 | reg = readl(host->base + LCDC_CTRL); | ||
363 | if (!(reg & CTRL_RUN)) | ||
364 | break; | ||
365 | loop--; | ||
366 | } | ||
367 | |||
368 | writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR); | ||
369 | |||
370 | clk_disable(host->clk); | ||
371 | |||
372 | host->enabled = 0; | ||
373 | } | ||
374 | |||
375 | static int mxsfb_set_par(struct fb_info *fb_info) | ||
376 | { | ||
377 | struct mxsfb_info *host = to_imxfb_host(fb_info); | ||
378 | u32 ctrl, vdctrl0, vdctrl4; | ||
379 | int line_size, fb_size; | ||
380 | int reenable = 0; | ||
381 | |||
382 | line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3); | ||
383 | fb_size = fb_info->var.yres_virtual * line_size; | ||
384 | |||
385 | if (fb_size > fb_info->fix.smem_len) | ||
386 | return -ENOMEM; | ||
387 | |||
388 | fb_info->fix.line_length = line_size; | ||
389 | |||
390 | /* | ||
391 | * It seems, you can't re-program the controller if it is still running. | ||
392 | * This may lead into shifted pictures (FIFO issue?). | ||
393 | * So, first stop the controller and drain its FIFOs | ||
394 | */ | ||
395 | if (host->enabled) { | ||
396 | reenable = 1; | ||
397 | mxsfb_disable_controller(fb_info); | ||
398 | } | ||
399 | |||
400 | /* clear the FIFOs */ | ||
401 | writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET); | ||
402 | |||
403 | ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER | | ||
404 | CTRL_SET_BUS_WIDTH(host->ld_intf_width);; | ||
405 | |||
406 | switch (fb_info->var.bits_per_pixel) { | ||
407 | case 16: | ||
408 | dev_dbg(&host->pdev->dev, "Setting up RGB565 mode\n"); | ||
409 | ctrl |= CTRL_SET_WORD_LENGTH(0); | ||
410 | writel(CTRL1_SET_BYTE_PACKAGING(0xf), host->base + LCDC_CTRL1); | ||
411 | break; | ||
412 | case 32: | ||
413 | dev_dbg(&host->pdev->dev, "Setting up RGB888/666 mode\n"); | ||
414 | ctrl |= CTRL_SET_WORD_LENGTH(3); | ||
415 | switch (host->ld_intf_width) { | ||
416 | case STMLCDIF_8BIT: | ||
417 | dev_dbg(&host->pdev->dev, | ||
418 | "Unsupported LCD bus width mapping\n"); | ||
419 | return -EINVAL; | ||
420 | case STMLCDIF_16BIT: | ||
421 | case STMLCDIF_18BIT: | ||
422 | /* 24 bit to 18 bit mapping */ | ||
423 | ctrl |= CTRL_DF24; /* ignore the upper 2 bits in | ||
424 | * each colour component | ||
425 | */ | ||
426 | break; | ||
427 | case STMLCDIF_24BIT: | ||
428 | /* real 24 bit */ | ||
429 | break; | ||
430 | } | ||
431 | /* do not use packed pixels = one pixel per word instead */ | ||
432 | writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1); | ||
433 | break; | ||
434 | default: | ||
435 | dev_dbg(&host->pdev->dev, "Unhandled color depth of %u\n", | ||
436 | fb_info->var.bits_per_pixel); | ||
437 | return -EINVAL; | ||
438 | } | ||
439 | |||
440 | writel(ctrl, host->base + LCDC_CTRL); | ||
441 | |||
442 | writel(TRANSFER_COUNT_SET_VCOUNT(fb_info->var.yres) | | ||
443 | TRANSFER_COUNT_SET_HCOUNT(fb_info->var.xres), | ||
444 | host->base + host->devdata->transfer_count); | ||
445 | |||
446 | vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* always in DOTCLOCK mode */ | ||
447 | VDCTRL0_VSYNC_PERIOD_UNIT | | ||
448 | VDCTRL0_VSYNC_PULSE_WIDTH_UNIT | | ||
449 | VDCTRL0_SET_VSYNC_PULSE_WIDTH(fb_info->var.vsync_len); | ||
450 | if (fb_info->var.sync & FB_SYNC_HOR_HIGH_ACT) | ||
451 | vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH; | ||
452 | if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT) | ||
453 | vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; | ||
454 | if (fb_info->var.sync & FB_SYNC_DATA_ENABLE_HIGH_ACT) | ||
455 | vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; | ||
456 | if (fb_info->var.sync & FB_SYNC_DOTCLK_FAILING_ACT) | ||
457 | vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING; | ||
458 | |||
459 | writel(vdctrl0, host->base + LCDC_VDCTRL0); | ||
460 | |||
461 | /* frame length in lines */ | ||
462 | writel(fb_info->var.upper_margin + fb_info->var.vsync_len + | ||
463 | fb_info->var.lower_margin + fb_info->var.yres, | ||
464 | host->base + LCDC_VDCTRL1); | ||
465 | |||
466 | /* line length in units of clocks or pixels */ | ||
467 | writel(set_hsync_pulse_width(host, fb_info->var.hsync_len) | | ||
468 | VDCTRL2_SET_HSYNC_PERIOD(fb_info->var.left_margin + | ||
469 | fb_info->var.hsync_len + fb_info->var.right_margin + | ||
470 | fb_info->var.xres), | ||
471 | host->base + LCDC_VDCTRL2); | ||
472 | |||
473 | writel(SET_HOR_WAIT_CNT(fb_info->var.left_margin + | ||
474 | fb_info->var.hsync_len) | | ||
475 | SET_VERT_WAIT_CNT(fb_info->var.upper_margin + | ||
476 | fb_info->var.vsync_len), | ||
477 | host->base + LCDC_VDCTRL3); | ||
478 | |||
479 | vdctrl4 = SET_DOTCLK_H_VALID_DATA_CNT(fb_info->var.xres); | ||
480 | if (mxsfb_is_v4(host)) | ||
481 | vdctrl4 |= VDCTRL4_SET_DOTCLK_DLY(host->dotclk_delay); | ||
482 | writel(vdctrl4, host->base + LCDC_VDCTRL4); | ||
483 | |||
484 | writel(fb_info->fix.smem_start + | ||
485 | fb_info->fix.line_length * fb_info->var.yoffset, | ||
486 | host->base + host->devdata->next_buf); | ||
487 | |||
488 | if (reenable) | ||
489 | mxsfb_enable_controller(fb_info); | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static int mxsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
495 | u_int transp, struct fb_info *fb_info) | ||
496 | { | ||
497 | unsigned int val; | ||
498 | int ret = -EINVAL; | ||
499 | |||
500 | /* | ||
501 | * If greyscale is true, then we convert the RGB value | ||
502 | * to greyscale no matter what visual we are using. | ||
503 | */ | ||
504 | if (fb_info->var.grayscale) | ||
505 | red = green = blue = (19595 * red + 38470 * green + | ||
506 | 7471 * blue) >> 16; | ||
507 | |||
508 | switch (fb_info->fix.visual) { | ||
509 | case FB_VISUAL_TRUECOLOR: | ||
510 | /* | ||
511 | * 12 or 16-bit True Colour. We encode the RGB value | ||
512 | * according to the RGB bitfield information. | ||
513 | */ | ||
514 | if (regno < 16) { | ||
515 | u32 *pal = fb_info->pseudo_palette; | ||
516 | |||
517 | val = chan_to_field(red, &fb_info->var.red); | ||
518 | val |= chan_to_field(green, &fb_info->var.green); | ||
519 | val |= chan_to_field(blue, &fb_info->var.blue); | ||
520 | |||
521 | pal[regno] = val; | ||
522 | ret = 0; | ||
523 | } | ||
524 | break; | ||
525 | |||
526 | case FB_VISUAL_STATIC_PSEUDOCOLOR: | ||
527 | case FB_VISUAL_PSEUDOCOLOR: | ||
528 | break; | ||
529 | } | ||
530 | |||
531 | return ret; | ||
532 | } | ||
533 | |||
534 | static int mxsfb_blank(int blank, struct fb_info *fb_info) | ||
535 | { | ||
536 | struct mxsfb_info *host = to_imxfb_host(fb_info); | ||
537 | |||
538 | switch (blank) { | ||
539 | case FB_BLANK_POWERDOWN: | ||
540 | case FB_BLANK_VSYNC_SUSPEND: | ||
541 | case FB_BLANK_HSYNC_SUSPEND: | ||
542 | case FB_BLANK_NORMAL: | ||
543 | if (host->enabled) | ||
544 | mxsfb_disable_controller(fb_info); | ||
545 | break; | ||
546 | |||
547 | case FB_BLANK_UNBLANK: | ||
548 | if (!host->enabled) | ||
549 | mxsfb_enable_controller(fb_info); | ||
550 | break; | ||
551 | } | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static int mxsfb_pan_display(struct fb_var_screeninfo *var, | ||
556 | struct fb_info *fb_info) | ||
557 | { | ||
558 | struct mxsfb_info *host = to_imxfb_host(fb_info); | ||
559 | unsigned offset; | ||
560 | |||
561 | if (var->xoffset != 0) | ||
562 | return -EINVAL; | ||
563 | |||
564 | offset = fb_info->fix.line_length * var->yoffset; | ||
565 | |||
566 | /* update on next VSYNC */ | ||
567 | writel(fb_info->fix.smem_start + offset, | ||
568 | host->base + host->devdata->next_buf); | ||
569 | |||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static struct fb_ops mxsfb_ops = { | ||
574 | .owner = THIS_MODULE, | ||
575 | .fb_check_var = mxsfb_check_var, | ||
576 | .fb_set_par = mxsfb_set_par, | ||
577 | .fb_setcolreg = mxsfb_setcolreg, | ||
578 | .fb_blank = mxsfb_blank, | ||
579 | .fb_pan_display = mxsfb_pan_display, | ||
580 | .fb_fillrect = cfb_fillrect, | ||
581 | .fb_copyarea = cfb_copyarea, | ||
582 | .fb_imageblit = cfb_imageblit, | ||
583 | }; | ||
584 | |||
585 | static int __devinit mxsfb_restore_mode(struct mxsfb_info *host) | ||
586 | { | ||
587 | struct fb_info *fb_info = &host->fb_info; | ||
588 | unsigned line_count; | ||
589 | unsigned period; | ||
590 | unsigned long pa, fbsize; | ||
591 | int bits_per_pixel, ofs; | ||
592 | u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl; | ||
593 | struct fb_videomode vmode; | ||
594 | |||
595 | /* Only restore the mode when the controller is running */ | ||
596 | ctrl = readl(host->base + LCDC_CTRL); | ||
597 | if (!(ctrl & CTRL_RUN)) | ||
598 | return -EINVAL; | ||
599 | |||
600 | vdctrl0 = readl(host->base + LCDC_VDCTRL0); | ||
601 | vdctrl2 = readl(host->base + LCDC_VDCTRL2); | ||
602 | vdctrl3 = readl(host->base + LCDC_VDCTRL3); | ||
603 | vdctrl4 = readl(host->base + LCDC_VDCTRL4); | ||
604 | |||
605 | transfer_count = readl(host->base + host->devdata->transfer_count); | ||
606 | |||
607 | vmode.xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count); | ||
608 | vmode.yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count); | ||
609 | |||
610 | switch (CTRL_GET_WORD_LENGTH(ctrl)) { | ||
611 | case 0: | ||
612 | bits_per_pixel = 16; | ||
613 | break; | ||
614 | case 3: | ||
615 | bits_per_pixel = 32; | ||
616 | case 1: | ||
617 | default: | ||
618 | return -EINVAL; | ||
619 | } | ||
620 | |||
621 | fb_info->var.bits_per_pixel = bits_per_pixel; | ||
622 | |||
623 | vmode.pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U); | ||
624 | vmode.hsync_len = get_hsync_pulse_width(host, vdctrl2); | ||
625 | vmode.left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode.hsync_len; | ||
626 | vmode.right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - vmode.hsync_len - | ||
627 | vmode.left_margin - vmode.xres; | ||
628 | vmode.vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0); | ||
629 | period = readl(host->base + LCDC_VDCTRL1); | ||
630 | vmode.upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode.vsync_len; | ||
631 | vmode.lower_margin = period - vmode.vsync_len - vmode.upper_margin - vmode.yres; | ||
632 | |||
633 | vmode.vmode = FB_VMODE_NONINTERLACED; | ||
634 | |||
635 | vmode.sync = 0; | ||
636 | if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH) | ||
637 | vmode.sync |= FB_SYNC_HOR_HIGH_ACT; | ||
638 | if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH) | ||
639 | vmode.sync |= FB_SYNC_VERT_HIGH_ACT; | ||
640 | |||
641 | pr_debug("Reconstructed video mode:\n"); | ||
642 | pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n", | ||
643 | vmode.xres, vmode.yres, | ||
644 | vmode.hsync_len, vmode.left_margin, vmode.right_margin, | ||
645 | vmode.vsync_len, vmode.upper_margin, vmode.lower_margin); | ||
646 | pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode.pixclock)); | ||
647 | |||
648 | fb_add_videomode(&vmode, &fb_info->modelist); | ||
649 | |||
650 | host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl); | ||
651 | host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4); | ||
652 | |||
653 | fb_info->fix.line_length = vmode.xres * (bits_per_pixel >> 3); | ||
654 | |||
655 | pa = readl(host->base + host->devdata->cur_buf); | ||
656 | fbsize = fb_info->fix.line_length * vmode.yres; | ||
657 | if (pa < fb_info->fix.smem_start) | ||
658 | return -EINVAL; | ||
659 | if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) | ||
660 | return -EINVAL; | ||
661 | ofs = pa - fb_info->fix.smem_start; | ||
662 | if (ofs) { | ||
663 | memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize); | ||
664 | writel(fb_info->fix.smem_start, host->base + host->devdata->next_buf); | ||
665 | } | ||
666 | |||
667 | line_count = fb_info->fix.smem_len / fb_info->fix.line_length; | ||
668 | fb_info->fix.ypanstep = 1; | ||
669 | |||
670 | clk_enable(host->clk); | ||
671 | host->enabled = 1; | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static int __devinit mxsfb_init_fbinfo(struct mxsfb_info *host) | ||
677 | { | ||
678 | struct fb_info *fb_info = &host->fb_info; | ||
679 | struct fb_var_screeninfo *var = &fb_info->var; | ||
680 | struct mxsfb_platform_data *pdata = host->pdev->dev.platform_data; | ||
681 | dma_addr_t fb_phys; | ||
682 | void *fb_virt; | ||
683 | unsigned fb_size = pdata->fb_size; | ||
684 | |||
685 | fb_info->fbops = &mxsfb_ops; | ||
686 | fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; | ||
687 | strlcpy(fb_info->fix.id, "mxs", sizeof(fb_info->fix.id)); | ||
688 | fb_info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
689 | fb_info->fix.ypanstep = 1; | ||
690 | fb_info->fix.visual = FB_VISUAL_TRUECOLOR, | ||
691 | fb_info->fix.accel = FB_ACCEL_NONE; | ||
692 | |||
693 | var->bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16; | ||
694 | var->nonstd = 0; | ||
695 | var->activate = FB_ACTIVATE_NOW; | ||
696 | var->accel_flags = 0; | ||
697 | var->vmode = FB_VMODE_NONINTERLACED; | ||
698 | |||
699 | host->dotclk_delay = pdata->dotclk_delay; | ||
700 | host->ld_intf_width = pdata->ld_intf_width; | ||
701 | |||
702 | /* Memory allocation for framebuffer */ | ||
703 | if (pdata->fb_phys) { | ||
704 | if (!fb_size) | ||
705 | return -EINVAL; | ||
706 | |||
707 | fb_phys = pdata->fb_phys; | ||
708 | |||
709 | if (!request_mem_region(fb_phys, fb_size, host->pdev->name)) | ||
710 | return -ENOMEM; | ||
711 | |||
712 | fb_virt = ioremap(fb_phys, fb_size); | ||
713 | if (!fb_virt) { | ||
714 | release_mem_region(fb_phys, fb_size); | ||
715 | return -ENOMEM; | ||
716 | } | ||
717 | host->mapped = 1; | ||
718 | } else { | ||
719 | if (!fb_size) | ||
720 | fb_size = SZ_2M; /* default */ | ||
721 | fb_virt = alloc_pages_exact(fb_size, GFP_DMA); | ||
722 | if (!fb_virt) | ||
723 | return -ENOMEM; | ||
724 | |||
725 | fb_phys = virt_to_phys(fb_virt); | ||
726 | } | ||
727 | |||
728 | fb_info->fix.smem_start = fb_phys; | ||
729 | fb_info->screen_base = fb_virt; | ||
730 | fb_info->screen_size = fb_info->fix.smem_len = fb_size; | ||
731 | |||
732 | if (mxsfb_restore_mode(host)) | ||
733 | memset(fb_virt, 0, fb_size); | ||
734 | |||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | static void __devexit mxsfb_free_videomem(struct mxsfb_info *host) | ||
739 | { | ||
740 | struct fb_info *fb_info = &host->fb_info; | ||
741 | |||
742 | if (host->mapped) { | ||
743 | iounmap(fb_info->screen_base); | ||
744 | release_mem_region(fb_info->fix.smem_start, | ||
745 | fb_info->screen_size); | ||
746 | } else { | ||
747 | free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len); | ||
748 | } | ||
749 | } | ||
750 | |||
751 | static int __devinit mxsfb_probe(struct platform_device *pdev) | ||
752 | { | ||
753 | struct mxsfb_platform_data *pdata = pdev->dev.platform_data; | ||
754 | struct resource *res; | ||
755 | struct mxsfb_info *host; | ||
756 | struct fb_info *fb_info; | ||
757 | struct fb_modelist *modelist; | ||
758 | int i, ret; | ||
759 | |||
760 | if (!pdata) { | ||
761 | dev_err(&pdev->dev, "No platformdata. Giving up\n"); | ||
762 | return -ENODEV; | ||
763 | } | ||
764 | |||
765 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
766 | if (!res) { | ||
767 | dev_err(&pdev->dev, "Cannot get memory IO resource\n"); | ||
768 | return -ENODEV; | ||
769 | } | ||
770 | |||
771 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) | ||
772 | return -EBUSY; | ||
773 | |||
774 | fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev); | ||
775 | if (!fb_info) { | ||
776 | dev_err(&pdev->dev, "Failed to allocate fbdev\n"); | ||
777 | ret = -ENOMEM; | ||
778 | goto error_alloc_info; | ||
779 | } | ||
780 | |||
781 | host = to_imxfb_host(fb_info); | ||
782 | |||
783 | host->base = ioremap(res->start, resource_size(res)); | ||
784 | if (!host->base) { | ||
785 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
786 | ret = -ENOMEM; | ||
787 | goto error_ioremap; | ||
788 | } | ||
789 | |||
790 | host->pdev = pdev; | ||
791 | platform_set_drvdata(pdev, host); | ||
792 | |||
793 | host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; | ||
794 | |||
795 | host->clk = clk_get(&host->pdev->dev, NULL); | ||
796 | if (IS_ERR(host->clk)) { | ||
797 | ret = PTR_ERR(host->clk); | ||
798 | goto error_getclock; | ||
799 | } | ||
800 | |||
801 | fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); | ||
802 | if (!fb_info->pseudo_palette) { | ||
803 | ret = -ENOMEM; | ||
804 | goto error_pseudo_pallette; | ||
805 | } | ||
806 | |||
807 | INIT_LIST_HEAD(&fb_info->modelist); | ||
808 | |||
809 | ret = mxsfb_init_fbinfo(host); | ||
810 | if (ret != 0) | ||
811 | goto error_init_fb; | ||
812 | |||
813 | for (i = 0; i < pdata->mode_count; i++) | ||
814 | fb_add_videomode(&pdata->mode_list[i], &fb_info->modelist); | ||
815 | |||
816 | modelist = list_first_entry(&fb_info->modelist, | ||
817 | struct fb_modelist, list); | ||
818 | fb_videomode_to_var(&fb_info->var, &modelist->mode); | ||
819 | |||
820 | /* init the color fields */ | ||
821 | mxsfb_check_var(&fb_info->var, fb_info); | ||
822 | |||
823 | platform_set_drvdata(pdev, fb_info); | ||
824 | |||
825 | ret = register_framebuffer(fb_info); | ||
826 | if (ret != 0) { | ||
827 | dev_err(&pdev->dev,"Failed to register framebuffer\n"); | ||
828 | goto error_register; | ||
829 | } | ||
830 | |||
831 | if (!host->enabled) { | ||
832 | writel(0, host->base + LCDC_CTRL); | ||
833 | mxsfb_set_par(fb_info); | ||
834 | mxsfb_enable_controller(fb_info); | ||
835 | } | ||
836 | |||
837 | dev_info(&pdev->dev, "initialized\n"); | ||
838 | |||
839 | return 0; | ||
840 | |||
841 | error_register: | ||
842 | if (host->enabled) | ||
843 | clk_disable(host->clk); | ||
844 | fb_destroy_modelist(&fb_info->modelist); | ||
845 | error_init_fb: | ||
846 | kfree(fb_info->pseudo_palette); | ||
847 | error_pseudo_pallette: | ||
848 | clk_put(host->clk); | ||
849 | error_getclock: | ||
850 | iounmap(host->base); | ||
851 | error_ioremap: | ||
852 | framebuffer_release(fb_info); | ||
853 | error_alloc_info: | ||
854 | release_mem_region(res->start, resource_size(res)); | ||
855 | |||
856 | return ret; | ||
857 | } | ||
858 | |||
859 | static int __devexit mxsfb_remove(struct platform_device *pdev) | ||
860 | { | ||
861 | struct fb_info *fb_info = platform_get_drvdata(pdev); | ||
862 | struct mxsfb_info *host = to_imxfb_host(fb_info); | ||
863 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
864 | |||
865 | if (host->enabled) | ||
866 | mxsfb_disable_controller(fb_info); | ||
867 | |||
868 | unregister_framebuffer(fb_info); | ||
869 | kfree(fb_info->pseudo_palette); | ||
870 | mxsfb_free_videomem(host); | ||
871 | iounmap(host->base); | ||
872 | clk_put(host->clk); | ||
873 | |||
874 | framebuffer_release(fb_info); | ||
875 | release_mem_region(res->start, resource_size(res)); | ||
876 | |||
877 | platform_set_drvdata(pdev, NULL); | ||
878 | |||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | static struct platform_device_id mxsfb_devtype[] = { | ||
883 | { | ||
884 | .name = "imx23-fb", | ||
885 | .driver_data = MXSFB_V3, | ||
886 | }, { | ||
887 | .name = "imx28-fb", | ||
888 | .driver_data = MXSFB_V4, | ||
889 | }, { | ||
890 | /* sentinel */ | ||
891 | } | ||
892 | }; | ||
893 | MODULE_DEVICE_TABLE(platform, mxsfb_devtype); | ||
894 | |||
895 | static struct platform_driver mxsfb_driver = { | ||
896 | .probe = mxsfb_probe, | ||
897 | .remove = __devexit_p(mxsfb_remove), | ||
898 | .id_table = mxsfb_devtype, | ||
899 | .driver = { | ||
900 | .name = DRIVER_NAME, | ||
901 | }, | ||
902 | }; | ||
903 | |||
904 | static int __init mxsfb_init(void) | ||
905 | { | ||
906 | return platform_driver_register(&mxsfb_driver); | ||
907 | } | ||
908 | |||
909 | static void __exit mxsfb_exit(void) | ||
910 | { | ||
911 | platform_driver_unregister(&mxsfb_driver); | ||
912 | } | ||
913 | |||
914 | module_init(mxsfb_init); | ||
915 | module_exit(mxsfb_exit); | ||
916 | |||
917 | MODULE_DESCRIPTION("Freescale mxs framebuffer driver"); | ||
918 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | ||
919 | MODULE_LICENSE("GPL"); | ||
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..15e7f1912af9 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 | ||
11 | config FB_OMAP_LCD_VGA | 12 | config 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. | ||
15 | choice | 20 | choice |
16 | depends on FB_OMAP && MACH_OVERO | 21 | depends on FB_OMAP && MACH_OVERO |
17 | prompt "Screen resolution" | 22 | prompt "Screen resolution" |
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 | ||
12 | config 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 | |||
12 | config PANEL_SHARP_LS037V7DW01 | 18 | config 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 @@ | |||
1 | obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o | 1 | obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o |
2 | obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o | ||
2 | obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o | 3 | obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o |
3 | obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o | 4 | obj-$(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 | ||
161 | struct panel_drv_data { | 186 | struct 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 | |||
26 | struct lb035q02_data { | ||
27 | struct mutex lock; | ||
28 | }; | ||
29 | |||
30 | static 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 | |||
45 | static 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; | ||
63 | err1: | ||
64 | omapdss_dpi_display_disable(dssdev); | ||
65 | err0: | ||
66 | return r; | ||
67 | } | ||
68 | |||
69 | static 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 | |||
80 | static 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; | ||
97 | err: | ||
98 | return r; | ||
99 | } | ||
100 | |||
101 | static 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 | |||
108 | static 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; | ||
122 | err: | ||
123 | mutex_unlock(&ld->lock); | ||
124 | return r; | ||
125 | } | ||
126 | |||
127 | static 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 | |||
139 | static 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 | |||
152 | static 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; | ||
166 | err: | ||
167 | mutex_unlock(&ld->lock); | ||
168 | return r; | ||
169 | } | ||
170 | |||
171 | static 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 | |||
186 | static 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 | |||
217 | static 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 | |||
246 | static 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 | |||
252 | static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi) | ||
253 | { | ||
254 | omap_dss_unregister_driver(&lb035q02_driver); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static 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 | |||
267 | static int __init lb035q02_panel_drv_init(void) | ||
268 | { | ||
269 | return spi_register_driver(&lb035q02_spi_driver); | ||
270 | } | ||
271 | |||
272 | static void __exit lb035q02_panel_drv_exit(void) | ||
273 | { | ||
274 | spi_unregister_driver(&lb035q02_spi_driver); | ||
275 | } | ||
276 | |||
277 | module_init(lb035q02_panel_drv_init); | ||
278 | module_exit(lb035q02_panel_drv_exit); | ||
279 | MODULE_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 | ||
260 | static int taal_dcs_read_1(u8 dcs_cmd, u8 *data) | 262 | static 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 | ||
275 | static int taal_dcs_write_0(u8 dcs_cmd) | 277 | static 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 | ||
280 | static int taal_dcs_write_1(u8 dcs_cmd, u8 param) | 282 | static 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 | ||
288 | static int taal_sleep_in(struct taal_data *td) | 290 | static 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 | ||
327 | static int taal_get_id(u8 *id1, u8 *id2, u8 *id3) | 329 | static 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 | ||
344 | static int taal_set_addr_mode(u8 rotate, bool mirror) | 346 | static 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 | ||
387 | static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h) | 389 | static 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; |
784 | err_sysfs: | 801 | |
802 | err_vc_id: | ||
803 | omap_dsi_release_vc(dssdev, td->channel); | ||
804 | err_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); |
787 | err_irq: | 807 | err_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; |
909 | err: | 930 | err: |
@@ -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 | ||
1442 | err3: | 1463 | err3: |
1443 | dsi_vc_set_max_rx_packet_size(TCH, 1); | 1464 | dsi_vc_set_max_rx_packet_size(td->channel, 1); |
1444 | err2: | 1465 | err2: |
1445 | dsi_bus_unlock(); | 1466 | dsi_bus_unlock(); |
1446 | err1: | 1467 | err1: |
@@ -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 @@ | |||
1 | menuconfig OMAP2_DSS | 1 | menuconfig 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 | ||
7 | if OMAP2_DSS | 7 | if 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 | ||
63 | config 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 | |||
63 | config OMAP2_DSS_SDI | 71 | config 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 | |||
5 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o | 5 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o |
6 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o | 6 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o |
7 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o | 7 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o |
8 | omapdss-$(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 | ||
42 | static struct { | 41 | static 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 | ||
58 | static void dss_clk_enable_all_no_ctx(void); | ||
59 | static void dss_clk_disable_all_no_ctx(void); | ||
60 | static void dss_clk_enable_no_ctx(enum dss_clock clks); | ||
61 | static void dss_clk_disable_no_ctx(enum dss_clock clks); | ||
62 | |||
63 | static char *def_disp_name; | 48 | static char *def_disp_name; |
64 | module_param_named(def_disp, def_disp_name, charp, 0); | 49 | module_param_named(def_disp, def_disp_name, charp, 0); |
65 | MODULE_PARM_DESC(def_disp_name, "default display name"); | 50 | MODULE_PARM_DESC(def_disp, "default display name"); |
66 | 51 | ||
67 | #ifdef DEBUG | 52 | #ifdef DEBUG |
68 | unsigned int dss_debug; | 53 | unsigned int dss_debug; |
69 | module_param_named(debug, dss_debug, bool, 0644); | 54 | module_param_named(debug, dss_debug, bool, 0644); |
70 | #endif | 55 | #endif |
71 | 56 | ||
72 | /* CONTEXT */ | ||
73 | static 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 | |||
89 | int 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 | |||
103 | static 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 | |||
118 | static 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 */ | ||
135 | static 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 | |||
161 | static 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 | |||
179 | static 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 | |||
211 | err: | ||
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 | |||
226 | static 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 | |||
236 | unsigned 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 | |||
255 | static 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 | |||
273 | static 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 | |||
291 | void 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 | |||
301 | static 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 | |||
319 | void 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 | |||
333 | static 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 | |||
343 | static 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 | |||
353 | static 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 | ||
365 | struct regulator *dss_get_vdds_dsi(void) | 59 | struct 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 | ||
393 | struct 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) |
409 | static 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 | |||
419 | static int dss_debug_show(struct seq_file *s, void *unused) | 88 | static 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) | |||
497 | static int omap_dss_probe(struct platform_device *pdev) | 166 | static 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 | ||
596 | err_register: | 244 | err_register: |
597 | dss_uninitialize_debugfs(); | 245 | dss_uninitialize_debugfs(); |
598 | err_debugfs: | 246 | err_debugfs: |
599 | if (cpu_is_omap34xx()) | 247 | hdmi_uninit_platform_driver(); |
600 | dsi_exit(); | 248 | err_hdmi: |
249 | dsi_uninit_platform_driver(); | ||
601 | err_dsi: | 250 | err_dsi: |
602 | if (cpu_is_omap34xx()) | 251 | venc_uninit_platform_driver(); |
603 | sdi_exit(); | ||
604 | err_sdi: | ||
605 | venc_exit(); | ||
606 | err_venc: | 252 | err_venc: |
607 | dispc_exit(); | 253 | dispc_uninit_platform_driver(); |
608 | err_dispc: | 254 | err_dispc: |
609 | dpi_exit(); | 255 | rfbi_uninit_platform_driver(); |
610 | err_dpi: | ||
611 | rfbi_exit(); | ||
612 | err_rfbi: | 256 | err_rfbi: |
613 | dss_exit(); | 257 | dss_uninit_platform_driver(); |
614 | err_dss: | 258 | err_dss: |
615 | dss_clk_disable_all_no_ctx(); | ||
616 | dss_put_clocks(); | ||
617 | err_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 | ||
49 | struct dispc_reg { u16 idx; }; | 48 | struct 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 | ||
180 | static struct { | 180 | static 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 | ||
378 | void dispc_restore_context(void) | 383 | void 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) | |||
552 | static inline void enable_clocks(bool enable) | 560 | static 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 | ||
560 | bool dispc_go_busy(enum omap_channel channel) | 568 | bool 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 | ||
1011 | void 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 | |||
1003 | static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) | 1025 | static 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, | |||
1215 | static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, | 1258 | static 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 | ||
1266 | static int color_mode_to_bpp(enum omap_color_mode color_mode) | 1310 | static 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 | ||
2340 | unsigned long dispc_pclk_rate(enum omap_channel channel) | 2396 | unsigned 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 | ||
2356 | void dispc_dump_clocks(struct seq_file *s) | 2411 | void 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. */ |
2869 | void dispc_irq_handler(void) | 2950 | static 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 | ||
2934 | static void dispc_error_worker(struct work_struct *work) | 3024 | static 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 | ||
3272 | int 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 | |||
3308 | void dispc_exit(void) | ||
3309 | { | ||
3310 | iounmap(dispc.base); | ||
3311 | } | ||
3312 | |||
3313 | int dispc_enable_plane(enum omap_plane plane, bool enable) | 3371 | int 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 */ | ||
3422 | static 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; | ||
3480 | fail1: | ||
3481 | iounmap(dispc.base); | ||
3482 | fail0: | ||
3483 | return r; | ||
3484 | } | ||
3485 | |||
3486 | static 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 | |||
3493 | static 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 | |||
3502 | int dispc_init_platform_driver(void) | ||
3503 | { | ||
3504 | return platform_driver_register(&omap_dispchw_driver); | ||
3505 | } | ||
3506 | |||
3507 | void 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 | ||
34 | static LIST_HEAD(display_list); | ||
35 | |||
36 | static ssize_t display_enabled_show(struct device *dev, | 33 | static 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 | ||
139 | err0: | 139 | err0: |
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(); |
201 | err3: | 201 | err3: |
202 | dss_clk_disable(DSS_CLK_FCK2); | 202 | dss_clk_disable(DSS_CLK_SYSCK); |
203 | #endif | 203 | #endif |
204 | err2: | 204 | err2: |
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); |
208 | err1: | 208 | err1: |
@@ -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 | ||
309 | int 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 | ||
322 | int dpi_init(void) | ||
323 | { | ||
324 | return 0; | ||
325 | } | ||
326 | |||
322 | void dpi_exit(void) | 327 | void 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 | |||
47 | struct dsi_reg { u16 idx; }; | 46 | struct 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 | 188 | typedef 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) | 192 | struct 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 | ||
197 | enum fifo_size { | 198 | enum 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 | ||
224 | struct 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 | |||
223 | static struct | 230 | static 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 | ||
338 | static void dsi_completion_handler(void *data, u32 mask) | ||
339 | { | ||
340 | complete((struct completion *)data); | ||
341 | } | ||
342 | |||
321 | static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, | 343 | static 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 | ||
388 | static void print_irq_status(u32 status) | 410 | static 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 | ||
423 | static void print_irq_status_vc(int channel, u32 status) | 448 | static 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 | ||
449 | static void print_irq_status_cio(u32 status) | 477 | static 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 | ||
481 | static int debug_irq; | 512 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
482 | 513 | static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus) | |
483 | /* called from dss */ | ||
484 | void 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 | ||
533 | static int debug_irq; | ||
534 | |||
535 | static 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 | |||
567 | static 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 | |||
580 | static 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 | 603 | static 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 */ | ||
666 | static 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 */ | ||
698 | static 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 */ | ||
710 | static 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 */ | ||
719 | static 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 | ||
571 | static void _dsi_initialize_irq(void) | 727 | static 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 | |||
744 | static 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 | |
778 | static 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 | ||
609 | static u32 dsi_get_errors(void) | 800 | static 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 | ||
620 | static void dsi_vc_enable_bta_irq(int channel) | 818 | static 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 | ||
631 | static void dsi_vc_disable_bta_irq(int channel) | 836 | static 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 | |||
856 | static 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 | |||
876 | static 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 | |||
894 | static 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 */ | 912 | static 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 */ | ||
641 | static inline void enable_clocks(bool enable) | 924 | static 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 */ |
650 | static inline void dsi_enable_pll_clock(bool enable) | 933 | static 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 | ||
710 | unsigned long dsi_get_dsi1_pll_rate(void) | 993 | unsigned 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 | ||
715 | static unsigned long dsi_get_dsi2_pll_rate(void) | 998 | static 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 | ||
720 | static unsigned long dsi_get_txbyteclkhs(void) | 1003 | static 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) | |||
795 | static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, | 1078 | static 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, ®n_start, ®n_end); | ||
1321 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, ®m_start, ®m_end); | ||
1322 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, ®m_dispc_start, | ||
1323 | ®m_dispc_end); | ||
1324 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, ®m_dsi_start, | ||
1325 | ®m_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 | ||
1625 | static 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 | |||
1639 | static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, | 1961 | static 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 | ||
1760 | static int dsi_vc_config_l4(int channel) | 2080 | static int dsi_vc_config_l4(int channel) |
@@ -1922,33 +2242,44 @@ static int dsi_vc_send_bta(int channel) | |||
1922 | 2242 | ||
1923 | int dsi_vc_send_bta_sync(int channel) | 2243 | int 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 | } |
1949 | err: | 2276 | err2: |
1950 | dsi_vc_disable_bta_irq(channel); | 2277 | dsi_unregister_isr(dsi_completion_handler, &completion, |
1951 | 2278 | DSI_IRQ_ERROR_MASK); | |
2279 | err1: | ||
2280 | dsi_unregister_isr_vc(channel, dsi_completion_handler, | ||
2281 | &completion, DSI_VC_IRQ_BTA); | ||
2282 | err0: | ||
1952 | return r; | 2283 | return r; |
1953 | } | 2284 | } |
1954 | EXPORT_SYMBOL(dsi_vc_send_bta_sync); | 2285 | EXPORT_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 | ||
3096 | static void dsi_framedone_bta_callback(void *data, u32 mask); | ||
3097 | |||
2765 | static void dsi_handle_framedone(int error) | 3098 | static 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 | ||
2811 | static void dsi_framedone_bta_callback(void) | 3143 | static 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) | |||
3082 | err3: | 3418 | err3: |
3083 | dsi_complexio_uninit(); | 3419 | dsi_complexio_uninit(); |
3084 | err2: | 3420 | err2: |
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); |
3087 | err1: | 3423 | err1: |
3088 | dsi_pll_uninit(); | 3424 | dsi_pll_uninit(); |
3089 | err0: | 3425 | err0: |
@@ -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 | ||
3229 | void dsi_wait_dsi1_pll_active(void) | 3575 | int 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 | } | ||
3590 | EXPORT_SYMBOL(omap_dsi_request_vc); | ||
3591 | |||
3592 | int 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 | } | ||
3614 | EXPORT_SYMBOL(omap_dsi_set_vc_id); | ||
3615 | |||
3616 | void 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 | } | ||
3624 | EXPORT_SYMBOL(omap_dsi_release_vc); | ||
3625 | |||
3626 | void 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 | ||
3235 | void dsi_wait_dsi2_pll_active(void) | 3634 | void 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 | |||
3642 | static 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 | ||
3241 | int dsi_init(struct platform_device *pdev) | 3653 | static 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 | ||
3301 | void dsi_exit(void) | 3734 | static 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 */ | ||
3750 | static 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 | } | ||
3759 | err_dsi: | ||
3760 | return r; | ||
3761 | } | ||
3762 | |||
3763 | static int omap_dsi1hw_remove(struct platform_device *pdev) | ||
3764 | { | ||
3765 | dsi_exit(); | ||
3766 | return 0; | ||
3767 | } | ||
3768 | |||
3769 | static 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 | |||
3778 | int dsi_init_platform_driver(void) | ||
3779 | { | ||
3780 | return platform_driver_register(&omap_dsi1hw_driver); | ||
3781 | } | ||
3782 | |||
3783 | void 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 | ||
61 | static struct { | 60 | static 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 | ||
85 | static 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 | |||
91 | static void dss_clk_enable_all_no_ctx(void); | ||
92 | static void dss_clk_disable_all_no_ctx(void); | ||
93 | static void dss_clk_enable_no_ctx(enum dss_clock clks); | ||
94 | static void dss_clk_disable_no_ctx(enum dss_clock clks); | ||
95 | |||
77 | static int _omap_dss_wait_reset(void); | 96 | static int _omap_dss_wait_reset(void); |
78 | 97 | ||
79 | static inline void dss_write_reg(const struct dss_reg idx, u32 val) | 98 | static 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 | ||
108 | void dss_restore_context(void) | 128 | void 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 | ||
233 | const 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 | |||
212 | void dss_dump_clocks(struct seq_file *s) | 238 | void 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 | ||
240 | void dss_dump_regs(struct seq_file *s) | 280 | void 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 | ||
259 | void dss_select_dispc_clk_source(enum dss_clk_source clk_src) | 303 | void 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 | ||
348 | void 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 | |||
293 | enum dss_clk_source dss_get_dispc_clk_source(void) | 376 | enum 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 | ||
386 | enum 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 */ |
304 | int dss_calc_clock_rates(struct dss_clock_info *cinfo) | 393 | int 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 | ||
319 | int dss_set_clock_div(struct dss_clock_info *cinfo) | 417 | int 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 | ||
338 | int dss_get_clock_div(struct dss_clock_info *cinfo) | 439 | int 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 | ||
356 | unsigned long dss_get_dpll4_rate(void) | 459 | unsigned 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 | ||
457 | found: | 562 | found: |
@@ -482,31 +587,6 @@ found: | |||
482 | return 0; | 587 | return 0; |
483 | } | 588 | } |
484 | 589 | ||
485 | |||
486 | |||
487 | static irqreturn_t dss_irq_handler_omap2(int irq, void *arg) | ||
488 | { | ||
489 | dispc_irq_handler(); | ||
490 | |||
491 | return IRQ_HANDLED; | ||
492 | } | ||
493 | |||
494 | static 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 | |||
510 | static int _omap_dss_wait_reset(void) | 590 | static 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 | ||
552 | int dss_init(bool skip_init) | 632 | void 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 | |||
637 | static 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 | ||
624 | fail2: | ||
625 | free_irq(INT_24XX_DSS_IRQ, NULL); | ||
626 | fail1: | 716 | fail1: |
627 | iounmap(dss.base); | 717 | iounmap(dss.base); |
628 | fail0: | 718 | fail0: |
629 | return r; | 719 | return r; |
630 | } | 720 | } |
631 | 721 | ||
632 | void dss_exit(void) | 722 | static 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 */ | ||
731 | static 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 | |||
747 | int 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 | |||
761 | static 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 | |||
776 | static 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 | |||
791 | static 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 | |||
809 | static 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 | |||
853 | err: | ||
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 | |||
868 | static 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 | |||
880 | unsigned 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 | |||
899 | static 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 | |||
917 | static 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 | |||
935 | void 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 | |||
953 | static 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 | |||
971 | void 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 | |||
985 | static 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 | |||
995 | static 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 */ | ||
1007 | static 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) | ||
1035 | void 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 */ | ||
1048 | static 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; | ||
1083 | err_sdi: | ||
1084 | dpi_exit(); | ||
1085 | err_dpi: | ||
1086 | dss_exit(); | ||
1087 | err_dss: | ||
1088 | dss_clk_disable_all_no_ctx(); | ||
1089 | dss_put_clocks(); | ||
1090 | err_clocks: | ||
1091 | return r; | ||
1092 | } | ||
1093 | |||
1094 | static 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 | |||
1111 | static 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 | |||
1120 | int dss_init_platform_driver(void) | ||
1121 | { | ||
1122 | return platform_driver_register(&omap_dsshw_driver); | ||
1123 | } | ||
1124 | |||
1125 | void 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 | |||
102 | enum omap_burst_size { | 100 | enum 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 | ||
114 | enum dss_clock { | 112 | enum 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 | ||
122 | enum dss_clk_source { | 120 | enum 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 | |||
129 | enum dss_hdmi_venc_clk_source_select { | ||
130 | DSS_VENC_TV_CLK = 0, | ||
131 | DSS_HDMI_M_PCLK = 1, | ||
126 | }; | 132 | }; |
127 | 133 | ||
128 | struct dss_clock_info { | 134 | struct 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 */ | ||
177 | struct 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 | ||
168 | struct seq_file; | 186 | struct seq_file; |
169 | struct platform_device; | 187 | struct platform_device; |
170 | 188 | ||
171 | /* core */ | 189 | /* core */ |
172 | void dss_clk_enable(enum dss_clock clks); | ||
173 | void dss_clk_disable(enum dss_clock clks); | ||
174 | unsigned long dss_clk_get_rate(enum dss_clock clk); | ||
175 | int dss_need_ctx_restore(void); | ||
176 | void dss_dump_clocks(struct seq_file *s); | ||
177 | struct bus_type *dss_get_bus(void); | 190 | struct bus_type *dss_get_bus(void); |
178 | struct regulator *dss_get_vdds_dsi(void); | 191 | struct regulator *dss_get_vdds_dsi(void); |
179 | struct regulator *dss_get_vdds_sdi(void); | 192 | struct regulator *dss_get_vdds_sdi(void); |
180 | struct regulator *dss_get_vdda_dac(void); | ||
181 | 193 | ||
182 | /* display */ | 194 | /* display */ |
183 | int dss_suspend_all_devices(void); | 195 | int dss_suspend_all_devices(void); |
@@ -214,13 +226,23 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr); | |||
214 | void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); | 226 | void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); |
215 | 227 | ||
216 | /* DSS */ | 228 | /* DSS */ |
217 | int dss_init(bool skip_init); | 229 | int dss_init_platform_driver(void); |
218 | void dss_exit(void); | 230 | void dss_uninit_platform_driver(void); |
219 | 231 | ||
232 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | ||
220 | void dss_save_context(void); | 233 | void dss_save_context(void); |
221 | void dss_restore_context(void); | 234 | void dss_restore_context(void); |
235 | void dss_clk_enable(enum dss_clock clks); | ||
236 | void dss_clk_disable(enum dss_clock clks); | ||
237 | unsigned long dss_clk_get_rate(enum dss_clock clk); | ||
238 | int dss_need_ctx_restore(void); | ||
239 | const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src); | ||
240 | void dss_dump_clocks(struct seq_file *s); | ||
222 | 241 | ||
223 | void dss_dump_regs(struct seq_file *s); | 242 | void dss_dump_regs(struct seq_file *s); |
243 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) | ||
244 | void dss_debug_dump_clocks(struct seq_file *s); | ||
245 | #endif | ||
224 | 246 | ||
225 | void dss_sdi_init(u8 datapairs); | 247 | void dss_sdi_init(u8 datapairs); |
226 | int dss_sdi_enable(void); | 248 | int dss_sdi_enable(void); |
@@ -228,8 +250,11 @@ void dss_sdi_disable(void); | |||
228 | 250 | ||
229 | void dss_select_dispc_clk_source(enum dss_clk_source clk_src); | 251 | void dss_select_dispc_clk_source(enum dss_clk_source clk_src); |
230 | void dss_select_dsi_clk_source(enum dss_clk_source clk_src); | 252 | void dss_select_dsi_clk_source(enum dss_clk_source clk_src); |
253 | void dss_select_lcd_clk_source(enum omap_channel channel, | ||
254 | enum dss_clk_source clk_src); | ||
231 | enum dss_clk_source dss_get_dispc_clk_source(void); | 255 | enum dss_clk_source dss_get_dispc_clk_source(void); |
232 | enum dss_clk_source dss_get_dsi_clk_source(void); | 256 | enum dss_clk_source dss_get_dsi_clk_source(void); |
257 | enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); | ||
233 | 258 | ||
234 | void dss_set_venc_output(enum omap_dss_venc_type type); | 259 | void dss_set_venc_output(enum omap_dss_venc_type type); |
235 | void dss_set_dac_pwrdn_bgz(bool enable); | 260 | void 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 |
247 | int sdi_init(bool skip_init); | 272 | int sdi_init(void); |
248 | void sdi_exit(void); | 273 | void sdi_exit(void); |
249 | int sdi_init_display(struct omap_dss_device *display); | 274 | int sdi_init_display(struct omap_dss_device *display); |
250 | #else | 275 | #else |
251 | static inline int sdi_init(bool skip_init) | 276 | static 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 |
262 | int dsi_init(struct platform_device *pdev); | 287 | int dsi_init_platform_driver(void); |
263 | void dsi_exit(void); | 288 | void dsi_uninit_platform_driver(void); |
264 | 289 | ||
265 | void dsi_dump_clocks(struct seq_file *s); | 290 | void dsi_dump_clocks(struct seq_file *s); |
266 | void dsi_dump_irqs(struct seq_file *s); | 291 | void dsi_dump_irqs(struct seq_file *s); |
@@ -271,7 +296,7 @@ void dsi_restore_context(void); | |||
271 | 296 | ||
272 | int dsi_init_display(struct omap_dss_device *display); | 297 | int dsi_init_display(struct omap_dss_device *display); |
273 | void dsi_irq_handler(void); | 298 | void dsi_irq_handler(void); |
274 | unsigned long dsi_get_dsi1_pll_rate(void); | 299 | unsigned long dsi_get_pll_hsdiv_dispc_rate(void); |
275 | int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); | 300 | int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); |
276 | int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, | 301 | int 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); | |||
282 | void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, | 307 | void 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); |
285 | void dsi_wait_dsi1_pll_active(void); | 310 | void dsi_wait_pll_hsdiv_dispc_active(void); |
286 | void dsi_wait_dsi2_pll_active(void); | 311 | void dsi_wait_pll_hsdiv_dsi_active(void); |
287 | #else | 312 | #else |
288 | static inline int dsi_init(struct platform_device *pdev) | 313 | static inline int dsi_init_platform_driver(void) |
289 | { | 314 | { |
290 | return 0; | 315 | return 0; |
291 | } | 316 | } |
292 | static inline void dsi_exit(void) | 317 | static inline void dsi_uninit_platform_driver(void) |
293 | { | 318 | { |
294 | } | 319 | } |
295 | static inline void dsi_wait_dsi1_pll_active(void) | 320 | static 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 | } |
298 | static inline void dsi_wait_dsi2_pll_active(void) | 325 | static inline void dsi_wait_pll_hsdiv_dispc_active(void) |
326 | { | ||
327 | } | ||
328 | static 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 |
305 | int dpi_init(struct platform_device *pdev); | 335 | int dpi_init(void); |
306 | void dpi_exit(void); | 336 | void dpi_exit(void); |
307 | int dpi_init_display(struct omap_dss_device *dssdev); | 337 | int dpi_init_display(struct omap_dss_device *dssdev); |
308 | #else | 338 | #else |
309 | static inline int dpi_init(struct platform_device *pdev) | 339 | static 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 */ |
319 | int dispc_init(void); | 349 | int dispc_init_platform_driver(void); |
320 | void dispc_exit(void); | 350 | void dispc_uninit_platform_driver(void); |
321 | void dispc_dump_clocks(struct seq_file *s); | 351 | void dispc_dump_clocks(struct seq_file *s); |
322 | void dispc_dump_irqs(struct seq_file *s); | 352 | void dispc_dump_irqs(struct seq_file *s); |
323 | void dispc_dump_regs(struct seq_file *s); | 353 | void dispc_dump_regs(struct seq_file *s); |
@@ -350,6 +380,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height); | |||
350 | void dispc_set_channel_out(enum omap_plane plane, | 380 | void dispc_set_channel_out(enum omap_plane plane, |
351 | enum omap_channel channel_out); | 381 | enum omap_channel channel_out); |
352 | 382 | ||
383 | void dispc_enable_gamma_table(bool enable); | ||
353 | int dispc_setup_plane(enum omap_plane plane, | 384 | int 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 |
412 | int venc_init(struct platform_device *pdev); | 443 | int venc_init_platform_driver(void); |
413 | void venc_exit(void); | 444 | void venc_uninit_platform_driver(void); |
414 | void venc_dump_regs(struct seq_file *s); | 445 | void venc_dump_regs(struct seq_file *s); |
415 | int venc_init_display(struct omap_dss_device *display); | 446 | int venc_init_display(struct omap_dss_device *display); |
416 | #else | 447 | #else |
417 | static inline int venc_init(struct platform_device *pdev) | 448 | static inline int venc_init_platform_driver(void) |
449 | { | ||
450 | return 0; | ||
451 | } | ||
452 | static inline void venc_uninit_platform_driver(void) | ||
453 | { | ||
454 | } | ||
455 | #endif | ||
456 | |||
457 | /* HDMI */ | ||
458 | #ifdef CONFIG_OMAP4_DSS_HDMI | ||
459 | int hdmi_init_platform_driver(void); | ||
460 | void hdmi_uninit_platform_driver(void); | ||
461 | int hdmi_init_display(struct omap_dss_device *dssdev); | ||
462 | #else | ||
463 | static inline int hdmi_init_display(struct omap_dss_device *dssdev) | ||
464 | { | ||
465 | return 0; | ||
466 | } | ||
467 | static inline int hdmi_init_platform_driver(void) | ||
418 | { | 468 | { |
419 | return 0; | 469 | return 0; |
420 | } | 470 | } |
421 | static inline void venc_exit(void) | 471 | static inline void hdmi_uninit_platform_driver(void) |
422 | { | 472 | { |
423 | } | 473 | } |
424 | #endif | 474 | #endif |
475 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); | ||
476 | void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); | ||
477 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); | ||
478 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | ||
479 | struct omap_video_timings *timings); | ||
480 | int hdmi_panel_init(void); | ||
481 | void hdmi_panel_exit(void); | ||
425 | 482 | ||
426 | /* RFBI */ | 483 | /* RFBI */ |
427 | #ifdef CONFIG_OMAP2_DSS_RFBI | 484 | #ifdef CONFIG_OMAP2_DSS_RFBI |
428 | int rfbi_init(void); | 485 | int rfbi_init_platform_driver(void); |
429 | void rfbi_exit(void); | 486 | void rfbi_uninit_platform_driver(void); |
430 | void rfbi_dump_regs(struct seq_file *s); | 487 | void rfbi_dump_regs(struct seq_file *s); |
431 | 488 | ||
432 | int rfbi_configure(int rfbi_module, int bpp, int lines); | 489 | int rfbi_configure(int rfbi_module, int bpp, int lines); |
@@ -437,11 +494,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); | |||
437 | unsigned long rfbi_get_max_tx_rate(void); | 494 | unsigned long rfbi_get_max_tx_rate(void); |
438 | int rfbi_init_display(struct omap_dss_device *display); | 495 | int rfbi_init_display(struct omap_dss_device *display); |
439 | #else | 496 | #else |
440 | static inline int rfbi_init(void) | 497 | static inline int rfbi_init_platform_driver(void) |
441 | { | 498 | { |
442 | return 0; | 499 | return 0; |
443 | } | 500 | } |
444 | static inline void rfbi_exit(void) | 501 | static 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 */ |
31 | struct dss_reg_field { | 32 | struct dss_reg_field { |
32 | enum dss_feat_reg_field id; | ||
33 | u8 start, end; | 33 | u8 start, end; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct dss_param_range { | ||
37 | int min, max; | ||
38 | }; | ||
39 | |||
36 | struct omap_dss_features { | 40 | struct 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 */ |
49 | static struct omap_dss_features *omap_current_dss_features; | 55 | static struct omap_dss_features *omap_current_dss_features; |
50 | 56 | ||
51 | static const struct dss_reg_field omap2_dss_reg_fields[] = { | 57 | static 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 | ||
59 | static const struct dss_reg_field omap3_dss_reg_fields[] = { | 72 | static 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 | |||
87 | static 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 | ||
67 | static const enum omap_display_type omap2_dss_supported_displays[] = { | 102 | static 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 | |||
110 | static 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 | ||
76 | static const enum omap_display_type omap3_dss_supported_displays[] = { | 119 | static 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 | ||
180 | static 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 | |||
186 | static 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 | |||
192 | static 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 | |||
198 | static 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 | |||
208 | static 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 | |||
218 | static 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 */ |
138 | static struct omap_dss_features omap2_dss_features = { | 229 | static 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 | ||
168 | static struct omap_dss_features omap3630_dss_features = { | 265 | static 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 */ |
184 | static struct omap_dss_features omap4_dss_features = { | 285 | static 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 | ||
313 | unsigned long dss_feat_get_param_min(enum dss_range_param param) | ||
314 | { | ||
315 | return omap_current_dss_features->dss_params[param].min; | ||
316 | } | ||
317 | |||
318 | unsigned long dss_feat_get_param_max(enum dss_range_param param) | ||
319 | { | ||
320 | return omap_current_dss_features->dss_params[param].max; | ||
321 | } | ||
322 | |||
209 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) | 323 | enum 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 | ||
340 | const 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 */ |
227 | bool dss_has_feature(enum dss_feat_id id) | 346 | bool 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 */ |
27 | enum dss_feat_id { | 28 | enum 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 | |||
61 | enum 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 */ |
48 | int dss_feat_get_num_mgrs(void); | 72 | int dss_feat_get_num_mgrs(void); |
49 | int dss_feat_get_num_ovls(void); | 73 | int dss_feat_get_num_ovls(void); |
74 | unsigned long dss_feat_get_param_min(enum dss_range_param param); | ||
75 | unsigned long dss_feat_get_param_max(enum dss_range_param param); | ||
50 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); | 76 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); |
51 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); | 77 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); |
52 | bool dss_feat_color_mode_supported(enum omap_plane plane, | 78 | bool dss_feat_color_mode_supported(enum omap_plane plane, |
53 | enum omap_color_mode color_mode); | 79 | enum omap_color_mode color_mode); |
80 | const char *dss_feat_get_clk_source_name(enum dss_clk_source id); | ||
54 | 81 | ||
55 | bool dss_has_feature(enum dss_feat_id id); | 82 | bool dss_has_feature(enum dss_feat_id id); |
56 | void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); | 83 | void 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..0d44f070ef36 --- /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 | |||
37 | static 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 | |||
64 | static 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 | */ | ||
106 | static 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 | */ | ||
117 | static 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 | |||
124 | static 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 | |||
135 | static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0}; | ||
136 | |||
137 | static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val) | ||
138 | { | ||
139 | __raw_writel(val, hdmi.base_wp + idx.idx); | ||
140 | } | ||
141 | |||
142 | static inline u32 hdmi_read_reg(const struct hdmi_reg idx) | ||
143 | { | ||
144 | return __raw_readl(hdmi.base_wp + idx.idx); | ||
145 | } | ||
146 | |||
147 | static 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 | |||
159 | int hdmi_init_display(struct omap_dss_device *dssdev) | ||
160 | { | ||
161 | DSSDBG("init_display\n"); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static 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 */ | ||
229 | static 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 */ | ||
244 | static 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 | |||
258 | static 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 | |||
272 | static 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 | |||
308 | static 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 | |||
322 | static 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 | |||
353 | static void hdmi_phy_off(void) | ||
354 | { | ||
355 | hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF); | ||
356 | } | ||
357 | |||
358 | static 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 | |||
454 | static 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 | |||
483 | static 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 | |||
503 | static 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 | |||
545 | static 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 */ | ||
583 | static 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 | /* seach 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 | |||
638 | static 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 | |||
668 | static 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 | |||
712 | static 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 | |||
718 | static 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 | |||
724 | static 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 */ | ||
731 | static 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 | |||
770 | static 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 | |||
844 | static 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 | |||
862 | static 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 | |||
887 | static void hdmi_wp_video_start(bool start) | ||
888 | { | ||
889 | REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31); | ||
890 | } | ||
891 | |||
892 | static 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 | |||
908 | static 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 | |||
920 | static 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 | |||
934 | static 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 | |||
953 | static 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 | |||
1039 | static 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 | |||
1055 | static 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 | |||
1094 | static 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 | |||
1104 | static 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; | ||
1177 | err: | ||
1178 | hdmi_enable_clocks(0); | ||
1179 | return -EIO; | ||
1180 | } | ||
1181 | |||
1182 | static 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 | |||
1194 | int 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 | |||
1209 | void 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 | |||
1221 | int 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 | |||
1252 | err2: | ||
1253 | if (dssdev->platform_disable) | ||
1254 | dssdev->platform_disable(dssdev); | ||
1255 | err1: | ||
1256 | omap_dss_stop_device(dssdev); | ||
1257 | err0: | ||
1258 | mutex_unlock(&hdmi.lock); | ||
1259 | return r; | ||
1260 | } | ||
1261 | |||
1262 | void 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 */ | ||
1279 | static 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 | |||
1306 | static 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 | |||
1315 | static 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 | |||
1324 | int hdmi_init_platform_driver(void) | ||
1325 | { | ||
1326 | return platform_driver_register(&omapdss_hdmihw_driver); | ||
1327 | } | ||
1328 | |||
1329 | void 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 | |||
33 | struct 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 */ | ||
202 | struct hdmi_timings { | ||
203 | struct omap_video_timings timings; | ||
204 | int vsync_pol; | ||
205 | int hsync_pol; | ||
206 | }; | ||
207 | |||
208 | enum hdmi_phy_pwr { | ||
209 | HDMI_PHYPWRCMD_OFF = 0, | ||
210 | HDMI_PHYPWRCMD_LDOON = 1, | ||
211 | HDMI_PHYPWRCMD_TXON = 2 | ||
212 | }; | ||
213 | |||
214 | enum 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 | |||
221 | enum 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 | |||
228 | enum hdmi_core_inputbus_width { | ||
229 | HDMI_INPUT_8BIT = 0, | ||
230 | HDMI_INPUT_10BIT = 1, | ||
231 | HDMI_INPUT_12BIT = 2 | ||
232 | }; | ||
233 | |||
234 | enum 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 | |||
243 | enum hdmi_core_deepcolor_ed { | ||
244 | HDMI_DEEPCOLORPACKECTDISABLE = 0, | ||
245 | HDMI_DEEPCOLORPACKECTENABLE = 1 | ||
246 | }; | ||
247 | |||
248 | enum 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 | |||
256 | enum hdmi_core_hdmi_dvi { | ||
257 | HDMI_DVI = 0, | ||
258 | HDMI_HDMI = 1 | ||
259 | }; | ||
260 | |||
261 | enum hdmi_core_tclkselclkmult { | ||
262 | HDMI_FPLL05IDCK = 0, | ||
263 | HDMI_FPLL10IDCK = 1, | ||
264 | HDMI_FPLL20IDCK = 2, | ||
265 | HDMI_FPLL40IDCK = 3 | ||
266 | }; | ||
267 | |||
268 | enum 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 */ | ||
276 | enum 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 | |||
323 | enum 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 | |||
330 | struct 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 | */ | ||
343 | struct 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 | |||
380 | struct 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 | |||
391 | struct 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 | |||
397 | struct hdmi_video_interface { | ||
398 | int vsp; /* Vsync polarity */ | ||
399 | int hsp; /* Hsync polarity */ | ||
400 | int interlacing; | ||
401 | int tm; /* Timing mode */ | ||
402 | }; | ||
403 | |||
404 | struct hdmi_cm { | ||
405 | int code; | ||
406 | int mode; | ||
407 | }; | ||
408 | |||
409 | struct 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 | |||
31 | static struct { | ||
32 | struct mutex hdmi_lock; | ||
33 | } hdmi; | ||
34 | |||
35 | |||
36 | static 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 | |||
57 | static void hdmi_panel_remove(struct omap_dss_device *dssdev) | ||
58 | { | ||
59 | |||
60 | } | ||
61 | |||
62 | static 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 | |||
82 | err: | ||
83 | mutex_unlock(&hdmi.hdmi_lock); | ||
84 | |||
85 | return r; | ||
86 | } | ||
87 | |||
88 | static 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 | |||
100 | static 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 | |||
115 | err: | ||
116 | mutex_unlock(&hdmi.hdmi_lock); | ||
117 | |||
118 | return r; | ||
119 | } | ||
120 | |||
121 | static 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 | |||
140 | err: | ||
141 | mutex_unlock(&hdmi.hdmi_lock); | ||
142 | |||
143 | return r; | ||
144 | } | ||
145 | |||
146 | static 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 | |||
156 | static 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 | |||
174 | static 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 | } | ||
188 | err: | ||
189 | mutex_unlock(&hdmi.hdmi_lock); | ||
190 | return r; | ||
191 | } | ||
192 | |||
193 | static 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 | |||
209 | int 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 | |||
218 | void 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 | |||
41 | struct rfbi_reg { u16 idx; }; | 39 | struct 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); | |||
100 | static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); | 98 | static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); |
101 | 99 | ||
102 | static struct { | 100 | static 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) | |||
142 | static void rfbi_enable_clocks(bool enable) | 141 | static 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 | ||
150 | void omap_rfbi_write_command(const void *buf, u32 len) | 149 | void 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 | ||
960 | int 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 | |||
997 | void rfbi_exit(void) | ||
998 | { | ||
999 | DSSDBG("rfbi_exit\n"); | ||
1000 | |||
1001 | iounmap(rfbi.base); | ||
1002 | } | ||
1003 | |||
1004 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) | 959 | int 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 */ | ||
1016 | static 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 | |||
1061 | static int omap_rfbihw_remove(struct platform_device *pdev) | ||
1062 | { | ||
1063 | iounmap(rfbi.base); | ||
1064 | return 0; | ||
1065 | } | ||
1066 | |||
1067 | static 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 | |||
1076 | int rfbi_init_platform_driver(void) | ||
1077 | { | ||
1078 | return platform_driver_register(&omap_rfbihw_driver); | ||
1079 | } | ||
1080 | |||
1081 | void 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 | ||
32 | static struct { | 32 | static 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; |
132 | err2: | 119 | err2: |
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); |
135 | err1: | 122 | err1: |
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 | ||
163 | int sdi_init(bool skip_init) | 163 | int 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 = { | |||
289 | EXPORT_SYMBOL(omap_dss_ntsc_timings); | 287 | EXPORT_SYMBOL(omap_dss_ntsc_timings); |
290 | 288 | ||
291 | static struct { | 289 | static 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) | |||
381 | static void venc_enable_clocks(int enable) | 380 | static 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 | ||
391 | static const struct venc_config *venc_timings_to_config( | 390 | static 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 | 643 | int venc_init_display(struct omap_dss_device *dssdev) | |
645 | |||
646 | int 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 | |||
677 | void venc_exit(void) | ||
678 | { | ||
679 | omap_dss_unregister_driver(&venc_driver); | ||
680 | |||
681 | iounmap(venc.base); | ||
682 | } | ||
683 | |||
684 | int 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 */ | ||
717 | static 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 | |||
749 | static 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 | |||
761 | static 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 | |||
770 | int 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 | |||
778 | void 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 @@ | |||
1 | menuconfig FB_OMAP2 | 1 | menuconfig 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 | ||
13 | config FB_OMAP2_DEBUG_SUPPORT | 13 | config 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/p9100.c b/drivers/video/p9100.c index b6c3fc2db632..d57cc58c5168 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c | |||
@@ -249,7 +249,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no | |||
249 | info->fix.accel = FB_ACCEL_SUN_CGTHREE; | 249 | info->fix.accel = FB_ACCEL_SUN_CGTHREE; |
250 | } | 250 | } |
251 | 251 | ||
252 | static int __devinit p9100_probe(struct platform_device *op, const struct of_device_id *match) | 252 | static int __devinit p9100_probe(struct platform_device *op) |
253 | { | 253 | { |
254 | struct device_node *dp = op->dev.of_node; | 254 | struct device_node *dp = op->dev.of_node; |
255 | struct fb_info *info; | 255 | struct fb_info *info; |
@@ -352,7 +352,7 @@ static const struct of_device_id p9100_match[] = { | |||
352 | }; | 352 | }; |
353 | MODULE_DEVICE_TABLE(of, p9100_match); | 353 | MODULE_DEVICE_TABLE(of, p9100_match); |
354 | 354 | ||
355 | static struct of_platform_driver p9100_driver = { | 355 | static struct platform_driver p9100_driver = { |
356 | .driver = { | 356 | .driver = { |
357 | .name = "p9100", | 357 | .name = "p9100", |
358 | .owner = THIS_MODULE, | 358 | .owner = THIS_MODULE, |
@@ -367,12 +367,12 @@ static int __init p9100_init(void) | |||
367 | if (fb_get_options("p9100fb", NULL)) | 367 | if (fb_get_options("p9100fb", NULL)) |
368 | return -ENODEV; | 368 | return -ENODEV; |
369 | 369 | ||
370 | return of_register_platform_driver(&p9100_driver); | 370 | return platform_driver_register(&p9100_driver); |
371 | } | 371 | } |
372 | 372 | ||
373 | static void __exit p9100_exit(void) | 373 | static void __exit p9100_exit(void) |
374 | { | 374 | { |
375 | of_unregister_platform_driver(&p9100_driver); | 375 | platform_driver_unregister(&p9100_driver); |
376 | } | 376 | } |
377 | 377 | ||
378 | module_init(p9100_init); | 378 | module_init(p9100_init); |
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index a50e1977b316..ef532d9d3c99 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
@@ -533,8 +533,7 @@ static int __init platinumfb_setup(char *options) | |||
533 | #define invalidate_cache(addr) | 533 | #define invalidate_cache(addr) |
534 | #endif | 534 | #endif |
535 | 535 | ||
536 | static int __devinit platinumfb_probe(struct platform_device* odev, | 536 | static int __devinit platinumfb_probe(struct platform_device* odev) |
537 | const struct of_device_id *match) | ||
538 | { | 537 | { |
539 | struct device_node *dp = odev->dev.of_node; | 538 | struct device_node *dp = odev->dev.of_node; |
540 | struct fb_info *info; | 539 | struct fb_info *info; |
@@ -677,7 +676,7 @@ static struct of_device_id platinumfb_match[] = | |||
677 | {}, | 676 | {}, |
678 | }; | 677 | }; |
679 | 678 | ||
680 | static struct of_platform_driver platinum_driver = | 679 | static struct platform_driver platinum_driver = |
681 | { | 680 | { |
682 | .driver = { | 681 | .driver = { |
683 | .name = "platinumfb", | 682 | .name = "platinumfb", |
@@ -697,14 +696,14 @@ static int __init platinumfb_init(void) | |||
697 | return -ENODEV; | 696 | return -ENODEV; |
698 | platinumfb_setup(option); | 697 | platinumfb_setup(option); |
699 | #endif | 698 | #endif |
700 | of_register_platform_driver(&platinum_driver); | 699 | platform_driver_register(&platinum_driver); |
701 | 700 | ||
702 | return 0; | 701 | return 0; |
703 | } | 702 | } |
704 | 703 | ||
705 | static void __exit platinumfb_exit(void) | 704 | static void __exit platinumfb_exit(void) |
706 | { | 705 | { |
707 | of_unregister_platform_driver(&platinum_driver); | 706 | platform_driver_unregister(&platinum_driver); |
708 | } | 707 | } |
709 | 708 | ||
710 | MODULE_LICENSE("GPL"); | 709 | MODULE_LICENSE("GPL"); |
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..6817d187d46e 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -1340,6 +1340,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
1340 | sfb->bus_clk = clk_get(dev, "lcd"); | 1340 | sfb->bus_clk = clk_get(dev, "lcd"); |
1341 | if (IS_ERR(sfb->bus_clk)) { | 1341 | if (IS_ERR(sfb->bus_clk)) { |
1342 | dev_err(dev, "failed to get bus clock\n"); | 1342 | dev_err(dev, "failed to get bus clock\n"); |
1343 | ret = PTR_ERR(sfb->bus_clk); | ||
1343 | goto err_sfb; | 1344 | goto err_sfb; |
1344 | } | 1345 | } |
1345 | 1346 | ||
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 75738a928610..ddedad9cd069 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c | |||
@@ -64,6 +64,8 @@ static const struct svga_fb_format s3fb_formats[] = { | |||
64 | 64 | ||
65 | static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, | 65 | static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, |
66 | 35000, 240000, 14318}; | 66 | 35000, 240000, 14318}; |
67 | static const struct svga_pll s3_trio3d_pll = {3, 129, 3, 31, 0, 4, | ||
68 | 230000, 460000, 14318}; | ||
67 | 69 | ||
68 | static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; | 70 | static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; |
69 | 71 | ||
@@ -72,7 +74,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", | |||
72 | "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", | 74 | "S3 Plato/PX", "S3 Aurora64VP", "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/GX2P", "S3 Virge/GX2P", |
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 |
@@ -93,6 +96,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", | |||
93 | #define CHIP_360_TRIO3D_1X 0x10 | 96 | #define CHIP_360_TRIO3D_1X 0x10 |
94 | #define CHIP_362_TRIO3D_2X 0x11 | 97 | #define CHIP_362_TRIO3D_2X 0x11 |
95 | #define CHIP_368_TRIO3D_2X 0x12 | 98 | #define CHIP_368_TRIO3D_2X 0x12 |
99 | #define CHIP_365_TRIO3D 0x13 | ||
96 | 100 | ||
97 | #define CHIP_XXX_TRIO 0x80 | 101 | #define CHIP_XXX_TRIO 0x80 |
98 | #define CHIP_XXX_TRIO64V2_DXGX 0x81 | 102 | #define CHIP_XXX_TRIO64V2_DXGX 0x81 |
@@ -119,9 +123,11 @@ static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07, | |||
119 | static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; | 123 | static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; |
120 | 124 | ||
121 | static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END}; | 125 | static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END}; |
122 | static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; | 126 | static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x69, 0, 4}, VGA_REGSET_END}; |
123 | static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ | 127 | static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ |
124 | 128 | ||
129 | static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END}; | ||
130 | |||
125 | static const struct svga_timing_regs s3_timing_regs = { | 131 | static const struct svga_timing_regs s3_timing_regs = { |
126 | s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs, | 132 | 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, | 133 | s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs, |
@@ -188,12 +194,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) | |||
188 | } | 194 | } |
189 | } | 195 | } |
190 | 196 | ||
197 | static void s3fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) | ||
198 | { | ||
199 | struct s3fb_info *par = info->par; | ||
200 | |||
201 | svga_tilecursor(par->state.vgabase, info, cursor); | ||
202 | } | ||
203 | |||
191 | static struct fb_tile_ops s3fb_tile_ops = { | 204 | static struct fb_tile_ops s3fb_tile_ops = { |
192 | .fb_settile = svga_settile, | 205 | .fb_settile = svga_settile, |
193 | .fb_tilecopy = svga_tilecopy, | 206 | .fb_tilecopy = svga_tilecopy, |
194 | .fb_tilefill = svga_tilefill, | 207 | .fb_tilefill = svga_tilefill, |
195 | .fb_tileblit = svga_tileblit, | 208 | .fb_tileblit = svga_tileblit, |
196 | .fb_tilecursor = svga_tilecursor, | 209 | .fb_tilecursor = s3fb_tilecursor, |
197 | .fb_get_tilemax = svga_get_tilemax, | 210 | .fb_get_tilemax = svga_get_tilemax, |
198 | }; | 211 | }; |
199 | 212 | ||
@@ -202,7 +215,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = { | |||
202 | .fb_tilecopy = svga_tilecopy, | 215 | .fb_tilecopy = svga_tilecopy, |
203 | .fb_tilefill = svga_tilefill, | 216 | .fb_tilefill = svga_tilefill, |
204 | .fb_tileblit = svga_tileblit, | 217 | .fb_tileblit = svga_tileblit, |
205 | .fb_tilecursor = svga_tilecursor, | 218 | .fb_tilecursor = s3fb_tilecursor, |
206 | .fb_get_tilemax = svga_get_tilemax, | 219 | .fb_get_tilemax = svga_get_tilemax, |
207 | }; | 220 | }; |
208 | 221 | ||
@@ -334,33 +347,34 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock) | |||
334 | u8 regval; | 347 | u8 regval; |
335 | int rv; | 348 | int rv; |
336 | 349 | ||
337 | rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); | 350 | rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll, |
351 | 1000000000 / pixclock, &m, &n, &r, info->node); | ||
338 | if (rv < 0) { | 352 | if (rv < 0) { |
339 | printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); | 353 | printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); |
340 | return; | 354 | return; |
341 | } | 355 | } |
342 | 356 | ||
343 | /* Set VGA misc register */ | 357 | /* Set VGA misc register */ |
344 | regval = vga_r(NULL, VGA_MIS_R); | 358 | regval = vga_r(par->state.vgabase, VGA_MIS_R); |
345 | vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); | 359 | vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); |
346 | 360 | ||
347 | /* Set S3 clock registers */ | 361 | /* Set S3 clock registers */ |
348 | if (par->chip == CHIP_360_TRIO3D_1X || | 362 | if (par->chip == CHIP_360_TRIO3D_1X || |
349 | par->chip == CHIP_362_TRIO3D_2X || | 363 | par->chip == CHIP_362_TRIO3D_2X || |
350 | par->chip == CHIP_368_TRIO3D_2X) { | 364 | par->chip == CHIP_368_TRIO3D_2X) { |
351 | vga_wseq(NULL, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ | 365 | 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 */ | 366 | vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */ |
353 | } else | 367 | } else |
354 | vga_wseq(NULL, 0x12, (n - 2) | (r << 5)); | 368 | vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5)); |
355 | vga_wseq(NULL, 0x13, m - 2); | 369 | vga_wseq(par->state.vgabase, 0x13, m - 2); |
356 | 370 | ||
357 | udelay(1000); | 371 | udelay(1000); |
358 | 372 | ||
359 | /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ | 373 | /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ |
360 | regval = vga_rseq (NULL, 0x15); /* | 0x80; */ | 374 | regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */ |
361 | vga_wseq(NULL, 0x15, regval & ~(1<<5)); | 375 | vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5)); |
362 | vga_wseq(NULL, 0x15, regval | (1<<5)); | 376 | vga_wseq(par->state.vgabase, 0x15, regval | (1<<5)); |
363 | vga_wseq(NULL, 0x15, regval & ~(1<<5)); | 377 | vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5)); |
364 | } | 378 | } |
365 | 379 | ||
366 | 380 | ||
@@ -372,7 +386,10 @@ static int s3fb_open(struct fb_info *info, int user) | |||
372 | 386 | ||
373 | mutex_lock(&(par->open_lock)); | 387 | mutex_lock(&(par->open_lock)); |
374 | if (par->ref_count == 0) { | 388 | if (par->ref_count == 0) { |
389 | void __iomem *vgabase = par->state.vgabase; | ||
390 | |||
375 | memset(&(par->state), 0, sizeof(struct vgastate)); | 391 | memset(&(par->state), 0, sizeof(struct vgastate)); |
392 | par->state.vgabase = vgabase; | ||
376 | par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; | 393 | par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; |
377 | par->state.num_crtc = 0x70; | 394 | par->state.num_crtc = 0x70; |
378 | par->state.num_seq = 0x20; | 395 | par->state.num_seq = 0x20; |
@@ -470,6 +487,7 @@ static int s3fb_set_par(struct fb_info *info) | |||
470 | struct s3fb_info *par = info->par; | 487 | struct s3fb_info *par = info->par; |
471 | u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; | 488 | u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; |
472 | u32 bpp = info->var.bits_per_pixel; | 489 | u32 bpp = info->var.bits_per_pixel; |
490 | u32 htotal, hsstart; | ||
473 | 491 | ||
474 | if (bpp != 0) { | 492 | if (bpp != 0) { |
475 | info->fix.ypanstep = 1; | 493 | info->fix.ypanstep = 1; |
@@ -504,99 +522,112 @@ static int s3fb_set_par(struct fb_info *info) | |||
504 | info->var.activate = FB_ACTIVATE_NOW; | 522 | info->var.activate = FB_ACTIVATE_NOW; |
505 | 523 | ||
506 | /* Unlock registers */ | 524 | /* Unlock registers */ |
507 | vga_wcrt(NULL, 0x38, 0x48); | 525 | vga_wcrt(par->state.vgabase, 0x38, 0x48); |
508 | vga_wcrt(NULL, 0x39, 0xA5); | 526 | vga_wcrt(par->state.vgabase, 0x39, 0xA5); |
509 | vga_wseq(NULL, 0x08, 0x06); | 527 | vga_wseq(par->state.vgabase, 0x08, 0x06); |
510 | svga_wcrt_mask(0x11, 0x00, 0x80); | 528 | svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80); |
511 | 529 | ||
512 | /* Blank screen and turn off sync */ | 530 | /* Blank screen and turn off sync */ |
513 | svga_wseq_mask(0x01, 0x20, 0x20); | 531 | svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); |
514 | svga_wcrt_mask(0x17, 0x00, 0x80); | 532 | svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80); |
515 | 533 | ||
516 | /* Set default values */ | 534 | /* Set default values */ |
517 | svga_set_default_gfx_regs(); | 535 | svga_set_default_gfx_regs(par->state.vgabase); |
518 | svga_set_default_atc_regs(); | 536 | svga_set_default_atc_regs(par->state.vgabase); |
519 | svga_set_default_seq_regs(); | 537 | svga_set_default_seq_regs(par->state.vgabase); |
520 | svga_set_default_crt_regs(); | 538 | svga_set_default_crt_regs(par->state.vgabase); |
521 | svga_wcrt_multi(s3_line_compare_regs, 0xFFFFFFFF); | 539 | svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF); |
522 | svga_wcrt_multi(s3_start_address_regs, 0); | 540 | svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0); |
523 | 541 | ||
524 | /* S3 specific initialization */ | 542 | /* S3 specific initialization */ |
525 | svga_wcrt_mask(0x58, 0x10, 0x10); /* enable linear framebuffer */ | 543 | 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 */ | 544 | svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */ |
527 | 545 | ||
528 | /* svga_wcrt_mask(0x33, 0x08, 0x08); */ /* DDR ? */ | 546 | /* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */ |
529 | /* svga_wcrt_mask(0x43, 0x01, 0x01); */ /* DDR ? */ | 547 | /* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */ |
530 | svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */ | 548 | svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */ |
531 | svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */ | 549 | svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */ |
532 | 550 | ||
533 | svga_wcrt_mask(0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ | 551 | svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ |
534 | 552 | ||
535 | /* svga_wcrt_mask(0x58, 0x03, 0x03); */ | 553 | /* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */ |
536 | 554 | ||
537 | /* svga_wcrt_mask(0x53, 0x12, 0x13); */ /* enable MMIO */ | 555 | /* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */ |
538 | /* svga_wcrt_mask(0x40, 0x08, 0x08); */ /* enable write buffer */ | 556 | /* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */ |
539 | 557 | ||
540 | 558 | ||
541 | /* Set the offset register */ | 559 | /* Set the offset register */ |
542 | pr_debug("fb%d: offset register : %d\n", info->node, offset_value); | 560 | pr_debug("fb%d: offset register : %d\n", info->node, offset_value); |
543 | svga_wcrt_multi(s3_offset_regs, offset_value); | 561 | svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value); |
544 | 562 | ||
545 | if (par->chip != CHIP_360_TRIO3D_1X && | 563 | if (par->chip != CHIP_360_TRIO3D_1X && |
546 | par->chip != CHIP_362_TRIO3D_2X && | 564 | par->chip != CHIP_362_TRIO3D_2X && |
547 | par->chip != CHIP_368_TRIO3D_2X) { | 565 | par->chip != CHIP_368_TRIO3D_2X) { |
548 | vga_wcrt(NULL, 0x54, 0x18); /* M parameter */ | 566 | vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ |
549 | vga_wcrt(NULL, 0x60, 0xff); /* N parameter */ | 567 | vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */ |
550 | vga_wcrt(NULL, 0x61, 0xff); /* L parameter */ | 568 | vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */ |
551 | vga_wcrt(NULL, 0x62, 0xff); /* L parameter */ | 569 | vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */ |
552 | } | 570 | } |
553 | 571 | ||
554 | vga_wcrt(NULL, 0x3A, 0x35); | 572 | vga_wcrt(par->state.vgabase, 0x3A, 0x35); |
555 | svga_wattr(0x33, 0x00); | 573 | svga_wattr(par->state.vgabase, 0x33, 0x00); |
556 | 574 | ||
557 | if (info->var.vmode & FB_VMODE_DOUBLE) | 575 | if (info->var.vmode & FB_VMODE_DOUBLE) |
558 | svga_wcrt_mask(0x09, 0x80, 0x80); | 576 | svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80); |
559 | else | 577 | else |
560 | svga_wcrt_mask(0x09, 0x00, 0x80); | 578 | svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80); |
561 | 579 | ||
562 | if (info->var.vmode & FB_VMODE_INTERLACED) | 580 | if (info->var.vmode & FB_VMODE_INTERLACED) |
563 | svga_wcrt_mask(0x42, 0x20, 0x20); | 581 | svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20); |
564 | else | 582 | else |
565 | svga_wcrt_mask(0x42, 0x00, 0x20); | 583 | svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20); |
566 | 584 | ||
567 | /* Disable hardware graphics cursor */ | 585 | /* Disable hardware graphics cursor */ |
568 | svga_wcrt_mask(0x45, 0x00, 0x01); | 586 | svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01); |
569 | /* Disable Streams engine */ | 587 | /* Disable Streams engine */ |
570 | svga_wcrt_mask(0x67, 0x00, 0x0C); | 588 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C); |
571 | 589 | ||
572 | mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); | 590 | mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); |
573 | 591 | ||
574 | /* S3 virge DX hack */ | 592 | /* S3 virge DX hack */ |
575 | if (par->chip == CHIP_375_VIRGE_DX) { | 593 | if (par->chip == CHIP_375_VIRGE_DX) { |
576 | vga_wcrt(NULL, 0x86, 0x80); | 594 | vga_wcrt(par->state.vgabase, 0x86, 0x80); |
577 | vga_wcrt(NULL, 0x90, 0x00); | 595 | vga_wcrt(par->state.vgabase, 0x90, 0x00); |
578 | } | 596 | } |
579 | 597 | ||
580 | /* S3 virge VX hack */ | 598 | /* S3 virge VX hack */ |
581 | if (par->chip == CHIP_988_VIRGE_VX) { | 599 | if (par->chip == CHIP_988_VIRGE_VX) { |
582 | vga_wcrt(NULL, 0x50, 0x00); | 600 | vga_wcrt(par->state.vgabase, 0x50, 0x00); |
583 | vga_wcrt(NULL, 0x67, 0x50); | 601 | vga_wcrt(par->state.vgabase, 0x67, 0x50); |
584 | 602 | ||
585 | vga_wcrt(NULL, 0x63, (mode <= 2) ? 0x90 : 0x09); | 603 | vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09); |
586 | vga_wcrt(NULL, 0x66, 0x90); | 604 | vga_wcrt(par->state.vgabase, 0x66, 0x90); |
587 | } | 605 | } |
588 | 606 | ||
589 | if (par->chip == CHIP_360_TRIO3D_1X || | 607 | if (par->chip == CHIP_360_TRIO3D_1X || |
590 | par->chip == CHIP_362_TRIO3D_2X || | 608 | par->chip == CHIP_362_TRIO3D_2X || |
591 | par->chip == CHIP_368_TRIO3D_2X) { | 609 | par->chip == CHIP_368_TRIO3D_2X || |
610 | par->chip == CHIP_365_TRIO3D || | ||
611 | par->chip == CHIP_375_VIRGE_DX || | ||
612 | par->chip == CHIP_385_VIRGE_GX) { | ||
592 | dbytes = info->var.xres * ((bpp+7)/8); | 613 | dbytes = info->var.xres * ((bpp+7)/8); |
593 | vga_wcrt(NULL, 0x91, (dbytes + 7) / 8); | 614 | vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8); |
594 | vga_wcrt(NULL, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); | 615 | vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); |
595 | 616 | ||
596 | vga_wcrt(NULL, 0x66, 0x81); | 617 | vga_wcrt(par->state.vgabase, 0x66, 0x81); |
597 | } | 618 | } |
598 | 619 | ||
599 | svga_wcrt_mask(0x31, 0x00, 0x40); | 620 | if (par->chip == CHIP_356_VIRGE_GX2 || |
621 | par->chip == CHIP_357_VIRGE_GX2P || | ||
622 | par->chip == CHIP_359_VIRGE_GX2P || | ||
623 | par->chip == CHIP_360_TRIO3D_1X || | ||
624 | par->chip == CHIP_362_TRIO3D_2X || | ||
625 | par->chip == CHIP_368_TRIO3D_2X) | ||
626 | vga_wcrt(par->state.vgabase, 0x34, 0x00); | ||
627 | else /* enable Data Transfer Position Control (DTPC) */ | ||
628 | vga_wcrt(par->state.vgabase, 0x34, 0x10); | ||
629 | |||
630 | svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40); | ||
600 | multiplex = 0; | 631 | multiplex = 0; |
601 | hmul = 1; | 632 | hmul = 1; |
602 | 633 | ||
@@ -604,51 +635,51 @@ static int s3fb_set_par(struct fb_info *info) | |||
604 | switch (mode) { | 635 | switch (mode) { |
605 | case 0: | 636 | case 0: |
606 | pr_debug("fb%d: text mode\n", info->node); | 637 | pr_debug("fb%d: text mode\n", info->node); |
607 | svga_set_textmode_vga_regs(); | 638 | svga_set_textmode_vga_regs(par->state.vgabase); |
608 | 639 | ||
609 | /* Set additional registers like in 8-bit mode */ | 640 | /* Set additional registers like in 8-bit mode */ |
610 | svga_wcrt_mask(0x50, 0x00, 0x30); | 641 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); |
611 | svga_wcrt_mask(0x67, 0x00, 0xF0); | 642 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); |
612 | 643 | ||
613 | /* Disable enhanced mode */ | 644 | /* Disable enhanced mode */ |
614 | svga_wcrt_mask(0x3A, 0x00, 0x30); | 645 | svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); |
615 | 646 | ||
616 | if (fasttext) { | 647 | if (fasttext) { |
617 | pr_debug("fb%d: high speed text mode set\n", info->node); | 648 | pr_debug("fb%d: high speed text mode set\n", info->node); |
618 | svga_wcrt_mask(0x31, 0x40, 0x40); | 649 | svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40); |
619 | } | 650 | } |
620 | break; | 651 | break; |
621 | case 1: | 652 | case 1: |
622 | pr_debug("fb%d: 4 bit pseudocolor\n", info->node); | 653 | pr_debug("fb%d: 4 bit pseudocolor\n", info->node); |
623 | vga_wgfx(NULL, VGA_GFX_MODE, 0x40); | 654 | vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40); |
624 | 655 | ||
625 | /* Set additional registers like in 8-bit mode */ | 656 | /* Set additional registers like in 8-bit mode */ |
626 | svga_wcrt_mask(0x50, 0x00, 0x30); | 657 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); |
627 | svga_wcrt_mask(0x67, 0x00, 0xF0); | 658 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); |
628 | 659 | ||
629 | /* disable enhanced mode */ | 660 | /* disable enhanced mode */ |
630 | svga_wcrt_mask(0x3A, 0x00, 0x30); | 661 | svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); |
631 | break; | 662 | break; |
632 | case 2: | 663 | case 2: |
633 | pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); | 664 | pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); |
634 | 665 | ||
635 | /* Set additional registers like in 8-bit mode */ | 666 | /* Set additional registers like in 8-bit mode */ |
636 | svga_wcrt_mask(0x50, 0x00, 0x30); | 667 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); |
637 | svga_wcrt_mask(0x67, 0x00, 0xF0); | 668 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); |
638 | 669 | ||
639 | /* disable enhanced mode */ | 670 | /* disable enhanced mode */ |
640 | svga_wcrt_mask(0x3A, 0x00, 0x30); | 671 | svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); |
641 | break; | 672 | break; |
642 | case 3: | 673 | case 3: |
643 | pr_debug("fb%d: 8 bit pseudocolor\n", info->node); | 674 | pr_debug("fb%d: 8 bit pseudocolor\n", info->node); |
644 | svga_wcrt_mask(0x50, 0x00, 0x30); | 675 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); |
645 | if (info->var.pixclock > 20000 || | 676 | if (info->var.pixclock > 20000 || |
646 | par->chip == CHIP_360_TRIO3D_1X || | 677 | par->chip == CHIP_360_TRIO3D_1X || |
647 | par->chip == CHIP_362_TRIO3D_2X || | 678 | par->chip == CHIP_362_TRIO3D_2X || |
648 | par->chip == CHIP_368_TRIO3D_2X) | 679 | par->chip == CHIP_368_TRIO3D_2X) |
649 | svga_wcrt_mask(0x67, 0x00, 0xF0); | 680 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); |
650 | else { | 681 | else { |
651 | svga_wcrt_mask(0x67, 0x10, 0xF0); | 682 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0); |
652 | multiplex = 1; | 683 | multiplex = 1; |
653 | } | 684 | } |
654 | break; | 685 | break; |
@@ -656,12 +687,21 @@ static int s3fb_set_par(struct fb_info *info) | |||
656 | pr_debug("fb%d: 5/5/5 truecolor\n", info->node); | 687 | pr_debug("fb%d: 5/5/5 truecolor\n", info->node); |
657 | if (par->chip == CHIP_988_VIRGE_VX) { | 688 | if (par->chip == CHIP_988_VIRGE_VX) { |
658 | if (info->var.pixclock > 20000) | 689 | if (info->var.pixclock > 20000) |
659 | svga_wcrt_mask(0x67, 0x20, 0xF0); | 690 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0); |
660 | else | 691 | else |
661 | svga_wcrt_mask(0x67, 0x30, 0xF0); | 692 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); |
693 | } else if (par->chip == CHIP_365_TRIO3D) { | ||
694 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); | ||
695 | if (info->var.pixclock > 8695) { | ||
696 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); | ||
697 | hmul = 2; | ||
698 | } else { | ||
699 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0); | ||
700 | multiplex = 1; | ||
701 | } | ||
662 | } else { | 702 | } else { |
663 | svga_wcrt_mask(0x50, 0x10, 0x30); | 703 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); |
664 | svga_wcrt_mask(0x67, 0x30, 0xF0); | 704 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); |
665 | if (par->chip != CHIP_360_TRIO3D_1X && | 705 | if (par->chip != CHIP_360_TRIO3D_1X && |
666 | par->chip != CHIP_362_TRIO3D_2X && | 706 | par->chip != CHIP_362_TRIO3D_2X && |
667 | par->chip != CHIP_368_TRIO3D_2X) | 707 | par->chip != CHIP_368_TRIO3D_2X) |
@@ -672,12 +712,21 @@ static int s3fb_set_par(struct fb_info *info) | |||
672 | pr_debug("fb%d: 5/6/5 truecolor\n", info->node); | 712 | pr_debug("fb%d: 5/6/5 truecolor\n", info->node); |
673 | if (par->chip == CHIP_988_VIRGE_VX) { | 713 | if (par->chip == CHIP_988_VIRGE_VX) { |
674 | if (info->var.pixclock > 20000) | 714 | if (info->var.pixclock > 20000) |
675 | svga_wcrt_mask(0x67, 0x40, 0xF0); | 715 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0); |
676 | else | 716 | else |
677 | svga_wcrt_mask(0x67, 0x50, 0xF0); | 717 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); |
718 | } else if (par->chip == CHIP_365_TRIO3D) { | ||
719 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); | ||
720 | if (info->var.pixclock > 8695) { | ||
721 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); | ||
722 | hmul = 2; | ||
723 | } else { | ||
724 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0); | ||
725 | multiplex = 1; | ||
726 | } | ||
678 | } else { | 727 | } else { |
679 | svga_wcrt_mask(0x50, 0x10, 0x30); | 728 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); |
680 | svga_wcrt_mask(0x67, 0x50, 0xF0); | 729 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); |
681 | if (par->chip != CHIP_360_TRIO3D_1X && | 730 | if (par->chip != CHIP_360_TRIO3D_1X && |
682 | par->chip != CHIP_362_TRIO3D_2X && | 731 | par->chip != CHIP_362_TRIO3D_2X && |
683 | par->chip != CHIP_368_TRIO3D_2X) | 732 | par->chip != CHIP_368_TRIO3D_2X) |
@@ -687,12 +736,12 @@ static int s3fb_set_par(struct fb_info *info) | |||
687 | case 6: | 736 | case 6: |
688 | /* VIRGE VX case */ | 737 | /* VIRGE VX case */ |
689 | pr_debug("fb%d: 8/8/8 truecolor\n", info->node); | 738 | pr_debug("fb%d: 8/8/8 truecolor\n", info->node); |
690 | svga_wcrt_mask(0x67, 0xD0, 0xF0); | 739 | svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0); |
691 | break; | 740 | break; |
692 | case 7: | 741 | case 7: |
693 | pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); | 742 | pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); |
694 | svga_wcrt_mask(0x50, 0x30, 0x30); | 743 | svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30); |
695 | svga_wcrt_mask(0x67, 0xD0, 0xF0); | 744 | svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0); |
696 | break; | 745 | break; |
697 | default: | 746 | default: |
698 | printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); | 747 | printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); |
@@ -700,25 +749,30 @@ static int s3fb_set_par(struct fb_info *info) | |||
700 | } | 749 | } |
701 | 750 | ||
702 | if (par->chip != CHIP_988_VIRGE_VX) { | 751 | if (par->chip != CHIP_988_VIRGE_VX) { |
703 | svga_wseq_mask(0x15, multiplex ? 0x10 : 0x00, 0x10); | 752 | svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10); |
704 | svga_wseq_mask(0x18, multiplex ? 0x80 : 0x00, 0x80); | 753 | svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80); |
705 | } | 754 | } |
706 | 755 | ||
707 | s3_set_pixclock(info, info->var.pixclock); | 756 | s3_set_pixclock(info, info->var.pixclock); |
708 | svga_set_timings(&s3_timing_regs, &(info->var), hmul, 1, | 757 | svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1, |
709 | (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, | 758 | (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, |
710 | (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, | 759 | (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, |
711 | hmul, info->node); | 760 | hmul, info->node); |
712 | 761 | ||
713 | /* Set interlaced mode start/end register */ | 762 | /* Set interlaced mode start/end register */ |
714 | value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; | 763 | htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; |
715 | value = ((value * hmul) / 8) - 5; | 764 | htotal = ((htotal * hmul) / 8) - 5; |
716 | vga_wcrt(NULL, 0x3C, (value + 1) / 2); | 765 | vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2); |
766 | |||
767 | /* Set Data Transfer Position */ | ||
768 | hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8; | ||
769 | value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1); | ||
770 | svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value); | ||
717 | 771 | ||
718 | memset_io(info->screen_base, 0x00, screen_size); | 772 | memset_io(info->screen_base, 0x00, screen_size); |
719 | /* Device and screen back on */ | 773 | /* Device and screen back on */ |
720 | svga_wcrt_mask(0x17, 0x80, 0x80); | 774 | svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80); |
721 | svga_wseq_mask(0x01, 0x00, 0x20); | 775 | svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20); |
722 | 776 | ||
723 | return 0; | 777 | return 0; |
724 | } | 778 | } |
@@ -788,31 +842,33 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
788 | 842 | ||
789 | static int s3fb_blank(int blank_mode, struct fb_info *info) | 843 | static int s3fb_blank(int blank_mode, struct fb_info *info) |
790 | { | 844 | { |
845 | struct s3fb_info *par = info->par; | ||
846 | |||
791 | switch (blank_mode) { | 847 | switch (blank_mode) { |
792 | case FB_BLANK_UNBLANK: | 848 | case FB_BLANK_UNBLANK: |
793 | pr_debug("fb%d: unblank\n", info->node); | 849 | pr_debug("fb%d: unblank\n", info->node); |
794 | svga_wcrt_mask(0x56, 0x00, 0x06); | 850 | svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06); |
795 | svga_wseq_mask(0x01, 0x00, 0x20); | 851 | svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20); |
796 | break; | 852 | break; |
797 | case FB_BLANK_NORMAL: | 853 | case FB_BLANK_NORMAL: |
798 | pr_debug("fb%d: blank\n", info->node); | 854 | pr_debug("fb%d: blank\n", info->node); |
799 | svga_wcrt_mask(0x56, 0x00, 0x06); | 855 | svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06); |
800 | svga_wseq_mask(0x01, 0x20, 0x20); | 856 | svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); |
801 | break; | 857 | break; |
802 | case FB_BLANK_HSYNC_SUSPEND: | 858 | case FB_BLANK_HSYNC_SUSPEND: |
803 | pr_debug("fb%d: hsync\n", info->node); | 859 | pr_debug("fb%d: hsync\n", info->node); |
804 | svga_wcrt_mask(0x56, 0x02, 0x06); | 860 | svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06); |
805 | svga_wseq_mask(0x01, 0x20, 0x20); | 861 | svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); |
806 | break; | 862 | break; |
807 | case FB_BLANK_VSYNC_SUSPEND: | 863 | case FB_BLANK_VSYNC_SUSPEND: |
808 | pr_debug("fb%d: vsync\n", info->node); | 864 | pr_debug("fb%d: vsync\n", info->node); |
809 | svga_wcrt_mask(0x56, 0x04, 0x06); | 865 | svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06); |
810 | svga_wseq_mask(0x01, 0x20, 0x20); | 866 | svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); |
811 | break; | 867 | break; |
812 | case FB_BLANK_POWERDOWN: | 868 | case FB_BLANK_POWERDOWN: |
813 | pr_debug("fb%d: sync down\n", info->node); | 869 | pr_debug("fb%d: sync down\n", info->node); |
814 | svga_wcrt_mask(0x56, 0x06, 0x06); | 870 | svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06); |
815 | svga_wseq_mask(0x01, 0x20, 0x20); | 871 | svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); |
816 | break; | 872 | break; |
817 | } | 873 | } |
818 | 874 | ||
@@ -822,8 +878,9 @@ static int s3fb_blank(int blank_mode, struct fb_info *info) | |||
822 | 878 | ||
823 | /* Pan the display */ | 879 | /* Pan the display */ |
824 | 880 | ||
825 | static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { | 881 | static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) |
826 | 882 | { | |
883 | struct s3fb_info *par = info->par; | ||
827 | unsigned int offset; | 884 | unsigned int offset; |
828 | 885 | ||
829 | /* Calculate the offset */ | 886 | /* Calculate the offset */ |
@@ -837,7 +894,7 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
837 | } | 894 | } |
838 | 895 | ||
839 | /* Set the offset */ | 896 | /* Set the offset */ |
840 | svga_wcrt_multi(s3_start_address_regs, offset); | 897 | svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset); |
841 | 898 | ||
842 | return 0; | 899 | return 0; |
843 | } | 900 | } |
@@ -863,12 +920,14 @@ static struct fb_ops s3fb_ops = { | |||
863 | 920 | ||
864 | /* ------------------------------------------------------------------------- */ | 921 | /* ------------------------------------------------------------------------- */ |
865 | 922 | ||
866 | static int __devinit s3_identification(int chip) | 923 | static int __devinit s3_identification(struct s3fb_info *par) |
867 | { | 924 | { |
925 | int chip = par->chip; | ||
926 | |||
868 | if (chip == CHIP_XXX_TRIO) { | 927 | if (chip == CHIP_XXX_TRIO) { |
869 | u8 cr30 = vga_rcrt(NULL, 0x30); | 928 | u8 cr30 = vga_rcrt(par->state.vgabase, 0x30); |
870 | u8 cr2e = vga_rcrt(NULL, 0x2e); | 929 | u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e); |
871 | u8 cr2f = vga_rcrt(NULL, 0x2f); | 930 | u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f); |
872 | 931 | ||
873 | if ((cr30 == 0xE0) || (cr30 == 0xE1)) { | 932 | if ((cr30 == 0xE0) || (cr30 == 0xE1)) { |
874 | if (cr2e == 0x10) | 933 | if (cr2e == 0x10) |
@@ -883,7 +942,7 @@ static int __devinit s3_identification(int chip) | |||
883 | } | 942 | } |
884 | 943 | ||
885 | if (chip == CHIP_XXX_TRIO64V2_DXGX) { | 944 | if (chip == CHIP_XXX_TRIO64V2_DXGX) { |
886 | u8 cr6f = vga_rcrt(NULL, 0x6f); | 945 | u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f); |
887 | 946 | ||
888 | if (! (cr6f & 0x01)) | 947 | if (! (cr6f & 0x01)) |
889 | return CHIP_775_TRIO64V2_DX; | 948 | return CHIP_775_TRIO64V2_DX; |
@@ -892,7 +951,7 @@ static int __devinit s3_identification(int chip) | |||
892 | } | 951 | } |
893 | 952 | ||
894 | if (chip == CHIP_XXX_VIRGE_DXGX) { | 953 | if (chip == CHIP_XXX_VIRGE_DXGX) { |
895 | u8 cr6f = vga_rcrt(NULL, 0x6f); | 954 | u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f); |
896 | 955 | ||
897 | if (! (cr6f & 0x01)) | 956 | if (! (cr6f & 0x01)) |
898 | return CHIP_375_VIRGE_DX; | 957 | return CHIP_375_VIRGE_DX; |
@@ -901,7 +960,7 @@ static int __devinit s3_identification(int chip) | |||
901 | } | 960 | } |
902 | 961 | ||
903 | if (chip == CHIP_36X_TRIO3D_1X_2X) { | 962 | if (chip == CHIP_36X_TRIO3D_1X_2X) { |
904 | switch (vga_rcrt(NULL, 0x2f)) { | 963 | switch (vga_rcrt(par->state.vgabase, 0x2f)) { |
905 | case 0x00: | 964 | case 0x00: |
906 | return CHIP_360_TRIO3D_1X; | 965 | return CHIP_360_TRIO3D_1X; |
907 | case 0x01: | 966 | case 0x01: |
@@ -919,6 +978,8 @@ static int __devinit s3_identification(int chip) | |||
919 | 978 | ||
920 | static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | 979 | static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
921 | { | 980 | { |
981 | struct pci_bus_region bus_reg; | ||
982 | struct resource vga_res; | ||
922 | struct fb_info *info; | 983 | struct fb_info *info; |
923 | struct s3fb_info *par; | 984 | struct s3fb_info *par; |
924 | int rc; | 985 | int rc; |
@@ -968,31 +1029,42 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i | |||
968 | goto err_iomap; | 1029 | goto err_iomap; |
969 | } | 1030 | } |
970 | 1031 | ||
1032 | bus_reg.start = 0; | ||
1033 | bus_reg.end = 64 * 1024; | ||
1034 | |||
1035 | vga_res.flags = IORESOURCE_IO; | ||
1036 | |||
1037 | pcibios_bus_to_resource(dev, &vga_res, &bus_reg); | ||
1038 | |||
1039 | par->state.vgabase = (void __iomem *) vga_res.start; | ||
1040 | |||
971 | /* Unlock regs */ | 1041 | /* Unlock regs */ |
972 | cr38 = vga_rcrt(NULL, 0x38); | 1042 | cr38 = vga_rcrt(par->state.vgabase, 0x38); |
973 | cr39 = vga_rcrt(NULL, 0x39); | 1043 | cr39 = vga_rcrt(par->state.vgabase, 0x39); |
974 | vga_wseq(NULL, 0x08, 0x06); | 1044 | vga_wseq(par->state.vgabase, 0x08, 0x06); |
975 | vga_wcrt(NULL, 0x38, 0x48); | 1045 | vga_wcrt(par->state.vgabase, 0x38, 0x48); |
976 | vga_wcrt(NULL, 0x39, 0xA5); | 1046 | vga_wcrt(par->state.vgabase, 0x39, 0xA5); |
977 | 1047 | ||
978 | /* Identify chip type */ | 1048 | /* Identify chip type */ |
979 | par->chip = id->driver_data & CHIP_MASK; | 1049 | par->chip = id->driver_data & CHIP_MASK; |
980 | par->rev = vga_rcrt(NULL, 0x2f); | 1050 | par->rev = vga_rcrt(par->state.vgabase, 0x2f); |
981 | if (par->chip & CHIP_UNDECIDED_FLAG) | 1051 | if (par->chip & CHIP_UNDECIDED_FLAG) |
982 | par->chip = s3_identification(par->chip); | 1052 | par->chip = s3_identification(par); |
983 | 1053 | ||
984 | /* Find how many physical memory there is on card */ | 1054 | /* Find how many physical memory there is on card */ |
985 | /* 0x36 register is accessible even if other registers are locked */ | 1055 | /* 0x36 register is accessible even if other registers are locked */ |
986 | regval = vga_rcrt(NULL, 0x36); | 1056 | regval = vga_rcrt(par->state.vgabase, 0x36); |
987 | if (par->chip == CHIP_360_TRIO3D_1X || | 1057 | if (par->chip == CHIP_360_TRIO3D_1X || |
988 | par->chip == CHIP_362_TRIO3D_2X || | 1058 | par->chip == CHIP_362_TRIO3D_2X || |
989 | par->chip == CHIP_368_TRIO3D_2X) { | 1059 | par->chip == CHIP_368_TRIO3D_2X || |
1060 | par->chip == CHIP_365_TRIO3D) { | ||
990 | switch ((regval & 0xE0) >> 5) { | 1061 | switch ((regval & 0xE0) >> 5) { |
991 | case 0: /* 8MB -- only 4MB usable for display */ | 1062 | case 0: /* 8MB -- only 4MB usable for display */ |
992 | case 1: /* 4MB with 32-bit bus */ | 1063 | case 1: /* 4MB with 32-bit bus */ |
993 | case 2: /* 4MB */ | 1064 | case 2: /* 4MB */ |
994 | info->screen_size = 4 << 20; | 1065 | info->screen_size = 4 << 20; |
995 | break; | 1066 | break; |
1067 | case 4: /* 2MB on 365 Trio3D */ | ||
996 | case 6: /* 2MB */ | 1068 | case 6: /* 2MB */ |
997 | info->screen_size = 2 << 20; | 1069 | info->screen_size = 2 << 20; |
998 | break; | 1070 | break; |
@@ -1002,13 +1074,13 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i | |||
1002 | info->fix.smem_len = info->screen_size; | 1074 | info->fix.smem_len = info->screen_size; |
1003 | 1075 | ||
1004 | /* Find MCLK frequency */ | 1076 | /* Find MCLK frequency */ |
1005 | regval = vga_rseq(NULL, 0x10); | 1077 | regval = vga_rseq(par->state.vgabase, 0x10); |
1006 | par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); | 1078 | par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); |
1007 | par->mclk_freq = par->mclk_freq >> (regval >> 5); | 1079 | par->mclk_freq = par->mclk_freq >> (regval >> 5); |
1008 | 1080 | ||
1009 | /* Restore locks */ | 1081 | /* Restore locks */ |
1010 | vga_wcrt(NULL, 0x38, cr38); | 1082 | vga_wcrt(par->state.vgabase, 0x38, cr38); |
1011 | vga_wcrt(NULL, 0x39, cr39); | 1083 | vga_wcrt(par->state.vgabase, 0x39, cr39); |
1012 | 1084 | ||
1013 | strcpy(info->fix.id, s3_names [par->chip]); | 1085 | strcpy(info->fix.id, s3_names [par->chip]); |
1014 | info->fix.mmio_start = 0; | 1086 | info->fix.mmio_start = 0; |
@@ -1027,6 +1099,14 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i | |||
1027 | goto err_find_mode; | 1099 | goto err_find_mode; |
1028 | } | 1100 | } |
1029 | 1101 | ||
1102 | /* maximize virtual vertical size for fast scrolling */ | ||
1103 | info->var.yres_virtual = info->fix.smem_len * 8 / | ||
1104 | (info->var.bits_per_pixel * info->var.xres_virtual); | ||
1105 | if (info->var.yres_virtual < info->var.yres) { | ||
1106 | dev_err(info->device, "virtual vertical size smaller than real\n"); | ||
1107 | goto err_find_mode; | ||
1108 | } | ||
1109 | |||
1030 | rc = fb_alloc_cmap(&info->cmap, 256, 0); | 1110 | rc = fb_alloc_cmap(&info->cmap, 256, 0); |
1031 | if (rc < 0) { | 1111 | if (rc < 0) { |
1032 | dev_err(info->device, "cannot allocate colormap\n"); | 1112 | dev_err(info->device, "cannot allocate colormap\n"); |
@@ -1044,8 +1124,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i | |||
1044 | 1124 | ||
1045 | if (par->chip == CHIP_UNKNOWN) | 1125 | if (par->chip == CHIP_UNKNOWN) |
1046 | printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", | 1126 | 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), | 1127 | info->node, vga_rcrt(par->state.vgabase, 0x2d), vga_rcrt(par->state.vgabase, 0x2e), |
1048 | vga_rcrt(NULL, 0x2f), vga_rcrt(NULL, 0x30)); | 1128 | vga_rcrt(par->state.vgabase, 0x2f), vga_rcrt(par->state.vgabase, 0x30)); |
1049 | 1129 | ||
1050 | /* Record a reference to the driver data */ | 1130 | /* Record a reference to the driver data */ |
1051 | pci_set_drvdata(dev, info); | 1131 | pci_set_drvdata(dev, info); |
@@ -1192,6 +1272,7 @@ static struct pci_device_id s3_devices[] __devinitdata = { | |||
1192 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, | 1272 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, |
1193 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, | 1273 | {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}, | 1274 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, |
1275 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D}, | ||
1195 | 1276 | ||
1196 | {0, 0, 0, 0, 0, 0, 0} | 1277 | {0, 0, 0, 0, 0, 0, 0} |
1197 | }; | 1278 | }; |
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 bf12e53aed5c..757665bc500f 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/ioctl.h> | 21 | #include <linux/ioctl.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/console.h> | 23 | #include <linux/console.h> |
24 | #include <linux/backlight.h> | ||
25 | #include <linux/gpio.h> | ||
24 | #include <video/sh_mobile_lcdc.h> | 26 | #include <video/sh_mobile_lcdc.h> |
25 | #include <asm/atomic.h> | 27 | #include <asm/atomic.h> |
26 | 28 | ||
@@ -67,6 +69,7 @@ static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { | |||
67 | [LDSM1R] = 0x428, | 69 | [LDSM1R] = 0x428, |
68 | [LDSM2R] = 0x42c, | 70 | [LDSM2R] = 0x42c, |
69 | [LDSA1R] = 0x430, | 71 | [LDSA1R] = 0x430, |
72 | [LDSA2R] = 0x434, | ||
70 | [LDMLSR] = 0x438, | 73 | [LDMLSR] = 0x438, |
71 | [LDHCNR] = 0x448, | 74 | [LDHCNR] = 0x448, |
72 | [LDHSYNR] = 0x44c, | 75 | [LDHSYNR] = 0x44c, |
@@ -151,6 +154,7 @@ static bool banked(int reg_nr) | |||
151 | case LDDFR: | 154 | case LDDFR: |
152 | case LDSM1R: | 155 | case LDSM1R: |
153 | case LDSA1R: | 156 | case LDSA1R: |
157 | case LDSA2R: | ||
154 | case LDMLSR: | 158 | case LDMLSR: |
155 | case LDHCNR: | 159 | case LDHCNR: |
156 | case LDHSYNR: | 160 | case LDHSYNR: |
@@ -463,6 +467,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
463 | struct sh_mobile_lcdc_board_cfg *board_cfg; | 467 | struct sh_mobile_lcdc_board_cfg *board_cfg; |
464 | unsigned long tmp; | 468 | unsigned long tmp; |
465 | int bpp = 0; | 469 | int bpp = 0; |
470 | unsigned long ldddsr; | ||
466 | int k, m; | 471 | int k, m; |
467 | int ret = 0; | 472 | int ret = 0; |
468 | 473 | ||
@@ -541,16 +546,21 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
541 | } | 546 | } |
542 | 547 | ||
543 | /* word and long word swap */ | 548 | /* word and long word swap */ |
544 | switch (bpp) { | 549 | ldddsr = lcdc_read(priv, _LDDDSR); |
545 | case 16: | 550 | if (priv->ch[0].info->var.nonstd) |
546 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); | 551 | lcdc_write(priv, _LDDDSR, ldddsr | 7); |
547 | break; | 552 | else { |
548 | case 24: | 553 | switch (bpp) { |
549 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 7); | 554 | case 16: |
550 | break; | 555 | lcdc_write(priv, _LDDDSR, ldddsr | 6); |
551 | case 32: | 556 | break; |
552 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 4); | 557 | case 24: |
553 | break; | 558 | lcdc_write(priv, _LDDDSR, ldddsr | 7); |
559 | break; | ||
560 | case 32: | ||
561 | lcdc_write(priv, _LDDDSR, ldddsr | 4); | ||
562 | break; | ||
563 | } | ||
554 | } | 564 | } |
555 | 565 | ||
556 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 566 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
@@ -561,21 +571,40 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
561 | 571 | ||
562 | /* set bpp format in PKF[4:0] */ | 572 | /* set bpp format in PKF[4:0] */ |
563 | tmp = lcdc_read_chan(ch, LDDFR); | 573 | tmp = lcdc_read_chan(ch, LDDFR); |
564 | tmp &= ~0x0001001f; | 574 | tmp &= ~0x0003031f; |
565 | switch (ch->info->var.bits_per_pixel) { | 575 | if (ch->info->var.nonstd) { |
566 | case 16: | 576 | tmp |= (ch->info->var.nonstd << 16); |
567 | tmp |= 0x03; | 577 | switch (ch->info->var.bits_per_pixel) { |
568 | break; | 578 | case 12: |
569 | case 24: | 579 | break; |
570 | tmp |= 0x0b; | 580 | case 16: |
571 | break; | 581 | tmp |= (0x1 << 8); |
572 | case 32: | 582 | break; |
573 | break; | 583 | case 24: |
584 | tmp |= (0x2 << 8); | ||
585 | break; | ||
586 | } | ||
587 | } else { | ||
588 | switch (ch->info->var.bits_per_pixel) { | ||
589 | case 16: | ||
590 | tmp |= 0x03; | ||
591 | break; | ||
592 | case 24: | ||
593 | tmp |= 0x0b; | ||
594 | break; | ||
595 | case 32: | ||
596 | break; | ||
597 | } | ||
574 | } | 598 | } |
575 | lcdc_write_chan(ch, LDDFR, tmp); | 599 | lcdc_write_chan(ch, LDDFR, tmp); |
576 | 600 | ||
577 | /* point out our frame buffer */ | 601 | /* point out our frame buffer */ |
578 | lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start); | 602 | lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start); |
603 | if (ch->info->var.nonstd) | ||
604 | lcdc_write_chan(ch, LDSA2R, | ||
605 | ch->info->fix.smem_start + | ||
606 | ch->info->var.xres * | ||
607 | ch->info->var.yres_virtual); | ||
579 | 608 | ||
580 | /* set line size */ | 609 | /* set line size */ |
581 | lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length); | 610 | lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length); |
@@ -618,6 +647,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
618 | board_cfg->display_on(board_cfg->board_data, ch->info); | 647 | board_cfg->display_on(board_cfg->board_data, ch->info); |
619 | module_put(board_cfg->owner); | 648 | module_put(board_cfg->owner); |
620 | } | 649 | } |
650 | |||
651 | if (ch->bl) { | ||
652 | ch->bl->props.power = FB_BLANK_UNBLANK; | ||
653 | backlight_update_status(ch->bl); | ||
654 | } | ||
621 | } | 655 | } |
622 | 656 | ||
623 | return 0; | 657 | return 0; |
@@ -648,6 +682,11 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
648 | sh_mobile_lcdc_clk_on(priv); | 682 | sh_mobile_lcdc_clk_on(priv); |
649 | } | 683 | } |
650 | 684 | ||
685 | if (ch->bl) { | ||
686 | ch->bl->props.power = FB_BLANK_POWERDOWN; | ||
687 | backlight_update_status(ch->bl); | ||
688 | } | ||
689 | |||
651 | board_cfg = &ch->cfg.board_cfg; | 690 | board_cfg = &ch->cfg.board_cfg; |
652 | if (try_module_get(board_cfg->owner) && board_cfg->display_off) { | 691 | if (try_module_get(board_cfg->owner) && board_cfg->display_off) { |
653 | board_cfg->display_off(board_cfg->board_data); | 692 | board_cfg->display_off(board_cfg->board_data); |
@@ -804,9 +843,15 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var, | |||
804 | struct sh_mobile_lcdc_priv *priv = ch->lcdc; | 843 | struct sh_mobile_lcdc_priv *priv = ch->lcdc; |
805 | unsigned long ldrcntr; | 844 | unsigned long ldrcntr; |
806 | unsigned long new_pan_offset; | 845 | unsigned long new_pan_offset; |
846 | unsigned long base_addr_y, base_addr_c; | ||
847 | unsigned long c_offset; | ||
807 | 848 | ||
808 | new_pan_offset = (var->yoffset * info->fix.line_length) + | 849 | if (!var->nonstd) |
809 | (var->xoffset * (info->var.bits_per_pixel / 8)); | 850 | new_pan_offset = (var->yoffset * info->fix.line_length) + |
851 | (var->xoffset * (info->var.bits_per_pixel / 8)); | ||
852 | else | ||
853 | new_pan_offset = (var->yoffset * info->fix.line_length) + | ||
854 | (var->xoffset); | ||
810 | 855 | ||
811 | if (new_pan_offset == ch->pan_offset) | 856 | if (new_pan_offset == ch->pan_offset) |
812 | return 0; /* No change, do nothing */ | 857 | return 0; /* No change, do nothing */ |
@@ -814,7 +859,26 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var, | |||
814 | ldrcntr = lcdc_read(priv, _LDRCNTR); | 859 | ldrcntr = lcdc_read(priv, _LDRCNTR); |
815 | 860 | ||
816 | /* Set the source address for the next refresh */ | 861 | /* Set the source address for the next refresh */ |
817 | lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset); | 862 | base_addr_y = ch->dma_handle + new_pan_offset; |
863 | if (var->nonstd) { | ||
864 | /* Set y offset */ | ||
865 | c_offset = (var->yoffset * | ||
866 | info->fix.line_length * | ||
867 | (info->var.bits_per_pixel - 8)) / 8; | ||
868 | base_addr_c = ch->dma_handle + var->xres * var->yres_virtual + | ||
869 | c_offset; | ||
870 | /* Set x offset */ | ||
871 | if (info->var.bits_per_pixel == 24) | ||
872 | base_addr_c += 2 * var->xoffset; | ||
873 | else | ||
874 | base_addr_c += var->xoffset; | ||
875 | } else | ||
876 | base_addr_c = 0; | ||
877 | |||
878 | lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y); | ||
879 | if (base_addr_c) | ||
880 | lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c); | ||
881 | |||
818 | if (lcdc_chan_is_sublcd(ch)) | 882 | if (lcdc_chan_is_sublcd(ch)) |
819 | lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); | 883 | lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); |
820 | else | 884 | else |
@@ -885,7 +949,10 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) | |||
885 | /* Couldn't reconfigure, hopefully, can continue as before */ | 949 | /* Couldn't reconfigure, hopefully, can continue as before */ |
886 | return; | 950 | return; |
887 | 951 | ||
888 | info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8); | 952 | if (info->var.nonstd) |
953 | info->fix.line_length = mode1.xres; | ||
954 | else | ||
955 | info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8); | ||
889 | 956 | ||
890 | /* | 957 | /* |
891 | * fb_set_var() calls the notifier change internally, only if | 958 | * fb_set_var() calls the notifier change internally, only if |
@@ -980,8 +1047,81 @@ static struct fb_ops sh_mobile_lcdc_ops = { | |||
980 | .fb_check_var = sh_mobile_check_var, | 1047 | .fb_check_var = sh_mobile_check_var, |
981 | }; | 1048 | }; |
982 | 1049 | ||
983 | static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) | 1050 | static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev) |
1051 | { | ||
1052 | struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); | ||
1053 | struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg; | ||
1054 | int brightness = bdev->props.brightness; | ||
1055 | |||
1056 | if (bdev->props.power != FB_BLANK_UNBLANK || | ||
1057 | bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) | ||
1058 | brightness = 0; | ||
1059 | |||
1060 | return cfg->set_brightness(cfg->board_data, brightness); | ||
1061 | } | ||
1062 | |||
1063 | static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev) | ||
984 | { | 1064 | { |
1065 | struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); | ||
1066 | struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg; | ||
1067 | |||
1068 | return cfg->get_brightness(cfg->board_data); | ||
1069 | } | ||
1070 | |||
1071 | static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev, | ||
1072 | struct fb_info *info) | ||
1073 | { | ||
1074 | return (info->bl_dev == bdev); | ||
1075 | } | ||
1076 | |||
1077 | static struct backlight_ops sh_mobile_lcdc_bl_ops = { | ||
1078 | .options = BL_CORE_SUSPENDRESUME, | ||
1079 | .update_status = sh_mobile_lcdc_update_bl, | ||
1080 | .get_brightness = sh_mobile_lcdc_get_brightness, | ||
1081 | .check_fb = sh_mobile_lcdc_check_fb, | ||
1082 | }; | ||
1083 | |||
1084 | static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent, | ||
1085 | struct sh_mobile_lcdc_chan *ch) | ||
1086 | { | ||
1087 | struct backlight_device *bl; | ||
1088 | |||
1089 | bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch, | ||
1090 | &sh_mobile_lcdc_bl_ops, NULL); | ||
1091 | if (IS_ERR(bl)) { | ||
1092 | dev_err(parent, "unable to register backlight device: %ld\n", | ||
1093 | PTR_ERR(bl)); | ||
1094 | return NULL; | ||
1095 | } | ||
1096 | |||
1097 | bl->props.max_brightness = ch->cfg.bl_info.max_brightness; | ||
1098 | bl->props.brightness = bl->props.max_brightness; | ||
1099 | backlight_update_status(bl); | ||
1100 | |||
1101 | return bl; | ||
1102 | } | ||
1103 | |||
1104 | static void sh_mobile_lcdc_bl_remove(struct backlight_device *bdev) | ||
1105 | { | ||
1106 | backlight_device_unregister(bdev); | ||
1107 | } | ||
1108 | |||
1109 | static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp, | ||
1110 | int nonstd) | ||
1111 | { | ||
1112 | if (nonstd) { | ||
1113 | switch (bpp) { | ||
1114 | case 12: | ||
1115 | case 16: | ||
1116 | case 24: | ||
1117 | var->bits_per_pixel = bpp; | ||
1118 | var->nonstd = nonstd; | ||
1119 | return 0; | ||
1120 | default: | ||
1121 | return -EINVAL; | ||
1122 | } | ||
1123 | } | ||
1124 | |||
985 | switch (bpp) { | 1125 | switch (bpp) { |
986 | case 16: /* PKF[4:0] = 00011 - RGB 565 */ | 1126 | case 16: /* PKF[4:0] = 00011 - RGB 565 */ |
987 | var->red.offset = 11; | 1127 | var->red.offset = 11; |
@@ -1198,6 +1338,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1198 | init_completion(&ch->vsync_completion); | 1338 | init_completion(&ch->vsync_completion); |
1199 | ch->pan_offset = 0; | 1339 | ch->pan_offset = 0; |
1200 | 1340 | ||
1341 | /* probe the backlight is there is one defined */ | ||
1342 | if (ch->cfg.bl_info.max_brightness) | ||
1343 | ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch); | ||
1344 | |||
1201 | switch (pdata->ch[i].chan) { | 1345 | switch (pdata->ch[i].chan) { |
1202 | case LCDC_CHAN_MAINLCD: | 1346 | case LCDC_CHAN_MAINLCD: |
1203 | ch->enabled = 1 << 1; | 1347 | ch->enabled = 1 << 1; |
@@ -1260,6 +1404,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1260 | k < cfg->num_cfg && lcd_cfg; | 1404 | k < cfg->num_cfg && lcd_cfg; |
1261 | k++, lcd_cfg++) { | 1405 | k++, lcd_cfg++) { |
1262 | unsigned long size = lcd_cfg->yres * lcd_cfg->xres; | 1406 | unsigned long size = lcd_cfg->yres * lcd_cfg->xres; |
1407 | /* NV12 buffers must have even number of lines */ | ||
1408 | if ((cfg->nonstd) && cfg->bpp == 12 && | ||
1409 | (lcd_cfg->yres & 0x1)) { | ||
1410 | dev_err(&pdev->dev, "yres must be multiple of 2" | ||
1411 | " for YCbCr420 mode.\n"); | ||
1412 | error = -EINVAL; | ||
1413 | goto err1; | ||
1414 | } | ||
1263 | 1415 | ||
1264 | if (size > max_size) { | 1416 | if (size > max_size) { |
1265 | max_cfg = lcd_cfg; | 1417 | max_cfg = lcd_cfg; |
@@ -1274,7 +1426,11 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1274 | max_cfg->xres, max_cfg->yres); | 1426 | max_cfg->xres, max_cfg->yres); |
1275 | 1427 | ||
1276 | info->fix = sh_mobile_lcdc_fix; | 1428 | info->fix = sh_mobile_lcdc_fix; |
1277 | info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; | 1429 | info->fix.smem_len = max_size * 2 * cfg->bpp / 8; |
1430 | |||
1431 | /* Only pan in 2 line steps for NV12 */ | ||
1432 | if (cfg->nonstd && cfg->bpp == 12) | ||
1433 | info->fix.ypanstep = 2; | ||
1278 | 1434 | ||
1279 | if (!mode) { | 1435 | if (!mode) { |
1280 | mode = &default_720p; | 1436 | mode = &default_720p; |
@@ -1292,7 +1448,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1292 | var->yres_virtual = var->yres * 2; | 1448 | var->yres_virtual = var->yres * 2; |
1293 | var->activate = FB_ACTIVATE_NOW; | 1449 | var->activate = FB_ACTIVATE_NOW; |
1294 | 1450 | ||
1295 | error = sh_mobile_lcdc_set_bpp(var, cfg->bpp); | 1451 | error = sh_mobile_lcdc_set_bpp(var, cfg->bpp, cfg->nonstd); |
1296 | if (error) | 1452 | if (error) |
1297 | break; | 1453 | break; |
1298 | 1454 | ||
@@ -1316,7 +1472,11 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1316 | } | 1472 | } |
1317 | 1473 | ||
1318 | info->fix.smem_start = ch->dma_handle; | 1474 | info->fix.smem_start = ch->dma_handle; |
1319 | info->fix.line_length = var->xres * (cfg->bpp / 8); | 1475 | if (var->nonstd) |
1476 | info->fix.line_length = var->xres; | ||
1477 | else | ||
1478 | info->fix.line_length = var->xres * (cfg->bpp / 8); | ||
1479 | |||
1320 | info->screen_base = buf; | 1480 | info->screen_base = buf; |
1321 | info->device = &pdev->dev; | 1481 | info->device = &pdev->dev; |
1322 | ch->display_var = *var; | 1482 | ch->display_var = *var; |
@@ -1345,6 +1505,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1345 | } | 1505 | } |
1346 | } | 1506 | } |
1347 | 1507 | ||
1508 | info->bl_dev = ch->bl; | ||
1509 | |||
1348 | error = register_framebuffer(info); | 1510 | error = register_framebuffer(info); |
1349 | if (error < 0) | 1511 | if (error < 0) |
1350 | goto err1; | 1512 | goto err1; |
@@ -1404,6 +1566,11 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
1404 | framebuffer_release(info); | 1566 | framebuffer_release(info); |
1405 | } | 1567 | } |
1406 | 1568 | ||
1569 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { | ||
1570 | if (priv->ch[i].bl) | ||
1571 | sh_mobile_lcdc_bl_remove(priv->ch[i].bl); | ||
1572 | } | ||
1573 | |||
1407 | if (priv->dot_clk) | 1574 | if (priv->dot_clk) |
1408 | clk_put(priv->dot_clk); | 1575 | clk_put(priv->dot_clk); |
1409 | 1576 | ||
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h index 9ecee2fba1d7..4635eed63eee 100644 --- a/drivers/video/sh_mobile_lcdcfb.h +++ b/drivers/video/sh_mobile_lcdcfb.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | /* per-channel registers */ | 9 | /* per-channel registers */ |
10 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, | 10 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, |
11 | LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, | 11 | LDSM2R, LDSA1R, LDSA2R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, |
12 | LDHAJR, | 12 | LDHAJR, |
13 | NR_CH_REGS }; | 13 | NR_CH_REGS }; |
14 | 14 | ||
@@ -16,6 +16,7 @@ enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, | |||
16 | 16 | ||
17 | struct sh_mobile_lcdc_priv; | 17 | struct sh_mobile_lcdc_priv; |
18 | struct fb_info; | 18 | struct fb_info; |
19 | struct backlight_device; | ||
19 | 20 | ||
20 | struct sh_mobile_lcdc_chan { | 21 | struct sh_mobile_lcdc_chan { |
21 | struct sh_mobile_lcdc_priv *lcdc; | 22 | struct sh_mobile_lcdc_priv *lcdc; |
@@ -26,6 +27,7 @@ struct sh_mobile_lcdc_chan { | |||
26 | u32 pseudo_palette[PALETTE_NR]; | 27 | u32 pseudo_palette[PALETTE_NR]; |
27 | unsigned long saved_ch_regs[NR_CH_REGS]; | 28 | unsigned long saved_ch_regs[NR_CH_REGS]; |
28 | struct fb_info *info; | 29 | struct fb_info *info; |
30 | struct backlight_device *bl; | ||
29 | dma_addr_t dma_handle; | 31 | dma_addr_t dma_handle; |
30 | struct fb_deferred_io defio; | 32 | struct fb_deferred_io defio; |
31 | struct scatterlist *sglist; | 33 | struct scatterlist *sglist; |
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 | ||
4566 | static inline int sisfb_xgi_is21(struct sis_video_info *ivideo) | ||
4567 | { | ||
4568 | return ivideo->chip_real_id == XGI_21; | ||
4569 | } | ||
4570 | |||
4566 | static void __devinit | 4571 | static void __devinit |
4567 | sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) | 4572 | sisfb_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 | ||
4630 | static void __devinit | 4635 | static int __devinit |
4631 | sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) | 4636 | sisfb_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 | ||
4878 | static void __devinit | 4888 | static 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 | ||
4944 | static void __devinit | ||
4945 | sisfb_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 | |||
4985 | static void __devinit | ||
4986 | sisfb_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 | |||
5027 | static void __devinit | ||
5028 | sisfb_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 | |||
5073 | static u8 __devinit | ||
5074 | sisfb_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 | |||
4934 | static int __devinit | 5113 | static int __devinit |
4935 | sisfb_post_xgi(struct pci_dev *pdev) | 5114 | sisfb_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..46d1a64fe80d 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 | |||
46 | static char *fb_mode = "640x480-16@60"; | ||
47 | static unsigned long default_bpp = 16; | ||
48 | |||
49 | static 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 | ||
46 | enum sm501_controller { | 66 | enum 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 | ||
118 | static inline void sm501fb_sync_regs(struct sm501fb_info *info) | 139 | static 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 |
@@ -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 | ||
1356 | static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 1382 | static 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 | ||
@@ -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) | |||
2149 | module_init(sm501fb_init); | 2243 | module_init(sm501fb_init); |
2150 | module_exit(sm501fb_cleanup); | 2244 | module_exit(sm501fb_cleanup); |
2151 | 2245 | ||
2246 | module_param_named(mode, fb_mode, charp, 0); | ||
2247 | MODULE_PARM_DESC(mode, | ||
2248 | "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); | ||
2249 | module_param_named(bpp, default_bpp, ulong, 0); | ||
2250 | MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode"); | ||
2152 | MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); | 2251 | MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); |
2153 | MODULE_DESCRIPTION("SM501 Framebuffer driver"); | 2252 | MODULE_DESCRIPTION("SM501 Framebuffer driver"); |
2154 | MODULE_LICENSE("GPL v2"); | 2253 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index 5dbe06af2226..b7f27acaf817 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c | |||
@@ -111,8 +111,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp) | |||
111 | return 0; | 111 | return 0; |
112 | } | 112 | } |
113 | 113 | ||
114 | static int __devinit gfb_probe(struct platform_device *op, | 114 | static int __devinit gfb_probe(struct platform_device *op) |
115 | const struct of_device_id *match) | ||
116 | { | 115 | { |
117 | struct device_node *dp = op->dev.of_node; | 116 | struct device_node *dp = op->dev.of_node; |
118 | struct fb_info *info; | 117 | struct fb_info *info; |
@@ -198,7 +197,7 @@ static const struct of_device_id gfb_match[] = { | |||
198 | }; | 197 | }; |
199 | MODULE_DEVICE_TABLE(of, ffb_match); | 198 | MODULE_DEVICE_TABLE(of, ffb_match); |
200 | 199 | ||
201 | static struct of_platform_driver gfb_driver = { | 200 | static struct platform_driver gfb_driver = { |
202 | .probe = gfb_probe, | 201 | .probe = gfb_probe, |
203 | .remove = __devexit_p(gfb_remove), | 202 | .remove = __devexit_p(gfb_remove), |
204 | .driver = { | 203 | .driver = { |
@@ -213,12 +212,12 @@ static int __init gfb_init(void) | |||
213 | if (fb_get_options("gfb", NULL)) | 212 | if (fb_get_options("gfb", NULL)) |
214 | return -ENODEV; | 213 | return -ENODEV; |
215 | 214 | ||
216 | return of_register_platform_driver(&gfb_driver); | 215 | return platform_driver_register(&gfb_driver); |
217 | } | 216 | } |
218 | 217 | ||
219 | static void __exit gfb_exit(void) | 218 | static void __exit gfb_exit(void) |
220 | { | 219 | { |
221 | of_unregister_platform_driver(&gfb_driver); | 220 | platform_driver_unregister(&gfb_driver); |
222 | } | 221 | } |
223 | 222 | ||
224 | module_init(gfb_init); | 223 | module_init(gfb_init); |
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 */ |
23 | void svga_wcrt_multi(const struct vga_regset *regset, u32 value) { | 23 | void 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 */ |
43 | void svga_wseq_multi(const struct vga_regset *regset, u32 value) { | 43 | void 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 */ |
78 | void svga_set_default_gfx_regs(void) | 78 | void 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 */ |
96 | void svga_set_default_atc_regs(void) | 96 | void 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 */ |
119 | void svga_set_default_seq_regs(void) | 119 | void 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 */ |
130 | void svga_set_default_crt_regs(void) | 130 | void 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 | ||
140 | void svga_set_textmode_vga_regs(void) | 140 | void 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 */ |
302 | void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) | 302 | void 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 | ||
344 | int svga_get_tilemax(struct fb_info *info) | 344 | int 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 */ |
510 | void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, | 510 | void 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 77ad27955cf0..07c66e946634 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c | |||
@@ -362,8 +362,7 @@ static void tcx_unmap_regs(struct platform_device *op, struct fb_info *info, | |||
362 | info->screen_base, info->fix.smem_len); | 362 | info->screen_base, info->fix.smem_len); |
363 | } | 363 | } |
364 | 364 | ||
365 | static int __devinit tcx_probe(struct platform_device *op, | 365 | static int __devinit tcx_probe(struct platform_device *op) |
366 | const struct of_device_id *match) | ||
367 | { | 366 | { |
368 | struct device_node *dp = op->dev.of_node; | 367 | struct device_node *dp = op->dev.of_node; |
369 | struct fb_info *info; | 368 | struct fb_info *info; |
@@ -481,6 +480,7 @@ out_dealloc_cmap: | |||
481 | 480 | ||
482 | out_unmap_regs: | 481 | out_unmap_regs: |
483 | tcx_unmap_regs(op, info, par); | 482 | tcx_unmap_regs(op, info, par); |
483 | framebuffer_release(info); | ||
484 | 484 | ||
485 | out_err: | 485 | out_err: |
486 | return err; | 486 | return err; |
@@ -511,7 +511,7 @@ static const struct of_device_id tcx_match[] = { | |||
511 | }; | 511 | }; |
512 | MODULE_DEVICE_TABLE(of, tcx_match); | 512 | MODULE_DEVICE_TABLE(of, tcx_match); |
513 | 513 | ||
514 | static struct of_platform_driver tcx_driver = { | 514 | static struct platform_driver tcx_driver = { |
515 | .driver = { | 515 | .driver = { |
516 | .name = "tcx", | 516 | .name = "tcx", |
517 | .owner = THIS_MODULE, | 517 | .owner = THIS_MODULE, |
@@ -526,12 +526,12 @@ static int __init tcx_init(void) | |||
526 | if (fb_get_options("tcxfb", NULL)) | 526 | if (fb_get_options("tcxfb", NULL)) |
527 | return -ENODEV; | 527 | return -ENODEV; |
528 | 528 | ||
529 | return of_register_platform_driver(&tcx_driver); | 529 | return platform_driver_register(&tcx_driver); |
530 | } | 530 | } |
531 | 531 | ||
532 | static void __exit tcx_exit(void) | 532 | static void __exit tcx_exit(void) |
533 | { | 533 | { |
534 | of_unregister_platform_driver(&tcx_driver); | 534 | platform_driver_unregister(&tcx_driver); |
535 | } | 535 | } |
536 | 536 | ||
537 | module_init(tcx_init); | 537 | module_init(tcx_init); |
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c index dfef88c803d4..9710bf8caeae 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 | */ |
251 | static int tmiofb_hw_stop(struct platform_device *dev) | 251 | static 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 | */ |
269 | static int tmiofb_hw_init(struct platform_device *dev) | 268 | static 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 | */ |
313 | static void tmiofb_hw_mode(struct platform_device *dev) | 312 | static 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; |
@@ -559,9 +557,8 @@ static int tmiofb_ioctl(struct fb_info *fbi, | |||
559 | static struct fb_videomode * | 557 | static struct fb_videomode * |
560 | tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) | 558 | tmiofb_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 | ||
684 | static int __devinit tmiofb_probe(struct platform_device *dev) | 680 | static 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 | ||
812 | static int __devexit tmiofb_remove(struct platform_device *dev) | 808 | static 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) | |||
973 | static int tmiofb_resume(struct platform_device *dev) | 969 | static 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/uvesafb.c b/drivers/video/uvesafb.c index 52ec0959d462..7f8472cc993b 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c | |||
@@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns | |||
73 | struct uvesafb_task *utask; | 73 | struct uvesafb_task *utask; |
74 | struct uvesafb_ktask *task; | 74 | struct uvesafb_ktask *task; |
75 | 75 | ||
76 | if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) | 76 | if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) |
77 | return; | 77 | return; |
78 | 78 | ||
79 | if (msg->seq >= UVESAFB_TASKS_MAX) | 79 | if (msg->seq >= UVESAFB_TASKS_MAX) |
@@ -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 | ||
1568 | static 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 | ||
1570 | static ssize_t uvesafb_show_vbe_ver(struct device *dev, | 1591 | static 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 | ||
1788 | out_reg: | ||
1789 | release_region(0x3c0, 32); | ||
1790 | out_unmap: | 1809 | out_unmap: |
1791 | iounmap(info->screen_base); | 1810 | iounmap(info->screen_base); |
1792 | out_mem: | 1811 | out_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); |
1813 | out_reg: | ||
1814 | release_region(0x3c0, 32); | ||
1794 | out_mode: | 1815 | out_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/via/chip.h b/drivers/video/via/chip.h index 48f1342897bd..781f3aa66b42 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h | |||
@@ -110,16 +110,13 @@ | |||
110 | struct tmds_chip_information { | 110 | struct tmds_chip_information { |
111 | int tmds_chip_name; | 111 | int tmds_chip_name; |
112 | int tmds_chip_slave_addr; | 112 | int tmds_chip_slave_addr; |
113 | int data_mode; | ||
114 | int output_interface; | 113 | int output_interface; |
115 | int i2c_port; | 114 | int i2c_port; |
116 | int device_type; | ||
117 | }; | 115 | }; |
118 | 116 | ||
119 | struct lvds_chip_information { | 117 | struct lvds_chip_information { |
120 | int lvds_chip_name; | 118 | int lvds_chip_name; |
121 | int lvds_chip_slave_addr; | 119 | int lvds_chip_slave_addr; |
122 | int data_mode; | ||
123 | int output_interface; | 120 | int output_interface; |
124 | int i2c_port; | 121 | int i2c_port; |
125 | }; | 122 | }; |
@@ -142,9 +139,6 @@ struct chip_information { | |||
142 | 139 | ||
143 | struct crt_setting_information { | 140 | struct crt_setting_information { |
144 | int iga_path; | 141 | int iga_path; |
145 | int h_active; | ||
146 | int v_active; | ||
147 | int bpp; | ||
148 | int refresh_rate; | 142 | int refresh_rate; |
149 | }; | 143 | }; |
150 | 144 | ||
@@ -162,8 +156,6 @@ struct lvds_setting_information { | |||
162 | int h_active; | 156 | int h_active; |
163 | int v_active; | 157 | int v_active; |
164 | int bpp; | 158 | int bpp; |
165 | int refresh_rate; | ||
166 | int lcd_panel_id; | ||
167 | int lcd_panel_hres; | 159 | int lcd_panel_hres; |
168 | int lcd_panel_vres; | 160 | int lcd_panel_vres; |
169 | int display_method; | 161 | int display_method; |
@@ -188,7 +180,6 @@ struct GFX_DPA_SETTING { | |||
188 | }; | 180 | }; |
189 | 181 | ||
190 | struct VT1636_DPA_SETTING { | 182 | struct VT1636_DPA_SETTING { |
191 | int PanelSizeID; | ||
192 | u8 CLK_SEL_ST1; | 183 | u8 CLK_SEL_ST1; |
193 | u8 CLK_SEL_ST2; | 184 | u8 CLK_SEL_ST2; |
194 | }; | 185 | }; |
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 84e21b39dd0b..41ca198b5098 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c | |||
@@ -195,7 +195,9 @@ void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp, | |||
195 | struct crt_mode_table *pDviTiming; | 195 | struct crt_mode_table *pDviTiming; |
196 | unsigned long desirePixelClock, maxPixelClock; | 196 | unsigned long desirePixelClock, maxPixelClock; |
197 | pDviTiming = mode->crtc; | 197 | pDviTiming = mode->crtc; |
198 | desirePixelClock = pDviTiming->clk / 1000000; | 198 | desirePixelClock = pDviTiming->refresh_rate |
199 | * pDviTiming->crtc.hor_total * pDviTiming->crtc.ver_total | ||
200 | / 1000000; | ||
199 | maxPixelClock = (unsigned long)viaparinfo-> | 201 | maxPixelClock = (unsigned long)viaparinfo-> |
200 | tmds_setting_info->max_pixel_clock; | 202 | tmds_setting_info->max_pixel_clock; |
201 | 203 | ||
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 36d73f940d8b..5728fd76bc11 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
@@ -22,342 +22,290 @@ | |||
22 | #include <linux/via-core.h> | 22 | #include <linux/via-core.h> |
23 | #include "global.h" | 23 | #include "global.h" |
24 | 24 | ||
25 | static struct pll_map pll_value[] = { | 25 | static struct pll_config cle266_pll_config[] = { |
26 | {25175000, | 26 | {19, 4, 0}, |
27 | {99, 7, 3}, | 27 | {26, 5, 0}, |
28 | {85, 3, 4}, /* ignoring bit difference: 0x00008000 */ | 28 | {28, 5, 0}, |
29 | {141, 5, 4}, | 29 | {31, 5, 0}, |
30 | {141, 5, 4} }, | 30 | {33, 5, 0}, |
31 | {29581000, | 31 | {55, 5, 0}, |
32 | {33, 4, 2}, | 32 | {102, 5, 0}, |
33 | {66, 2, 4}, /* ignoring bit difference: 0x00808000 */ | 33 | {53, 6, 0}, |
34 | {166, 5, 4}, /* ignoring bit difference: 0x00008000 */ | 34 | {92, 6, 0}, |
35 | {165, 5, 4} }, | 35 | {98, 6, 0}, |
36 | {26880000, | 36 | {112, 6, 0}, |
37 | {15, 4, 1}, | 37 | {41, 7, 0}, |
38 | {30, 2, 3}, /* ignoring bit difference: 0x00808000 */ | 38 | {60, 7, 0}, |
39 | {150, 5, 4}, | 39 | {99, 7, 0}, |
40 | {150, 5, 4} }, | 40 | {100, 7, 0}, |
41 | {31500000, | 41 | {83, 8, 0}, |
42 | {53, 3, 3}, /* ignoring bit difference: 0x00008000 */ | 42 | {86, 8, 0}, |
43 | {141, 4, 4}, /* ignoring bit difference: 0x00008000 */ | 43 | {108, 8, 0}, |
44 | {176, 5, 4}, | 44 | {87, 9, 0}, |
45 | {176, 5, 4} }, | 45 | {118, 9, 0}, |
46 | {31728000, | 46 | {95, 12, 0}, |
47 | {31, 7, 1}, | 47 | {115, 12, 0}, |
48 | {177, 5, 4}, /* ignoring bit difference: 0x00008000 */ | 48 | {108, 13, 0}, |
49 | {177, 5, 4}, | 49 | {83, 17, 0}, |
50 | {142, 4, 4} }, | 50 | {67, 20, 0}, |
51 | {32688000, | 51 | {86, 20, 0}, |
52 | {73, 4, 3}, | 52 | {98, 20, 0}, |
53 | {146, 4, 4}, /* ignoring bit difference: 0x00008000 */ | 53 | {121, 24, 0}, |
54 | {183, 5, 4}, | 54 | {99, 29, 0}, |
55 | {146, 4, 4} }, | 55 | {33, 3, 1}, |
56 | {36000000, | 56 | {15, 4, 1}, |
57 | {101, 5, 3}, /* ignoring bit difference: 0x00008000 */ | 57 | {23, 4, 1}, |
58 | {161, 4, 4}, /* ignoring bit difference: 0x00008000 */ | 58 | {37, 5, 1}, |
59 | {202, 5, 4}, | 59 | {83, 5, 1}, |
60 | {161, 4, 4} }, | 60 | {85, 5, 1}, |
61 | {40000000, | 61 | {94, 5, 1}, |
62 | {89, 4, 3}, | 62 | {103, 5, 1}, |
63 | {89, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 63 | {109, 5, 1}, |
64 | {112, 5, 3}, | 64 | {113, 5, 1}, |
65 | {112, 5, 3} }, | 65 | {121, 5, 1}, |
66 | {41291000, | 66 | {82, 6, 1}, |
67 | {23, 4, 1}, | 67 | {31, 7, 1}, |
68 | {69, 3, 3}, /* ignoring bit difference: 0x00008000 */ | 68 | {55, 7, 1}, |
69 | {115, 5, 3}, | 69 | {84, 7, 1}, |
70 | {115, 5, 3} }, | 70 | {83, 8, 1}, |
71 | {43163000, | 71 | {76, 9, 1}, |
72 | {121, 5, 3}, | 72 | {127, 9, 1}, |
73 | {121, 5, 3}, /* ignoring bit difference: 0x00008000 */ | 73 | {33, 4, 2}, |
74 | {121, 5, 3}, | 74 | {75, 4, 2}, |
75 | {121, 5, 3} }, | 75 | {119, 4, 2}, |
76 | {45250000, | 76 | {121, 4, 2}, |
77 | {127, 5, 3}, | 77 | {91, 5, 2}, |
78 | {127, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 78 | {118, 5, 2}, |
79 | {127, 5, 3}, | 79 | {83, 6, 2}, |
80 | {127, 5, 3} }, | 80 | {109, 6, 2}, |
81 | {46000000, | 81 | {90, 7, 2}, |
82 | {90, 7, 2}, | 82 | {93, 2, 3}, |
83 | {103, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 83 | {53, 3, 3}, |
84 | {129, 5, 3}, | 84 | {73, 4, 3}, |
85 | {103, 4, 3} }, | 85 | {89, 4, 3}, |
86 | {46996000, | 86 | {105, 4, 3}, |
87 | {105, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 87 | {117, 4, 3}, |
88 | {131, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 88 | {101, 5, 3}, |
89 | {131, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 89 | {121, 5, 3}, |
90 | {105, 4, 3} }, | 90 | {127, 5, 3}, |
91 | {48000000, | 91 | {99, 7, 3} |
92 | {67, 20, 0}, | 92 | }; |
93 | {134, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 93 | |
94 | {134, 5, 3}, | 94 | static struct pll_config k800_pll_config[] = { |
95 | {134, 5, 3} }, | 95 | {22, 2, 0}, |
96 | {48875000, | 96 | {28, 3, 0}, |
97 | {99, 29, 0}, | 97 | {81, 3, 1}, |
98 | {82, 3, 3}, /* ignoring bit difference: 0x00808000 */ | 98 | {85, 3, 1}, |
99 | {82, 3, 3}, /* ignoring bit difference: 0x00808000 */ | 99 | {98, 3, 1}, |
100 | {137, 5, 3} }, | 100 | {112, 3, 1}, |
101 | {49500000, | 101 | {86, 4, 1}, |
102 | {83, 6, 2}, | 102 | {166, 4, 1}, |
103 | {83, 3, 3}, /* ignoring bit difference: 0x00008000 */ | 103 | {109, 5, 1}, |
104 | {138, 5, 3}, | 104 | {113, 5, 1}, |
105 | {83, 3, 3} }, | 105 | {121, 5, 1}, |
106 | {52406000, | 106 | {131, 5, 1}, |
107 | {117, 4, 3}, | 107 | {143, 5, 1}, |
108 | {117, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 108 | {153, 5, 1}, |
109 | {117, 4, 3}, | 109 | {66, 3, 2}, |
110 | {88, 3, 3} }, | 110 | {68, 3, 2}, |
111 | {52977000, | 111 | {95, 3, 2}, |
112 | {37, 5, 1}, | 112 | {106, 3, 2}, |
113 | {148, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 113 | {116, 3, 2}, |
114 | {148, 5, 3}, | 114 | {93, 4, 2}, |
115 | {148, 5, 3} }, | 115 | {119, 4, 2}, |
116 | {56250000, | 116 | {121, 4, 2}, |
117 | {55, 7, 1}, /* ignoring bit difference: 0x00008000 */ | 117 | {133, 4, 2}, |
118 | {126, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 118 | {137, 4, 2}, |
119 | {157, 5, 3}, | 119 | {117, 5, 2}, |
120 | {157, 5, 3} }, | 120 | {118, 5, 2}, |
121 | {57275000, | 121 | {120, 5, 2}, |
122 | {0, 0, 0}, | 122 | {124, 5, 2}, |
123 | {2, 2, 0}, | 123 | {132, 5, 2}, |
124 | {2, 2, 0}, | 124 | {137, 5, 2}, |
125 | {157, 5, 3} }, /* ignoring bit difference: 0x00808000 */ | 125 | {141, 5, 2}, |
126 | {60466000, | 126 | {166, 5, 2}, |
127 | {76, 9, 1}, | 127 | {170, 5, 2}, |
128 | {169, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 128 | {191, 5, 2}, |
129 | {169, 5, 3}, /* FIXED: old = {72, 2, 3} */ | 129 | {206, 5, 2}, |
130 | {169, 5, 3} }, | 130 | {208, 5, 2}, |
131 | {61500000, | 131 | {30, 2, 3}, |
132 | {86, 20, 0}, | 132 | {69, 3, 3}, |
133 | {172, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 133 | {82, 3, 3}, |
134 | {172, 5, 3}, | 134 | {83, 3, 3}, |
135 | {172, 5, 3} }, | 135 | {109, 3, 3}, |
136 | {65000000, | 136 | {114, 3, 3}, |
137 | {109, 6, 2}, /* ignoring bit difference: 0x00008000 */ | 137 | {125, 3, 3}, |
138 | {109, 3, 3}, /* ignoring bit difference: 0x00008000 */ | 138 | {89, 4, 3}, |
139 | {109, 3, 3}, | 139 | {103, 4, 3}, |
140 | {109, 3, 3} }, | 140 | {117, 4, 3}, |
141 | {65178000, | 141 | {126, 4, 3}, |
142 | {91, 5, 2}, | 142 | {150, 4, 3}, |
143 | {182, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 143 | {161, 4, 3}, |
144 | {109, 3, 3}, | 144 | {121, 5, 3}, |
145 | {182, 5, 3} }, | 145 | {127, 5, 3}, |
146 | {66750000, | 146 | {131, 5, 3}, |
147 | {75, 4, 2}, | 147 | {134, 5, 3}, |
148 | {150, 4, 3}, /* ignoring bit difference: 0x00808000 */ | 148 | {148, 5, 3}, |
149 | {150, 4, 3}, | 149 | {169, 5, 3}, |
150 | {112, 3, 3} }, | 150 | {172, 5, 3}, |
151 | {68179000, | 151 | {182, 5, 3}, |
152 | {19, 4, 0}, | 152 | {195, 5, 3}, |
153 | {114, 3, 3}, /* ignoring bit difference: 0x00008000 */ | 153 | {196, 5, 3}, |
154 | {190, 5, 3}, | 154 | {208, 5, 3}, |
155 | {191, 5, 3} }, | 155 | {66, 2, 4}, |
156 | {69924000, | 156 | {85, 3, 4}, |
157 | {83, 17, 0}, | 157 | {141, 4, 4}, |
158 | {195, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 158 | {146, 4, 4}, |
159 | {195, 5, 3}, | 159 | {161, 4, 4}, |
160 | {195, 5, 3} }, | 160 | {177, 5, 4} |
161 | {70159000, | 161 | }; |
162 | {98, 20, 0}, | 162 | |
163 | {196, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 163 | static struct pll_config cx700_pll_config[] = { |
164 | {196, 5, 3}, | 164 | {98, 3, 1}, |
165 | {195, 5, 3} }, | 165 | {86, 4, 1}, |
166 | {72000000, | 166 | {109, 5, 1}, |
167 | {121, 24, 0}, | 167 | {110, 5, 1}, |
168 | {161, 4, 3}, /* ignoring bit difference: 0x00808000 */ | 168 | {113, 5, 1}, |
169 | {161, 4, 3}, | 169 | {121, 5, 1}, |
170 | {161, 4, 3} }, | 170 | {131, 5, 1}, |
171 | {78750000, | 171 | {135, 5, 1}, |
172 | {33, 3, 1}, | 172 | {142, 5, 1}, |
173 | {66, 3, 2}, /* ignoring bit difference: 0x00008000 */ | 173 | {143, 5, 1}, |
174 | {110, 5, 2}, | 174 | {153, 5, 1}, |
175 | {110, 5, 2} }, | 175 | {187, 5, 1}, |
176 | {80136000, | 176 | {208, 5, 1}, |
177 | {28, 5, 0}, | 177 | {68, 2, 2}, |
178 | {68, 3, 2}, /* ignoring bit difference: 0x00008000 */ | 178 | {95, 3, 2}, |
179 | {112, 5, 2}, | 179 | {116, 3, 2}, |
180 | {112, 5, 2} }, | 180 | {93, 4, 2}, |
181 | {83375000, | 181 | {119, 4, 2}, |
182 | {93, 2, 3}, | 182 | {133, 4, 2}, |
183 | {93, 4, 2}, /* ignoring bit difference: 0x00800000 */ | 183 | {137, 4, 2}, |
184 | {93, 4, 2}, /* ignoring bit difference: 0x00800000 */ | 184 | {151, 4, 2}, |
185 | {117, 5, 2} }, | 185 | {166, 4, 2}, |
186 | {83950000, | 186 | {110, 5, 2}, |
187 | {41, 7, 0}, | 187 | {112, 5, 2}, |
188 | {117, 5, 2}, /* ignoring bit difference: 0x00008000 */ | 188 | {117, 5, 2}, |
189 | {117, 5, 2}, | 189 | {118, 5, 2}, |
190 | {117, 5, 2} }, | 190 | {120, 5, 2}, |
191 | {84750000, | 191 | {132, 5, 2}, |
192 | {118, 5, 2}, | 192 | {137, 5, 2}, |
193 | {118, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 193 | {141, 5, 2}, |
194 | {118, 5, 2}, | 194 | {151, 5, 2}, |
195 | {118, 5, 2} }, | 195 | {166, 5, 2}, |
196 | {85860000, | 196 | {175, 5, 2}, |
197 | {84, 7, 1}, | 197 | {191, 5, 2}, |
198 | {120, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 198 | {206, 5, 2}, |
199 | {120, 5, 2}, | 199 | {174, 7, 2}, |
200 | {118, 5, 2} }, | 200 | {82, 3, 3}, |
201 | {88750000, | 201 | {109, 3, 3}, |
202 | {31, 5, 0}, | 202 | {117, 4, 3}, |
203 | {124, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 203 | {150, 4, 3}, |
204 | {174, 7, 2}, /* ignoring bit difference: 0x00808000 */ | 204 | {161, 4, 3}, |
205 | {124, 5, 2} }, | 205 | {112, 5, 3}, |
206 | {94500000, | 206 | {115, 5, 3}, |
207 | {33, 5, 0}, | 207 | {121, 5, 3}, |
208 | {132, 5, 2}, /* ignoring bit difference: 0x00008000 */ | 208 | {127, 5, 3}, |
209 | {132, 5, 2}, | 209 | {129, 5, 3}, |
210 | {132, 5, 2} }, | 210 | {131, 5, 3}, |
211 | {97750000, | 211 | {134, 5, 3}, |
212 | {82, 6, 1}, | 212 | {138, 5, 3}, |
213 | {137, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 213 | {148, 5, 3}, |
214 | {137, 5, 2}, | 214 | {157, 5, 3}, |
215 | {137, 5, 2} }, | 215 | {169, 5, 3}, |
216 | {101000000, | 216 | {172, 5, 3}, |
217 | {127, 9, 1}, | 217 | {190, 5, 3}, |
218 | {141, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 218 | {195, 5, 3}, |
219 | {141, 5, 2}, | 219 | {196, 5, 3}, |
220 | {141, 5, 2} }, | 220 | {208, 5, 3}, |
221 | {106500000, | 221 | {141, 5, 4}, |
222 | {119, 4, 2}, | 222 | {150, 5, 4}, |
223 | {119, 4, 2}, /* ignoring bit difference: 0x00808000 */ | 223 | {166, 5, 4}, |
224 | {119, 4, 2}, | 224 | {176, 5, 4}, |
225 | {149, 5, 2} }, | 225 | {177, 5, 4}, |
226 | {108000000, | 226 | {183, 5, 4}, |
227 | {121, 4, 2}, | 227 | {202, 5, 4} |
228 | {121, 4, 2}, /* ignoring bit difference: 0x00808000 */ | 228 | }; |
229 | {151, 5, 2}, | 229 | |
230 | {151, 5, 2} }, | 230 | static struct pll_config vx855_pll_config[] = { |
231 | {113309000, | 231 | {86, 4, 1}, |
232 | {95, 12, 0}, | 232 | {108, 5, 1}, |
233 | {95, 3, 2}, /* ignoring bit difference: 0x00808000 */ | 233 | {110, 5, 1}, |
234 | {95, 3, 2}, | 234 | {113, 5, 1}, |
235 | {159, 5, 2} }, | 235 | {121, 5, 1}, |
236 | {118840000, | 236 | {131, 5, 1}, |
237 | {83, 5, 1}, | 237 | {135, 5, 1}, |
238 | {166, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 238 | {142, 5, 1}, |
239 | {166, 5, 2}, | 239 | {143, 5, 1}, |
240 | {166, 5, 2} }, | 240 | {153, 5, 1}, |
241 | {119000000, | 241 | {164, 5, 1}, |
242 | {108, 13, 0}, | 242 | {187, 5, 1}, |
243 | {133, 4, 2}, /* ignoring bit difference: 0x00808000 */ | 243 | {208, 5, 1}, |
244 | {133, 4, 2}, | 244 | {110, 5, 2}, |
245 | {167, 5, 2} }, | 245 | {112, 5, 2}, |
246 | {121750000, | 246 | {117, 5, 2}, |
247 | {85, 5, 1}, | 247 | {118, 5, 2}, |
248 | {170, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 248 | {124, 5, 2}, |
249 | {68, 2, 2}, | 249 | {132, 5, 2}, |
250 | {0, 0, 0} }, | 250 | {137, 5, 2}, |
251 | {125104000, | 251 | {141, 5, 2}, |
252 | {53, 6, 0}, /* ignoring bit difference: 0x00008000 */ | 252 | {149, 5, 2}, |
253 | {106, 3, 2}, /* ignoring bit difference: 0x00008000 */ | 253 | {151, 5, 2}, |
254 | {175, 5, 2}, | 254 | {159, 5, 2}, |
255 | {0, 0, 0} }, | 255 | {166, 5, 2}, |
256 | {135000000, | 256 | {167, 5, 2}, |
257 | {94, 5, 1}, | 257 | {172, 5, 2}, |
258 | {28, 3, 0}, /* ignoring bit difference: 0x00804000 */ | 258 | {189, 5, 2}, |
259 | {151, 4, 2}, | 259 | {191, 5, 2}, |
260 | {189, 5, 2} }, | 260 | {194, 5, 2}, |
261 | {136700000, | 261 | {206, 5, 2}, |
262 | {115, 12, 0}, | 262 | {208, 5, 2}, |
263 | {191, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 263 | {83, 3, 3}, |
264 | {191, 5, 2}, | 264 | {88, 3, 3}, |
265 | {191, 5, 2} }, | 265 | {109, 3, 3}, |
266 | {138400000, | 266 | {112, 3, 3}, |
267 | {87, 9, 0}, | 267 | {103, 4, 3}, |
268 | {116, 3, 2}, /* ignoring bit difference: 0x00808000 */ | 268 | {105, 4, 3}, |
269 | {116, 3, 2}, | 269 | {161, 4, 3}, |
270 | {194, 5, 2} }, | 270 | {112, 5, 3}, |
271 | {146760000, | 271 | {115, 5, 3}, |
272 | {103, 5, 1}, | 272 | {121, 5, 3}, |
273 | {206, 5, 2}, /* ignoring bit difference: 0x00808000 */ | 273 | {127, 5, 3}, |
274 | {206, 5, 2}, | 274 | {134, 5, 3}, |
275 | {206, 5, 2} }, | 275 | {137, 5, 3}, |
276 | {153920000, | 276 | {148, 5, 3}, |
277 | {86, 8, 0}, | 277 | {157, 5, 3}, |
278 | {86, 4, 1}, /* ignoring bit difference: 0x00808000 */ | 278 | {169, 5, 3}, |
279 | {86, 4, 1}, | 279 | {172, 5, 3}, |
280 | {86, 4, 1} }, /* FIXED: old = {84, 2, 1} */ | 280 | {182, 5, 3}, |
281 | {156000000, | 281 | {191, 5, 3}, |
282 | {109, 5, 1}, | 282 | {195, 5, 3}, |
283 | {109, 5, 1}, /* ignoring bit difference: 0x00808000 */ | 283 | {209, 5, 3}, |
284 | {109, 5, 1}, | 284 | {142, 4, 4}, |
285 | {108, 5, 1} }, | 285 | {146, 4, 4}, |
286 | {157500000, | 286 | {161, 4, 4}, |
287 | {55, 5, 0}, /* ignoring bit difference: 0x00008000 */ | 287 | {141, 5, 4}, |
288 | {22, 2, 0}, /* ignoring bit difference: 0x00802000 */ | 288 | {150, 5, 4}, |
289 | {110, 5, 1}, | 289 | {165, 5, 4}, |
290 | {110, 5, 1} }, | 290 | {176, 5, 4} |
291 | {162000000, | 291 | }; |
292 | {113, 5, 1}, | 292 | |
293 | {113, 5, 1}, /* ignoring bit difference: 0x00808000 */ | 293 | /* according to VIA Technologies these values are based on experiment */ |
294 | {113, 5, 1}, | 294 | static struct io_reg scaling_parameters[] = { |
295 | {113, 5, 1} }, | 295 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ |
296 | {187000000, | 296 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ |
297 | {118, 9, 0}, | 297 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ |
298 | {131, 5, 1}, /* ignoring bit difference: 0x00808000 */ | 298 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ |
299 | {131, 5, 1}, | 299 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ |
300 | {131, 5, 1} }, | 300 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ |
301 | {193295000, | 301 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ |
302 | {108, 8, 0}, | 302 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ |
303 | {81, 3, 1}, /* ignoring bit difference: 0x00808000 */ | 303 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ |
304 | {135, 5, 1}, | 304 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ |
305 | {135, 5, 1} }, | 305 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ |
306 | {202500000, | 306 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ |
307 | {99, 7, 0}, | 307 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ |
308 | {85, 3, 1}, /* ignoring bit difference: 0x00808000 */ | 308 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ |
309 | {142, 5, 1}, | ||
310 | {142, 5, 1} }, | ||
311 | {204000000, | ||
312 | {100, 7, 0}, | ||
313 | {143, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
314 | {143, 5, 1}, | ||
315 | {143, 5, 1} }, | ||
316 | {218500000, | ||
317 | {92, 6, 0}, | ||
318 | {153, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
319 | {153, 5, 1}, | ||
320 | {153, 5, 1} }, | ||
321 | {234000000, | ||
322 | {98, 6, 0}, | ||
323 | {98, 3, 1}, /* ignoring bit difference: 0x00008000 */ | ||
324 | {98, 3, 1}, | ||
325 | {164, 5, 1} }, | ||
326 | {267250000, | ||
327 | {112, 6, 0}, | ||
328 | {112, 3, 1}, /* ignoring bit difference: 0x00808000 */ | ||
329 | {187, 5, 1}, | ||
330 | {187, 5, 1} }, | ||
331 | {297500000, | ||
332 | {102, 5, 0}, /* ignoring bit difference: 0x00008000 */ | ||
333 | {166, 4, 1}, /* ignoring bit difference: 0x00008000 */ | ||
334 | {208, 5, 1}, | ||
335 | {208, 5, 1} }, | ||
336 | {74481000, | ||
337 | {26, 5, 0}, | ||
338 | {125, 3, 3}, /* ignoring bit difference: 0x00808000 */ | ||
339 | {208, 5, 3}, | ||
340 | {209, 5, 3} }, | ||
341 | {172798000, | ||
342 | {121, 5, 1}, | ||
343 | {121, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
344 | {121, 5, 1}, | ||
345 | {121, 5, 1} }, | ||
346 | {122614000, | ||
347 | {60, 7, 0}, | ||
348 | {137, 4, 2}, /* ignoring bit difference: 0x00808000 */ | ||
349 | {137, 4, 2}, | ||
350 | {172, 5, 2} }, | ||
351 | {74270000, | ||
352 | {83, 8, 1}, | ||
353 | {208, 5, 3}, | ||
354 | {208, 5, 3}, | ||
355 | {0, 0, 0} }, | ||
356 | {148500000, | ||
357 | {83, 8, 0}, | ||
358 | {208, 5, 2}, | ||
359 | {166, 4, 2}, | ||
360 | {208, 5, 2} } | ||
361 | }; | 309 | }; |
362 | 310 | ||
363 | static struct fifo_depth_select display_fifo_depth_reg = { | 311 | static struct fifo_depth_select display_fifo_depth_reg = { |
@@ -751,7 +699,7 @@ void viafb_unlock_crt(void) | |||
751 | viafb_write_reg_mask(CR47, VIACR, 0, BIT0); | 699 | viafb_write_reg_mask(CR47, VIACR, 0, BIT0); |
752 | } | 700 | } |
753 | 701 | ||
754 | void write_dac_reg(u8 index, u8 r, u8 g, u8 b) | 702 | static void write_dac_reg(u8 index, u8 r, u8 g, u8 b) |
755 | { | 703 | { |
756 | outb(index, LUT_INDEX_WRITE); | 704 | outb(index, LUT_INDEX_WRITE); |
757 | outb(r, LUT_DATA); | 705 | outb(r, LUT_DATA); |
@@ -1674,43 +1622,63 @@ static u32 vx855_encode_pll(struct pll_config pll) | |||
1674 | | pll.multiplier; | 1622 | | pll.multiplier; |
1675 | } | 1623 | } |
1676 | 1624 | ||
1677 | u32 viafb_get_clk_value(int clk) | 1625 | static inline u32 get_pll_internal_frequency(u32 ref_freq, |
1626 | struct pll_config pll) | ||
1678 | { | 1627 | { |
1679 | u32 value = 0; | 1628 | return ref_freq / pll.divisor * pll.multiplier; |
1680 | int i = 0; | 1629 | } |
1681 | 1630 | ||
1682 | while (i < NUM_TOTAL_PLL_TABLE && clk != pll_value[i].clk) | 1631 | static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) |
1683 | i++; | 1632 | { |
1633 | return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; | ||
1634 | } | ||
1684 | 1635 | ||
1685 | if (i == NUM_TOTAL_PLL_TABLE) { | 1636 | static struct pll_config get_pll_config(struct pll_config *config, int size, |
1686 | printk(KERN_WARNING "viafb_get_clk_value: PLL lookup failed!"); | 1637 | int clk) |
1687 | } else { | 1638 | { |
1688 | switch (viaparinfo->chip_info->gfx_chip_name) { | 1639 | struct pll_config best = config[0]; |
1689 | case UNICHROME_CLE266: | 1640 | const u32 f0 = 14318180; /* X1 frequency */ |
1690 | case UNICHROME_K400: | 1641 | int i; |
1691 | value = cle266_encode_pll(pll_value[i].cle266_pll); | ||
1692 | break; | ||
1693 | 1642 | ||
1694 | case UNICHROME_K800: | 1643 | for (i = 1; i < size; i++) { |
1695 | case UNICHROME_PM800: | 1644 | if (abs(get_pll_output_frequency(f0, config[i]) - clk) |
1696 | case UNICHROME_CN700: | 1645 | < abs(get_pll_output_frequency(f0, best) - clk)) |
1697 | value = k800_encode_pll(pll_value[i].k800_pll); | 1646 | best = config[i]; |
1698 | break; | 1647 | } |
1699 | 1648 | ||
1700 | case UNICHROME_CX700: | 1649 | return best; |
1701 | case UNICHROME_CN750: | 1650 | } |
1702 | case UNICHROME_K8M890: | ||
1703 | case UNICHROME_P4M890: | ||
1704 | case UNICHROME_P4M900: | ||
1705 | case UNICHROME_VX800: | ||
1706 | value = k800_encode_pll(pll_value[i].cx700_pll); | ||
1707 | break; | ||
1708 | 1651 | ||
1709 | case UNICHROME_VX855: | 1652 | u32 viafb_get_clk_value(int clk) |
1710 | case UNICHROME_VX900: | 1653 | { |
1711 | value = vx855_encode_pll(pll_value[i].vx855_pll); | 1654 | u32 value = 0; |
1712 | break; | 1655 | |
1713 | } | 1656 | switch (viaparinfo->chip_info->gfx_chip_name) { |
1657 | case UNICHROME_CLE266: | ||
1658 | case UNICHROME_K400: | ||
1659 | value = cle266_encode_pll(get_pll_config(cle266_pll_config, | ||
1660 | ARRAY_SIZE(cle266_pll_config), clk)); | ||
1661 | break; | ||
1662 | case UNICHROME_K800: | ||
1663 | case UNICHROME_PM800: | ||
1664 | case UNICHROME_CN700: | ||
1665 | value = k800_encode_pll(get_pll_config(k800_pll_config, | ||
1666 | ARRAY_SIZE(k800_pll_config), clk)); | ||
1667 | break; | ||
1668 | case UNICHROME_CX700: | ||
1669 | case UNICHROME_CN750: | ||
1670 | case UNICHROME_K8M890: | ||
1671 | case UNICHROME_P4M890: | ||
1672 | case UNICHROME_P4M900: | ||
1673 | case UNICHROME_VX800: | ||
1674 | value = k800_encode_pll(get_pll_config(cx700_pll_config, | ||
1675 | ARRAY_SIZE(cx700_pll_config), clk)); | ||
1676 | break; | ||
1677 | case UNICHROME_VX855: | ||
1678 | case UNICHROME_VX900: | ||
1679 | value = vx855_encode_pll(get_pll_config(vx855_pll_config, | ||
1680 | ARRAY_SIZE(vx855_pll_config), clk)); | ||
1681 | break; | ||
1714 | } | 1682 | } |
1715 | 1683 | ||
1716 | return value; | 1684 | return value; |
@@ -2034,7 +2002,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
2034 | int i; | 2002 | int i; |
2035 | int index = 0; | 2003 | int index = 0; |
2036 | int h_addr, v_addr; | 2004 | int h_addr, v_addr; |
2037 | u32 pll_D_N; | 2005 | u32 pll_D_N, clock; |
2038 | 2006 | ||
2039 | for (i = 0; i < video_mode->mode_array; i++) { | 2007 | for (i = 0; i < video_mode->mode_array; i++) { |
2040 | index = i; | 2008 | index = i; |
@@ -2087,7 +2055,9 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
2087 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) | 2055 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) |
2088 | viafb_load_FIFO_reg(set_iga, h_addr, v_addr); | 2056 | viafb_load_FIFO_reg(set_iga, h_addr, v_addr); |
2089 | 2057 | ||
2090 | pll_D_N = viafb_get_clk_value(crt_table[index].clk); | 2058 | clock = crt_reg.hor_total * crt_reg.ver_total |
2059 | * crt_table[index].refresh_rate; | ||
2060 | pll_D_N = viafb_get_clk_value(clock); | ||
2091 | DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); | 2061 | DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); |
2092 | viafb_set_vclock(pll_D_N, set_iga); | 2062 | viafb_set_vclock(pll_D_N, set_iga); |
2093 | 2063 | ||
@@ -2117,9 +2087,6 @@ void viafb_update_device_setting(int hres, int vres, | |||
2117 | int bpp, int vmode_refresh, int flag) | 2087 | int bpp, int vmode_refresh, int flag) |
2118 | { | 2088 | { |
2119 | if (flag == 0) { | 2089 | if (flag == 0) { |
2120 | viaparinfo->crt_setting_info->h_active = hres; | ||
2121 | viaparinfo->crt_setting_info->v_active = vres; | ||
2122 | viaparinfo->crt_setting_info->bpp = bpp; | ||
2123 | viaparinfo->crt_setting_info->refresh_rate = | 2090 | viaparinfo->crt_setting_info->refresh_rate = |
2124 | vmode_refresh; | 2091 | vmode_refresh; |
2125 | 2092 | ||
@@ -2129,13 +2096,9 @@ void viafb_update_device_setting(int hres, int vres, | |||
2129 | viaparinfo->lvds_setting_info->h_active = hres; | 2096 | viaparinfo->lvds_setting_info->h_active = hres; |
2130 | viaparinfo->lvds_setting_info->v_active = vres; | 2097 | viaparinfo->lvds_setting_info->v_active = vres; |
2131 | viaparinfo->lvds_setting_info->bpp = bpp; | 2098 | viaparinfo->lvds_setting_info->bpp = bpp; |
2132 | viaparinfo->lvds_setting_info->refresh_rate = | ||
2133 | vmode_refresh; | ||
2134 | viaparinfo->lvds_setting_info2->h_active = hres; | 2099 | viaparinfo->lvds_setting_info2->h_active = hres; |
2135 | viaparinfo->lvds_setting_info2->v_active = vres; | 2100 | viaparinfo->lvds_setting_info2->v_active = vres; |
2136 | viaparinfo->lvds_setting_info2->bpp = bpp; | 2101 | viaparinfo->lvds_setting_info2->bpp = bpp; |
2137 | viaparinfo->lvds_setting_info2->refresh_rate = | ||
2138 | vmode_refresh; | ||
2139 | } else { | 2102 | } else { |
2140 | 2103 | ||
2141 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { | 2104 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { |
@@ -2147,15 +2110,11 @@ void viafb_update_device_setting(int hres, int vres, | |||
2147 | viaparinfo->lvds_setting_info->h_active = hres; | 2110 | viaparinfo->lvds_setting_info->h_active = hres; |
2148 | viaparinfo->lvds_setting_info->v_active = vres; | 2111 | viaparinfo->lvds_setting_info->v_active = vres; |
2149 | viaparinfo->lvds_setting_info->bpp = bpp; | 2112 | viaparinfo->lvds_setting_info->bpp = bpp; |
2150 | viaparinfo->lvds_setting_info->refresh_rate = | ||
2151 | vmode_refresh; | ||
2152 | } | 2113 | } |
2153 | if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) { | 2114 | if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) { |
2154 | viaparinfo->lvds_setting_info2->h_active = hres; | 2115 | viaparinfo->lvds_setting_info2->h_active = hres; |
2155 | viaparinfo->lvds_setting_info2->v_active = vres; | 2116 | viaparinfo->lvds_setting_info2->v_active = vres; |
2156 | viaparinfo->lvds_setting_info2->bpp = bpp; | 2117 | viaparinfo->lvds_setting_info2->bpp = bpp; |
2157 | viaparinfo->lvds_setting_info2->refresh_rate = | ||
2158 | vmode_refresh; | ||
2159 | } | 2118 | } |
2160 | } | 2119 | } |
2161 | } | 2120 | } |
@@ -2430,6 +2389,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2430 | break; | 2389 | break; |
2431 | } | 2390 | } |
2432 | 2391 | ||
2392 | viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters)); | ||
2433 | device_off(); | 2393 | device_off(); |
2434 | via_set_state(devices, VIA_STATE_OFF); | 2394 | via_set_state(devices, VIA_STATE_OFF); |
2435 | 2395 | ||
@@ -2608,35 +2568,43 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2608 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh) | 2568 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh) |
2609 | { | 2569 | { |
2610 | int i; | 2570 | int i; |
2571 | struct crt_mode_table *best; | ||
2572 | struct VideoModeTable *vmode = viafb_get_mode(hres, vres); | ||
2573 | |||
2574 | if (!vmode) | ||
2575 | return RES_640X480_60HZ_PIXCLOCK; | ||
2611 | 2576 | ||
2612 | for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { | 2577 | best = &vmode->crtc[0]; |
2613 | if ((hres == res_map_refresh_tbl[i].hres) | 2578 | for (i = 1; i < vmode->mode_array; i++) { |
2614 | && (vres == res_map_refresh_tbl[i].vres) | 2579 | if (abs(vmode->crtc[i].refresh_rate - vmode_refresh) |
2615 | && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh)) | 2580 | < abs(best->refresh_rate - vmode_refresh)) |
2616 | return res_map_refresh_tbl[i].pixclock; | 2581 | best = &vmode->crtc[i]; |
2617 | } | 2582 | } |
2618 | return RES_640X480_60HZ_PIXCLOCK; | ||
2619 | 2583 | ||
2584 | return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total) | ||
2585 | * 1000 / best->refresh_rate; | ||
2620 | } | 2586 | } |
2621 | 2587 | ||
2622 | int viafb_get_refresh(int hres, int vres, u32 long_refresh) | 2588 | int viafb_get_refresh(int hres, int vres, u32 long_refresh) |
2623 | { | 2589 | { |
2624 | #define REFRESH_TOLERANCE 3 | 2590 | int i; |
2625 | int i, nearest = -1, diff = REFRESH_TOLERANCE; | 2591 | struct crt_mode_table *best; |
2626 | for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { | 2592 | struct VideoModeTable *vmode = viafb_get_mode(hres, vres); |
2627 | if ((hres == res_map_refresh_tbl[i].hres) | 2593 | |
2628 | && (vres == res_map_refresh_tbl[i].vres) | 2594 | if (!vmode) |
2629 | && (diff > (abs(long_refresh - | 2595 | return 60; |
2630 | res_map_refresh_tbl[i].vmode_refresh)))) { | 2596 | |
2631 | diff = abs(long_refresh - res_map_refresh_tbl[i]. | 2597 | best = &vmode->crtc[0]; |
2632 | vmode_refresh); | 2598 | for (i = 1; i < vmode->mode_array; i++) { |
2633 | nearest = i; | 2599 | if (abs(vmode->crtc[i].refresh_rate - long_refresh) |
2634 | } | 2600 | < abs(best->refresh_rate - long_refresh)) |
2601 | best = &vmode->crtc[i]; | ||
2635 | } | 2602 | } |
2636 | #undef REFRESH_TOLERANCE | 2603 | |
2637 | if (nearest > 0) | 2604 | if (abs(best->refresh_rate - long_refresh) > 3) |
2638 | return res_map_refresh_tbl[nearest].vmode_refresh; | 2605 | return 60; |
2639 | return 60; | 2606 | |
2607 | return best->refresh_rate; | ||
2640 | } | 2608 | } |
2641 | 2609 | ||
2642 | static void device_off(void) | 2610 | static void device_off(void) |
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 668d534542ef..7295263299f7 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h | |||
@@ -893,8 +893,6 @@ struct iga2_crtc_timing { | |||
893 | /* VT3410 chipset*/ | 893 | /* VT3410 chipset*/ |
894 | #define VX900_FUNCTION3 0x3410 | 894 | #define VX900_FUNCTION3 0x3410 |
895 | 895 | ||
896 | #define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) | ||
897 | |||
898 | struct IODATA { | 896 | struct IODATA { |
899 | u8 Index; | 897 | u8 Index; |
900 | u8 Mask; | 898 | u8 Mask; |
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 3425c3969806..64bc7e763103 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c | |||
@@ -26,10 +26,12 @@ | |||
26 | 26 | ||
27 | /* CLE266 Software Power Sequence */ | 27 | /* CLE266 Software Power Sequence */ |
28 | /* {Mask}, {Data}, {Delay} */ | 28 | /* {Mask}, {Data}, {Delay} */ |
29 | int PowerSequenceOn[3][3] = { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, | 29 | static const int PowerSequenceOn[3][3] = { |
30 | {0x19, 0x1FE, 0x01} }; | 30 | {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} |
31 | int PowerSequenceOff[3][3] = { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, | 31 | }; |
32 | {0xD2, 0x19, 0x01} }; | 32 | static const int PowerSequenceOff[3][3] = { |
33 | {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} | ||
34 | }; | ||
33 | 35 | ||
34 | static struct _lcd_scaling_factor lcd_scaling_factor = { | 36 | static struct _lcd_scaling_factor lcd_scaling_factor = { |
35 | /* LCD Horizontal Scaling Factor Register */ | 37 | /* LCD Horizontal Scaling Factor Register */ |
@@ -95,8 +97,6 @@ void __devinit viafb_init_lcd_size(void) | |||
95 | DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); | 97 | DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); |
96 | 98 | ||
97 | fp_id_to_vindex(viafb_lcd_panel_id); | 99 | fp_id_to_vindex(viafb_lcd_panel_id); |
98 | viaparinfo->lvds_setting_info2->lcd_panel_id = | ||
99 | viaparinfo->lvds_setting_info->lcd_panel_id; | ||
100 | viaparinfo->lvds_setting_info2->lcd_panel_hres = | 100 | viaparinfo->lvds_setting_info2->lcd_panel_hres = |
101 | viaparinfo->lvds_setting_info->lcd_panel_hres; | 101 | viaparinfo->lvds_setting_info->lcd_panel_hres; |
102 | viaparinfo->lvds_setting_info2->lcd_panel_vres = | 102 | viaparinfo->lvds_setting_info2->lcd_panel_vres = |
@@ -203,176 +203,132 @@ static void __devinit fp_id_to_vindex(int panel_id) | |||
203 | case 0x0: | 203 | case 0x0: |
204 | viaparinfo->lvds_setting_info->lcd_panel_hres = 640; | 204 | viaparinfo->lvds_setting_info->lcd_panel_hres = 640; |
205 | viaparinfo->lvds_setting_info->lcd_panel_vres = 480; | 205 | viaparinfo->lvds_setting_info->lcd_panel_vres = 480; |
206 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
207 | LCD_PANEL_ID0_640X480; | ||
208 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 206 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
209 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 207 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
210 | break; | 208 | break; |
211 | case 0x1: | 209 | case 0x1: |
212 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | 210 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; |
213 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; | 211 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; |
214 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
215 | LCD_PANEL_ID1_800X600; | ||
216 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 212 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
217 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 213 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
218 | break; | 214 | break; |
219 | case 0x2: | 215 | case 0x2: |
220 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 216 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
221 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 217 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
222 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
223 | LCD_PANEL_ID2_1024X768; | ||
224 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 218 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
225 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 219 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
226 | break; | 220 | break; |
227 | case 0x3: | 221 | case 0x3: |
228 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 222 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
229 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 223 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
230 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
231 | LCD_PANEL_ID3_1280X768; | ||
232 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 224 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
233 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 225 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
234 | break; | 226 | break; |
235 | case 0x4: | 227 | case 0x4: |
236 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 228 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
237 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; | 229 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; |
238 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
239 | LCD_PANEL_ID4_1280X1024; | ||
240 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 230 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
241 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 231 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
242 | break; | 232 | break; |
243 | case 0x5: | 233 | case 0x5: |
244 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; | 234 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; |
245 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; | 235 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; |
246 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
247 | LCD_PANEL_ID5_1400X1050; | ||
248 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 236 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
249 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 237 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
250 | break; | 238 | break; |
251 | case 0x6: | 239 | case 0x6: |
252 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; | 240 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; |
253 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; | 241 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; |
254 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
255 | LCD_PANEL_ID6_1600X1200; | ||
256 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 242 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
257 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 243 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
258 | break; | 244 | break; |
259 | case 0x8: | 245 | case 0x8: |
260 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | 246 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; |
261 | viaparinfo->lvds_setting_info->lcd_panel_vres = 480; | 247 | viaparinfo->lvds_setting_info->lcd_panel_vres = 480; |
262 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
263 | LCD_PANEL_IDA_800X480; | ||
264 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 248 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
265 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 249 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
266 | break; | 250 | break; |
267 | case 0x9: | 251 | case 0x9: |
268 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 252 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
269 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 253 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
270 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
271 | LCD_PANEL_ID2_1024X768; | ||
272 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 254 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
273 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 255 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
274 | break; | 256 | break; |
275 | case 0xA: | 257 | case 0xA: |
276 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 258 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
277 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 259 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
278 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
279 | LCD_PANEL_ID2_1024X768; | ||
280 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 260 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
281 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 261 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
282 | break; | 262 | break; |
283 | case 0xB: | 263 | case 0xB: |
284 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 264 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
285 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 265 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
286 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
287 | LCD_PANEL_ID2_1024X768; | ||
288 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 266 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
289 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 267 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
290 | break; | 268 | break; |
291 | case 0xC: | 269 | case 0xC: |
292 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 270 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
293 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 271 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
294 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
295 | LCD_PANEL_ID3_1280X768; | ||
296 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 272 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
297 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 273 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
298 | break; | 274 | break; |
299 | case 0xD: | 275 | case 0xD: |
300 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 276 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
301 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; | 277 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; |
302 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
303 | LCD_PANEL_ID4_1280X1024; | ||
304 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 278 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
305 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 279 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
306 | break; | 280 | break; |
307 | case 0xE: | 281 | case 0xE: |
308 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; | 282 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; |
309 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; | 283 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; |
310 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
311 | LCD_PANEL_ID5_1400X1050; | ||
312 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 284 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
313 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 285 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
314 | break; | 286 | break; |
315 | case 0xF: | 287 | case 0xF: |
316 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; | 288 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; |
317 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; | 289 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; |
318 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
319 | LCD_PANEL_ID6_1600X1200; | ||
320 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 290 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
321 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 291 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
322 | break; | 292 | break; |
323 | case 0x10: | 293 | case 0x10: |
324 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; | 294 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; |
325 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 295 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
326 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
327 | LCD_PANEL_ID7_1366X768; | ||
328 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 296 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
329 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 297 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
330 | break; | 298 | break; |
331 | case 0x11: | 299 | case 0x11: |
332 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 300 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
333 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; | 301 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; |
334 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
335 | LCD_PANEL_ID8_1024X600; | ||
336 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 302 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
337 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 303 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
338 | break; | 304 | break; |
339 | case 0x12: | 305 | case 0x12: |
340 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 306 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
341 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 307 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
342 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
343 | LCD_PANEL_ID3_1280X768; | ||
344 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 308 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
345 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 309 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
346 | break; | 310 | break; |
347 | case 0x13: | 311 | case 0x13: |
348 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 312 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
349 | viaparinfo->lvds_setting_info->lcd_panel_vres = 800; | 313 | viaparinfo->lvds_setting_info->lcd_panel_vres = 800; |
350 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
351 | LCD_PANEL_ID9_1280X800; | ||
352 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 314 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
353 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 315 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
354 | break; | 316 | break; |
355 | case 0x14: | 317 | case 0x14: |
356 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; | 318 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; |
357 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 319 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
358 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
359 | LCD_PANEL_IDB_1360X768; | ||
360 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 320 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
361 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 321 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
362 | break; | 322 | break; |
363 | case 0x15: | 323 | case 0x15: |
364 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 324 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
365 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | 325 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; |
366 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
367 | LCD_PANEL_ID3_1280X768; | ||
368 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 326 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
369 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 327 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
370 | break; | 328 | break; |
371 | case 0x16: | 329 | case 0x16: |
372 | viaparinfo->lvds_setting_info->lcd_panel_hres = 480; | 330 | viaparinfo->lvds_setting_info->lcd_panel_hres = 480; |
373 | viaparinfo->lvds_setting_info->lcd_panel_vres = 640; | 331 | viaparinfo->lvds_setting_info->lcd_panel_vres = 640; |
374 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
375 | LCD_PANEL_IDC_480X640; | ||
376 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 332 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
377 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 333 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
378 | break; | 334 | break; |
@@ -380,16 +336,12 @@ static void __devinit fp_id_to_vindex(int panel_id) | |||
380 | /* OLPC XO-1.5 panel */ | 336 | /* OLPC XO-1.5 panel */ |
381 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1200; | 337 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1200; |
382 | viaparinfo->lvds_setting_info->lcd_panel_vres = 900; | 338 | viaparinfo->lvds_setting_info->lcd_panel_vres = 900; |
383 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
384 | LCD_PANEL_IDD_1200X900; | ||
385 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 339 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
386 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 340 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
387 | break; | 341 | break; |
388 | default: | 342 | default: |
389 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | 343 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; |
390 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; | 344 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; |
391 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
392 | LCD_PANEL_ID1_800X600; | ||
393 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 345 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
394 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 346 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
395 | } | 347 | } |
@@ -610,7 +562,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
610 | int set_vres = plvds_setting_info->v_active; | 562 | int set_vres = plvds_setting_info->v_active; |
611 | int panel_hres = plvds_setting_info->lcd_panel_hres; | 563 | int panel_hres = plvds_setting_info->lcd_panel_hres; |
612 | int panel_vres = plvds_setting_info->lcd_panel_vres; | 564 | int panel_vres = plvds_setting_info->lcd_panel_vres; |
613 | u32 pll_D_N; | 565 | u32 pll_D_N, clock; |
614 | struct display_timing mode_crt_reg, panel_crt_reg; | 566 | struct display_timing mode_crt_reg, panel_crt_reg; |
615 | struct crt_mode_table *panel_crt_table = NULL; | 567 | struct crt_mode_table *panel_crt_table = NULL; |
616 | struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, | 568 | struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, |
@@ -625,7 +577,9 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
625 | DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); | 577 | DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); |
626 | if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) | 578 | if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) |
627 | viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); | 579 | viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); |
628 | plvds_setting_info->vclk = panel_crt_table->clk; | 580 | clock = panel_crt_reg.hor_total * panel_crt_reg.ver_total |
581 | * panel_crt_table->refresh_rate; | ||
582 | plvds_setting_info->vclk = clock; | ||
629 | if (set_iga == IGA1) { | 583 | if (set_iga == IGA1) { |
630 | /* IGA1 doesn't have LCD scaling, so set it as centering. */ | 584 | /* IGA1 doesn't have LCD scaling, so set it as centering. */ |
631 | viafb_load_crtc_timing(lcd_centering_timging | 585 | viafb_load_crtc_timing(lcd_centering_timging |
@@ -660,7 +614,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
660 | 614 | ||
661 | fill_lcd_format(); | 615 | fill_lcd_format(); |
662 | 616 | ||
663 | pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk); | 617 | pll_D_N = viafb_get_clk_value(clock); |
664 | DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); | 618 | DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); |
665 | viafb_set_vclock(pll_D_N, set_iga); | 619 | viafb_set_vclock(pll_D_N, set_iga); |
666 | lcd_patch_skew(plvds_setting_info, plvds_chip_info); | 620 | lcd_patch_skew(plvds_setting_info, plvds_chip_info); |
@@ -1064,34 +1018,33 @@ static struct display_timing lcd_centering_timging(struct display_timing | |||
1064 | 1018 | ||
1065 | bool viafb_lcd_get_mobile_state(bool *mobile) | 1019 | bool viafb_lcd_get_mobile_state(bool *mobile) |
1066 | { | 1020 | { |
1067 | unsigned char *romptr, *tableptr; | 1021 | unsigned char __iomem *romptr, *tableptr, *biosptr; |
1068 | u8 core_base; | 1022 | u8 core_base; |
1069 | unsigned char *biosptr; | ||
1070 | /* Rom address */ | 1023 | /* Rom address */ |
1071 | u32 romaddr = 0x000C0000; | 1024 | const u32 romaddr = 0x000C0000; |
1072 | u16 start_pattern = 0; | 1025 | u16 start_pattern; |
1073 | 1026 | ||
1074 | biosptr = ioremap(romaddr, 0x10000); | 1027 | biosptr = ioremap(romaddr, 0x10000); |
1028 | start_pattern = readw(biosptr); | ||
1075 | 1029 | ||
1076 | memcpy(&start_pattern, biosptr, 2); | ||
1077 | /* Compare pattern */ | 1030 | /* Compare pattern */ |
1078 | if (start_pattern == 0xAA55) { | 1031 | if (start_pattern == 0xAA55) { |
1079 | /* Get the start of Table */ | 1032 | /* Get the start of Table */ |
1080 | /* 0x1B means BIOS offset position */ | 1033 | /* 0x1B means BIOS offset position */ |
1081 | romptr = biosptr + 0x1B; | 1034 | romptr = biosptr + 0x1B; |
1082 | tableptr = biosptr + *((u16 *) romptr); | 1035 | tableptr = biosptr + readw(romptr); |
1083 | 1036 | ||
1084 | /* Get the start of biosver structure */ | 1037 | /* Get the start of biosver structure */ |
1085 | /* 18 means BIOS version position. */ | 1038 | /* 18 means BIOS version position. */ |
1086 | romptr = tableptr + 18; | 1039 | romptr = tableptr + 18; |
1087 | romptr = biosptr + *((u16 *) romptr); | 1040 | romptr = biosptr + readw(romptr); |
1088 | 1041 | ||
1089 | /* The offset should be 44, but the | 1042 | /* The offset should be 44, but the |
1090 | actual image is less three char. */ | 1043 | actual image is less three char. */ |
1091 | /* pRom += 44; */ | 1044 | /* pRom += 44; */ |
1092 | romptr += 41; | 1045 | romptr += 41; |
1093 | 1046 | ||
1094 | core_base = *romptr++; | 1047 | core_base = readb(romptr); |
1095 | 1048 | ||
1096 | if (core_base & 0x8) | 1049 | if (core_base & 0x8) |
1097 | *mobile = false; | 1050 | *mobile = false; |
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h index 2cbe1031b421..4b7831f0d012 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/via/share.h | |||
@@ -627,77 +627,6 @@ | |||
627 | #define M2048x1536_R60_HSP NEGATIVE | 627 | #define M2048x1536_R60_HSP NEGATIVE |
628 | #define M2048x1536_R60_VSP POSITIVE | 628 | #define M2048x1536_R60_VSP POSITIVE |
629 | 629 | ||
630 | /* define PLL index: */ | ||
631 | #define CLK_25_175M 25175000 | ||
632 | #define CLK_26_880M 26880000 | ||
633 | #define CLK_29_581M 29581000 | ||
634 | #define CLK_31_500M 31500000 | ||
635 | #define CLK_31_728M 31728000 | ||
636 | #define CLK_32_668M 32688000 | ||
637 | #define CLK_36_000M 36000000 | ||
638 | #define CLK_40_000M 40000000 | ||
639 | #define CLK_41_291M 41291000 | ||
640 | #define CLK_43_163M 43163000 | ||
641 | #define CLK_45_250M 45250000 /* 45.46MHz */ | ||
642 | #define CLK_46_000M 46000000 | ||
643 | #define CLK_46_996M 46996000 | ||
644 | #define CLK_48_000M 48000000 | ||
645 | #define CLK_48_875M 48875000 | ||
646 | #define CLK_49_500M 49500000 | ||
647 | #define CLK_52_406M 52406000 | ||
648 | #define CLK_52_977M 52977000 | ||
649 | #define CLK_56_250M 56250000 | ||
650 | #define CLK_57_275M 57275000 | ||
651 | #define CLK_60_466M 60466000 | ||
652 | #define CLK_61_500M 61500000 | ||
653 | #define CLK_65_000M 65000000 | ||
654 | #define CLK_65_178M 65178000 | ||
655 | #define CLK_66_750M 66750000 /* 67.116MHz */ | ||
656 | #define CLK_68_179M 68179000 | ||
657 | #define CLK_69_924M 69924000 | ||
658 | #define CLK_70_159M 70159000 | ||
659 | #define CLK_72_000M 72000000 | ||
660 | #define CLK_74_270M 74270000 | ||
661 | #define CLK_78_750M 78750000 | ||
662 | #define CLK_80_136M 80136000 | ||
663 | #define CLK_83_375M 83375000 | ||
664 | #define CLK_83_950M 83950000 | ||
665 | #define CLK_84_750M 84750000 /* 84.537Mhz */ | ||
666 | #define CLK_85_860M 85860000 | ||
667 | #define CLK_88_750M 88750000 | ||
668 | #define CLK_94_500M 94500000 | ||
669 | #define CLK_97_750M 97750000 | ||
670 | #define CLK_101_000M 101000000 | ||
671 | #define CLK_106_500M 106500000 | ||
672 | #define CLK_108_000M 108000000 | ||
673 | #define CLK_113_309M 113309000 | ||
674 | #define CLK_118_840M 118840000 | ||
675 | #define CLK_119_000M 119000000 | ||
676 | #define CLK_121_750M 121750000 /* 121.704MHz */ | ||
677 | #define CLK_125_104M 125104000 | ||
678 | #define CLK_135_000M 135000000 | ||
679 | #define CLK_136_700M 136700000 | ||
680 | #define CLK_138_400M 138400000 | ||
681 | #define CLK_146_760M 146760000 | ||
682 | #define CLK_148_500M 148500000 | ||
683 | |||
684 | #define CLK_153_920M 153920000 | ||
685 | #define CLK_156_000M 156000000 | ||
686 | #define CLK_157_500M 157500000 | ||
687 | #define CLK_162_000M 162000000 | ||
688 | #define CLK_187_000M 187000000 | ||
689 | #define CLK_193_295M 193295000 | ||
690 | #define CLK_202_500M 202500000 | ||
691 | #define CLK_204_000M 204000000 | ||
692 | #define CLK_218_500M 218500000 | ||
693 | #define CLK_234_000M 234000000 | ||
694 | #define CLK_267_250M 267250000 | ||
695 | #define CLK_297_500M 297500000 | ||
696 | #define CLK_74_481M 74481000 | ||
697 | #define CLK_172_798M 172798000 | ||
698 | #define CLK_122_614M 122614000 | ||
699 | |||
700 | |||
701 | /* Definition CRTC Timing Index */ | 630 | /* Definition CRTC Timing Index */ |
702 | #define H_TOTAL_INDEX 0 | 631 | #define H_TOTAL_INDEX 0 |
703 | #define H_ADDR_INDEX 1 | 632 | #define H_ADDR_INDEX 1 |
@@ -722,76 +651,7 @@ | |||
722 | 651 | ||
723 | /* Definition Video Mode Pixel Clock (picoseconds) | 652 | /* Definition Video Mode Pixel Clock (picoseconds) |
724 | */ | 653 | */ |
725 | #define RES_480X640_60HZ_PIXCLOCK 39722 | ||
726 | #define RES_640X480_60HZ_PIXCLOCK 39722 | 654 | #define RES_640X480_60HZ_PIXCLOCK 39722 |
727 | #define RES_640X480_75HZ_PIXCLOCK 31747 | ||
728 | #define RES_640X480_85HZ_PIXCLOCK 27777 | ||
729 | #define RES_640X480_100HZ_PIXCLOCK 23168 | ||
730 | #define RES_640X480_120HZ_PIXCLOCK 19081 | ||
731 | #define RES_720X480_60HZ_PIXCLOCK 37020 | ||
732 | #define RES_720X576_60HZ_PIXCLOCK 30611 | ||
733 | #define RES_800X600_60HZ_PIXCLOCK 25000 | ||
734 | #define RES_800X600_75HZ_PIXCLOCK 20203 | ||
735 | #define RES_800X600_85HZ_PIXCLOCK 17777 | ||
736 | #define RES_800X600_100HZ_PIXCLOCK 14667 | ||
737 | #define RES_800X600_120HZ_PIXCLOCK 11912 | ||
738 | #define RES_800X480_60HZ_PIXCLOCK 33805 | ||
739 | #define RES_848X480_60HZ_PIXCLOCK 31756 | ||
740 | #define RES_856X480_60HZ_PIXCLOCK 31518 | ||
741 | #define RES_1024X512_60HZ_PIXCLOCK 24218 | ||
742 | #define RES_1024X600_60HZ_PIXCLOCK 20460 | ||
743 | #define RES_1024X768_60HZ_PIXCLOCK 15385 | ||
744 | #define RES_1024X768_75HZ_PIXCLOCK 12699 | ||
745 | #define RES_1024X768_85HZ_PIXCLOCK 10582 | ||
746 | #define RES_1024X768_100HZ_PIXCLOCK 8825 | ||
747 | #define RES_1152X864_75HZ_PIXCLOCK 9259 | ||
748 | #define RES_1280X768_60HZ_PIXCLOCK 12480 | ||
749 | #define RES_1280X800_60HZ_PIXCLOCK 11994 | ||
750 | #define RES_1280X960_60HZ_PIXCLOCK 9259 | ||
751 | #define RES_1280X1024_60HZ_PIXCLOCK 9260 | ||
752 | #define RES_1280X1024_75HZ_PIXCLOCK 7408 | ||
753 | #define RES_1280X768_85HZ_PIXCLOCK 6349 | ||
754 | #define RES_1440X1050_60HZ_PIXCLOCK 7993 | ||
755 | #define RES_1600X1200_60HZ_PIXCLOCK 6172 | ||
756 | #define RES_1600X1200_75HZ_PIXCLOCK 4938 | ||
757 | #define RES_1280X720_60HZ_PIXCLOCK 13426 | ||
758 | #define RES_1200X900_60HZ_PIXCLOCK 17459 | ||
759 | #define RES_1920X1080_60HZ_PIXCLOCK 5787 | ||
760 | #define RES_1400X1050_60HZ_PIXCLOCK 8214 | ||
761 | #define RES_1400X1050_75HZ_PIXCLOCK 6410 | ||
762 | #define RES_1368X768_60HZ_PIXCLOCK 11647 | ||
763 | #define RES_960X600_60HZ_PIXCLOCK 22099 | ||
764 | #define RES_1000X600_60HZ_PIXCLOCK 20834 | ||
765 | #define RES_1024X576_60HZ_PIXCLOCK 21278 | ||
766 | #define RES_1088X612_60HZ_PIXCLOCK 18877 | ||
767 | #define RES_1152X720_60HZ_PIXCLOCK 14981 | ||
768 | #define RES_1200X720_60HZ_PIXCLOCK 14253 | ||
769 | #define RES_1280X600_60HZ_PIXCLOCK 16260 | ||
770 | #define RES_1280X720_50HZ_PIXCLOCK 16538 | ||
771 | #define RES_1280X768_50HZ_PIXCLOCK 15342 | ||
772 | #define RES_1366X768_50HZ_PIXCLOCK 14301 | ||
773 | #define RES_1366X768_60HZ_PIXCLOCK 11646 | ||
774 | #define RES_1360X768_60HZ_PIXCLOCK 11799 | ||
775 | #define RES_1440X900_60HZ_PIXCLOCK 9390 | ||
776 | #define RES_1440X900_75HZ_PIXCLOCK 7315 | ||
777 | #define RES_1600X900_60HZ_PIXCLOCK 8415 | ||
778 | #define RES_1600X1024_60HZ_PIXCLOCK 7315 | ||
779 | #define RES_1680X1050_60HZ_PIXCLOCK 6814 | ||
780 | #define RES_1680X1050_75HZ_PIXCLOCK 5348 | ||
781 | #define RES_1792X1344_60HZ_PIXCLOCK 4902 | ||
782 | #define RES_1856X1392_60HZ_PIXCLOCK 4577 | ||
783 | #define RES_1920X1200_60HZ_PIXCLOCK 5173 | ||
784 | #define RES_1920X1440_60HZ_PIXCLOCK 4274 | ||
785 | #define RES_1920X1440_75HZ_PIXCLOCK 3367 | ||
786 | #define RES_2048X1536_60HZ_PIXCLOCK 3742 | ||
787 | |||
788 | #define RES_1360X768_RB_60HZ_PIXCLOCK 13889 | ||
789 | #define RES_1400X1050_RB_60HZ_PIXCLOCK 9901 | ||
790 | #define RES_1440X900_RB_60HZ_PIXCLOCK 11268 | ||
791 | #define RES_1600X900_RB_60HZ_PIXCLOCK 10230 | ||
792 | #define RES_1680X1050_RB_60HZ_PIXCLOCK 8403 | ||
793 | #define RES_1920X1080_RB_60HZ_PIXCLOCK 7225 | ||
794 | #define RES_1920X1200_RB_60HZ_PIXCLOCK 6497 | ||
795 | 655 | ||
796 | /* LCD display method | 656 | /* LCD display method |
797 | */ | 657 | */ |
@@ -822,7 +682,6 @@ struct display_timing { | |||
822 | 682 | ||
823 | struct crt_mode_table { | 683 | struct crt_mode_table { |
824 | int refresh_rate; | 684 | int refresh_rate; |
825 | unsigned long clk; | ||
826 | int h_sync_polarity; | 685 | int h_sync_polarity; |
827 | int v_sync_polarity; | 686 | int v_sync_polarity; |
828 | struct display_timing crtc; | 687 | struct display_timing crtc; |
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/via/tblDPASetting.c index 0c4c8cc712f4..73bb554e7c1e 100644 --- a/drivers/video/via/tblDPASetting.c +++ b/drivers/video/via/tblDPASetting.c | |||
@@ -20,17 +20,6 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include "global.h" | 22 | #include "global.h" |
23 | /* For VT3324: */ | ||
24 | struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[] = { | ||
25 | /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */ | ||
26 | {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */ | ||
27 | {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */ | ||
28 | {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */ | ||
29 | {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */ | ||
30 | {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */ | ||
31 | {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */ | ||
32 | {LCD_PANEL_ID6_1600X1200, 0x0B, 0x03} /* For 1600x1200 */ | ||
33 | }; | ||
34 | 23 | ||
35 | struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = { | 24 | struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = { |
36 | /* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, | 25 | /* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, |
@@ -57,18 +46,6 @@ struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = { | |||
57 | 0x00}, | 46 | 0x00}, |
58 | }; | 47 | }; |
59 | 48 | ||
60 | /* For VT3327: */ | ||
61 | struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[] = { | ||
62 | /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */ | ||
63 | {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */ | ||
64 | {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */ | ||
65 | {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */ | ||
66 | {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */ | ||
67 | {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */ | ||
68 | {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */ | ||
69 | {LCD_PANEL_ID6_1600X1200, 0x00, 0x00} /* For 1600x1200 */ | ||
70 | }; | ||
71 | |||
72 | struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = { | 49 | struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = { |
73 | /* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, | 50 | /* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, |
74 | DVP1Driving, DFPHigh, DFPLow */ | 51 | DVP1Driving, DFPHigh, DFPLow */ |
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/via/tblDPASetting.h index b065a83481d3..6db61519cb5d 100644 --- a/drivers/video/via/tblDPASetting.h +++ b/drivers/video/via/tblDPASetting.h | |||
@@ -38,9 +38,7 @@ enum DPA_RANGE { | |||
38 | DPA_CLK_RANGE_150M | 38 | DPA_CLK_RANGE_150M |
39 | }; | 39 | }; |
40 | 40 | ||
41 | extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[7]; | ||
42 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6]; | 41 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6]; |
43 | extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[7]; | ||
44 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[]; | 42 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[]; |
45 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6]; | 43 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6]; |
46 | 44 | ||
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 3844b558b7bd..78f1405dbab7 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c | |||
@@ -32,7 +32,7 @@ | |||
32 | */ | 32 | */ |
33 | #define VIAFB_NUM_I2C 5 | 33 | #define VIAFB_NUM_I2C 5 |
34 | static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C]; | 34 | static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C]; |
35 | struct viafb_dev *i2c_vdev; /* Passed in from core */ | 35 | static struct viafb_dev *i2c_vdev; /* Passed in from core */ |
36 | 36 | ||
37 | static void via_i2c_setscl(void *data, int state) | 37 | static void via_i2c_setscl(void *data, int state) |
38 | { | 38 | { |
@@ -209,7 +209,6 @@ static int create_i2c_bus(struct i2c_adapter *adapter, | |||
209 | sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", | 209 | sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", |
210 | adap_cfg->ioport_index); | 210 | adap_cfg->ioport_index); |
211 | adapter->owner = THIS_MODULE; | 211 | adapter->owner = THIS_MODULE; |
212 | adapter->id = 0x01FFFF; | ||
213 | adapter->class = I2C_CLASS_DDC; | 212 | adapter->class = I2C_CLASS_DDC; |
214 | adapter->algo_data = algo; | 213 | adapter->algo_data = algo; |
215 | if (pdev) | 214 | if (pdev) |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 4e66349e4366..f555b891cc72 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -43,11 +43,11 @@ static int viafb_second_size; | |||
43 | static int viafb_accel = 1; | 43 | static int viafb_accel = 1; |
44 | 44 | ||
45 | /* Added for specifying active devices.*/ | 45 | /* Added for specifying active devices.*/ |
46 | char *viafb_active_dev; | 46 | static char *viafb_active_dev; |
47 | 47 | ||
48 | /*Added for specify lcd output port*/ | 48 | /*Added for specify lcd output port*/ |
49 | char *viafb_lcd_port = ""; | 49 | static char *viafb_lcd_port = ""; |
50 | char *viafb_dvi_port = ""; | 50 | static char *viafb_dvi_port = ""; |
51 | 51 | ||
52 | static void retrieve_device_setting(struct viafb_ioctl_setting | 52 | static void retrieve_device_setting(struct viafb_ioctl_setting |
53 | *setting_info); | 53 | *setting_info); |
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; | |||
94 | extern int viafb_DVI_ON; | 94 | extern int viafb_DVI_ON; |
95 | extern int viafb_hotplug; | 95 | extern int viafb_hotplug; |
96 | 96 | ||
97 | extern int strict_strtoul(const char *cp, unsigned int base, | ||
98 | unsigned long *res); | ||
99 | |||
100 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | 97 | u8 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/via/viamode.c b/drivers/video/via/viamode.c index 2dbad3c0f679..8c5bc41ff6a4 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c | |||
@@ -21,72 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/via-core.h> | 22 | #include <linux/via-core.h> |
23 | #include "global.h" | 23 | #include "global.h" |
24 | struct res_map_refresh res_map_refresh_tbl[] = { | ||
25 | /*hres, vres, vclock, vmode_refresh*/ | ||
26 | {480, 640, RES_480X640_60HZ_PIXCLOCK, 60}, | ||
27 | {640, 480, RES_640X480_60HZ_PIXCLOCK, 60}, | ||
28 | {640, 480, RES_640X480_75HZ_PIXCLOCK, 75}, | ||
29 | {640, 480, RES_640X480_85HZ_PIXCLOCK, 85}, | ||
30 | {640, 480, RES_640X480_100HZ_PIXCLOCK, 100}, | ||
31 | {640, 480, RES_640X480_120HZ_PIXCLOCK, 120}, | ||
32 | {720, 480, RES_720X480_60HZ_PIXCLOCK, 60}, | ||
33 | {720, 576, RES_720X576_60HZ_PIXCLOCK, 60}, | ||
34 | {800, 480, RES_800X480_60HZ_PIXCLOCK, 60}, | ||
35 | {800, 600, RES_800X600_60HZ_PIXCLOCK, 60}, | ||
36 | {800, 600, RES_800X600_75HZ_PIXCLOCK, 75}, | ||
37 | {800, 600, RES_800X600_85HZ_PIXCLOCK, 85}, | ||
38 | {800, 600, RES_800X600_100HZ_PIXCLOCK, 100}, | ||
39 | {800, 600, RES_800X600_120HZ_PIXCLOCK, 120}, | ||
40 | {848, 480, RES_848X480_60HZ_PIXCLOCK, 60}, | ||
41 | {856, 480, RES_856X480_60HZ_PIXCLOCK, 60}, | ||
42 | {1024, 512, RES_1024X512_60HZ_PIXCLOCK, 60}, | ||
43 | {1024, 600, RES_1024X600_60HZ_PIXCLOCK, 60}, | ||
44 | {1024, 768, RES_1024X768_60HZ_PIXCLOCK, 60}, | ||
45 | {1024, 768, RES_1024X768_75HZ_PIXCLOCK, 75}, | ||
46 | {1024, 768, RES_1024X768_85HZ_PIXCLOCK, 85}, | ||
47 | {1024, 768, RES_1024X768_100HZ_PIXCLOCK, 100}, | ||
48 | /* {1152,864, RES_1152X864_70HZ_PIXCLOCK, 70},*/ | ||
49 | {1152, 864, RES_1152X864_75HZ_PIXCLOCK, 75}, | ||
50 | {1280, 768, RES_1280X768_60HZ_PIXCLOCK, 60}, | ||
51 | {1280, 800, RES_1280X800_60HZ_PIXCLOCK, 60}, | ||
52 | {1280, 960, RES_1280X960_60HZ_PIXCLOCK, 60}, | ||
53 | {1280, 1024, RES_1280X1024_60HZ_PIXCLOCK, 60}, | ||
54 | {1280, 1024, RES_1280X1024_75HZ_PIXCLOCK, 75}, | ||
55 | {1280, 1024, RES_1280X768_85HZ_PIXCLOCK, 85}, | ||
56 | {1440, 1050, RES_1440X1050_60HZ_PIXCLOCK, 60}, | ||
57 | {1600, 1200, RES_1600X1200_60HZ_PIXCLOCK, 60}, | ||
58 | {1600, 1200, RES_1600X1200_75HZ_PIXCLOCK, 75}, | ||
59 | {1280, 720, RES_1280X720_60HZ_PIXCLOCK, 60}, | ||
60 | {1920, 1080, RES_1920X1080_60HZ_PIXCLOCK, 60}, | ||
61 | {1400, 1050, RES_1400X1050_60HZ_PIXCLOCK, 60}, | ||
62 | {1400, 1050, RES_1400X1050_75HZ_PIXCLOCK, 75}, | ||
63 | {1368, 768, RES_1368X768_60HZ_PIXCLOCK, 60}, | ||
64 | {960, 600, RES_960X600_60HZ_PIXCLOCK, 60}, | ||
65 | {1000, 600, RES_1000X600_60HZ_PIXCLOCK, 60}, | ||
66 | {1024, 576, RES_1024X576_60HZ_PIXCLOCK, 60}, | ||
67 | {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60}, | ||
68 | {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60}, | ||
69 | {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60}, | ||
70 | {1200, 900, RES_1200X900_60HZ_PIXCLOCK, 60}, | ||
71 | {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60}, | ||
72 | {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50}, | ||
73 | {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50}, | ||
74 | {1360, 768, RES_1360X768_60HZ_PIXCLOCK, 60}, | ||
75 | {1366, 768, RES_1366X768_50HZ_PIXCLOCK, 50}, | ||
76 | {1366, 768, RES_1366X768_60HZ_PIXCLOCK, 60}, | ||
77 | {1440, 900, RES_1440X900_60HZ_PIXCLOCK, 60}, | ||
78 | {1440, 900, RES_1440X900_75HZ_PIXCLOCK, 75}, | ||
79 | {1600, 900, RES_1600X900_60HZ_PIXCLOCK, 60}, | ||
80 | {1600, 1024, RES_1600X1024_60HZ_PIXCLOCK, 60}, | ||
81 | {1680, 1050, RES_1680X1050_60HZ_PIXCLOCK, 60}, | ||
82 | {1680, 1050, RES_1680X1050_75HZ_PIXCLOCK, 75}, | ||
83 | {1792, 1344, RES_1792X1344_60HZ_PIXCLOCK, 60}, | ||
84 | {1856, 1392, RES_1856X1392_60HZ_PIXCLOCK, 60}, | ||
85 | {1920, 1200, RES_1920X1200_60HZ_PIXCLOCK, 60}, | ||
86 | {1920, 1440, RES_1920X1440_60HZ_PIXCLOCK, 60}, | ||
87 | {1920, 1440, RES_1920X1440_75HZ_PIXCLOCK, 75}, | ||
88 | {2048, 1536, RES_2048X1536_60HZ_PIXCLOCK, 60} | ||
89 | }; | ||
90 | 24 | ||
91 | struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | 25 | struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, |
92 | {VIASR, SR15, 0x02, 0x02}, | 26 | {VIASR, SR15, 0x02, 0x02}, |
@@ -108,20 +42,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | |||
108 | {VIACR, CR6A, 0xFF, 0x40}, | 42 | {VIACR, CR6A, 0xFF, 0x40}, |
109 | {VIACR, CR6B, 0xFF, 0x00}, | 43 | {VIACR, CR6B, 0xFF, 0x00}, |
110 | {VIACR, CR6C, 0xFF, 0x00}, | 44 | {VIACR, CR6C, 0xFF, 0x00}, |
111 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
112 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
113 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
114 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
115 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
116 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
117 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
118 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
119 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
120 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
121 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
122 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
123 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
124 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
125 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | 45 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ |
126 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | 46 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ |
127 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | 47 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ |
@@ -172,20 +92,6 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | |||
172 | {VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ | 92 | {VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ |
173 | {VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ | 93 | {VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ |
174 | {VIACR, CR9F, 0x03, 0x00}, /* LCD scaling Factor */ | 94 | {VIACR, CR9F, 0x03, 0x00}, /* LCD scaling Factor */ |
175 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
176 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
177 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
178 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
179 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
180 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
181 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
182 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
183 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
184 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
185 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
186 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
187 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
188 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
189 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | 95 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ |
190 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | 96 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ |
191 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | 97 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ |
@@ -229,20 +135,6 @@ struct io_reg KM400_ModeXregs[] = { | |||
229 | {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */ | 135 | {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */ |
230 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ | 136 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ |
231 | {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */ | 137 | {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */ |
232 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
233 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
234 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
235 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
236 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
237 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
238 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
239 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
240 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
241 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
242 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
243 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
244 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
245 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
246 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | 138 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ |
247 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | 139 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ |
248 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | 140 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ |
@@ -283,20 +175,6 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | |||
283 | {VIACR, CR6A, 0xFF, 0x40}, | 175 | {VIACR, CR6A, 0xFF, 0x40}, |
284 | {VIACR, CR6B, 0xFF, 0x00}, | 176 | {VIACR, CR6B, 0xFF, 0x00}, |
285 | {VIACR, CR6C, 0xFF, 0x00}, | 177 | {VIACR, CR6C, 0xFF, 0x00}, |
286 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
287 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
288 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
289 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
290 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
291 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
292 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
293 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
294 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
295 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
296 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
297 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
298 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
299 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
300 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | 178 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ |
301 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | 179 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ |
302 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | 180 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ |
@@ -342,20 +220,6 @@ struct io_reg VX855_ModeXregs[] = { | |||
342 | {VIACR, CR6A, 0xFD, 0x60}, | 220 | {VIACR, CR6A, 0xFD, 0x60}, |
343 | {VIACR, CR6B, 0xFF, 0x00}, | 221 | {VIACR, CR6B, 0xFF, 0x00}, |
344 | {VIACR, CR6C, 0xFF, 0x00}, | 222 | {VIACR, CR6C, 0xFF, 0x00}, |
345 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
346 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
347 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
348 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
349 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
350 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
351 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
352 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
353 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
354 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
355 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
356 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
357 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
358 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
359 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | 223 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ |
360 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | 224 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ |
361 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | 225 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ |
@@ -390,21 +254,6 @@ struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00}, | |||
390 | {VIAGR, GR20, 0xFF, 0x00}, | 254 | {VIAGR, GR20, 0xFF, 0x00}, |
391 | {VIAGR, GR21, 0xFF, 0x00}, | 255 | {VIAGR, GR21, 0xFF, 0x00}, |
392 | {VIAGR, GR22, 0xFF, 0x00}, | 256 | {VIAGR, GR22, 0xFF, 0x00}, |
393 | /* LCD Parameters */ | ||
394 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Parameter 1 */ | ||
395 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Parameter 2 */ | ||
396 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Parameter 3 */ | ||
397 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Parameter 4 */ | ||
398 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Parameter 5 */ | ||
399 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Parameter 6 */ | ||
400 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Parameter 7 */ | ||
401 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Parameter 8 */ | ||
402 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Parameter 9 */ | ||
403 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Parameter 10 */ | ||
404 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Parameter 11 */ | ||
405 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Parameter 12 */ | ||
406 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Parameter 13 */ | ||
407 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Parameter 14 */ | ||
408 | 257 | ||
409 | }; | 258 | }; |
410 | 259 | ||
@@ -443,328 +292,321 @@ struct VPITTable VPIT = { | |||
443 | /********************/ | 292 | /********************/ |
444 | 293 | ||
445 | /* 480x640 */ | 294 | /* 480x640 */ |
446 | struct crt_mode_table CRTM480x640[] = { | 295 | static struct crt_mode_table CRTM480x640[] = { |
447 | /* r_rate, vclk, hsp, vsp */ | 296 | /* r_rate, hsp, vsp */ |
448 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 297 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
449 | {REFRESH_60, CLK_25_175M, M480X640_R60_HSP, M480X640_R60_VSP, | 298 | {REFRESH_60, M480X640_R60_HSP, M480X640_R60_VSP, |
450 | {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} } /* GTF*/ | 299 | {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} } /* GTF*/ |
451 | }; | 300 | }; |
452 | 301 | ||
453 | /* 640x480*/ | 302 | /* 640x480*/ |
454 | struct crt_mode_table CRTM640x480[] = { | 303 | static struct crt_mode_table CRTM640x480[] = { |
455 | /*r_rate,vclk,hsp,vsp */ | 304 | /*r_rate,hsp,vsp */ |
456 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 305 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
457 | {REFRESH_60, CLK_25_175M, M640X480_R60_HSP, M640X480_R60_VSP, | 306 | {REFRESH_60, M640X480_R60_HSP, M640X480_R60_VSP, |
458 | {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} }, | 307 | {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} }, |
459 | {REFRESH_75, CLK_31_500M, M640X480_R75_HSP, M640X480_R75_VSP, | 308 | {REFRESH_75, M640X480_R75_HSP, M640X480_R75_VSP, |
460 | {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} }, | 309 | {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} }, |
461 | {REFRESH_85, CLK_36_000M, M640X480_R85_HSP, M640X480_R85_VSP, | 310 | {REFRESH_85, M640X480_R85_HSP, M640X480_R85_VSP, |
462 | {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} }, | 311 | {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} }, |
463 | {REFRESH_100, CLK_43_163M, M640X480_R100_HSP, M640X480_R100_VSP, | 312 | {REFRESH_100, M640X480_R100_HSP, M640X480_R100_VSP, |
464 | {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/ | 313 | {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/ |
465 | {REFRESH_120, CLK_52_406M, M640X480_R120_HSP, | 314 | {REFRESH_120, M640X480_R120_HSP, M640X480_R120_VSP, |
466 | M640X480_R120_VSP, | 315 | {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481, 3} } /*GTF*/ |
467 | {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481, | ||
468 | 3} } /*GTF*/ | ||
469 | }; | 316 | }; |
470 | 317 | ||
471 | /*720x480 (GTF)*/ | 318 | /*720x480 (GTF)*/ |
472 | struct crt_mode_table CRTM720x480[] = { | 319 | static struct crt_mode_table CRTM720x480[] = { |
473 | /*r_rate,vclk,hsp,vsp */ | 320 | /*r_rate,hsp,vsp */ |
474 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 321 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
475 | {REFRESH_60, CLK_26_880M, M720X480_R60_HSP, M720X480_R60_VSP, | 322 | {REFRESH_60, M720X480_R60_HSP, M720X480_R60_VSP, |
476 | {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} } | 323 | {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} } |
477 | 324 | ||
478 | }; | 325 | }; |
479 | 326 | ||
480 | /*720x576 (GTF)*/ | 327 | /*720x576 (GTF)*/ |
481 | struct crt_mode_table CRTM720x576[] = { | 328 | static struct crt_mode_table CRTM720x576[] = { |
482 | /*r_rate,vclk,hsp,vsp */ | 329 | /*r_rate,hsp,vsp */ |
483 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 330 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
484 | {REFRESH_60, CLK_32_668M, M720X576_R60_HSP, M720X576_R60_VSP, | 331 | {REFRESH_60, M720X576_R60_HSP, M720X576_R60_VSP, |
485 | {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} } | 332 | {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} } |
486 | }; | 333 | }; |
487 | 334 | ||
488 | /* 800x480 (CVT) */ | 335 | /* 800x480 (CVT) */ |
489 | struct crt_mode_table CRTM800x480[] = { | 336 | static struct crt_mode_table CRTM800x480[] = { |
490 | /* r_rate, vclk, hsp, vsp */ | 337 | /* r_rate, hsp, vsp */ |
491 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 338 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
492 | {REFRESH_60, CLK_29_581M, M800X480_R60_HSP, M800X480_R60_VSP, | 339 | {REFRESH_60, M800X480_R60_HSP, M800X480_R60_VSP, |
493 | {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} } | 340 | {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} } |
494 | }; | 341 | }; |
495 | 342 | ||
496 | /* 800x600*/ | 343 | /* 800x600*/ |
497 | struct crt_mode_table CRTM800x600[] = { | 344 | static struct crt_mode_table CRTM800x600[] = { |
498 | /*r_rate,vclk,hsp,vsp */ | 345 | /*r_rate,hsp,vsp */ |
499 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 346 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
500 | {REFRESH_60, CLK_40_000M, M800X600_R60_HSP, M800X600_R60_VSP, | 347 | {REFRESH_60, M800X600_R60_HSP, M800X600_R60_VSP, |
501 | {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} }, | 348 | {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} }, |
502 | {REFRESH_75, CLK_49_500M, M800X600_R75_HSP, M800X600_R75_VSP, | 349 | {REFRESH_75, M800X600_R75_HSP, M800X600_R75_VSP, |
503 | {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} }, | 350 | {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} }, |
504 | {REFRESH_85, CLK_56_250M, M800X600_R85_HSP, M800X600_R85_VSP, | 351 | {REFRESH_85, M800X600_R85_HSP, M800X600_R85_VSP, |
505 | {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} }, | 352 | {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} }, |
506 | {REFRESH_100, CLK_68_179M, M800X600_R100_HSP, M800X600_R100_VSP, | 353 | {REFRESH_100, M800X600_R100_HSP, M800X600_R100_VSP, |
507 | {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} }, | 354 | {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} }, |
508 | {REFRESH_120, CLK_83_950M, M800X600_R120_HSP, | 355 | {REFRESH_120, M800X600_R120_HSP, M800X600_R120_VSP, |
509 | M800X600_R120_VSP, | 356 | {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601, 3} } |
510 | {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601, | ||
511 | 3} } | ||
512 | }; | 357 | }; |
513 | 358 | ||
514 | /* 848x480 (CVT) */ | 359 | /* 848x480 (CVT) */ |
515 | struct crt_mode_table CRTM848x480[] = { | 360 | static struct crt_mode_table CRTM848x480[] = { |
516 | /* r_rate, vclk, hsp, vsp */ | 361 | /* r_rate, hsp, vsp */ |
517 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 362 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
518 | {REFRESH_60, CLK_31_500M, M848X480_R60_HSP, M848X480_R60_VSP, | 363 | {REFRESH_60, M848X480_R60_HSP, M848X480_R60_VSP, |
519 | {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} } | 364 | {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} } |
520 | }; | 365 | }; |
521 | 366 | ||
522 | /*856x480 (GTF) convert to 852x480*/ | 367 | /*856x480 (GTF) convert to 852x480*/ |
523 | struct crt_mode_table CRTM852x480[] = { | 368 | static struct crt_mode_table CRTM852x480[] = { |
524 | /*r_rate,vclk,hsp,vsp */ | 369 | /*r_rate,hsp,vsp */ |
525 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 370 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
526 | {REFRESH_60, CLK_31_728M, M852X480_R60_HSP, M852X480_R60_VSP, | 371 | {REFRESH_60, M852X480_R60_HSP, M852X480_R60_VSP, |
527 | {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} } | 372 | {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} } |
528 | }; | 373 | }; |
529 | 374 | ||
530 | /*1024x512 (GTF)*/ | 375 | /*1024x512 (GTF)*/ |
531 | struct crt_mode_table CRTM1024x512[] = { | 376 | static struct crt_mode_table CRTM1024x512[] = { |
532 | /*r_rate,vclk,hsp,vsp */ | 377 | /*r_rate,hsp,vsp */ |
533 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 378 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
534 | {REFRESH_60, CLK_41_291M, M1024X512_R60_HSP, M1024X512_R60_VSP, | 379 | {REFRESH_60, M1024X512_R60_HSP, M1024X512_R60_VSP, |
535 | {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} } | 380 | {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} } |
536 | 381 | ||
537 | }; | 382 | }; |
538 | 383 | ||
539 | /* 1024x600*/ | 384 | /* 1024x600*/ |
540 | struct crt_mode_table CRTM1024x600[] = { | 385 | static struct crt_mode_table CRTM1024x600[] = { |
541 | /*r_rate,vclk,hsp,vsp */ | 386 | /*r_rate,hsp,vsp */ |
542 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 387 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
543 | {REFRESH_60, CLK_48_875M, M1024X600_R60_HSP, M1024X600_R60_VSP, | 388 | {REFRESH_60, M1024X600_R60_HSP, M1024X600_R60_VSP, |
544 | {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} }, | 389 | {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} }, |
545 | }; | 390 | }; |
546 | 391 | ||
547 | /* 1024x768*/ | 392 | /* 1024x768*/ |
548 | struct crt_mode_table CRTM1024x768[] = { | 393 | static struct crt_mode_table CRTM1024x768[] = { |
549 | /*r_rate,vclk,hsp,vsp */ | 394 | /*r_rate,hsp,vsp */ |
550 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 395 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
551 | {REFRESH_60, CLK_65_000M, M1024X768_R60_HSP, M1024X768_R60_VSP, | 396 | {REFRESH_60, M1024X768_R60_HSP, M1024X768_R60_VSP, |
552 | {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} }, | 397 | {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} }, |
553 | {REFRESH_75, CLK_78_750M, M1024X768_R75_HSP, M1024X768_R75_VSP, | 398 | {REFRESH_75, M1024X768_R75_HSP, M1024X768_R75_VSP, |
554 | {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} }, | 399 | {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} }, |
555 | {REFRESH_85, CLK_94_500M, M1024X768_R85_HSP, M1024X768_R85_VSP, | 400 | {REFRESH_85, M1024X768_R85_HSP, M1024X768_R85_VSP, |
556 | {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} }, | 401 | {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} }, |
557 | {REFRESH_100, CLK_113_309M, M1024X768_R100_HSP, M1024X768_R100_VSP, | 402 | {REFRESH_100, M1024X768_R100_HSP, M1024X768_R100_VSP, |
558 | {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} } | 403 | {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} } |
559 | }; | 404 | }; |
560 | 405 | ||
561 | /* 1152x864*/ | 406 | /* 1152x864*/ |
562 | struct crt_mode_table CRTM1152x864[] = { | 407 | static struct crt_mode_table CRTM1152x864[] = { |
563 | /*r_rate,vclk,hsp,vsp */ | 408 | /*r_rate,hsp,vsp */ |
564 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 409 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
565 | {REFRESH_75, CLK_108_000M, M1152X864_R75_HSP, M1152X864_R75_VSP, | 410 | {REFRESH_75, M1152X864_R75_HSP, M1152X864_R75_VSP, |
566 | {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} } | 411 | {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} } |
567 | 412 | ||
568 | }; | 413 | }; |
569 | 414 | ||
570 | /* 1280x720 (HDMI 720P)*/ | 415 | /* 1280x720 (HDMI 720P)*/ |
571 | struct crt_mode_table CRTM1280x720[] = { | 416 | static struct crt_mode_table CRTM1280x720[] = { |
572 | /*r_rate,vclk,hsp,vsp */ | 417 | /*r_rate,hsp,vsp */ |
573 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 418 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
574 | {REFRESH_60, CLK_74_481M, M1280X720_R60_HSP, M1280X720_R60_VSP, | 419 | {REFRESH_60, M1280X720_R60_HSP, M1280X720_R60_VSP, |
575 | {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} }, | 420 | {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} }, |
576 | {REFRESH_50, CLK_60_466M, M1280X720_R50_HSP, M1280X720_R50_VSP, | 421 | {REFRESH_50, M1280X720_R50_HSP, M1280X720_R50_VSP, |
577 | {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} } | 422 | {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} } |
578 | }; | 423 | }; |
579 | 424 | ||
580 | /*1280x768 (GTF)*/ | 425 | /*1280x768 (GTF)*/ |
581 | struct crt_mode_table CRTM1280x768[] = { | 426 | static struct crt_mode_table CRTM1280x768[] = { |
582 | /*r_rate,vclk,hsp,vsp */ | 427 | /*r_rate,hsp,vsp */ |
583 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 428 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
584 | {REFRESH_60, CLK_80_136M, M1280X768_R60_HSP, M1280X768_R60_VSP, | 429 | {REFRESH_60, M1280X768_R60_HSP, M1280X768_R60_VSP, |
585 | {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} }, | 430 | {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} }, |
586 | {REFRESH_50, CLK_65_178M, M1280X768_R50_HSP, M1280X768_R50_VSP, | 431 | {REFRESH_50, M1280X768_R50_HSP, M1280X768_R50_VSP, |
587 | {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} } | 432 | {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} } |
588 | }; | 433 | }; |
589 | 434 | ||
590 | /* 1280x800 (CVT) */ | 435 | /* 1280x800 (CVT) */ |
591 | struct crt_mode_table CRTM1280x800[] = { | 436 | static struct crt_mode_table CRTM1280x800[] = { |
592 | /* r_rate, vclk, hsp, vsp */ | 437 | /* r_rate, hsp, vsp */ |
593 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 438 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
594 | {REFRESH_60, CLK_83_375M, M1280X800_R60_HSP, M1280X800_R60_VSP, | 439 | {REFRESH_60, M1280X800_R60_HSP, M1280X800_R60_VSP, |
595 | {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} } | 440 | {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} } |
596 | }; | 441 | }; |
597 | 442 | ||
598 | /*1280x960*/ | 443 | /*1280x960*/ |
599 | struct crt_mode_table CRTM1280x960[] = { | 444 | static struct crt_mode_table CRTM1280x960[] = { |
600 | /*r_rate,vclk,hsp,vsp */ | 445 | /*r_rate,hsp,vsp */ |
601 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 446 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
602 | {REFRESH_60, CLK_108_000M, M1280X960_R60_HSP, M1280X960_R60_VSP, | 447 | {REFRESH_60, M1280X960_R60_HSP, M1280X960_R60_VSP, |
603 | {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} } | 448 | {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} } |
604 | }; | 449 | }; |
605 | 450 | ||
606 | /* 1280x1024*/ | 451 | /* 1280x1024*/ |
607 | struct crt_mode_table CRTM1280x1024[] = { | 452 | static struct crt_mode_table CRTM1280x1024[] = { |
608 | /*r_rate,vclk,,hsp,vsp */ | 453 | /*r_rate,hsp,vsp */ |
609 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 454 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
610 | {REFRESH_60, CLK_108_000M, M1280X1024_R60_HSP, M1280X1024_R60_VSP, | 455 | {REFRESH_60, M1280X1024_R60_HSP, M1280X1024_R60_VSP, |
611 | {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025, | 456 | {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025, |
612 | 3} }, | 457 | 3} }, |
613 | {REFRESH_75, CLK_135_000M, M1280X1024_R75_HSP, M1280X1024_R75_VSP, | 458 | {REFRESH_75, M1280X1024_R75_HSP, M1280X1024_R75_VSP, |
614 | {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025, | 459 | {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025, |
615 | 3} }, | 460 | 3} }, |
616 | {REFRESH_85, CLK_157_500M, M1280X1024_R85_HSP, M1280X1024_R85_VSP, | 461 | {REFRESH_85, M1280X1024_R85_HSP, M1280X1024_R85_VSP, |
617 | {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} } | 462 | {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} } |
618 | }; | 463 | }; |
619 | 464 | ||
620 | /* 1368x768 (GTF) */ | 465 | /* 1368x768 (GTF) */ |
621 | struct crt_mode_table CRTM1368x768[] = { | 466 | static struct crt_mode_table CRTM1368x768[] = { |
622 | /* r_rate, vclk, hsp, vsp */ | 467 | /* r_rate, hsp, vsp */ |
623 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 468 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
624 | {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP, | 469 | {REFRESH_60, M1368X768_R60_HSP, M1368X768_R60_VSP, |
625 | {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} } | 470 | {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} } |
626 | }; | 471 | }; |
627 | 472 | ||
628 | /*1440x1050 (GTF)*/ | 473 | /*1440x1050 (GTF)*/ |
629 | struct crt_mode_table CRTM1440x1050[] = { | 474 | static struct crt_mode_table CRTM1440x1050[] = { |
630 | /*r_rate,vclk,hsp,vsp */ | 475 | /*r_rate,hsp,vsp */ |
631 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 476 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
632 | {REFRESH_60, CLK_125_104M, M1440X1050_R60_HSP, M1440X1050_R60_VSP, | 477 | {REFRESH_60, M1440X1050_R60_HSP, M1440X1050_R60_VSP, |
633 | {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} } | 478 | {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} } |
634 | }; | 479 | }; |
635 | 480 | ||
636 | /* 1600x1200*/ | 481 | /* 1600x1200*/ |
637 | struct crt_mode_table CRTM1600x1200[] = { | 482 | static struct crt_mode_table CRTM1600x1200[] = { |
638 | /*r_rate,vclk,hsp,vsp */ | 483 | /*r_rate,hsp,vsp */ |
639 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 484 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
640 | {REFRESH_60, CLK_162_000M, M1600X1200_R60_HSP, M1600X1200_R60_VSP, | 485 | {REFRESH_60, M1600X1200_R60_HSP, M1600X1200_R60_VSP, |
641 | {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, | 486 | {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, |
642 | 3} }, | 487 | 3} }, |
643 | {REFRESH_75, CLK_202_500M, M1600X1200_R75_HSP, M1600X1200_R75_VSP, | 488 | {REFRESH_75, M1600X1200_R75_HSP, M1600X1200_R75_VSP, |
644 | {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} } | 489 | {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} } |
645 | 490 | ||
646 | }; | 491 | }; |
647 | 492 | ||
648 | /* 1680x1050 (CVT) */ | 493 | /* 1680x1050 (CVT) */ |
649 | struct crt_mode_table CRTM1680x1050[] = { | 494 | static struct crt_mode_table CRTM1680x1050[] = { |
650 | /* r_rate, vclk, hsp, vsp */ | 495 | /* r_rate, hsp, vsp */ |
651 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 496 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
652 | {REFRESH_60, CLK_146_760M, M1680x1050_R60_HSP, M1680x1050_R60_VSP, | 497 | {REFRESH_60, M1680x1050_R60_HSP, M1680x1050_R60_VSP, |
653 | {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053, | 498 | {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053, |
654 | 6} }, | 499 | 6} }, |
655 | {REFRESH_75, CLK_187_000M, M1680x1050_R75_HSP, M1680x1050_R75_VSP, | 500 | {REFRESH_75, M1680x1050_R75_HSP, M1680x1050_R75_VSP, |
656 | {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} } | 501 | {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} } |
657 | }; | 502 | }; |
658 | 503 | ||
659 | /* 1680x1050 (CVT Reduce Blanking) */ | 504 | /* 1680x1050 (CVT Reduce Blanking) */ |
660 | struct crt_mode_table CRTM1680x1050_RB[] = { | 505 | static struct crt_mode_table CRTM1680x1050_RB[] = { |
661 | /* r_rate, vclk, hsp, vsp */ | 506 | /* r_rate, hsp, vsp */ |
662 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 507 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
663 | {REFRESH_60, CLK_119_000M, M1680x1050_RB_R60_HSP, | 508 | {REFRESH_60, M1680x1050_RB_R60_HSP, M1680x1050_RB_R60_VSP, |
664 | M1680x1050_RB_R60_VSP, | ||
665 | {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} } | 509 | {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} } |
666 | }; | 510 | }; |
667 | 511 | ||
668 | /* 1920x1080 (CVT)*/ | 512 | /* 1920x1080 (CVT)*/ |
669 | struct crt_mode_table CRTM1920x1080[] = { | 513 | static struct crt_mode_table CRTM1920x1080[] = { |
670 | /*r_rate,vclk,hsp,vsp */ | 514 | /*r_rate,hsp,vsp */ |
671 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 515 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
672 | {REFRESH_60, CLK_172_798M, M1920X1080_R60_HSP, M1920X1080_R60_VSP, | 516 | {REFRESH_60, M1920X1080_R60_HSP, M1920X1080_R60_VSP, |
673 | {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} } | 517 | {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} } |
674 | }; | 518 | }; |
675 | 519 | ||
676 | /* 1920x1080 (CVT with Reduce Blanking) */ | 520 | /* 1920x1080 (CVT with Reduce Blanking) */ |
677 | struct crt_mode_table CRTM1920x1080_RB[] = { | 521 | static struct crt_mode_table CRTM1920x1080_RB[] = { |
678 | /* r_rate, vclk, hsp, vsp */ | 522 | /* r_rate, hsp, vsp */ |
679 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 523 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
680 | {REFRESH_60, CLK_138_400M, M1920X1080_RB_R60_HSP, | 524 | {REFRESH_60, M1920X1080_RB_R60_HSP, M1920X1080_RB_R60_VSP, |
681 | M1920X1080_RB_R60_VSP, | ||
682 | {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} } | 525 | {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} } |
683 | }; | 526 | }; |
684 | 527 | ||
685 | /* 1920x1440*/ | 528 | /* 1920x1440*/ |
686 | struct crt_mode_table CRTM1920x1440[] = { | 529 | static struct crt_mode_table CRTM1920x1440[] = { |
687 | /*r_rate,vclk,hsp,vsp */ | 530 | /*r_rate,hsp,vsp */ |
688 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 531 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
689 | {REFRESH_60, CLK_234_000M, M1920X1440_R60_HSP, M1920X1440_R60_VSP, | 532 | {REFRESH_60, M1920X1440_R60_HSP, M1920X1440_R60_VSP, |
690 | {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441, | 533 | {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441, |
691 | 3} }, | 534 | 3} }, |
692 | {REFRESH_75, CLK_297_500M, M1920X1440_R75_HSP, M1920X1440_R75_VSP, | 535 | {REFRESH_75, M1920X1440_R75_HSP, M1920X1440_R75_VSP, |
693 | {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} } | 536 | {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} } |
694 | }; | 537 | }; |
695 | 538 | ||
696 | /* 1400x1050 (CVT) */ | 539 | /* 1400x1050 (CVT) */ |
697 | struct crt_mode_table CRTM1400x1050[] = { | 540 | static struct crt_mode_table CRTM1400x1050[] = { |
698 | /* r_rate, vclk, hsp, vsp */ | 541 | /* r_rate, hsp, vsp */ |
699 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 542 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
700 | {REFRESH_60, CLK_121_750M, M1400X1050_R60_HSP, M1400X1050_R60_VSP, | 543 | {REFRESH_60, M1400X1050_R60_HSP, M1400X1050_R60_VSP, |
701 | {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053, | 544 | {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053, |
702 | 4} }, | 545 | 4} }, |
703 | {REFRESH_75, CLK_156_000M, M1400X1050_R75_HSP, M1400X1050_R75_VSP, | 546 | {REFRESH_75, M1400X1050_R75_HSP, M1400X1050_R75_VSP, |
704 | {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} } | 547 | {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} } |
705 | }; | 548 | }; |
706 | 549 | ||
707 | /* 1400x1050 (CVT Reduce Blanking) */ | 550 | /* 1400x1050 (CVT Reduce Blanking) */ |
708 | struct crt_mode_table CRTM1400x1050_RB[] = { | 551 | static struct crt_mode_table CRTM1400x1050_RB[] = { |
709 | /* r_rate, vclk, hsp, vsp */ | 552 | /* r_rate, hsp, vsp */ |
710 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 553 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
711 | {REFRESH_60, CLK_101_000M, M1400X1050_RB_R60_HSP, | 554 | {REFRESH_60, M1400X1050_RB_R60_HSP, M1400X1050_RB_R60_VSP, |
712 | M1400X1050_RB_R60_VSP, | ||
713 | {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} } | 555 | {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} } |
714 | }; | 556 | }; |
715 | 557 | ||
716 | /* 960x600 (CVT) */ | 558 | /* 960x600 (CVT) */ |
717 | struct crt_mode_table CRTM960x600[] = { | 559 | static struct crt_mode_table CRTM960x600[] = { |
718 | /* r_rate, vclk, hsp, vsp */ | 560 | /* r_rate, hsp, vsp */ |
719 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 561 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
720 | {REFRESH_60, CLK_45_250M, M960X600_R60_HSP, M960X600_R60_VSP, | 562 | {REFRESH_60, M960X600_R60_HSP, M960X600_R60_VSP, |
721 | {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} } | 563 | {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} } |
722 | }; | 564 | }; |
723 | 565 | ||
724 | /* 1000x600 (GTF) */ | 566 | /* 1000x600 (GTF) */ |
725 | struct crt_mode_table CRTM1000x600[] = { | 567 | static struct crt_mode_table CRTM1000x600[] = { |
726 | /* r_rate, vclk, hsp, vsp */ | 568 | /* r_rate, hsp, vsp */ |
727 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 569 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
728 | {REFRESH_60, CLK_48_000M, M1000X600_R60_HSP, M1000X600_R60_VSP, | 570 | {REFRESH_60, M1000X600_R60_HSP, M1000X600_R60_VSP, |
729 | {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} } | 571 | {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} } |
730 | }; | 572 | }; |
731 | 573 | ||
732 | /* 1024x576 (GTF) */ | 574 | /* 1024x576 (GTF) */ |
733 | struct crt_mode_table CRTM1024x576[] = { | 575 | static struct crt_mode_table CRTM1024x576[] = { |
734 | /* r_rate, vclk, hsp, vsp */ | 576 | /* r_rate, hsp, vsp */ |
735 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 577 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
736 | {REFRESH_60, CLK_46_996M, M1024X576_R60_HSP, M1024X576_R60_VSP, | 578 | {REFRESH_60, M1024X576_R60_HSP, M1024X576_R60_VSP, |
737 | {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} } | 579 | {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} } |
738 | }; | 580 | }; |
739 | 581 | ||
740 | /* 1088x612 (CVT) */ | 582 | /* 1088x612 (CVT) */ |
741 | struct crt_mode_table CRTM1088x612[] = { | 583 | static struct crt_mode_table CRTM1088x612[] = { |
742 | /* r_rate, vclk, hsp, vsp */ | 584 | /* r_rate, hsp, vsp */ |
743 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 585 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
744 | {REFRESH_60, CLK_52_977M, M1088X612_R60_HSP, M1088X612_R60_VSP, | 586 | {REFRESH_60, M1088X612_R60_HSP, M1088X612_R60_VSP, |
745 | {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} } | 587 | {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} } |
746 | }; | 588 | }; |
747 | 589 | ||
748 | /* 1152x720 (CVT) */ | 590 | /* 1152x720 (CVT) */ |
749 | struct crt_mode_table CRTM1152x720[] = { | 591 | static struct crt_mode_table CRTM1152x720[] = { |
750 | /* r_rate, vclk, hsp, vsp */ | 592 | /* r_rate, hsp, vsp */ |
751 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 593 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
752 | {REFRESH_60, CLK_66_750M, M1152X720_R60_HSP, M1152X720_R60_VSP, | 594 | {REFRESH_60, M1152X720_R60_HSP, M1152X720_R60_VSP, |
753 | {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} } | 595 | {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} } |
754 | }; | 596 | }; |
755 | 597 | ||
756 | /* 1200x720 (GTF) */ | 598 | /* 1200x720 (GTF) */ |
757 | struct crt_mode_table CRTM1200x720[] = { | 599 | static struct crt_mode_table CRTM1200x720[] = { |
758 | /* r_rate, vclk, hsp, vsp */ | 600 | /* r_rate, hsp, vsp */ |
759 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 601 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
760 | {REFRESH_60, CLK_70_159M, M1200X720_R60_HSP, M1200X720_R60_VSP, | 602 | {REFRESH_60, M1200X720_R60_HSP, M1200X720_R60_VSP, |
761 | {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} } | 603 | {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} } |
762 | }; | 604 | }; |
763 | 605 | ||
764 | /* 1200x900 (DCON) */ | 606 | /* 1200x900 (DCON) */ |
765 | struct crt_mode_table DCON1200x900[] = { | 607 | static struct crt_mode_table DCON1200x900[] = { |
766 | /* r_rate, vclk, hsp, vsp */ | 608 | /* r_rate, hsp, vsp */ |
767 | {REFRESH_60, CLK_57_275M, M1200X900_R60_HSP, M1200X900_R60_VSP, | 609 | {REFRESH_60, M1200X900_R60_HSP, M1200X900_R60_VSP, |
768 | /* The correct htotal is 1240, but this doesn't raster on VX855. */ | 610 | /* The correct htotal is 1240, but this doesn't raster on VX855. */ |
769 | /* Via suggested changing to a multiple of 16, hence 1264. */ | 611 | /* Via suggested changing to a multiple of 16, hence 1264. */ |
770 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 612 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
@@ -772,126 +614,122 @@ struct crt_mode_table DCON1200x900[] = { | |||
772 | }; | 614 | }; |
773 | 615 | ||
774 | /* 1280x600 (GTF) */ | 616 | /* 1280x600 (GTF) */ |
775 | struct crt_mode_table CRTM1280x600[] = { | 617 | static struct crt_mode_table CRTM1280x600[] = { |
776 | /* r_rate, vclk, hsp, vsp */ | 618 | /* r_rate, hsp, vsp */ |
777 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 619 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
778 | {REFRESH_60, CLK_61_500M, M1280x600_R60_HSP, M1280x600_R60_VSP, | 620 | {REFRESH_60, M1280x600_R60_HSP, M1280x600_R60_VSP, |
779 | {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} } | 621 | {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} } |
780 | }; | 622 | }; |
781 | 623 | ||
782 | /* 1360x768 (CVT) */ | 624 | /* 1360x768 (CVT) */ |
783 | struct crt_mode_table CRTM1360x768[] = { | 625 | static struct crt_mode_table CRTM1360x768[] = { |
784 | /* r_rate, vclk, hsp, vsp */ | 626 | /* r_rate, hsp, vsp */ |
785 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 627 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
786 | {REFRESH_60, CLK_84_750M, M1360X768_R60_HSP, M1360X768_R60_VSP, | 628 | {REFRESH_60, M1360X768_R60_HSP, M1360X768_R60_VSP, |
787 | {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} } | 629 | {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} } |
788 | }; | 630 | }; |
789 | 631 | ||
790 | /* 1360x768 (CVT Reduce Blanking) */ | 632 | /* 1360x768 (CVT Reduce Blanking) */ |
791 | struct crt_mode_table CRTM1360x768_RB[] = { | 633 | static struct crt_mode_table CRTM1360x768_RB[] = { |
792 | /* r_rate, vclk, hsp, vsp */ | 634 | /* r_rate, hsp, vsp */ |
793 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 635 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
794 | {REFRESH_60, CLK_72_000M, M1360X768_RB_R60_HSP, | 636 | {REFRESH_60, M1360X768_RB_R60_HSP, M1360X768_RB_R60_VSP, |
795 | M1360X768_RB_R60_VSP, | ||
796 | {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} } | 637 | {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} } |
797 | }; | 638 | }; |
798 | 639 | ||
799 | /* 1366x768 (GTF) */ | 640 | /* 1366x768 (GTF) */ |
800 | struct crt_mode_table CRTM1366x768[] = { | 641 | static struct crt_mode_table CRTM1366x768[] = { |
801 | /* r_rate, vclk, hsp, vsp */ | 642 | /* r_rate, hsp, vsp */ |
802 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 643 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
803 | {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP, | 644 | {REFRESH_60, M1368X768_R60_HSP, M1368X768_R60_VSP, |
804 | {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }, | 645 | {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }, |
805 | {REFRESH_50, CLK_69_924M, M1368X768_R50_HSP, M1368X768_R50_VSP, | 646 | {REFRESH_50, M1368X768_R50_HSP, M1368X768_R50_VSP, |
806 | {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} } | 647 | {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} } |
807 | }; | 648 | }; |
808 | 649 | ||
809 | /* 1440x900 (CVT) */ | 650 | /* 1440x900 (CVT) */ |
810 | struct crt_mode_table CRTM1440x900[] = { | 651 | static struct crt_mode_table CRTM1440x900[] = { |
811 | /* r_rate, vclk, hsp, vsp */ | 652 | /* r_rate, hsp, vsp */ |
812 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 653 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
813 | {REFRESH_60, CLK_106_500M, M1440X900_R60_HSP, M1440X900_R60_VSP, | 654 | {REFRESH_60, M1440X900_R60_HSP, M1440X900_R60_VSP, |
814 | {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} }, | 655 | {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} }, |
815 | {REFRESH_75, CLK_136_700M, M1440X900_R75_HSP, M1440X900_R75_VSP, | 656 | {REFRESH_75, M1440X900_R75_HSP, M1440X900_R75_VSP, |
816 | {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} } | 657 | {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} } |
817 | }; | 658 | }; |
818 | 659 | ||
819 | /* 1440x900 (CVT Reduce Blanking) */ | 660 | /* 1440x900 (CVT Reduce Blanking) */ |
820 | struct crt_mode_table CRTM1440x900_RB[] = { | 661 | static struct crt_mode_table CRTM1440x900_RB[] = { |
821 | /* r_rate, vclk, hsp, vsp */ | 662 | /* r_rate, hsp, vsp */ |
822 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 663 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
823 | {REFRESH_60, CLK_88_750M, M1440X900_RB_R60_HSP, | 664 | {REFRESH_60, M1440X900_RB_R60_HSP, M1440X900_RB_R60_VSP, |
824 | M1440X900_RB_R60_VSP, | ||
825 | {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} } | 665 | {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} } |
826 | }; | 666 | }; |
827 | 667 | ||
828 | /* 1600x900 (CVT) */ | 668 | /* 1600x900 (CVT) */ |
829 | struct crt_mode_table CRTM1600x900[] = { | 669 | static struct crt_mode_table CRTM1600x900[] = { |
830 | /* r_rate, vclk, hsp, vsp */ | 670 | /* r_rate, hsp, vsp */ |
831 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 671 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
832 | {REFRESH_60, CLK_118_840M, M1600X900_R60_HSP, M1600X900_R60_VSP, | 672 | {REFRESH_60, M1600X900_R60_HSP, M1600X900_R60_VSP, |
833 | {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} } | 673 | {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} } |
834 | }; | 674 | }; |
835 | 675 | ||
836 | /* 1600x900 (CVT Reduce Blanking) */ | 676 | /* 1600x900 (CVT Reduce Blanking) */ |
837 | struct crt_mode_table CRTM1600x900_RB[] = { | 677 | static struct crt_mode_table CRTM1600x900_RB[] = { |
838 | /* r_rate, vclk, hsp, vsp */ | 678 | /* r_rate, hsp, vsp */ |
839 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 679 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
840 | {REFRESH_60, CLK_97_750M, M1600X900_RB_R60_HSP, | 680 | {REFRESH_60, M1600X900_RB_R60_HSP, M1600X900_RB_R60_VSP, |
841 | M1600X900_RB_R60_VSP, | ||
842 | {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} } | 681 | {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} } |
843 | }; | 682 | }; |
844 | 683 | ||
845 | /* 1600x1024 (GTF) */ | 684 | /* 1600x1024 (GTF) */ |
846 | struct crt_mode_table CRTM1600x1024[] = { | 685 | static struct crt_mode_table CRTM1600x1024[] = { |
847 | /* r_rate, vclk, hsp, vsp */ | 686 | /* r_rate, hsp, vsp */ |
848 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 687 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
849 | {REFRESH_60, CLK_136_700M, M1600X1024_R60_HSP, M1600X1024_R60_VSP, | 688 | {REFRESH_60, M1600X1024_R60_HSP, M1600X1024_R60_VSP, |
850 | {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} } | 689 | {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} } |
851 | }; | 690 | }; |
852 | 691 | ||
853 | /* 1792x1344 (DMT) */ | 692 | /* 1792x1344 (DMT) */ |
854 | struct crt_mode_table CRTM1792x1344[] = { | 693 | static struct crt_mode_table CRTM1792x1344[] = { |
855 | /* r_rate, vclk, hsp, vsp */ | 694 | /* r_rate, hsp, vsp */ |
856 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 695 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
857 | {REFRESH_60, CLK_204_000M, M1792x1344_R60_HSP, M1792x1344_R60_VSP, | 696 | {REFRESH_60, M1792x1344_R60_HSP, M1792x1344_R60_VSP, |
858 | {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} } | 697 | {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} } |
859 | }; | 698 | }; |
860 | 699 | ||
861 | /* 1856x1392 (DMT) */ | 700 | /* 1856x1392 (DMT) */ |
862 | struct crt_mode_table CRTM1856x1392[] = { | 701 | static struct crt_mode_table CRTM1856x1392[] = { |
863 | /* r_rate, vclk, hsp, vsp */ | 702 | /* r_rate, hsp, vsp */ |
864 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 703 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
865 | {REFRESH_60, CLK_218_500M, M1856x1392_R60_HSP, M1856x1392_R60_VSP, | 704 | {REFRESH_60, M1856x1392_R60_HSP, M1856x1392_R60_VSP, |
866 | {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} } | 705 | {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} } |
867 | }; | 706 | }; |
868 | 707 | ||
869 | /* 1920x1200 (CVT) */ | 708 | /* 1920x1200 (CVT) */ |
870 | struct crt_mode_table CRTM1920x1200[] = { | 709 | static struct crt_mode_table CRTM1920x1200[] = { |
871 | /* r_rate, vclk, hsp, vsp */ | 710 | /* r_rate, hsp, vsp */ |
872 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 711 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
873 | {REFRESH_60, CLK_193_295M, M1920X1200_R60_HSP, M1920X1200_R60_VSP, | 712 | {REFRESH_60, M1920X1200_R60_HSP, M1920X1200_R60_VSP, |
874 | {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} } | 713 | {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} } |
875 | }; | 714 | }; |
876 | 715 | ||
877 | /* 1920x1200 (CVT with Reduce Blanking) */ | 716 | /* 1920x1200 (CVT with Reduce Blanking) */ |
878 | struct crt_mode_table CRTM1920x1200_RB[] = { | 717 | static struct crt_mode_table CRTM1920x1200_RB[] = { |
879 | /* r_rate, vclk, hsp, vsp */ | 718 | /* r_rate, hsp, vsp */ |
880 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 719 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
881 | {REFRESH_60, CLK_153_920M, M1920X1200_RB_R60_HSP, | 720 | {REFRESH_60, M1920X1200_RB_R60_HSP, M1920X1200_RB_R60_VSP, |
882 | M1920X1200_RB_R60_VSP, | ||
883 | {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} } | 721 | {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} } |
884 | }; | 722 | }; |
885 | 723 | ||
886 | /* 2048x1536 (CVT) */ | 724 | /* 2048x1536 (CVT) */ |
887 | struct crt_mode_table CRTM2048x1536[] = { | 725 | static struct crt_mode_table CRTM2048x1536[] = { |
888 | /* r_rate, vclk, hsp, vsp */ | 726 | /* r_rate, hsp, vsp */ |
889 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 727 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
890 | {REFRESH_60, CLK_267_250M, M2048x1536_R60_HSP, M2048x1536_R60_VSP, | 728 | {REFRESH_60, M2048x1536_R60_HSP, M2048x1536_R60_VSP, |
891 | {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} } | 729 | {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} } |
892 | }; | 730 | }; |
893 | 731 | ||
894 | struct VideoModeTable viafb_modes[] = { | 732 | static struct VideoModeTable viafb_modes[] = { |
895 | /* Display : 480x640 (GTF) */ | 733 | /* Display : 480x640 (GTF) */ |
896 | {CRTM480x640, ARRAY_SIZE(CRTM480x640)}, | 734 | {CRTM480x640, ARRAY_SIZE(CRTM480x640)}, |
897 | 735 | ||
@@ -1016,7 +854,7 @@ struct VideoModeTable viafb_modes[] = { | |||
1016 | {CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)} | 854 | {CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)} |
1017 | }; | 855 | }; |
1018 | 856 | ||
1019 | struct VideoModeTable viafb_rb_modes[] = { | 857 | static struct VideoModeTable viafb_rb_modes[] = { |
1020 | /* Display : 1360x768 (CVT Reduce Blanking) */ | 858 | /* Display : 1360x768 (CVT Reduce Blanking) */ |
1021 | {CRTM1360x768_RB, ARRAY_SIZE(CRTM1360x768_RB)}, | 859 | {CRTM1360x768_RB, ARRAY_SIZE(CRTM1360x768_RB)}, |
1022 | 860 | ||
@@ -1040,14 +878,12 @@ struct VideoModeTable viafb_rb_modes[] = { | |||
1040 | }; | 878 | }; |
1041 | 879 | ||
1042 | struct crt_mode_table CEAM1280x720[] = { | 880 | struct crt_mode_table CEAM1280x720[] = { |
1043 | {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP, | 881 | {REFRESH_60, M1280X720_CEA_R60_HSP, M1280X720_CEA_R60_VSP, |
1044 | M1280X720_CEA_R60_VSP, | ||
1045 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 882 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
1046 | {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} } | 883 | {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} } |
1047 | }; | 884 | }; |
1048 | struct crt_mode_table CEAM1920x1080[] = { | 885 | struct crt_mode_table CEAM1920x1080[] = { |
1049 | {REFRESH_60, CLK_148_500M, M1920X1080_CEA_R60_HSP, | 886 | {REFRESH_60, M1920X1080_CEA_R60_HSP, M1920X1080_CEA_R60_VSP, |
1050 | M1920X1080_CEA_R60_VSP, | ||
1051 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | 887 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ |
1052 | {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} } | 888 | {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} } |
1053 | }; | 889 | }; |
@@ -1057,7 +893,6 @@ struct VideoModeTable CEA_HDMI_Modes[] = { | |||
1057 | {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} | 893 | {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} |
1058 | }; | 894 | }; |
1059 | 895 | ||
1060 | int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl); | ||
1061 | int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes); | 896 | int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes); |
1062 | int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs); | 897 | int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs); |
1063 | int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs); | 898 | int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs); |
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h index 5b1ced86514b..8a67ea1b5ef0 100644 --- a/drivers/video/via/viamode.h +++ b/drivers/video/via/viamode.h | |||
@@ -41,14 +41,6 @@ struct patch_table { | |||
41 | struct io_reg *io_reg_table; | 41 | struct io_reg *io_reg_table; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct res_map_refresh { | ||
45 | int hres; | ||
46 | int vres; | ||
47 | int pixclock; | ||
48 | int vmode_refresh; | ||
49 | }; | ||
50 | |||
51 | extern int NUM_TOTAL_RES_MAP_REFRESH; | ||
52 | extern int NUM_TOTAL_CEA_MODES; | 44 | extern int NUM_TOTAL_CEA_MODES; |
53 | extern int NUM_TOTAL_CN400_ModeXregs; | 45 | extern int NUM_TOTAL_CN400_ModeXregs; |
54 | extern int NUM_TOTAL_CN700_ModeXregs; | 46 | extern int NUM_TOTAL_CN700_ModeXregs; |
@@ -66,7 +58,6 @@ extern struct crt_mode_table CEAM1280x720[]; | |||
66 | extern struct crt_mode_table CEAM1920x1080[]; | 58 | extern struct crt_mode_table CEAM1920x1080[]; |
67 | extern struct VideoModeTable CEA_HDMI_Modes[]; | 59 | extern struct VideoModeTable CEA_HDMI_Modes[]; |
68 | 60 | ||
69 | extern struct res_map_refresh res_map_refresh_tbl[]; | ||
70 | extern struct io_reg CN400_ModeXregs[]; | 61 | extern struct io_reg CN400_ModeXregs[]; |
71 | extern struct io_reg CN700_ModeXregs[]; | 62 | extern struct io_reg CN700_ModeXregs[]; |
72 | extern struct io_reg KM400_ModeXregs[]; | 63 | extern struct io_reg KM400_ModeXregs[]; |
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index 60e4192c2b34..ee2903b472cf 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c | |||
@@ -167,22 +167,6 @@ static int get_clk_range_index(u32 Clk) | |||
167 | return DPA_CLK_RANGE_150M; | 167 | return DPA_CLK_RANGE_150M; |
168 | } | 168 | } |
169 | 169 | ||
170 | static int get_lvds_dpa_setting_index(int panel_size_id, | ||
171 | struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl, | ||
172 | int tbl_size) | ||
173 | { | ||
174 | int i; | ||
175 | |||
176 | for (i = 0; i < tbl_size; i++) { | ||
177 | if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID) | ||
178 | return i; | ||
179 | |||
180 | p_vt1636_dpasetting_tbl++; | ||
181 | } | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static void set_dpa_vt1636(struct lvds_setting_information | 170 | static void set_dpa_vt1636(struct lvds_setting_information |
187 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, | 171 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, |
188 | struct VT1636_DPA_SETTING *p_vt1636_dpa_setting) | 172 | struct VT1636_DPA_SETTING *p_vt1636_dpa_setting) |
@@ -206,7 +190,9 @@ void viafb_vt1636_patch_skew_on_vt3324( | |||
206 | struct lvds_setting_information *plvds_setting_info, | 190 | struct lvds_setting_information *plvds_setting_info, |
207 | struct lvds_chip_information *plvds_chip_info) | 191 | struct lvds_chip_information *plvds_chip_info) |
208 | { | 192 | { |
209 | int index, size; | 193 | struct VT1636_DPA_SETTING dpa = {0x00, 0x00}, dpa_16x12 = {0x0B, 0x03}, |
194 | *pdpa; | ||
195 | int index; | ||
210 | 196 | ||
211 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n"); | 197 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n"); |
212 | 198 | ||
@@ -216,19 +202,21 @@ void viafb_vt1636_patch_skew_on_vt3324( | |||
216 | &GFX_DPA_SETTING_TBL_VT3324[index]); | 202 | &GFX_DPA_SETTING_TBL_VT3324[index]); |
217 | 203 | ||
218 | /* LVDS Transmitter DPA settings: */ | 204 | /* LVDS Transmitter DPA settings: */ |
219 | size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324); | 205 | if (plvds_setting_info->lcd_panel_hres == 1600 && |
220 | index = | 206 | plvds_setting_info->lcd_panel_vres == 1200) |
221 | get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id, | 207 | pdpa = &dpa_16x12; |
222 | VT1636_DPA_SETTING_TBL_VT3324, size); | 208 | else |
223 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, | 209 | pdpa = &dpa; |
224 | &VT1636_DPA_SETTING_TBL_VT3324[index]); | 210 | |
211 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, pdpa); | ||
225 | } | 212 | } |
226 | 213 | ||
227 | void viafb_vt1636_patch_skew_on_vt3327( | 214 | void viafb_vt1636_patch_skew_on_vt3327( |
228 | struct lvds_setting_information *plvds_setting_info, | 215 | struct lvds_setting_information *plvds_setting_info, |
229 | struct lvds_chip_information *plvds_chip_info) | 216 | struct lvds_chip_information *plvds_chip_info) |
230 | { | 217 | { |
231 | int index, size; | 218 | struct VT1636_DPA_SETTING dpa = {0x00, 0x00}; |
219 | int index; | ||
232 | 220 | ||
233 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n"); | 221 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n"); |
234 | 222 | ||
@@ -238,12 +226,7 @@ void viafb_vt1636_patch_skew_on_vt3327( | |||
238 | &GFX_DPA_SETTING_TBL_VT3327[index]); | 226 | &GFX_DPA_SETTING_TBL_VT3327[index]); |
239 | 227 | ||
240 | /* LVDS Transmitter DPA settings: */ | 228 | /* LVDS Transmitter DPA settings: */ |
241 | size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327); | 229 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, &dpa); |
242 | index = | ||
243 | get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id, | ||
244 | VT1636_DPA_SETTING_TBL_VT3327, size); | ||
245 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, | ||
246 | &VT1636_DPA_SETTING_TBL_VT3327[index]); | ||
247 | } | 230 | } |
248 | 231 | ||
249 | void viafb_vt1636_patch_skew_on_vt3364( | 232 | void viafb_vt1636_patch_skew_on_vt3364( |
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 | ||
124 | static 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 | ||
125 | static struct fb_tile_ops vt8623fb_tile_ops = { | 131 | static 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 | ||
254 | static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock) | 260 | static 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 | |||
373 | static int vt8623fb_set_par(struct fb_info *info) | 383 | static 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 | ||
570 | static int vt8623fb_blank(int blank_mode, struct fb_info *info) | 581 | static 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 | ||
604 | static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 617 | static 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 | ||
648 | static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | 662 | static 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/xilinxfb.c b/drivers/video/xilinxfb.c index 68bd23476c64..77dea015ff69 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
@@ -404,8 +404,7 @@ static int xilinxfb_release(struct device *dev) | |||
404 | * OF bus binding | 404 | * OF bus binding |
405 | */ | 405 | */ |
406 | 406 | ||
407 | static int __devinit | 407 | static int __devinit xilinxfb_of_probe(struct platform_device *op) |
408 | xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match) | ||
409 | { | 408 | { |
410 | const u32 *prop; | 409 | const u32 *prop; |
411 | u32 *p; | 410 | u32 *p; |
@@ -418,8 +417,6 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match) | |||
418 | /* Copy with the default pdata (not a ptr reference!) */ | 417 | /* Copy with the default pdata (not a ptr reference!) */ |
419 | pdata = xilinx_fb_default_pdata; | 418 | pdata = xilinx_fb_default_pdata; |
420 | 419 | ||
421 | dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); | ||
422 | |||
423 | /* Allocate the driver data region */ | 420 | /* Allocate the driver data region */ |
424 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | 421 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); |
425 | if (!drvdata) { | 422 | if (!drvdata) { |
@@ -505,7 +502,7 @@ static struct of_device_id xilinxfb_of_match[] __devinitdata = { | |||
505 | }; | 502 | }; |
506 | MODULE_DEVICE_TABLE(of, xilinxfb_of_match); | 503 | MODULE_DEVICE_TABLE(of, xilinxfb_of_match); |
507 | 504 | ||
508 | static struct of_platform_driver xilinxfb_of_driver = { | 505 | static struct platform_driver xilinxfb_of_driver = { |
509 | .probe = xilinxfb_of_probe, | 506 | .probe = xilinxfb_of_probe, |
510 | .remove = __devexit_p(xilinxfb_of_remove), | 507 | .remove = __devexit_p(xilinxfb_of_remove), |
511 | .driver = { | 508 | .driver = { |
@@ -523,13 +520,13 @@ static struct of_platform_driver xilinxfb_of_driver = { | |||
523 | static int __init | 520 | static int __init |
524 | xilinxfb_init(void) | 521 | xilinxfb_init(void) |
525 | { | 522 | { |
526 | return of_register_platform_driver(&xilinxfb_of_driver); | 523 | return platform_driver_register(&xilinxfb_of_driver); |
527 | } | 524 | } |
528 | 525 | ||
529 | static void __exit | 526 | static void __exit |
530 | xilinxfb_cleanup(void) | 527 | xilinxfb_cleanup(void) |
531 | { | 528 | { |
532 | of_unregister_platform_driver(&xilinxfb_of_driver); | 529 | platform_driver_unregister(&xilinxfb_of_driver); |
533 | } | 530 | } |
534 | 531 | ||
535 | module_init(xilinxfb_init); | 532 | module_init(xilinxfb_init); |