diff options
Diffstat (limited to 'drivers/video')
138 files changed, 14803 insertions, 4457 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d6d65ef85f54..188e1ba3b69f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -7,6 +7,8 @@ menu "Graphics support" | |||
7 | 7 | ||
8 | source "drivers/char/agp/Kconfig" | 8 | source "drivers/char/agp/Kconfig" |
9 | 9 | ||
10 | source "drivers/gpu/vga/Kconfig" | ||
11 | |||
10 | source "drivers/gpu/drm/Kconfig" | 12 | source "drivers/gpu/drm/Kconfig" |
11 | 13 | ||
12 | config VGASTATE | 14 | config VGASTATE |
@@ -616,6 +618,8 @@ config FB_STI | |||
616 | select FB_CFB_FILLRECT | 618 | select FB_CFB_FILLRECT |
617 | select FB_CFB_COPYAREA | 619 | select FB_CFB_COPYAREA |
618 | select FB_CFB_IMAGEBLIT | 620 | select FB_CFB_IMAGEBLIT |
621 | select STI_CONSOLE | ||
622 | select VT | ||
619 | default y | 623 | default y |
620 | ---help--- | 624 | ---help--- |
621 | STI refers to the HP "Standard Text Interface" which is a set of | 625 | STI refers to the HP "Standard Text Interface" which is a set of |
@@ -933,7 +937,7 @@ config FB_S1D13XXX | |||
933 | 937 | ||
934 | config FB_ATMEL | 938 | config FB_ATMEL |
935 | tristate "AT91/AT32 LCD Controller support" | 939 | tristate "AT91/AT32 LCD Controller support" |
936 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32) | 940 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9G10 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32) |
937 | select FB_CFB_FILLRECT | 941 | select FB_CFB_FILLRECT |
938 | select FB_CFB_COPYAREA | 942 | select FB_CFB_COPYAREA |
939 | select FB_CFB_IMAGEBLIT | 943 | select FB_CFB_IMAGEBLIT |
@@ -949,7 +953,7 @@ config FB_INTSRAM | |||
949 | 953 | ||
950 | config FB_ATMEL_STN | 954 | config FB_ATMEL_STN |
951 | bool "Use a STN display with AT91/AT32 LCD Controller" | 955 | bool "Use a STN display with AT91/AT32 LCD Controller" |
952 | depends on FB_ATMEL && MACH_AT91SAM9261EK | 956 | depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK) |
953 | default n | 957 | default n |
954 | help | 958 | help |
955 | Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD | 959 | Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD |
@@ -1117,12 +1121,13 @@ config FB_CARILLO_RANCH | |||
1117 | 1121 | ||
1118 | config FB_INTEL | 1122 | config FB_INTEL |
1119 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" | 1123 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" |
1120 | depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL | 1124 | depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL && EMBEDDED |
1121 | select FB_MODE_HELPERS | 1125 | select FB_MODE_HELPERS |
1122 | select FB_CFB_FILLRECT | 1126 | select FB_CFB_FILLRECT |
1123 | select FB_CFB_COPYAREA | 1127 | select FB_CFB_COPYAREA |
1124 | select FB_CFB_IMAGEBLIT | 1128 | select FB_CFB_IMAGEBLIT |
1125 | select FB_BOOT_VESA_SUPPORT if FB_INTEL = y | 1129 | select FB_BOOT_VESA_SUPPORT if FB_INTEL = y |
1130 | depends on !DRM_I915 | ||
1126 | help | 1131 | help |
1127 | This driver supports the on-board graphics built in to the Intel | 1132 | This driver supports the on-board graphics built in to the Intel |
1128 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. | 1133 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. |
@@ -1270,26 +1275,6 @@ config FB_MATROX_MAVEN | |||
1270 | painting procedures (the secondary head does not use acceleration | 1275 | painting procedures (the secondary head does not use acceleration |
1271 | engine). | 1276 | engine). |
1272 | 1277 | ||
1273 | config FB_MATROX_MULTIHEAD | ||
1274 | bool "Multihead support" | ||
1275 | depends on FB_MATROX | ||
1276 | ---help--- | ||
1277 | Say Y here if you have more than one (supported) Matrox device in | ||
1278 | your computer and you want to use all of them for different monitors | ||
1279 | ("multihead"). If you have only one device, you should say N because | ||
1280 | the driver compiled with Y is larger and a bit slower, especially on | ||
1281 | ia32 (ix86). | ||
1282 | |||
1283 | If you said M to "Matrox unified accelerated driver" and N here, you | ||
1284 | will still be able to use several Matrox devices simultaneously: | ||
1285 | insert several instances of the module matroxfb into the kernel | ||
1286 | with insmod, supplying the parameter "dev=N" where N is 0, 1, etc. | ||
1287 | for the different Matrox devices. This method is slightly faster but | ||
1288 | uses 40 KB of kernel memory per Matrox card. | ||
1289 | |||
1290 | There is no need for enabling 'Matrox multihead support' if you have | ||
1291 | only one Matrox card in the box. | ||
1292 | |||
1293 | config FB_RADEON | 1278 | config FB_RADEON |
1294 | tristate "ATI Radeon display support" | 1279 | tristate "ATI Radeon display support" |
1295 | depends on FB && PCI | 1280 | depends on FB && PCI |
@@ -1864,7 +1849,7 @@ config FB_W100 | |||
1864 | 1849 | ||
1865 | config FB_SH_MOBILE_LCDC | 1850 | config FB_SH_MOBILE_LCDC |
1866 | tristate "SuperH Mobile LCDC framebuffer support" | 1851 | tristate "SuperH Mobile LCDC framebuffer support" |
1867 | depends on FB && SUPERH | 1852 | depends on FB && SUPERH && HAVE_CLK |
1868 | select FB_SYS_FILLRECT | 1853 | select FB_SYS_FILLRECT |
1869 | select FB_SYS_COPYAREA | 1854 | select FB_SYS_COPYAREA |
1870 | select FB_SYS_IMAGEBLIT | 1855 | select FB_SYS_IMAGEBLIT |
@@ -2036,6 +2021,17 @@ config FB_SH7760 | |||
2036 | and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for | 2021 | and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for |
2037 | panels <= 320 pixel horizontal resolution. | 2022 | panels <= 320 pixel horizontal resolution. |
2038 | 2023 | ||
2024 | config FB_DA8XX | ||
2025 | tristate "DA8xx/OMAP-L1xx Framebuffer support" | ||
2026 | depends on FB && ARCH_DAVINCI_DA8XX | ||
2027 | select FB_CFB_FILLRECT | ||
2028 | select FB_CFB_COPYAREA | ||
2029 | select FB_CFB_IMAGEBLIT | ||
2030 | ---help--- | ||
2031 | This is the frame buffer device driver for the TI LCD controller | ||
2032 | found on DA8xx/OMAP-L1xx SoCs. | ||
2033 | If unsure, say N. | ||
2034 | |||
2039 | config FB_VIRTUAL | 2035 | config FB_VIRTUAL |
2040 | tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" | 2036 | tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" |
2041 | depends on FB | 2037 | depends on FB |
@@ -2112,13 +2108,32 @@ config FB_MB862XX_LIME | |||
2112 | ---help--- | 2108 | ---help--- |
2113 | Framebuffer support for Fujitsu Lime GDC on host CPU bus. | 2109 | Framebuffer support for Fujitsu Lime GDC on host CPU bus. |
2114 | 2110 | ||
2111 | config FB_EP93XX | ||
2112 | tristate "EP93XX frame buffer support" | ||
2113 | depends on FB && ARCH_EP93XX | ||
2114 | select FB_CFB_FILLRECT | ||
2115 | select FB_CFB_COPYAREA | ||
2116 | select FB_CFB_IMAGEBLIT | ||
2117 | ---help--- | ||
2118 | Framebuffer driver for the Cirrus Logic EP93XX series of processors. | ||
2119 | This driver is also available as a module. The module will be called | ||
2120 | ep93xx-fb. | ||
2121 | |||
2115 | config FB_PRE_INIT_FB | 2122 | config FB_PRE_INIT_FB |
2116 | bool "Don't reinitialize, use bootloader's GDC/Display configuration" | 2123 | bool "Don't reinitialize, use bootloader's GDC/Display configuration" |
2117 | depends on FB_MB862XX_LIME | 2124 | depends on FB && FB_MB862XX_LIME |
2118 | ---help--- | 2125 | ---help--- |
2119 | Select this option if display contents should be inherited as set by | 2126 | Select this option if display contents should be inherited as set by |
2120 | the bootloader. | 2127 | the bootloader. |
2121 | 2128 | ||
2129 | config FB_MSM | ||
2130 | tristate | ||
2131 | depends on FB && ARCH_MSM | ||
2132 | select FB_CFB_FILLRECT | ||
2133 | select FB_CFB_COPYAREA | ||
2134 | select FB_CFB_IMAGEBLIT | ||
2135 | default y | ||
2136 | |||
2122 | config FB_MX3 | 2137 | config FB_MX3 |
2123 | tristate "MX3 Framebuffer support" | 2138 | tristate "MX3 Framebuffer support" |
2124 | depends on FB && MX3_IPU | 2139 | depends on FB && MX3_IPU |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 01a819f47371..80232e124889 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -85,6 +85,7 @@ obj-$(CONFIG_FB_Q40) += q40fb.o | |||
85 | obj-$(CONFIG_FB_TGA) += tgafb.o | 85 | obj-$(CONFIG_FB_TGA) += tgafb.o |
86 | obj-$(CONFIG_FB_HP300) += hpfb.o | 86 | obj-$(CONFIG_FB_HP300) += hpfb.o |
87 | obj-$(CONFIG_FB_G364) += g364fb.o | 87 | obj-$(CONFIG_FB_G364) += g364fb.o |
88 | obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o | ||
88 | obj-$(CONFIG_FB_SA1100) += sa1100fb.o | 89 | obj-$(CONFIG_FB_SA1100) += sa1100fb.o |
89 | obj-$(CONFIG_FB_HIT) += hitfb.o | 90 | obj-$(CONFIG_FB_HIT) += hitfb.o |
90 | obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o | 91 | obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o |
@@ -126,6 +127,7 @@ obj-$(CONFIG_FB_OMAP) += omap/ | |||
126 | obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o | 127 | obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o |
127 | obj-$(CONFIG_FB_CARMINE) += carminefb.o | 128 | obj-$(CONFIG_FB_CARMINE) += carminefb.o |
128 | obj-$(CONFIG_FB_MB862XX) += mb862xx/ | 129 | obj-$(CONFIG_FB_MB862XX) += mb862xx/ |
130 | obj-$(CONFIG_FB_MSM) += msm/ | ||
129 | 131 | ||
130 | # Platform or fallback drivers go here | 132 | # Platform or fallback drivers go here |
131 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | 133 | obj-$(CONFIG_FB_UVESA) += uvesafb.o |
@@ -136,6 +138,7 @@ obj-$(CONFIG_FB_OF) += offb.o | |||
136 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o | 138 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o |
137 | obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o | 139 | obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o |
138 | obj-$(CONFIG_FB_MX3) += mx3fb.o | 140 | obj-$(CONFIG_FB_MX3) += mx3fb.o |
141 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o | ||
139 | 142 | ||
140 | # the test framebuffer is last | 143 | # the test framebuffer is last |
141 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o | 144 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index fb8163d181ab..a21efcd10b78 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -226,9 +226,10 @@ static int clcdfb_set_par(struct fb_info *info) | |||
226 | clcdfb_enable(fb, regs.cntl); | 226 | clcdfb_enable(fb, regs.cntl); |
227 | 227 | ||
228 | #ifdef DEBUG | 228 | #ifdef DEBUG |
229 | printk(KERN_INFO "CLCD: Registers set to\n" | 229 | printk(KERN_INFO |
230 | KERN_INFO " %08x %08x %08x %08x\n" | 230 | "CLCD: Registers set to\n" |
231 | KERN_INFO " %08x %08x %08x %08x\n", | 231 | " %08x %08x %08x %08x\n" |
232 | " %08x %08x %08x %08x\n", | ||
232 | readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), | 233 | readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), |
233 | readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), | 234 | readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), |
234 | readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), | 235 | readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), |
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index 018850c116c6..37624f74e88b 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c | |||
@@ -329,12 +329,6 @@ extern unsigned char fontdata_8x16[]; | |||
329 | * | 329 | * |
330 | * * perform fb specific mmap * | 330 | * * perform fb specific mmap * |
331 | * int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma); | 331 | * int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma); |
332 | * | ||
333 | * * save current hardware state * | ||
334 | * void (*fb_save_state)(struct fb_info *info); | ||
335 | * | ||
336 | * * restore saved state * | ||
337 | * void (*fb_restore_state)(struct fb_info *info); | ||
338 | * } ; | 332 | * } ; |
339 | */ | 333 | */ |
340 | 334 | ||
@@ -2405,6 +2399,9 @@ static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) | |||
2405 | return 0; | 2399 | return 0; |
2406 | } | 2400 | } |
2407 | 2401 | ||
2402 | /* fbhw->encode_fix() must be called with fb_info->mm_lock held | ||
2403 | * if it is called after the register_framebuffer() - not a case here | ||
2404 | */ | ||
2408 | static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | 2405 | static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) |
2409 | { | 2406 | { |
2410 | struct atafb_par par; | 2407 | struct atafb_par par; |
@@ -2414,7 +2411,8 @@ static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | |||
2414 | if (err) | 2411 | if (err) |
2415 | return err; | 2412 | return err; |
2416 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | 2413 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); |
2417 | return fbhw->encode_fix(fix, &par); | 2414 | err = fbhw->encode_fix(fix, &par); |
2415 | return err; | ||
2418 | } | 2416 | } |
2419 | 2417 | ||
2420 | static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info) | 2418 | static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info) |
@@ -2743,7 +2741,9 @@ static int atafb_set_par(struct fb_info *info) | |||
2743 | 2741 | ||
2744 | /* Decode wanted screen parameters */ | 2742 | /* Decode wanted screen parameters */ |
2745 | fbhw->decode_var(&info->var, par); | 2743 | fbhw->decode_var(&info->var, par); |
2744 | mutex_lock(&info->mm_lock); | ||
2746 | fbhw->encode_fix(&info->fix, par); | 2745 | fbhw->encode_fix(&info->fix, par); |
2746 | mutex_unlock(&info->mm_lock); | ||
2747 | 2747 | ||
2748 | /* Set new videomode */ | 2748 | /* Set new videomode */ |
2749 | ata_set_par(par); | 2749 | ata_set_par(par); |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 5afd64482f55..d5e801076d33 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -182,7 +182,8 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) | |||
182 | { | 182 | { |
183 | unsigned long value; | 183 | unsigned long value; |
184 | 184 | ||
185 | if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000())) | 185 | if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() |
186 | || cpu_is_at32ap7000())) | ||
186 | return xres; | 187 | return xres; |
187 | 188 | ||
188 | value = xres; | 189 | value = xres; |
@@ -261,6 +262,9 @@ static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo) | |||
261 | /** | 262 | /** |
262 | * atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory | 263 | * atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory |
263 | * @sinfo: the frame buffer to allocate memory for | 264 | * @sinfo: the frame buffer to allocate memory for |
265 | * | ||
266 | * This function is called only from the atmel_lcdfb_probe() | ||
267 | * so no locking by fb_info->mm_lock around smem_len setting is needed. | ||
264 | */ | 268 | */ |
265 | static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) | 269 | static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) |
266 | { | 270 | { |
@@ -480,6 +484,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) | |||
480 | unsigned long value; | 484 | unsigned long value; |
481 | unsigned long clk_value_khz; | 485 | unsigned long clk_value_khz; |
482 | unsigned long bits_per_line; | 486 | unsigned long bits_per_line; |
487 | unsigned long pix_factor = 2; | ||
483 | 488 | ||
484 | might_sleep(); | 489 | might_sleep(); |
485 | 490 | ||
@@ -512,20 +517,24 @@ static int atmel_lcdfb_set_par(struct fb_info *info) | |||
512 | /* Now, the LCDC core... */ | 517 | /* Now, the LCDC core... */ |
513 | 518 | ||
514 | /* Set pixel clock */ | 519 | /* Set pixel clock */ |
520 | if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) | ||
521 | pix_factor = 1; | ||
522 | |||
515 | clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; | 523 | clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; |
516 | 524 | ||
517 | value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock)); | 525 | value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock)); |
518 | 526 | ||
519 | if (value < 2) { | 527 | if (value < pix_factor) { |
520 | dev_notice(info->device, "Bypassing pixel clock divider\n"); | 528 | dev_notice(info->device, "Bypassing pixel clock divider\n"); |
521 | lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS); | 529 | lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS); |
522 | } else { | 530 | } else { |
523 | value = (value / 2) - 1; | 531 | value = (value / pix_factor) - 1; |
524 | dev_dbg(info->device, " * programming CLKVAL = 0x%08lx\n", | 532 | dev_dbg(info->device, " * programming CLKVAL = 0x%08lx\n", |
525 | value); | 533 | value); |
526 | lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, | 534 | lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, |
527 | value << ATMEL_LCDC_CLKVAL_OFFSET); | 535 | value << ATMEL_LCDC_CLKVAL_OFFSET); |
528 | info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1))); | 536 | info->var.pixclock = |
537 | KHZ2PICOS(clk_value_khz / (pix_factor * (value + 1))); | ||
529 | dev_dbg(info->device, " updated pixclk: %lu KHz\n", | 538 | dev_dbg(info->device, " updated pixclk: %lu KHz\n", |
530 | PICOS2KHZ(info->var.pixclock)); | 539 | PICOS2KHZ(info->var.pixclock)); |
531 | } | 540 | } |
@@ -821,7 +830,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) | |||
821 | info->fix = atmel_lcdfb_fix; | 830 | info->fix = atmel_lcdfb_fix; |
822 | 831 | ||
823 | /* Enable LCDC Clocks */ | 832 | /* Enable LCDC Clocks */ |
824 | if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) { | 833 | if (cpu_is_at91sam9261() || cpu_is_at91sam9g10() |
834 | || cpu_is_at32ap7000()) { | ||
825 | sinfo->bus_clk = clk_get(dev, "hck1"); | 835 | sinfo->bus_clk = clk_get(dev, "hck1"); |
826 | if (IS_ERR(sinfo->bus_clk)) { | 836 | if (IS_ERR(sinfo->bus_clk)) { |
827 | ret = PTR_ERR(sinfo->bus_clk); | 837 | ret = PTR_ERR(sinfo->bus_clk); |
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index 7691e73823d3..1f39a62f899b 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h | |||
@@ -187,6 +187,8 @@ struct atyfb_par { | |||
187 | int mtrr_reg; | 187 | int mtrr_reg; |
188 | #endif | 188 | #endif |
189 | u32 mem_cntl; | 189 | u32 mem_cntl; |
190 | struct crtc saved_crtc; | ||
191 | union aty_pll saved_pll; | ||
190 | }; | 192 | }; |
191 | 193 | ||
192 | /* | 194 | /* |
@@ -217,6 +219,7 @@ struct atyfb_par { | |||
217 | #define M64F_XL_DLL 0x00080000 | 219 | #define M64F_XL_DLL 0x00080000 |
218 | #define M64F_MFB_FORCE_4 0x00100000 | 220 | #define M64F_MFB_FORCE_4 0x00100000 |
219 | #define M64F_HW_TRIPLE 0x00200000 | 221 | #define M64F_HW_TRIPLE 0x00200000 |
222 | #define M64F_XL_MEM 0x00400000 | ||
220 | /* | 223 | /* |
221 | * Register access | 224 | * Register access |
222 | */ | 225 | */ |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 1207c208a30b..913b4a47ae52 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -66,6 +66,8 @@ | |||
66 | #include <linux/spinlock.h> | 66 | #include <linux/spinlock.h> |
67 | #include <linux/wait.h> | 67 | #include <linux/wait.h> |
68 | #include <linux/backlight.h> | 68 | #include <linux/backlight.h> |
69 | #include <linux/reboot.h> | ||
70 | #include <linux/dmi.h> | ||
69 | 71 | ||
70 | #include <asm/io.h> | 72 | #include <asm/io.h> |
71 | #include <linux/uaccess.h> | 73 | #include <linux/uaccess.h> |
@@ -130,7 +132,7 @@ | |||
130 | #endif | 132 | #endif |
131 | 133 | ||
132 | #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args) | 134 | #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args) |
133 | #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) | 135 | #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) |
134 | 136 | ||
135 | #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ | 137 | #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ |
136 | defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) | 138 | defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) |
@@ -186,24 +188,23 @@ u32 aty_ld_lcd(int index, const struct atyfb_par *par) | |||
186 | */ | 188 | */ |
187 | static void ATIReduceRatio(int *Numerator, int *Denominator) | 189 | static void ATIReduceRatio(int *Numerator, int *Denominator) |
188 | { | 190 | { |
189 | int Multiplier, Divider, Remainder; | 191 | int Multiplier, Divider, Remainder; |
190 | 192 | ||
191 | Multiplier = *Numerator; | 193 | Multiplier = *Numerator; |
192 | Divider = *Denominator; | 194 | Divider = *Denominator; |
193 | 195 | ||
194 | while ((Remainder = Multiplier % Divider)) | 196 | while ((Remainder = Multiplier % Divider)) { |
195 | { | 197 | Multiplier = Divider; |
196 | Multiplier = Divider; | 198 | Divider = Remainder; |
197 | Divider = Remainder; | 199 | } |
198 | } | ||
199 | 200 | ||
200 | *Numerator /= Divider; | 201 | *Numerator /= Divider; |
201 | *Denominator /= Divider; | 202 | *Denominator /= Divider; |
202 | } | 203 | } |
203 | #endif | 204 | #endif |
204 | /* | 205 | /* |
205 | * The Hardware parameters for each card | 206 | * The Hardware parameters for each card |
206 | */ | 207 | */ |
207 | 208 | ||
208 | struct pci_mmap_map { | 209 | struct pci_mmap_map { |
209 | unsigned long voff; | 210 | unsigned long voff; |
@@ -221,17 +222,19 @@ static struct fb_fix_screeninfo atyfb_fix __devinitdata = { | |||
221 | .ypanstep = 1, | 222 | .ypanstep = 1, |
222 | }; | 223 | }; |
223 | 224 | ||
224 | /* | 225 | /* |
225 | * Frame buffer device API | 226 | * Frame buffer device API |
226 | */ | 227 | */ |
227 | 228 | ||
228 | static int atyfb_open(struct fb_info *info, int user); | 229 | static int atyfb_open(struct fb_info *info, int user); |
229 | static int atyfb_release(struct fb_info *info, int user); | 230 | static int atyfb_release(struct fb_info *info, int user); |
230 | static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); | 231 | static int atyfb_check_var(struct fb_var_screeninfo *var, |
232 | struct fb_info *info); | ||
231 | static int atyfb_set_par(struct fb_info *info); | 233 | static int atyfb_set_par(struct fb_info *info); |
232 | static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | 234 | static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, |
233 | u_int transp, struct fb_info *info); | 235 | u_int transp, struct fb_info *info); |
234 | static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); | 236 | static int atyfb_pan_display(struct fb_var_screeninfo *var, |
237 | struct fb_info *info); | ||
235 | static int atyfb_blank(int blank, struct fb_info *info); | 238 | static int atyfb_blank(int blank, struct fb_info *info); |
236 | static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); | 239 | static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); |
237 | #ifdef __sparc__ | 240 | #ifdef __sparc__ |
@@ -239,9 +242,9 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma); | |||
239 | #endif | 242 | #endif |
240 | static int atyfb_sync(struct fb_info *info); | 243 | static int atyfb_sync(struct fb_info *info); |
241 | 244 | ||
242 | /* | 245 | /* |
243 | * Internal routines | 246 | * Internal routines |
244 | */ | 247 | */ |
245 | 248 | ||
246 | static int aty_init(struct fb_info *info); | 249 | static int aty_init(struct fb_info *info); |
247 | 250 | ||
@@ -249,22 +252,25 @@ static int aty_init(struct fb_info *info); | |||
249 | static int store_video_par(char *videopar, unsigned char m64_num); | 252 | static int store_video_par(char *videopar, unsigned char m64_num); |
250 | #endif | 253 | #endif |
251 | 254 | ||
252 | static struct crtc saved_crtc; | ||
253 | static union aty_pll saved_pll; | ||
254 | static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); | 255 | static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); |
255 | 256 | ||
256 | static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); | 257 | static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); |
257 | static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc); | 258 | static int aty_var_to_crtc(const struct fb_info *info, |
258 | static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var); | 259 | const struct fb_var_screeninfo *var, |
260 | struct crtc *crtc); | ||
261 | static int aty_crtc_to_var(const struct crtc *crtc, | ||
262 | struct fb_var_screeninfo *var); | ||
259 | static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); | 263 | static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); |
260 | #ifdef CONFIG_PPC | 264 | #ifdef CONFIG_PPC |
261 | static int read_aty_sense(const struct atyfb_par *par); | 265 | static int read_aty_sense(const struct atyfb_par *par); |
262 | #endif | 266 | #endif |
263 | 267 | ||
268 | static DEFINE_MUTEX(reboot_lock); | ||
269 | static struct fb_info *reboot_info; | ||
264 | 270 | ||
265 | /* | 271 | /* |
266 | * Interface used by the world | 272 | * Interface used by the world |
267 | */ | 273 | */ |
268 | 274 | ||
269 | static struct fb_var_screeninfo default_var = { | 275 | static struct fb_var_screeninfo default_var = { |
270 | /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ | 276 | /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ |
@@ -361,8 +367,8 @@ static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, }; | |||
361 | #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) | 367 | #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) |
362 | #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) | 368 | #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) |
363 | 369 | ||
364 | #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4) | 370 | #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM) |
365 | #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS) | 371 | #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS) |
366 | 372 | ||
367 | static struct { | 373 | static struct { |
368 | u16 pci_id; | 374 | u16 pci_id; |
@@ -450,14 +456,14 @@ static int __devinit correct_chipset(struct atyfb_par *par) | |||
450 | type = chip_id & CFG_CHIP_TYPE; | 456 | type = chip_id & CFG_CHIP_TYPE; |
451 | rev = (chip_id & CFG_CHIP_REV) >> 24; | 457 | rev = (chip_id & CFG_CHIP_REV) >> 24; |
452 | 458 | ||
453 | switch(par->pci_id) { | 459 | switch (par->pci_id) { |
454 | #ifdef CONFIG_FB_ATY_GX | 460 | #ifdef CONFIG_FB_ATY_GX |
455 | case PCI_CHIP_MACH64GX: | 461 | case PCI_CHIP_MACH64GX: |
456 | if(type != 0x00d7) | 462 | if (type != 0x00d7) |
457 | return -ENODEV; | 463 | return -ENODEV; |
458 | break; | 464 | break; |
459 | case PCI_CHIP_MACH64CX: | 465 | case PCI_CHIP_MACH64CX: |
460 | if(type != 0x0057) | 466 | if (type != 0x0057) |
461 | return -ENODEV; | 467 | return -ENODEV; |
462 | break; | 468 | break; |
463 | #endif | 469 | #endif |
@@ -539,6 +545,7 @@ static char ram_edo[] __devinitdata = "EDO"; | |||
539 | static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; | 545 | static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; |
540 | static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; | 546 | static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; |
541 | static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; | 547 | static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; |
548 | static char ram_wram[] __devinitdata = "WRAM"; | ||
542 | static char ram_off[] __devinitdata = "OFF"; | 549 | static char ram_off[] __devinitdata = "OFF"; |
543 | #endif /* CONFIG_FB_ATY_CT */ | 550 | #endif /* CONFIG_FB_ATY_CT */ |
544 | 551 | ||
@@ -553,11 +560,16 @@ static char *aty_gx_ram[8] __devinitdata = { | |||
553 | #ifdef CONFIG_FB_ATY_CT | 560 | #ifdef CONFIG_FB_ATY_CT |
554 | static char *aty_ct_ram[8] __devinitdata = { | 561 | static char *aty_ct_ram[8] __devinitdata = { |
555 | ram_off, ram_dram, ram_edo, ram_edo, | 562 | ram_off, ram_dram, ram_edo, ram_edo, |
563 | ram_sdram, ram_sgram, ram_wram, ram_resv | ||
564 | }; | ||
565 | static char *aty_xl_ram[8] __devinitdata = { | ||
566 | ram_off, ram_dram, ram_edo, ram_edo, | ||
556 | ram_sdram, ram_sgram, ram_sdram32, ram_resv | 567 | ram_sdram, ram_sgram, ram_sdram32, ram_resv |
557 | }; | 568 | }; |
558 | #endif /* CONFIG_FB_ATY_CT */ | 569 | #endif /* CONFIG_FB_ATY_CT */ |
559 | 570 | ||
560 | static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par) | 571 | static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, |
572 | struct atyfb_par *par) | ||
561 | { | 573 | { |
562 | u32 pixclock = var->pixclock; | 574 | u32 pixclock = var->pixclock; |
563 | #ifdef CONFIG_FB_ATY_GENERIC_LCD | 575 | #ifdef CONFIG_FB_ATY_GENERIC_LCD |
@@ -565,7 +577,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p | |||
565 | par->pll.ct.xres = 0; | 577 | par->pll.ct.xres = 0; |
566 | if (par->lcd_table != 0) { | 578 | if (par->lcd_table != 0) { |
567 | lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par); | 579 | lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par); |
568 | if(lcd_on_off & LCD_ON) { | 580 | if (lcd_on_off & LCD_ON) { |
569 | par->pll.ct.xres = var->xres; | 581 | par->pll.ct.xres = var->xres; |
570 | pixclock = par->lcd_pixclock; | 582 | pixclock = par->lcd_pixclock; |
571 | } | 583 | } |
@@ -577,7 +589,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p | |||
577 | #if defined(CONFIG_PPC) | 589 | #if defined(CONFIG_PPC) |
578 | 590 | ||
579 | /* | 591 | /* |
580 | * Apple monitor sense | 592 | * Apple monitor sense |
581 | */ | 593 | */ |
582 | 594 | ||
583 | static int __devinit read_aty_sense(const struct atyfb_par *par) | 595 | static int __devinit read_aty_sense(const struct atyfb_par *par) |
@@ -618,16 +630,16 @@ static int __devinit read_aty_sense(const struct atyfb_par *par) | |||
618 | /* ------------------------------------------------------------------------- */ | 630 | /* ------------------------------------------------------------------------- */ |
619 | 631 | ||
620 | /* | 632 | /* |
621 | * CRTC programming | 633 | * CRTC programming |
622 | */ | 634 | */ |
623 | 635 | ||
624 | static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) | 636 | static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) |
625 | { | 637 | { |
626 | #ifdef CONFIG_FB_ATY_GENERIC_LCD | 638 | #ifdef CONFIG_FB_ATY_GENERIC_LCD |
627 | if (par->lcd_table != 0) { | 639 | if (par->lcd_table != 0) { |
628 | if(!M64_HAS(LT_LCD_REGS)) { | 640 | if (!M64_HAS(LT_LCD_REGS)) { |
629 | crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); | 641 | crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); |
630 | aty_st_le32(LCD_INDEX, crtc->lcd_index, par); | 642 | aty_st_le32(LCD_INDEX, crtc->lcd_index, par); |
631 | } | 643 | } |
632 | crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); | 644 | crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); |
633 | crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); | 645 | crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); |
@@ -635,7 +647,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) | |||
635 | 647 | ||
636 | /* switch to non shadow registers */ | 648 | /* switch to non shadow registers */ |
637 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & | 649 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & |
638 | ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); | 650 | ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); |
639 | 651 | ||
640 | /* save stretching */ | 652 | /* save stretching */ |
641 | crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); | 653 | crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); |
@@ -656,7 +668,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) | |||
656 | if (par->lcd_table != 0) { | 668 | if (par->lcd_table != 0) { |
657 | /* switch to shadow registers */ | 669 | /* switch to shadow registers */ |
658 | aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | | 670 | aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | |
659 | SHADOW_EN | SHADOW_RW_EN, par); | 671 | SHADOW_EN | SHADOW_RW_EN, par); |
660 | 672 | ||
661 | crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); | 673 | crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); |
662 | crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); | 674 | crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); |
@@ -673,21 +685,20 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) | |||
673 | #ifdef CONFIG_FB_ATY_GENERIC_LCD | 685 | #ifdef CONFIG_FB_ATY_GENERIC_LCD |
674 | if (par->lcd_table != 0) { | 686 | if (par->lcd_table != 0) { |
675 | /* stop CRTC */ | 687 | /* stop CRTC */ |
676 | aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par); | 688 | aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & |
689 | ~(CRTC_EXT_DISP_EN | CRTC_EN), par); | ||
677 | 690 | ||
678 | /* update non-shadow registers first */ | 691 | /* update non-shadow registers first */ |
679 | aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); | 692 | aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); |
680 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & | 693 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & |
681 | ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); | 694 | ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); |
682 | 695 | ||
683 | /* temporarily disable stretching */ | 696 | /* temporarily disable stretching */ |
684 | aty_st_lcd(HORZ_STRETCHING, | 697 | aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching & |
685 | crtc->horz_stretching & | 698 | ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par); |
686 | ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par); | 699 | aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching & |
687 | aty_st_lcd(VERT_STRETCHING, | 700 | ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 | |
688 | crtc->vert_stretching & | 701 | VERT_STRETCH_USE0 | VERT_STRETCH_EN), par); |
689 | ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 | | ||
690 | VERT_STRETCH_USE0 | VERT_STRETCH_EN), par); | ||
691 | } | 702 | } |
692 | #endif | 703 | #endif |
693 | /* turn off CRT */ | 704 | /* turn off CRT */ |
@@ -695,17 +706,19 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) | |||
695 | 706 | ||
696 | DPRINTK("setting up CRTC\n"); | 707 | DPRINTK("setting up CRTC\n"); |
697 | DPRINTK("set primary CRT to %ix%i %c%c composite %c\n", | 708 | DPRINTK("set primary CRT to %ix%i %c%c composite %c\n", |
698 | ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1), | 709 | ((((crtc->h_tot_disp >> 16) & 0xff) + 1) << 3), |
699 | (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P', | 710 | (((crtc->v_tot_disp >> 16) & 0x7ff) + 1), |
700 | (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N'); | 711 | (crtc->h_sync_strt_wid & 0x200000) ? 'N' : 'P', |
701 | 712 | (crtc->v_sync_strt_wid & 0x200000) ? 'N' : 'P', | |
702 | DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp); | 713 | (crtc->gen_cntl & CRTC_CSYNC_EN) ? 'P' : 'N'); |
703 | DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid); | 714 | |
704 | DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp); | 715 | DPRINTK("CRTC_H_TOTAL_DISP: %x\n", crtc->h_tot_disp); |
705 | DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid); | 716 | DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n", crtc->h_sync_strt_wid); |
717 | DPRINTK("CRTC_V_TOTAL_DISP: %x\n", crtc->v_tot_disp); | ||
718 | DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n", crtc->v_sync_strt_wid); | ||
706 | DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch); | 719 | DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch); |
707 | DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline); | 720 | DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline); |
708 | DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl); | 721 | DPRINTK("CRTC_GEN_CNTL: %x\n", crtc->gen_cntl); |
709 | 722 | ||
710 | aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par); | 723 | aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par); |
711 | aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par); | 724 | aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par); |
@@ -725,16 +738,22 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) | |||
725 | if (par->lcd_table != 0) { | 738 | if (par->lcd_table != 0) { |
726 | /* switch to shadow registers */ | 739 | /* switch to shadow registers */ |
727 | aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | | 740 | aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | |
728 | (SHADOW_EN | SHADOW_RW_EN), par); | 741 | SHADOW_EN | SHADOW_RW_EN, par); |
729 | 742 | ||
730 | DPRINTK("set shadow CRT to %ix%i %c%c\n", | 743 | DPRINTK("set shadow CRT to %ix%i %c%c\n", |
731 | ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1), | 744 | ((((crtc->shadow_h_tot_disp >> 16) & 0xff) + 1) << 3), |
732 | (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P'); | 745 | (((crtc->shadow_v_tot_disp >> 16) & 0x7ff) + 1), |
733 | 746 | (crtc->shadow_h_sync_strt_wid & 0x200000) ? 'N' : 'P', | |
734 | DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp); | 747 | (crtc->shadow_v_sync_strt_wid & 0x200000) ? 'N' : 'P'); |
735 | DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid); | 748 | |
736 | DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp); | 749 | DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", |
737 | DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid); | 750 | crtc->shadow_h_tot_disp); |
751 | DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", | ||
752 | crtc->shadow_h_sync_strt_wid); | ||
753 | DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", | ||
754 | crtc->shadow_v_tot_disp); | ||
755 | DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", | ||
756 | crtc->shadow_v_sync_strt_wid); | ||
738 | 757 | ||
739 | aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par); | 758 | aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par); |
740 | aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par); | 759 | aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par); |
@@ -745,23 +764,35 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) | |||
745 | DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl); | 764 | DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl); |
746 | DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching); | 765 | DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching); |
747 | DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching); | 766 | DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching); |
748 | if(!M64_HAS(LT_LCD_REGS)) | 767 | if (!M64_HAS(LT_LCD_REGS)) |
749 | DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch); | 768 | DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch); |
750 | 769 | ||
751 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par); | 770 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par); |
752 | aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par); | 771 | aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par); |
753 | aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par); | 772 | aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par); |
754 | if(!M64_HAS(LT_LCD_REGS)) { | 773 | if (!M64_HAS(LT_LCD_REGS)) { |
755 | aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par); | 774 | aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par); |
756 | aty_ld_le32(LCD_INDEX, par); | 775 | aty_ld_le32(LCD_INDEX, par); |
757 | aty_st_le32(LCD_INDEX, crtc->lcd_index, par); | 776 | aty_st_le32(LCD_INDEX, crtc->lcd_index, par); |
758 | } | 777 | } |
759 | } | 778 | } |
760 | #endif /* CONFIG_FB_ATY_GENERIC_LCD */ | 779 | #endif /* CONFIG_FB_ATY_GENERIC_LCD */ |
761 | } | 780 | } |
762 | 781 | ||
782 | static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp) | ||
783 | { | ||
784 | u32 line_length = vxres * bpp / 8; | ||
785 | |||
786 | if (par->ram_type == SGRAM || | ||
787 | (!M64_HAS(XL_MEM) && par->ram_type == WRAM)) | ||
788 | line_length = (line_length + 63) & ~63; | ||
789 | |||
790 | return line_length; | ||
791 | } | ||
792 | |||
763 | static int aty_var_to_crtc(const struct fb_info *info, | 793 | static int aty_var_to_crtc(const struct fb_info *info, |
764 | const struct fb_var_screeninfo *var, struct crtc *crtc) | 794 | const struct fb_var_screeninfo *var, |
795 | struct crtc *crtc) | ||
765 | { | 796 | { |
766 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 797 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
767 | u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp; | 798 | u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp; |
@@ -769,13 +800,14 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
769 | u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; | 800 | u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; |
770 | u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; | 801 | u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; |
771 | u32 pix_width, dp_pix_width, dp_chain_mask; | 802 | u32 pix_width, dp_pix_width, dp_chain_mask; |
803 | u32 line_length; | ||
772 | 804 | ||
773 | /* input */ | 805 | /* input */ |
774 | xres = var->xres; | 806 | xres = (var->xres + 7) & ~7; |
775 | yres = var->yres; | 807 | yres = var->yres; |
776 | vxres = var->xres_virtual; | 808 | vxres = (var->xres_virtual + 7) & ~7; |
777 | vyres = var->yres_virtual; | 809 | vyres = var->yres_virtual; |
778 | xoffset = var->xoffset; | 810 | xoffset = (var->xoffset + 7) & ~7; |
779 | yoffset = var->yoffset; | 811 | yoffset = var->yoffset; |
780 | bpp = var->bits_per_pixel; | 812 | bpp = var->bits_per_pixel; |
781 | if (bpp == 16) | 813 | if (bpp == 16) |
@@ -795,47 +827,47 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
795 | if (bpp <= 8) { | 827 | if (bpp <= 8) { |
796 | bpp = 8; | 828 | bpp = 8; |
797 | pix_width = CRTC_PIX_WIDTH_8BPP; | 829 | pix_width = CRTC_PIX_WIDTH_8BPP; |
798 | dp_pix_width = | 830 | dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | |
799 | HOST_8BPP | SRC_8BPP | DST_8BPP | | 831 | BYTE_ORDER_LSB_TO_MSB; |
800 | BYTE_ORDER_LSB_TO_MSB; | ||
801 | dp_chain_mask = DP_CHAIN_8BPP; | 832 | dp_chain_mask = DP_CHAIN_8BPP; |
802 | } else if (bpp <= 15) { | 833 | } else if (bpp <= 15) { |
803 | bpp = 16; | 834 | bpp = 16; |
804 | pix_width = CRTC_PIX_WIDTH_15BPP; | 835 | pix_width = CRTC_PIX_WIDTH_15BPP; |
805 | dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP | | 836 | dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP | |
806 | BYTE_ORDER_LSB_TO_MSB; | 837 | BYTE_ORDER_LSB_TO_MSB; |
807 | dp_chain_mask = DP_CHAIN_15BPP; | 838 | dp_chain_mask = DP_CHAIN_15BPP; |
808 | } else if (bpp <= 16) { | 839 | } else if (bpp <= 16) { |
809 | bpp = 16; | 840 | bpp = 16; |
810 | pix_width = CRTC_PIX_WIDTH_16BPP; | 841 | pix_width = CRTC_PIX_WIDTH_16BPP; |
811 | dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP | | 842 | dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP | |
812 | BYTE_ORDER_LSB_TO_MSB; | 843 | BYTE_ORDER_LSB_TO_MSB; |
813 | dp_chain_mask = DP_CHAIN_16BPP; | 844 | dp_chain_mask = DP_CHAIN_16BPP; |
814 | } else if (bpp <= 24 && M64_HAS(INTEGRATED)) { | 845 | } else if (bpp <= 24 && M64_HAS(INTEGRATED)) { |
815 | bpp = 24; | 846 | bpp = 24; |
816 | pix_width = CRTC_PIX_WIDTH_24BPP; | 847 | pix_width = CRTC_PIX_WIDTH_24BPP; |
817 | dp_pix_width = | 848 | dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | |
818 | HOST_8BPP | SRC_8BPP | DST_8BPP | | 849 | BYTE_ORDER_LSB_TO_MSB; |
819 | BYTE_ORDER_LSB_TO_MSB; | ||
820 | dp_chain_mask = DP_CHAIN_24BPP; | 850 | dp_chain_mask = DP_CHAIN_24BPP; |
821 | } else if (bpp <= 32) { | 851 | } else if (bpp <= 32) { |
822 | bpp = 32; | 852 | bpp = 32; |
823 | pix_width = CRTC_PIX_WIDTH_32BPP; | 853 | pix_width = CRTC_PIX_WIDTH_32BPP; |
824 | dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP | | 854 | dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP | |
825 | BYTE_ORDER_LSB_TO_MSB; | 855 | BYTE_ORDER_LSB_TO_MSB; |
826 | dp_chain_mask = DP_CHAIN_32BPP; | 856 | dp_chain_mask = DP_CHAIN_32BPP; |
827 | } else | 857 | } else |
828 | FAIL("invalid bpp"); | 858 | FAIL("invalid bpp"); |
829 | 859 | ||
830 | if (vxres * vyres * bpp / 8 > info->fix.smem_len) | 860 | line_length = calc_line_length(par, vxres, bpp); |
861 | |||
862 | if (vyres * line_length > info->fix.smem_len) | ||
831 | FAIL("not enough video RAM"); | 863 | FAIL("not enough video RAM"); |
832 | 864 | ||
833 | h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; | 865 | h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; |
834 | v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; | 866 | v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; |
835 | 867 | ||
836 | if((xres > 1600) || (yres > 1200)) { | 868 | if ((xres > 1600) || (yres > 1200)) { |
837 | FAIL("MACH64 chips are designed for max 1600x1200\n" | 869 | FAIL("MACH64 chips are designed for max 1600x1200\n" |
838 | "select anoter resolution."); | 870 | "select anoter resolution."); |
839 | } | 871 | } |
840 | h_sync_strt = h_disp + var->right_margin; | 872 | h_sync_strt = h_disp + var->right_margin; |
841 | h_sync_end = h_sync_strt + var->hsync_len; | 873 | h_sync_end = h_sync_strt + var->hsync_len; |
@@ -848,11 +880,12 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
848 | 880 | ||
849 | #ifdef CONFIG_FB_ATY_GENERIC_LCD | 881 | #ifdef CONFIG_FB_ATY_GENERIC_LCD |
850 | if (par->lcd_table != 0) { | 882 | if (par->lcd_table != 0) { |
851 | if(!M64_HAS(LT_LCD_REGS)) { | 883 | if (!M64_HAS(LT_LCD_REGS)) { |
852 | u32 lcd_index = aty_ld_le32(LCD_INDEX, par); | 884 | u32 lcd_index = aty_ld_le32(LCD_INDEX, par); |
853 | crtc->lcd_index = lcd_index & | 885 | crtc->lcd_index = lcd_index & |
854 | ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS); | 886 | ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | |
855 | aty_st_le32(LCD_INDEX, lcd_index, par); | 887 | LCD_SRC_SEL | CRTC2_DISPLAY_DIS); |
888 | aty_st_le32(LCD_INDEX, lcd_index, par); | ||
856 | } | 889 | } |
857 | 890 | ||
858 | if (!M64_HAS(MOBIL_BUS)) | 891 | if (!M64_HAS(MOBIL_BUS)) |
@@ -867,12 +900,14 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
867 | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); | 900 | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); |
868 | crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT; | 901 | crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT; |
869 | 902 | ||
870 | if((crtc->lcd_gen_cntl & LCD_ON) && | 903 | if ((crtc->lcd_gen_cntl & LCD_ON) && |
871 | ((xres > par->lcd_width) || (yres > par->lcd_height))) { | 904 | ((xres > par->lcd_width) || (yres > par->lcd_height))) { |
872 | /* We cannot display the mode on the LCD. If the CRT is enabled | 905 | /* |
873 | we can turn off the LCD. | 906 | * We cannot display the mode on the LCD. If the CRT is |
874 | If the CRT is off, it isn't a good idea to switch it on; we don't | 907 | * enabled we can turn off the LCD. |
875 | know if one is connected. So it's better to fail then. | 908 | * If the CRT is off, it isn't a good idea to switch it |
909 | * on; we don't know if one is connected. So it's better | ||
910 | * to fail then. | ||
876 | */ | 911 | */ |
877 | if (crtc->lcd_gen_cntl & CRT_ON) { | 912 | if (crtc->lcd_gen_cntl & CRT_ON) { |
878 | if (!(var->activate & FB_ACTIVATE_TEST)) | 913 | if (!(var->activate & FB_ACTIVATE_TEST)) |
@@ -895,17 +930,18 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
895 | 930 | ||
896 | vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); | 931 | vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); |
897 | 932 | ||
898 | /* This is horror! When we simulate, say 640x480 on an 800x600 | 933 | /* |
899 | LCD monitor, the CRTC should be programmed 800x600 values for | 934 | * This is horror! When we simulate, say 640x480 on an 800x600 |
900 | the non visible part, but 640x480 for the visible part. | 935 | * LCD monitor, the CRTC should be programmed 800x600 values for |
901 | This code has been tested on a laptop with it's 1400x1050 LCD | 936 | * the non visible part, but 640x480 for the visible part. |
902 | monitor and a conventional monitor both switched on. | 937 | * This code has been tested on a laptop with it's 1400x1050 LCD |
903 | Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, | 938 | * monitor and a conventional monitor both switched on. |
904 | works with little glitches also with DOUBLESCAN modes | 939 | * Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, |
940 | * works with little glitches also with DOUBLESCAN modes | ||
905 | */ | 941 | */ |
906 | if (yres < par->lcd_height) { | 942 | if (yres < par->lcd_height) { |
907 | VScan = par->lcd_height / yres; | 943 | VScan = par->lcd_height / yres; |
908 | if(VScan > 1) { | 944 | if (VScan > 1) { |
909 | VScan = 2; | 945 | VScan = 2; |
910 | vmode |= FB_VMODE_DOUBLE; | 946 | vmode |= FB_VMODE_DOUBLE; |
911 | } | 947 | } |
@@ -931,7 +967,7 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
931 | FAIL_MAX("h_disp too large", h_disp, 0xff); | 967 | FAIL_MAX("h_disp too large", h_disp, 0xff); |
932 | FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff); | 968 | FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff); |
933 | /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/ | 969 | /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/ |
934 | if(h_sync_wid > 0x1f) | 970 | if (h_sync_wid > 0x1f) |
935 | h_sync_wid = 0x1f; | 971 | h_sync_wid = 0x1f; |
936 | FAIL_MAX("h_total too large", h_total, 0x1ff); | 972 | FAIL_MAX("h_total too large", h_total, 0x1ff); |
937 | 973 | ||
@@ -957,7 +993,7 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
957 | FAIL_MAX("v_disp too large", v_disp, 0x7ff); | 993 | FAIL_MAX("v_disp too large", v_disp, 0x7ff); |
958 | FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff); | 994 | FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff); |
959 | /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/ | 995 | /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/ |
960 | if(v_sync_wid > 0x1f) | 996 | if (v_sync_wid > 0x1f) |
961 | v_sync_wid = 0x1f; | 997 | v_sync_wid = 0x1f; |
962 | FAIL_MAX("v_total too large", v_total, 0x7ff); | 998 | FAIL_MAX("v_total too large", v_total, 0x7ff); |
963 | 999 | ||
@@ -969,14 +1005,18 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
969 | crtc->xoffset = xoffset; | 1005 | crtc->xoffset = xoffset; |
970 | crtc->yoffset = yoffset; | 1006 | crtc->yoffset = yoffset; |
971 | crtc->bpp = bpp; | 1007 | crtc->bpp = bpp; |
972 | crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19); | 1008 | crtc->off_pitch = |
1009 | ((yoffset * line_length + xoffset * bpp / 8) / 8) | | ||
1010 | ((line_length / bpp) << 22); | ||
973 | crtc->vline_crnt_vline = 0; | 1011 | crtc->vline_crnt_vline = 0; |
974 | 1012 | ||
975 | crtc->h_tot_disp = h_total | (h_disp<<16); | 1013 | crtc->h_tot_disp = h_total | (h_disp << 16); |
976 | crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) | | 1014 | crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) | |
977 | ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21); | 1015 | ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) | |
978 | crtc->v_tot_disp = v_total | (v_disp<<16); | 1016 | (h_sync_pol << 21); |
979 | crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21); | 1017 | crtc->v_tot_disp = v_total | (v_disp << 16); |
1018 | crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) | | ||
1019 | (v_sync_pol << 21); | ||
980 | 1020 | ||
981 | /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */ | 1021 | /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */ |
982 | crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync; | 1022 | crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync; |
@@ -991,13 +1031,15 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
991 | #ifdef CONFIG_FB_ATY_GENERIC_LCD | 1031 | #ifdef CONFIG_FB_ATY_GENERIC_LCD |
992 | if (par->lcd_table != 0) { | 1032 | if (par->lcd_table != 0) { |
993 | vdisplay = yres; | 1033 | vdisplay = yres; |
994 | if(vmode & FB_VMODE_DOUBLE) | 1034 | if (vmode & FB_VMODE_DOUBLE) |
995 | vdisplay <<= 1; | 1035 | vdisplay <<= 1; |
996 | crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); | 1036 | crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); |
997 | crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | | 1037 | crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | |
998 | /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ | 1038 | /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ |
999 | USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); | 1039 | USE_SHADOWED_VEND | |
1000 | crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/); | 1040 | USE_SHADOWED_ROWCUR | |
1041 | SHADOW_EN | SHADOW_RW_EN); | ||
1042 | crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR/* | LOCK_8DOT*/; | ||
1001 | 1043 | ||
1002 | /* MOBILITY M1 tested, FIXME: LT */ | 1044 | /* MOBILITY M1 tested, FIXME: LT */ |
1003 | crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); | 1045 | crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); |
@@ -1005,28 +1047,32 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
1005 | crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) & | 1047 | crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) & |
1006 | ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3); | 1048 | ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3); |
1007 | 1049 | ||
1008 | crtc->horz_stretching &= | 1050 | crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO | |
1009 | ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | | 1051 | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | |
1010 | HORZ_STRETCH_MODE | HORZ_STRETCH_EN); | 1052 | HORZ_STRETCH_MODE | HORZ_STRETCH_EN); |
1011 | if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { | 1053 | if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { |
1012 | do { | 1054 | do { |
1013 | /* | 1055 | /* |
1014 | * The horizontal blender misbehaves when HDisplay is less than a | 1056 | * The horizontal blender misbehaves when |
1015 | * a certain threshold (440 for a 1024-wide panel). It doesn't | 1057 | * HDisplay is less than a certain threshold |
1016 | * stretch such modes enough. Use pixel replication instead of | 1058 | * (440 for a 1024-wide panel). It doesn't |
1017 | * blending to stretch modes that can be made to exactly fit the | 1059 | * stretch such modes enough. Use pixel |
1018 | * panel width. The undocumented "NoLCDBlend" option allows the | 1060 | * replication instead of blending to stretch |
1019 | * pixel-replicated mode to be slightly wider or narrower than the | 1061 | * modes that can be made to exactly fit the |
1020 | * panel width. It also causes a mode that is exactly half as wide | 1062 | * panel width. The undocumented "NoLCDBlend" |
1021 | * as the panel to be pixel-replicated, rather than blended. | 1063 | * option allows the pixel-replicated mode to |
1022 | */ | 1064 | * be slightly wider or narrower than the |
1065 | * panel width. It also causes a mode that is | ||
1066 | * exactly half as wide as the panel to be | ||
1067 | * pixel-replicated, rather than blended. | ||
1068 | */ | ||
1023 | int HDisplay = xres & ~7; | 1069 | int HDisplay = xres & ~7; |
1024 | int nStretch = par->lcd_width / HDisplay; | 1070 | int nStretch = par->lcd_width / HDisplay; |
1025 | int Remainder = par->lcd_width % HDisplay; | 1071 | int Remainder = par->lcd_width % HDisplay; |
1026 | 1072 | ||
1027 | if ((!Remainder && ((nStretch > 2))) || | 1073 | if ((!Remainder && ((nStretch > 2))) || |
1028 | (((HDisplay * 16) / par->lcd_width) < 7)) { | 1074 | (((HDisplay * 16) / par->lcd_width) < 7)) { |
1029 | static const char StretchLoops[] = {10, 12, 13, 15, 16}; | 1075 | static const char StretchLoops[] = { 10, 12, 13, 15, 16 }; |
1030 | int horz_stretch_loop = -1, BestRemainder; | 1076 | int horz_stretch_loop = -1, BestRemainder; |
1031 | int Numerator = HDisplay, Denominator = par->lcd_width; | 1077 | int Numerator = HDisplay, Denominator = par->lcd_width; |
1032 | int Index = 5; | 1078 | int Index = 5; |
@@ -1075,12 +1121,12 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
1075 | (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); | 1121 | (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); |
1076 | 1122 | ||
1077 | if (!M64_HAS(LT_LCD_REGS) && | 1123 | if (!M64_HAS(LT_LCD_REGS) && |
1078 | xres <= (M64_HAS(MOBIL_BUS)?1024:800)) | 1124 | xres <= (M64_HAS(MOBIL_BUS) ? 1024 : 800)) |
1079 | crtc->ext_vert_stretch |= VERT_STRETCH_MODE; | 1125 | crtc->ext_vert_stretch |= VERT_STRETCH_MODE; |
1080 | } else { | 1126 | } else { |
1081 | /* | 1127 | /* |
1082 | * Don't use vertical blending if the mode is too wide or not | 1128 | * Don't use vertical blending if the mode is too wide |
1083 | * vertically stretched. | 1129 | * or not vertically stretched. |
1084 | */ | 1130 | */ |
1085 | crtc->vert_stretching = 0; | 1131 | crtc->vert_stretching = 0; |
1086 | } | 1132 | } |
@@ -1102,11 +1148,11 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
1102 | return 0; | 1148 | return 0; |
1103 | } | 1149 | } |
1104 | 1150 | ||
1105 | static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var) | 1151 | static int aty_crtc_to_var(const struct crtc *crtc, |
1152 | struct fb_var_screeninfo *var) | ||
1106 | { | 1153 | { |
1107 | u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync; | 1154 | u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync; |
1108 | u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, | 1155 | u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol; |
1109 | h_sync_pol; | ||
1110 | u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync; | 1156 | u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync; |
1111 | u32 pix_width; | 1157 | u32 pix_width; |
1112 | u32 double_scan, interlace; | 1158 | u32 double_scan, interlace; |
@@ -1138,8 +1184,8 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va | |||
1138 | lower = v_sync_strt - v_disp; | 1184 | lower = v_sync_strt - v_disp; |
1139 | vslen = v_sync_wid; | 1185 | vslen = v_sync_wid; |
1140 | sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) | | 1186 | sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) | |
1141 | (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) | | 1187 | (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) | |
1142 | (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0); | 1188 | (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0); |
1143 | 1189 | ||
1144 | switch (pix_width) { | 1190 | switch (pix_width) { |
1145 | #if 0 | 1191 | #if 0 |
@@ -1229,20 +1275,21 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va | |||
1229 | var->vsync_len = vslen; | 1275 | var->vsync_len = vslen; |
1230 | var->sync = sync; | 1276 | var->sync = sync; |
1231 | var->vmode = FB_VMODE_NONINTERLACED; | 1277 | var->vmode = FB_VMODE_NONINTERLACED; |
1232 | /* In double scan mode, the vertical parameters are doubled, so we need to | 1278 | /* |
1233 | half them to get the right values. | 1279 | * In double scan mode, the vertical parameters are doubled, |
1234 | In interlaced mode the values are already correct, so no correction is | 1280 | * so we need to halve them to get the right values. |
1235 | necessary. | 1281 | * In interlaced mode the values are already correct, |
1282 | * so no correction is necessary. | ||
1236 | */ | 1283 | */ |
1237 | if (interlace) | 1284 | if (interlace) |
1238 | var->vmode = FB_VMODE_INTERLACED; | 1285 | var->vmode = FB_VMODE_INTERLACED; |
1239 | 1286 | ||
1240 | if (double_scan) { | 1287 | if (double_scan) { |
1241 | var->vmode = FB_VMODE_DOUBLE; | 1288 | var->vmode = FB_VMODE_DOUBLE; |
1242 | var->yres>>=1; | 1289 | var->yres >>= 1; |
1243 | var->upper_margin>>=1; | 1290 | var->upper_margin >>= 1; |
1244 | var->lower_margin>>=1; | 1291 | var->lower_margin >>= 1; |
1245 | var->vsync_len>>=1; | 1292 | var->vsync_len >>= 1; |
1246 | } | 1293 | } |
1247 | 1294 | ||
1248 | return 0; | 1295 | return 0; |
@@ -1263,7 +1310,8 @@ static int atyfb_set_par(struct fb_info *info) | |||
1263 | if (par->asleep) | 1310 | if (par->asleep) |
1264 | return 0; | 1311 | return 0; |
1265 | 1312 | ||
1266 | if ((err = aty_var_to_crtc(info, var, &par->crtc))) | 1313 | err = aty_var_to_crtc(info, var, &par->crtc); |
1314 | if (err) | ||
1267 | return err; | 1315 | return err; |
1268 | 1316 | ||
1269 | pixclock = atyfb_get_pixclock(var, par); | 1317 | pixclock = atyfb_get_pixclock(var, par); |
@@ -1272,7 +1320,9 @@ static int atyfb_set_par(struct fb_info *info) | |||
1272 | PRINTKE("Invalid pixclock\n"); | 1320 | PRINTKE("Invalid pixclock\n"); |
1273 | return -EINVAL; | 1321 | return -EINVAL; |
1274 | } else { | 1322 | } else { |
1275 | if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll))) | 1323 | err = par->pll_ops->var_to_pll(info, pixclock, |
1324 | var->bits_per_pixel, &par->pll); | ||
1325 | if (err) | ||
1276 | return err; | 1326 | return err; |
1277 | } | 1327 | } |
1278 | 1328 | ||
@@ -1290,22 +1340,23 @@ static int atyfb_set_par(struct fb_info *info) | |||
1290 | wait_for_idle(par); | 1340 | wait_for_idle(par); |
1291 | 1341 | ||
1292 | aty_set_crtc(par, &par->crtc); | 1342 | aty_set_crtc(par, &par->crtc); |
1293 | par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags); | 1343 | par->dac_ops->set_dac(info, &par->pll, |
1344 | var->bits_per_pixel, par->accel_flags); | ||
1294 | par->pll_ops->set_pll(info, &par->pll); | 1345 | par->pll_ops->set_pll(info, &par->pll); |
1295 | 1346 | ||
1296 | #ifdef DEBUG | 1347 | #ifdef DEBUG |
1297 | if(par->pll_ops && par->pll_ops->pll_to_var) | 1348 | if (par->pll_ops && par->pll_ops->pll_to_var) |
1298 | pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll)); | 1349 | pixclock_in_ps = par->pll_ops->pll_to_var(info, &par->pll); |
1299 | else | 1350 | else |
1300 | pixclock_in_ps = 0; | 1351 | pixclock_in_ps = 0; |
1301 | 1352 | ||
1302 | if(0 == pixclock_in_ps) { | 1353 | if (0 == pixclock_in_ps) { |
1303 | PRINTKE("ALERT ops->pll_to_var get 0\n"); | 1354 | PRINTKE("ALERT ops->pll_to_var get 0\n"); |
1304 | pixclock_in_ps = pixclock; | 1355 | pixclock_in_ps = pixclock; |
1305 | } | 1356 | } |
1306 | 1357 | ||
1307 | memset(&debug, 0, sizeof(debug)); | 1358 | memset(&debug, 0, sizeof(debug)); |
1308 | if(!aty_crtc_to_var(&(par->crtc), &debug)) { | 1359 | if (!aty_crtc_to_var(&par->crtc, &debug)) { |
1309 | u32 hSync, vRefresh; | 1360 | u32 hSync, vRefresh; |
1310 | u32 h_disp, h_sync_strt, h_sync_end, h_total; | 1361 | u32 h_disp, h_sync_strt, h_sync_end, h_total; |
1311 | u32 v_disp, v_sync_strt, v_sync_end, v_total; | 1362 | u32 v_disp, v_sync_strt, v_sync_end, v_total; |
@@ -1321,16 +1372,20 @@ static int atyfb_set_par(struct fb_info *info) | |||
1321 | 1372 | ||
1322 | hSync = 1000000000 / (pixclock_in_ps * h_total); | 1373 | hSync = 1000000000 / (pixclock_in_ps * h_total); |
1323 | vRefresh = (hSync * 1000) / v_total; | 1374 | vRefresh = (hSync * 1000) / v_total; |
1324 | if (par->crtc.gen_cntl & CRTC_INTERLACE_EN) | 1375 | if (par->crtc.gen_cntl & CRTC_INTERLACE_EN) |
1325 | vRefresh *= 2; | 1376 | vRefresh *= 2; |
1326 | if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) | 1377 | if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) |
1327 | vRefresh /= 2; | 1378 | vRefresh /= 2; |
1328 | 1379 | ||
1329 | DPRINTK("atyfb_set_par\n"); | 1380 | DPRINTK("atyfb_set_par\n"); |
1330 | DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel); | 1381 | DPRINTK(" Set Visible Mode to %ix%i-%i\n", |
1331 | DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n", | 1382 | var->xres, var->yres, var->bits_per_pixel); |
1332 | var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps); | 1383 | DPRINTK(" Virtual resolution %ix%i, " |
1333 | DPRINTK(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps); | 1384 | "pixclock_in_ps %i (calculated %i)\n", |
1385 | var->xres_virtual, var->yres_virtual, | ||
1386 | pixclock, pixclock_in_ps); | ||
1387 | DPRINTK(" Dot clock: %i MHz\n", | ||
1388 | 1000000 / pixclock_in_ps); | ||
1334 | DPRINTK(" Horizontal sync: %i kHz\n", hSync); | 1389 | DPRINTK(" Horizontal sync: %i kHz\n", hSync); |
1335 | DPRINTK(" Vertical refresh: %i Hz\n", vRefresh); | 1390 | DPRINTK(" Vertical refresh: %i Hz\n", vRefresh); |
1336 | DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n", | 1391 | DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n", |
@@ -1394,7 +1449,9 @@ static int atyfb_set_par(struct fb_info *info) | |||
1394 | } | 1449 | } |
1395 | aty_st_8(DAC_MASK, 0xff, par); | 1450 | aty_st_8(DAC_MASK, 0xff, par); |
1396 | 1451 | ||
1397 | info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8; | 1452 | info->fix.line_length = calc_line_length(par, var->xres_virtual, |
1453 | var->bits_per_pixel); | ||
1454 | |||
1398 | info->fix.visual = var->bits_per_pixel <= 8 ? | 1455 | info->fix.visual = var->bits_per_pixel <= 8 ? |
1399 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; | 1456 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; |
1400 | 1457 | ||
@@ -1423,7 +1480,8 @@ static int atyfb_set_par(struct fb_info *info) | |||
1423 | base = 0x2000; | 1480 | base = 0x2000; |
1424 | printk("debug atyfb: Mach64 non-shadow register values:"); | 1481 | printk("debug atyfb: Mach64 non-shadow register values:"); |
1425 | for (i = 0; i < 256; i = i+4) { | 1482 | for (i = 0; i < 256; i = i+4) { |
1426 | if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i); | 1483 | if (i % 16 == 0) |
1484 | printk("\ndebug atyfb: 0x%04X: ", base + i); | ||
1427 | printk(" %08X", aty_ld_le32(i, par)); | 1485 | printk(" %08X", aty_ld_le32(i, par)); |
1428 | } | 1486 | } |
1429 | printk("\n\n"); | 1487 | printk("\n\n"); |
@@ -1433,8 +1491,10 @@ static int atyfb_set_par(struct fb_info *info) | |||
1433 | base = 0x00; | 1491 | base = 0x00; |
1434 | printk("debug atyfb: Mach64 PLL register values:"); | 1492 | printk("debug atyfb: Mach64 PLL register values:"); |
1435 | for (i = 0; i < 64; i++) { | 1493 | for (i = 0; i < 64; i++) { |
1436 | if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i); | 1494 | if (i % 16 == 0) |
1437 | if(i%4 == 0) printk(" "); | 1495 | printk("\ndebug atyfb: 0x%02X: ", base + i); |
1496 | if (i % 4 == 0) | ||
1497 | printk(" "); | ||
1438 | printk("%02X", aty_ld_pll_ct(i, par)); | 1498 | printk("%02X", aty_ld_pll_ct(i, par)); |
1439 | } | 1499 | } |
1440 | printk("\n\n"); | 1500 | printk("\n\n"); |
@@ -1445,19 +1505,21 @@ static int atyfb_set_par(struct fb_info *info) | |||
1445 | /* LCD registers */ | 1505 | /* LCD registers */ |
1446 | base = 0x00; | 1506 | base = 0x00; |
1447 | printk("debug atyfb: LCD register values:"); | 1507 | printk("debug atyfb: LCD register values:"); |
1448 | if(M64_HAS(LT_LCD_REGS)) { | 1508 | if (M64_HAS(LT_LCD_REGS)) { |
1449 | for(i = 0; i <= POWER_MANAGEMENT; i++) { | 1509 | for (i = 0; i <= POWER_MANAGEMENT; i++) { |
1450 | if(i == EXT_VERT_STRETCH) | 1510 | if (i == EXT_VERT_STRETCH) |
1451 | continue; | 1511 | continue; |
1452 | printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]); | 1512 | printk("\ndebug atyfb: 0x%04X: ", |
1453 | printk(" %08X", aty_ld_lcd(i, par)); | 1513 | lt_lcd_regs[i]); |
1454 | } | 1514 | printk(" %08X", aty_ld_lcd(i, par)); |
1455 | 1515 | } | |
1456 | } else { | 1516 | } else { |
1457 | for (i = 0; i < 64; i++) { | 1517 | for (i = 0; i < 64; i++) { |
1458 | if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i); | 1518 | if (i % 4 == 0) |
1459 | printk(" %08X", aty_ld_lcd(i, par)); | 1519 | printk("\ndebug atyfb: 0x%02X: ", |
1460 | } | 1520 | base + i); |
1521 | printk(" %08X", aty_ld_lcd(i, par)); | ||
1522 | } | ||
1461 | } | 1523 | } |
1462 | printk("\n\n"); | 1524 | printk("\n\n"); |
1463 | } | 1525 | } |
@@ -1475,9 +1537,10 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
1475 | union aty_pll pll; | 1537 | union aty_pll pll; |
1476 | u32 pixclock; | 1538 | u32 pixclock; |
1477 | 1539 | ||
1478 | memcpy(&pll, &(par->pll), sizeof(pll)); | 1540 | memcpy(&pll, &par->pll, sizeof(pll)); |
1479 | 1541 | ||
1480 | if((err = aty_var_to_crtc(info, var, &crtc))) | 1542 | err = aty_var_to_crtc(info, var, &crtc); |
1543 | if (err) | ||
1481 | return err; | 1544 | return err; |
1482 | 1545 | ||
1483 | pixclock = atyfb_get_pixclock(var, par); | 1546 | pixclock = atyfb_get_pixclock(var, par); |
@@ -1487,7 +1550,9 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
1487 | PRINTKE("Invalid pixclock\n"); | 1550 | PRINTKE("Invalid pixclock\n"); |
1488 | return -EINVAL; | 1551 | return -EINVAL; |
1489 | } else { | 1552 | } else { |
1490 | if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll))) | 1553 | err = par->pll_ops->var_to_pll(info, pixclock, |
1554 | var->bits_per_pixel, &pll); | ||
1555 | if (err) | ||
1491 | return err; | 1556 | return err; |
1492 | } | 1557 | } |
1493 | 1558 | ||
@@ -1505,16 +1570,18 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info) | |||
1505 | { | 1570 | { |
1506 | u32 xoffset = info->var.xoffset; | 1571 | u32 xoffset = info->var.xoffset; |
1507 | u32 yoffset = info->var.yoffset; | 1572 | u32 yoffset = info->var.yoffset; |
1508 | u32 vxres = par->crtc.vxres; | 1573 | u32 line_length = info->fix.line_length; |
1509 | u32 bpp = info->var.bits_per_pixel; | 1574 | u32 bpp = info->var.bits_per_pixel; |
1510 | 1575 | ||
1511 | par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19); | 1576 | par->crtc.off_pitch = |
1577 | ((yoffset * line_length + xoffset * bpp / 8) / 8) | | ||
1578 | ((line_length / bpp) << 22); | ||
1512 | } | 1579 | } |
1513 | 1580 | ||
1514 | 1581 | ||
1515 | /* | 1582 | /* |
1516 | * Open/Release the frame buffer device | 1583 | * Open/Release the frame buffer device |
1517 | */ | 1584 | */ |
1518 | 1585 | ||
1519 | static int atyfb_open(struct fb_info *info, int user) | 1586 | static int atyfb_open(struct fb_info *info, int user) |
1520 | { | 1587 | { |
@@ -1526,7 +1593,7 @@ static int atyfb_open(struct fb_info *info, int user) | |||
1526 | par->mmaped = 0; | 1593 | par->mmaped = 0; |
1527 | #endif | 1594 | #endif |
1528 | } | 1595 | } |
1529 | return (0); | 1596 | return 0; |
1530 | } | 1597 | } |
1531 | 1598 | ||
1532 | static irqreturn_t aty_irq(int irq, void *dev_id) | 1599 | static irqreturn_t aty_irq(int irq, void *dev_id) |
@@ -1541,7 +1608,8 @@ static irqreturn_t aty_irq(int irq, void *dev_id) | |||
1541 | 1608 | ||
1542 | if (int_cntl & CRTC_VBLANK_INT) { | 1609 | if (int_cntl & CRTC_VBLANK_INT) { |
1543 | /* clear interrupt */ | 1610 | /* clear interrupt */ |
1544 | aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par); | 1611 | aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | |
1612 | CRTC_VBLANK_INT_AK, par); | ||
1545 | par->vblank.count++; | 1613 | par->vblank.count++; |
1546 | if (par->vblank.pan_display) { | 1614 | if (par->vblank.pan_display) { |
1547 | par->vblank.pan_display = 0; | 1615 | par->vblank.pan_display = 0; |
@@ -1576,9 +1644,11 @@ static int aty_enable_irq(struct atyfb_par *par, int reenable) | |||
1576 | spin_lock_irq(&par->int_lock); | 1644 | spin_lock_irq(&par->int_lock); |
1577 | int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; | 1645 | int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; |
1578 | if (!(int_cntl & CRTC_VBLANK_INT_EN)) { | 1646 | if (!(int_cntl & CRTC_VBLANK_INT_EN)) { |
1579 | printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl); | 1647 | printk("atyfb: someone disabled IRQ [%08x]\n", |
1648 | int_cntl); | ||
1580 | /* re-enable interrupt */ | 1649 | /* re-enable interrupt */ |
1581 | aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par ); | 1650 | aty_st_le32(CRTC_INT_CNTL, int_cntl | |
1651 | CRTC_VBLANK_INT_EN, par); | ||
1582 | } | 1652 | } |
1583 | spin_unlock_irq(&par->int_lock); | 1653 | spin_unlock_irq(&par->int_lock); |
1584 | } | 1654 | } |
@@ -1598,7 +1668,7 @@ static int aty_disable_irq(struct atyfb_par *par) | |||
1598 | spin_lock_irq(&par->int_lock); | 1668 | spin_lock_irq(&par->int_lock); |
1599 | int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; | 1669 | int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; |
1600 | /* disable interrupt */ | 1670 | /* disable interrupt */ |
1601 | aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par ); | 1671 | aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par); |
1602 | spin_unlock_irq(&par->int_lock); | 1672 | spin_unlock_irq(&par->int_lock); |
1603 | free_irq(par->irq, par); | 1673 | free_irq(par->irq, par); |
1604 | } | 1674 | } |
@@ -1609,50 +1679,62 @@ static int aty_disable_irq(struct atyfb_par *par) | |||
1609 | static int atyfb_release(struct fb_info *info, int user) | 1679 | static int atyfb_release(struct fb_info *info, int user) |
1610 | { | 1680 | { |
1611 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 1681 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
1612 | if (user) { | ||
1613 | par->open--; | ||
1614 | mdelay(1); | ||
1615 | wait_for_idle(par); | ||
1616 | if (!par->open) { | ||
1617 | #ifdef __sparc__ | 1682 | #ifdef __sparc__ |
1618 | int was_mmaped = par->mmaped; | 1683 | int was_mmaped; |
1684 | #endif | ||
1619 | 1685 | ||
1620 | par->mmaped = 0; | 1686 | if (!user) |
1687 | return 0; | ||
1621 | 1688 | ||
1622 | if (was_mmaped) { | 1689 | par->open--; |
1623 | struct fb_var_screeninfo var; | 1690 | mdelay(1); |
1691 | wait_for_idle(par); | ||
1624 | 1692 | ||
1625 | /* Now reset the default display config, we have no | 1693 | if (par->open) |
1626 | * idea what the program(s) which mmap'd the chip did | 1694 | return 0; |
1627 | * to the configuration, nor whether it restored it | 1695 | |
1628 | * correctly. | 1696 | #ifdef __sparc__ |
1629 | */ | 1697 | was_mmaped = par->mmaped; |
1630 | var = default_var; | 1698 | |
1631 | if (noaccel) | 1699 | par->mmaped = 0; |
1632 | var.accel_flags &= ~FB_ACCELF_TEXT; | 1700 | |
1633 | else | 1701 | if (was_mmaped) { |
1634 | var.accel_flags |= FB_ACCELF_TEXT; | 1702 | struct fb_var_screeninfo var; |
1635 | if (var.yres == var.yres_virtual) { | 1703 | |
1636 | u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); | 1704 | /* |
1637 | var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual; | 1705 | * Now reset the default display config, we have |
1638 | if (var.yres_virtual < var.yres) | 1706 | * no idea what the program(s) which mmap'd the |
1639 | var.yres_virtual = var.yres; | 1707 | * chip did to the configuration, nor whether it |
1640 | } | 1708 | * restored it correctly. |
1641 | } | 1709 | */ |
1642 | #endif | 1710 | var = default_var; |
1643 | aty_disable_irq(par); | 1711 | if (noaccel) |
1712 | var.accel_flags &= ~FB_ACCELF_TEXT; | ||
1713 | else | ||
1714 | var.accel_flags |= FB_ACCELF_TEXT; | ||
1715 | if (var.yres == var.yres_virtual) { | ||
1716 | u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); | ||
1717 | var.yres_virtual = | ||
1718 | ((videoram * 8) / var.bits_per_pixel) / | ||
1719 | var.xres_virtual; | ||
1720 | if (var.yres_virtual < var.yres) | ||
1721 | var.yres_virtual = var.yres; | ||
1644 | } | 1722 | } |
1645 | } | 1723 | } |
1646 | return (0); | 1724 | #endif |
1725 | aty_disable_irq(par); | ||
1726 | |||
1727 | return 0; | ||
1647 | } | 1728 | } |
1648 | 1729 | ||
1649 | /* | 1730 | /* |
1650 | * Pan or Wrap the Display | 1731 | * Pan or Wrap the Display |
1651 | * | 1732 | * |
1652 | * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag | 1733 | * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag |
1653 | */ | 1734 | */ |
1654 | 1735 | ||
1655 | static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 1736 | static int atyfb_pan_display(struct fb_var_screeninfo *var, |
1737 | struct fb_info *info) | ||
1656 | { | 1738 | { |
1657 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 1739 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
1658 | u32 xres, yres, xoffset, yoffset; | 1740 | u32 xres, yres, xoffset, yoffset; |
@@ -1663,7 +1745,8 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info | |||
1663 | yres >>= 1; | 1745 | yres >>= 1; |
1664 | xoffset = (var->xoffset + 7) & ~7; | 1746 | xoffset = (var->xoffset + 7) & ~7; |
1665 | yoffset = var->yoffset; | 1747 | yoffset = var->yoffset; |
1666 | if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres) | 1748 | if (xoffset + xres > par->crtc.vxres || |
1749 | yoffset + yres > par->crtc.vyres) | ||
1667 | return -EINVAL; | 1750 | return -EINVAL; |
1668 | info->var.xoffset = xoffset; | 1751 | info->var.xoffset = xoffset; |
1669 | info->var.yoffset = yoffset; | 1752 | info->var.yoffset = yoffset; |
@@ -1700,10 +1783,10 @@ static int aty_waitforvblank(struct atyfb_par *par, u32 crtc) | |||
1700 | return ret; | 1783 | return ret; |
1701 | 1784 | ||
1702 | count = vbl->count; | 1785 | count = vbl->count; |
1703 | ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10); | 1786 | ret = wait_event_interruptible_timeout(vbl->wait, |
1704 | if (ret < 0) { | 1787 | count != vbl->count, HZ/10); |
1788 | if (ret < 0) | ||
1705 | return ret; | 1789 | return ret; |
1706 | } | ||
1707 | if (ret == 0) { | 1790 | if (ret == 0) { |
1708 | aty_enable_irq(par, 1); | 1791 | aty_enable_irq(par, 1); |
1709 | return -ETIMEDOUT; | 1792 | return -ETIMEDOUT; |
@@ -1757,7 +1840,8 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
1757 | fbtyp.fb_depth = info->var.bits_per_pixel; | 1840 | fbtyp.fb_depth = info->var.bits_per_pixel; |
1758 | fbtyp.fb_cmsize = info->cmap.len; | 1841 | fbtyp.fb_cmsize = info->cmap.len; |
1759 | fbtyp.fb_size = info->fix.smem_len; | 1842 | fbtyp.fb_size = info->fix.smem_len; |
1760 | if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp))) | 1843 | if (copy_to_user((struct fbtype __user *) arg, &fbtyp, |
1844 | sizeof(fbtyp))) | ||
1761 | return -EFAULT; | 1845 | return -EFAULT; |
1762 | break; | 1846 | break; |
1763 | #endif /* __sparc__ */ | 1847 | #endif /* __sparc__ */ |
@@ -1777,7 +1861,7 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
1777 | case ATYIO_CLKR: | 1861 | case ATYIO_CLKR: |
1778 | if (M64_HAS(INTEGRATED)) { | 1862 | if (M64_HAS(INTEGRATED)) { |
1779 | struct atyclk clk; | 1863 | struct atyclk clk; |
1780 | union aty_pll *pll = &(par->pll); | 1864 | union aty_pll *pll = &par->pll; |
1781 | u32 dsp_config = pll->ct.dsp_config; | 1865 | u32 dsp_config = pll->ct.dsp_config; |
1782 | u32 dsp_on_off = pll->ct.dsp_on_off; | 1866 | u32 dsp_on_off = pll->ct.dsp_on_off; |
1783 | clk.ref_clk_per = par->ref_clk_per; | 1867 | clk.ref_clk_per = par->ref_clk_per; |
@@ -1802,8 +1886,9 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
1802 | case ATYIO_CLKW: | 1886 | case ATYIO_CLKW: |
1803 | if (M64_HAS(INTEGRATED)) { | 1887 | if (M64_HAS(INTEGRATED)) { |
1804 | struct atyclk clk; | 1888 | struct atyclk clk; |
1805 | union aty_pll *pll = &(par->pll); | 1889 | union aty_pll *pll = &par->pll; |
1806 | if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk))) | 1890 | if (copy_from_user(&clk, (struct atyclk __user *) arg, |
1891 | sizeof(clk))) | ||
1807 | return -EFAULT; | 1892 | return -EFAULT; |
1808 | par->ref_clk_per = clk.ref_clk_per; | 1893 | par->ref_clk_per = clk.ref_clk_per; |
1809 | pll->ct.pll_ref_div = clk.pll_ref_div; | 1894 | pll->ct.pll_ref_div = clk.pll_ref_div; |
@@ -1814,8 +1899,10 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
1814 | pll->ct.vclk_fb_div = clk.vclk_fb_div; | 1899 | pll->ct.vclk_fb_div = clk.vclk_fb_div; |
1815 | pll->ct.vclk_post_div_real = clk.vclk_post_div; | 1900 | pll->ct.vclk_post_div_real = clk.vclk_post_div; |
1816 | pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) | | 1901 | pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) | |
1817 | ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20); | 1902 | ((clk.dsp_loop_latency & 0xf) << 16) | |
1818 | pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16); | 1903 | ((clk.dsp_precision & 7) << 20); |
1904 | pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | | ||
1905 | ((clk.dsp_on & 0x7ff) << 16); | ||
1819 | /*aty_calc_pll_ct(info, &pll->ct);*/ | 1906 | /*aty_calc_pll_ct(info, &pll->ct);*/ |
1820 | aty_set_pll_ct(info, pll); | 1907 | aty_set_pll_ct(info, pll); |
1821 | } else | 1908 | } else |
@@ -1886,8 +1973,7 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
1886 | continue; | 1973 | continue; |
1887 | 1974 | ||
1888 | map_size = par->mmap_map[i].size - (offset - start); | 1975 | map_size = par->mmap_map[i].size - (offset - start); |
1889 | map_offset = | 1976 | map_offset = par->mmap_map[i].poff + (offset - start); |
1890 | par->mmap_map[i].poff + (offset - start); | ||
1891 | break; | 1977 | break; |
1892 | } | 1978 | } |
1893 | if (!map_size) { | 1979 | if (!map_size) { |
@@ -1897,8 +1983,7 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
1897 | if (page + map_size > size) | 1983 | if (page + map_size > size) |
1898 | map_size = size - page; | 1984 | map_size = size - page; |
1899 | 1985 | ||
1900 | pgprot_val(vma->vm_page_prot) &= | 1986 | pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask); |
1901 | ~(par->mmap_map[i].prot_mask); | ||
1902 | pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; | 1987 | pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; |
1903 | 1988 | ||
1904 | if (remap_pfn_range(vma, vma->vm_start + page, | 1989 | if (remap_pfn_range(vma, vma->vm_start + page, |
@@ -2002,7 +2087,8 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2002 | par->asleep = 1; | 2087 | par->asleep = 1; |
2003 | par->lock_blank = 1; | 2088 | par->lock_blank = 1; |
2004 | 2089 | ||
2005 | /* Because we may change PCI D state ourselves, we need to | 2090 | /* |
2091 | * Because we may change PCI D state ourselves, we need to | ||
2006 | * first save the config space content so the core can | 2092 | * first save the config space content so the core can |
2007 | * restore it properly on resume. | 2093 | * restore it properly on resume. |
2008 | */ | 2094 | */ |
@@ -2053,7 +2139,8 @@ static int atyfb_pci_resume(struct pci_dev *pdev) | |||
2053 | 2139 | ||
2054 | acquire_console_sem(); | 2140 | acquire_console_sem(); |
2055 | 2141 | ||
2056 | /* PCI state will have been restored by the core, so | 2142 | /* |
2143 | * PCI state will have been restored by the core, so | ||
2057 | * we should be in D0 now with our config space fully | 2144 | * we should be in D0 now with our config space fully |
2058 | * restored | 2145 | * restored |
2059 | */ | 2146 | */ |
@@ -2165,8 +2252,8 @@ static void aty_bl_init(struct atyfb_par *par) | |||
2165 | 2252 | ||
2166 | info->bl_dev = bd; | 2253 | info->bl_dev = bd; |
2167 | fb_bl_default_curve(info, 0, | 2254 | fb_bl_default_curve(info, 0, |
2168 | 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, | 2255 | 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, |
2169 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); | 2256 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); |
2170 | 2257 | ||
2171 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | 2258 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; |
2172 | bd->props.brightness = bd->props.max_brightness; | 2259 | bd->props.brightness = bd->props.max_brightness; |
@@ -2201,7 +2288,7 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) | |||
2201 | const int *refresh_tbl; | 2288 | const int *refresh_tbl; |
2202 | int i, size; | 2289 | int i, size; |
2203 | 2290 | ||
2204 | if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { | 2291 | if (M64_HAS(XL_MEM)) { |
2205 | refresh_tbl = ragexl_tbl; | 2292 | refresh_tbl = ragexl_tbl; |
2206 | size = ARRAY_SIZE(ragexl_tbl); | 2293 | size = ARRAY_SIZE(ragexl_tbl); |
2207 | } else { | 2294 | } else { |
@@ -2209,16 +2296,16 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) | |||
2209 | size = ARRAY_SIZE(ragepro_tbl); | 2296 | size = ARRAY_SIZE(ragepro_tbl); |
2210 | } | 2297 | } |
2211 | 2298 | ||
2212 | for (i=0; i < size; i++) { | 2299 | for (i = 0; i < size; i++) { |
2213 | if (xclk < refresh_tbl[i]) | 2300 | if (xclk < refresh_tbl[i]) |
2214 | break; | 2301 | break; |
2215 | } | 2302 | } |
2216 | par->mem_refresh_rate = i; | 2303 | par->mem_refresh_rate = i; |
2217 | } | 2304 | } |
2218 | 2305 | ||
2219 | /* | 2306 | /* |
2220 | * Initialisation | 2307 | * Initialisation |
2221 | */ | 2308 | */ |
2222 | 2309 | ||
2223 | static struct fb_info *fb_list = NULL; | 2310 | static struct fb_info *fb_list = NULL; |
2224 | 2311 | ||
@@ -2335,7 +2422,10 @@ static int __devinit aty_init(struct fb_info *info) | |||
2335 | par->pll_ops = &aty_pll_ct; | 2422 | par->pll_ops = &aty_pll_ct; |
2336 | par->bus_type = PCI; | 2423 | par->bus_type = PCI; |
2337 | par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); | 2424 | par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); |
2338 | ramname = aty_ct_ram[par->ram_type]; | 2425 | if (M64_HAS(XL_MEM)) |
2426 | ramname = aty_xl_ram[par->ram_type]; | ||
2427 | else | ||
2428 | ramname = aty_ct_ram[par->ram_type]; | ||
2339 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ | 2429 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ |
2340 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) | 2430 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) |
2341 | par->pll_limits.mclk = 63; | 2431 | par->pll_limits.mclk = 63; |
@@ -2345,8 +2435,10 @@ static int __devinit aty_init(struct fb_info *info) | |||
2345 | } | 2435 | } |
2346 | #endif | 2436 | #endif |
2347 | #ifdef CONFIG_PPC_PMAC | 2437 | #ifdef CONFIG_PPC_PMAC |
2348 | /* The Apple iBook1 uses non-standard memory frequencies. We detect it | 2438 | /* |
2349 | * and set the frequency manually. */ | 2439 | * The Apple iBook1 uses non-standard memory frequencies. |
2440 | * We detect it and set the frequency manually. | ||
2441 | */ | ||
2350 | if (machine_is_compatible("PowerBook2,1")) { | 2442 | if (machine_is_compatible("PowerBook2,1")) { |
2351 | par->pll_limits.mclk = 70; | 2443 | par->pll_limits.mclk = 70; |
2352 | par->pll_limits.xclk = 53; | 2444 | par->pll_limits.xclk = 53; |
@@ -2390,14 +2482,15 @@ static int __devinit aty_init(struct fb_info *info) | |||
2390 | #endif /* CONFIG_FB_ATY_CT */ | 2482 | #endif /* CONFIG_FB_ATY_CT */ |
2391 | 2483 | ||
2392 | /* save previous video mode */ | 2484 | /* save previous video mode */ |
2393 | aty_get_crtc(par, &saved_crtc); | 2485 | aty_get_crtc(par, &par->saved_crtc); |
2394 | if(par->pll_ops->get_pll) | 2486 | if (par->pll_ops->get_pll) |
2395 | par->pll_ops->get_pll(info, &saved_pll); | 2487 | par->pll_ops->get_pll(info, &par->saved_pll); |
2396 | 2488 | ||
2397 | par->mem_cntl = aty_ld_le32(MEM_CNTL, par); | 2489 | par->mem_cntl = aty_ld_le32(MEM_CNTL, par); |
2398 | gtb_memsize = M64_HAS(GTB_DSP); | 2490 | gtb_memsize = M64_HAS(GTB_DSP); |
2399 | if (gtb_memsize) | 2491 | if (gtb_memsize) |
2400 | switch (par->mem_cntl & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ | 2492 | /* 0xF used instead of MEM_SIZE_ALIAS */ |
2493 | switch (par->mem_cntl & 0xF) { | ||
2401 | case MEM_SIZE_512K: | 2494 | case MEM_SIZE_512K: |
2402 | info->fix.smem_len = 0x80000; | 2495 | info->fix.smem_len = 0x80000; |
2403 | break; | 2496 | break; |
@@ -2466,8 +2559,8 @@ static int __devinit aty_init(struct fb_info *info) | |||
2466 | } | 2559 | } |
2467 | 2560 | ||
2468 | /* | 2561 | /* |
2469 | * Reg Block 0 (CT-compatible block) is at mmio_start | 2562 | * Reg Block 0 (CT-compatible block) is at mmio_start |
2470 | * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400 | 2563 | * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400 |
2471 | */ | 2564 | */ |
2472 | if (M64_HAS(GX)) { | 2565 | if (M64_HAS(GX)) { |
2473 | info->fix.mmio_len = 0x400; | 2566 | info->fix.mmio_len = 0x400; |
@@ -2486,84 +2579,98 @@ static int __devinit aty_init(struct fb_info *info) | |||
2486 | } | 2579 | } |
2487 | 2580 | ||
2488 | PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n", | 2581 | PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n", |
2489 | info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20), | 2582 | info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len>>20), |
2490 | info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max, | 2583 | info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, |
2491 | par->pll_limits.mclk, par->pll_limits.xclk); | 2584 | par->pll_limits.pll_max, par->pll_limits.mclk, |
2585 | par->pll_limits.xclk); | ||
2492 | 2586 | ||
2493 | #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) | 2587 | #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) |
2494 | if (M64_HAS(INTEGRATED)) { | 2588 | if (M64_HAS(INTEGRATED)) { |
2495 | int i; | 2589 | int i; |
2496 | printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL " | 2590 | printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL " |
2497 | "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n" | 2591 | "EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG " |
2498 | "debug atyfb: %08x %08x %08x %08x %08x %08x %08x %08x\n" | 2592 | "DSP_ON_OFF CLOCK_CNTL\n" |
2593 | "debug atyfb: %08x %08x %08x " | ||
2594 | "%08x %08x %08x " | ||
2595 | "%08x %08x\n" | ||
2499 | "debug atyfb: PLL", | 2596 | "debug atyfb: PLL", |
2500 | aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par), | 2597 | aty_ld_le32(BUS_CNTL, par), |
2501 | aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par), | 2598 | aty_ld_le32(DAC_CNTL, par), |
2502 | aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par), | 2599 | aty_ld_le32(MEM_CNTL, par), |
2503 | aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par)); | 2600 | aty_ld_le32(EXT_MEM_CNTL, par), |
2601 | aty_ld_le32(CRTC_GEN_CNTL, par), | ||
2602 | aty_ld_le32(DSP_CONFIG, par), | ||
2603 | aty_ld_le32(DSP_ON_OFF, par), | ||
2604 | aty_ld_le32(CLOCK_CNTL, par)); | ||
2504 | for (i = 0; i < 40; i++) | 2605 | for (i = 0; i < 40; i++) |
2505 | printk(" %02x", aty_ld_pll_ct(i, par)); | 2606 | printk(" %02x", aty_ld_pll_ct(i, par)); |
2506 | printk("\n"); | 2607 | printk("\n"); |
2507 | } | 2608 | } |
2508 | #endif | 2609 | #endif |
2509 | if(par->pll_ops->init_pll) | 2610 | if (par->pll_ops->init_pll) |
2510 | par->pll_ops->init_pll(info, &par->pll); | 2611 | par->pll_ops->init_pll(info, &par->pll); |
2511 | if (par->pll_ops->resume_pll) | 2612 | if (par->pll_ops->resume_pll) |
2512 | par->pll_ops->resume_pll(info, &par->pll); | 2613 | par->pll_ops->resume_pll(info, &par->pll); |
2513 | 2614 | ||
2514 | /* | 2615 | /* |
2515 | * Last page of 8 MB (4 MB on ISA) aperture is MMIO, | 2616 | * Last page of 8 MB (4 MB on ISA) aperture is MMIO, |
2516 | * unless the auxiliary register aperture is used. | 2617 | * unless the auxiliary register aperture is used. |
2517 | */ | 2618 | */ |
2518 | |||
2519 | if (!par->aux_start && | 2619 | if (!par->aux_start && |
2520 | (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000))) | 2620 | (info->fix.smem_len == 0x800000 || |
2621 | (par->bus_type == ISA && info->fix.smem_len == 0x400000))) | ||
2521 | info->fix.smem_len -= GUI_RESERVE; | 2622 | info->fix.smem_len -= GUI_RESERVE; |
2522 | 2623 | ||
2523 | /* | 2624 | /* |
2524 | * Disable register access through the linear aperture | 2625 | * Disable register access through the linear aperture |
2525 | * if the auxiliary aperture is used so we can access | 2626 | * if the auxiliary aperture is used so we can access |
2526 | * the full 8 MB of video RAM on 8 MB boards. | 2627 | * the full 8 MB of video RAM on 8 MB boards. |
2527 | */ | 2628 | */ |
2528 | if (par->aux_start) | 2629 | if (par->aux_start) |
2529 | aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par); | 2630 | aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | |
2631 | BUS_APER_REG_DIS, par); | ||
2530 | 2632 | ||
2531 | #ifdef CONFIG_MTRR | 2633 | #ifdef CONFIG_MTRR |
2532 | par->mtrr_aper = -1; | 2634 | par->mtrr_aper = -1; |
2533 | par->mtrr_reg = -1; | 2635 | par->mtrr_reg = -1; |
2534 | if (!nomtrr) { | 2636 | if (!nomtrr) { |
2535 | /* Cover the whole resource. */ | 2637 | /* Cover the whole resource. */ |
2536 | par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1); | 2638 | par->mtrr_aper = mtrr_add(par->res_start, par->res_size, |
2537 | if (par->mtrr_aper >= 0 && !par->aux_start) { | 2639 | MTRR_TYPE_WRCOMB, 1); |
2640 | if (par->mtrr_aper >= 0 && !par->aux_start) { | ||
2538 | /* Make a hole for mmio. */ | 2641 | /* Make a hole for mmio. */ |
2539 | par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE, | 2642 | par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - |
2540 | GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1); | 2643 | GUI_RESERVE, GUI_RESERVE, |
2644 | MTRR_TYPE_UNCACHABLE, 1); | ||
2541 | if (par->mtrr_reg < 0) { | 2645 | if (par->mtrr_reg < 0) { |
2542 | mtrr_del(par->mtrr_aper, 0, 0); | 2646 | mtrr_del(par->mtrr_aper, 0, 0); |
2543 | par->mtrr_aper = -1; | 2647 | par->mtrr_aper = -1; |
2544 | } | 2648 | } |
2545 | } | 2649 | } |
2546 | } | 2650 | } |
2547 | #endif | 2651 | #endif |
2548 | 2652 | ||
2549 | info->fbops = &atyfb_ops; | 2653 | info->fbops = &atyfb_ops; |
2550 | info->pseudo_palette = par->pseudo_palette; | 2654 | info->pseudo_palette = par->pseudo_palette; |
2551 | info->flags = FBINFO_DEFAULT | | 2655 | info->flags = FBINFO_DEFAULT | |
2552 | FBINFO_HWACCEL_IMAGEBLIT | | 2656 | FBINFO_HWACCEL_IMAGEBLIT | |
2553 | FBINFO_HWACCEL_FILLRECT | | 2657 | FBINFO_HWACCEL_FILLRECT | |
2554 | FBINFO_HWACCEL_COPYAREA | | 2658 | FBINFO_HWACCEL_COPYAREA | |
2555 | FBINFO_HWACCEL_YPAN; | 2659 | FBINFO_HWACCEL_YPAN; |
2556 | 2660 | ||
2557 | #ifdef CONFIG_PMAC_BACKLIGHT | 2661 | #ifdef CONFIG_PMAC_BACKLIGHT |
2558 | if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { | 2662 | if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { |
2559 | /* these bits let the 101 powerbook wake up from sleep -- paulus */ | 2663 | /* |
2560 | aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) | 2664 | * these bits let the 101 powerbook |
2561 | | (USE_F32KHZ | TRISTATE_MEM_EN), par); | 2665 | * wake up from sleep -- paulus |
2666 | */ | ||
2667 | aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) | | ||
2668 | USE_F32KHZ | TRISTATE_MEM_EN, par); | ||
2562 | } else | 2669 | } else |
2563 | #endif | 2670 | #endif |
2564 | if (M64_HAS(MOBIL_BUS) && backlight) { | 2671 | if (M64_HAS(MOBIL_BUS) && backlight) { |
2565 | #ifdef CONFIG_FB_ATY_BACKLIGHT | 2672 | #ifdef CONFIG_FB_ATY_BACKLIGHT |
2566 | aty_bl_init (par); | 2673 | aty_bl_init(par); |
2567 | #endif | 2674 | #endif |
2568 | } | 2675 | } |
2569 | 2676 | ||
@@ -2571,8 +2678,8 @@ static int __devinit aty_init(struct fb_info *info) | |||
2571 | #ifdef CONFIG_PPC | 2678 | #ifdef CONFIG_PPC |
2572 | if (machine_is(powermac)) { | 2679 | if (machine_is(powermac)) { |
2573 | /* | 2680 | /* |
2574 | * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it | 2681 | * FIXME: The NVRAM stuff should be put in a Mac-specific file, |
2575 | * applies to all Mac video cards | 2682 | * as it applies to all Mac video cards |
2576 | */ | 2683 | */ |
2577 | if (mode) { | 2684 | if (mode) { |
2578 | if (mac_find_mode(&var, info, mode, 8)) | 2685 | if (mac_find_mode(&var, info, mode, 8)) |
@@ -2585,8 +2692,7 @@ static int __devinit aty_init(struct fb_info *info) | |||
2585 | default_vmode = VMODE_1024_768_60; | 2692 | default_vmode = VMODE_1024_768_60; |
2586 | else if (machine_is_compatible("iMac")) | 2693 | else if (machine_is_compatible("iMac")) |
2587 | default_vmode = VMODE_1024_768_75; | 2694 | default_vmode = VMODE_1024_768_75; |
2588 | else if (machine_is_compatible | 2695 | else if (machine_is_compatible("PowerBook2,1")) |
2589 | ("PowerBook2,1")) | ||
2590 | /* iBook with 800x600 LCD */ | 2696 | /* iBook with 800x600 LCD */ |
2591 | default_vmode = VMODE_800_600_60; | 2697 | default_vmode = VMODE_800_600_60; |
2592 | else | 2698 | else |
@@ -2600,7 +2706,7 @@ static int __devinit aty_init(struct fb_info *info) | |||
2600 | if (default_cmode < CMODE_8 || default_cmode > CMODE_32) | 2706 | if (default_cmode < CMODE_8 || default_cmode > CMODE_32) |
2601 | default_cmode = CMODE_8; | 2707 | default_cmode = CMODE_8; |
2602 | if (!mac_vmode_to_var(default_vmode, default_cmode, | 2708 | if (!mac_vmode_to_var(default_vmode, default_cmode, |
2603 | &var)) | 2709 | &var)) |
2604 | has_var = 1; | 2710 | has_var = 1; |
2605 | } | 2711 | } |
2606 | } | 2712 | } |
@@ -2667,17 +2773,17 @@ static int __devinit aty_init(struct fb_info *info) | |||
2667 | 2773 | ||
2668 | aty_init_exit: | 2774 | aty_init_exit: |
2669 | /* restore video mode */ | 2775 | /* restore video mode */ |
2670 | aty_set_crtc(par, &saved_crtc); | 2776 | aty_set_crtc(par, &par->saved_crtc); |
2671 | par->pll_ops->set_pll(info, &saved_pll); | 2777 | par->pll_ops->set_pll(info, &par->saved_pll); |
2672 | 2778 | ||
2673 | #ifdef CONFIG_MTRR | 2779 | #ifdef CONFIG_MTRR |
2674 | if (par->mtrr_reg >= 0) { | 2780 | if (par->mtrr_reg >= 0) { |
2675 | mtrr_del(par->mtrr_reg, 0, 0); | 2781 | mtrr_del(par->mtrr_reg, 0, 0); |
2676 | par->mtrr_reg = -1; | 2782 | par->mtrr_reg = -1; |
2677 | } | 2783 | } |
2678 | if (par->mtrr_aper >= 0) { | 2784 | if (par->mtrr_aper >= 0) { |
2679 | mtrr_del(par->mtrr_aper, 0, 0); | 2785 | mtrr_del(par->mtrr_aper, 0, 0); |
2680 | par->mtrr_aper = -1; | 2786 | par->mtrr_aper = -1; |
2681 | } | 2787 | } |
2682 | #endif | 2788 | #endif |
2683 | return ret; | 2789 | return ret; |
@@ -2705,18 +2811,18 @@ static int __devinit store_video_par(char *video_str, unsigned char m64_num) | |||
2705 | phys_size[m64_num] = size; | 2811 | phys_size[m64_num] = size; |
2706 | phys_guiregbase[m64_num] = guiregbase; | 2812 | phys_guiregbase[m64_num] = guiregbase; |
2707 | PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size, | 2813 | PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size, |
2708 | guiregbase); | 2814 | guiregbase); |
2709 | return 0; | 2815 | return 0; |
2710 | 2816 | ||
2711 | mach64_invalid: | 2817 | mach64_invalid: |
2712 | phys_vmembase[m64_num] = 0; | 2818 | phys_vmembase[m64_num] = 0; |
2713 | return -1; | 2819 | return -1; |
2714 | } | 2820 | } |
2715 | #endif /* CONFIG_ATARI */ | 2821 | #endif /* CONFIG_ATARI */ |
2716 | 2822 | ||
2717 | /* | 2823 | /* |
2718 | * Blank the display. | 2824 | * Blank the display. |
2719 | */ | 2825 | */ |
2720 | 2826 | ||
2721 | static int atyfb_blank(int blank, struct fb_info *info) | 2827 | static int atyfb_blank(int blank, struct fb_info *info) |
2722 | { | 2828 | { |
@@ -2738,20 +2844,20 @@ static int atyfb_blank(int blank, struct fb_info *info) | |||
2738 | gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); | 2844 | gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); |
2739 | gen_cntl &= ~0x400004c; | 2845 | gen_cntl &= ~0x400004c; |
2740 | switch (blank) { | 2846 | switch (blank) { |
2741 | case FB_BLANK_UNBLANK: | 2847 | case FB_BLANK_UNBLANK: |
2742 | break; | 2848 | break; |
2743 | case FB_BLANK_NORMAL: | 2849 | case FB_BLANK_NORMAL: |
2744 | gen_cntl |= 0x4000040; | 2850 | gen_cntl |= 0x4000040; |
2745 | break; | 2851 | break; |
2746 | case FB_BLANK_VSYNC_SUSPEND: | 2852 | case FB_BLANK_VSYNC_SUSPEND: |
2747 | gen_cntl |= 0x4000048; | 2853 | gen_cntl |= 0x4000048; |
2748 | break; | 2854 | break; |
2749 | case FB_BLANK_HSYNC_SUSPEND: | 2855 | case FB_BLANK_HSYNC_SUSPEND: |
2750 | gen_cntl |= 0x4000044; | 2856 | gen_cntl |= 0x4000044; |
2751 | break; | 2857 | break; |
2752 | case FB_BLANK_POWERDOWN: | 2858 | case FB_BLANK_POWERDOWN: |
2753 | gen_cntl |= 0x400004c; | 2859 | gen_cntl |= 0x400004c; |
2754 | break; | 2860 | break; |
2755 | } | 2861 | } |
2756 | aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); | 2862 | aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); |
2757 | 2863 | ||
@@ -2776,15 +2882,15 @@ static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue, | |||
2776 | aty_st_8(DAC_DATA, blue, par); | 2882 | aty_st_8(DAC_DATA, blue, par); |
2777 | } | 2883 | } |
2778 | 2884 | ||
2779 | /* | 2885 | /* |
2780 | * Set a single color register. The values supplied are already | 2886 | * Set a single color register. The values supplied are already |
2781 | * rounded down to the hardware's capabilities (according to the | 2887 | * rounded down to the hardware's capabilities (according to the |
2782 | * entries in the var structure). Return != 0 for invalid regno. | 2888 | * entries in the var structure). Return != 0 for invalid regno. |
2783 | * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR | 2889 | * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR |
2784 | */ | 2890 | */ |
2785 | 2891 | ||
2786 | static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | 2892 | static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, |
2787 | u_int transp, struct fb_info *info) | 2893 | u_int transp, struct fb_info *info) |
2788 | { | 2894 | { |
2789 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 2895 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
2790 | int i, depth; | 2896 | int i, depth; |
@@ -2838,16 +2944,15 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
2838 | if (depth == 16) { | 2944 | if (depth == 16) { |
2839 | if (regno < 32) | 2945 | if (regno < 32) |
2840 | aty_st_pal(regno << 3, red, | 2946 | aty_st_pal(regno << 3, red, |
2841 | par->palette[regno<<1].green, | 2947 | par->palette[regno << 1].green, |
2842 | blue, par); | 2948 | blue, par); |
2843 | red = par->palette[regno>>1].red; | 2949 | red = par->palette[regno >> 1].red; |
2844 | blue = par->palette[regno>>1].blue; | 2950 | blue = par->palette[regno >> 1].blue; |
2845 | regno <<= 2; | 2951 | regno <<= 2; |
2846 | } else if (depth == 15) { | 2952 | } else if (depth == 15) { |
2847 | regno <<= 3; | 2953 | regno <<= 3; |
2848 | for(i = 0; i < 8; i++) { | 2954 | for (i = 0; i < 8; i++) |
2849 | aty_st_pal(regno + i, red, green, blue, par); | 2955 | aty_st_pal(regno + i, red, green, blue, par); |
2850 | } | ||
2851 | } | 2956 | } |
2852 | } | 2957 | } |
2853 | aty_st_pal(regno, red, green, blue, par); | 2958 | aty_st_pal(regno, red, green, blue, par); |
@@ -2860,7 +2965,8 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
2860 | #ifdef __sparc__ | 2965 | #ifdef __sparc__ |
2861 | 2966 | ||
2862 | static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, | 2967 | static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, |
2863 | struct fb_info *info, unsigned long addr) | 2968 | struct fb_info *info, |
2969 | unsigned long addr) | ||
2864 | { | 2970 | { |
2865 | struct atyfb_par *par = info->par; | 2971 | struct atyfb_par *par = info->par; |
2866 | struct device_node *dp; | 2972 | struct device_node *dp; |
@@ -2948,7 +3054,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, | |||
2948 | j++; | 3054 | j++; |
2949 | } | 3055 | } |
2950 | 3056 | ||
2951 | if((ret = correct_chipset(par))) | 3057 | ret = correct_chipset(par); |
3058 | if (ret) | ||
2952 | return ret; | 3059 | return ret; |
2953 | 3060 | ||
2954 | if (IS_XL(pdev->device)) { | 3061 | if (IS_XL(pdev->device)) { |
@@ -3078,28 +3185,28 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) | |||
3078 | u32 driv_inf_tab, sig; | 3185 | u32 driv_inf_tab, sig; |
3079 | u16 lcd_ofs; | 3186 | u16 lcd_ofs; |
3080 | 3187 | ||
3081 | /* To support an LCD panel, we should know it's dimensions and | 3188 | /* |
3189 | * To support an LCD panel, we should know it's dimensions and | ||
3082 | * it's desired pixel clock. | 3190 | * it's desired pixel clock. |
3083 | * There are two ways to do it: | 3191 | * There are two ways to do it: |
3084 | * - Check the startup video mode and calculate the panel | 3192 | * - Check the startup video mode and calculate the panel |
3085 | * size from it. This is unreliable. | 3193 | * size from it. This is unreliable. |
3086 | * - Read it from the driver information table in the video BIOS. | 3194 | * - Read it from the driver information table in the video BIOS. |
3087 | */ | 3195 | */ |
3088 | /* Address of driver information table is at offset 0x78. */ | 3196 | /* Address of driver information table is at offset 0x78. */ |
3089 | driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78)); | 3197 | driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78)); |
3090 | 3198 | ||
3091 | /* Check for the driver information table signature. */ | 3199 | /* Check for the driver information table signature. */ |
3092 | sig = (*(u32 *)driv_inf_tab); | 3200 | sig = *(u32 *)driv_inf_tab; |
3093 | if ((sig == 0x54504c24) || /* Rage LT pro */ | 3201 | if ((sig == 0x54504c24) || /* Rage LT pro */ |
3094 | (sig == 0x544d5224) || /* Rage mobility */ | 3202 | (sig == 0x544d5224) || /* Rage mobility */ |
3095 | (sig == 0x54435824) || /* Rage XC */ | 3203 | (sig == 0x54435824) || /* Rage XC */ |
3096 | (sig == 0x544c5824)) { /* Rage XL */ | 3204 | (sig == 0x544c5824)) { /* Rage XL */ |
3097 | PRINTKI("BIOS contains driver information table.\n"); | 3205 | PRINTKI("BIOS contains driver information table.\n"); |
3098 | lcd_ofs = (*(u16 *)(driv_inf_tab + 10)); | 3206 | lcd_ofs = *(u16 *)(driv_inf_tab + 10); |
3099 | par->lcd_table = 0; | 3207 | par->lcd_table = 0; |
3100 | if (lcd_ofs != 0) { | 3208 | if (lcd_ofs != 0) |
3101 | par->lcd_table = bios_base + lcd_ofs; | 3209 | par->lcd_table = bios_base + lcd_ofs; |
3102 | } | ||
3103 | } | 3210 | } |
3104 | 3211 | ||
3105 | if (par->lcd_table != 0) { | 3212 | if (par->lcd_table != 0) { |
@@ -3114,14 +3221,16 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) | |||
3114 | u16 width, height, panel_type, refresh_rates; | 3221 | u16 width, height, panel_type, refresh_rates; |
3115 | u16 *lcdmodeptr; | 3222 | u16 *lcdmodeptr; |
3116 | u32 format; | 3223 | u32 format; |
3117 | u8 lcd_refresh_rates[16] = {50,56,60,67,70,72,75,76,85,90,100,120,140,150,160,200}; | 3224 | u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85, |
3118 | /* The most important information is the panel size at | 3225 | 90, 100, 120, 140, 150, 160, 200 }; |
3226 | /* | ||
3227 | * The most important information is the panel size at | ||
3119 | * offset 25 and 27, but there's some other nice information | 3228 | * offset 25 and 27, but there's some other nice information |
3120 | * which we print to the screen. | 3229 | * which we print to the screen. |
3121 | */ | 3230 | */ |
3122 | id = *(u8 *)par->lcd_table; | 3231 | id = *(u8 *)par->lcd_table; |
3123 | strncpy(model,(char *)par->lcd_table+1,24); | 3232 | strncpy(model, (char *)par->lcd_table+1, 24); |
3124 | model[23]=0; | 3233 | model[23] = 0; |
3125 | 3234 | ||
3126 | width = par->lcd_width = *(u16 *)(par->lcd_table+25); | 3235 | width = par->lcd_width = *(u16 *)(par->lcd_table+25); |
3127 | height = par->lcd_height = *(u16 *)(par->lcd_table+27); | 3236 | height = par->lcd_height = *(u16 *)(par->lcd_table+27); |
@@ -3134,7 +3243,7 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) | |||
3134 | txtdual = "dual (split) "; | 3243 | txtdual = "dual (split) "; |
3135 | else | 3244 | else |
3136 | txtdual = ""; | 3245 | txtdual = ""; |
3137 | tech = (panel_type>>2) & 63; | 3246 | tech = (panel_type >> 2) & 63; |
3138 | switch (tech) { | 3247 | switch (tech) { |
3139 | case 0: | 3248 | case 0: |
3140 | txtmonitor = "passive matrix"; | 3249 | txtmonitor = "passive matrix"; |
@@ -3194,22 +3303,24 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) | |||
3194 | } | 3303 | } |
3195 | } | 3304 | } |
3196 | PRINTKI("%s%s %s monitor detected: %s\n", | 3305 | PRINTKI("%s%s %s monitor detected: %s\n", |
3197 | txtdual ,txtcolour, txtmonitor, model); | 3306 | txtdual, txtcolour, txtmonitor, model); |
3198 | PRINTKI(" id=%d, %dx%d pixels, %s\n", | 3307 | PRINTKI(" id=%d, %dx%d pixels, %s\n", |
3199 | id, width, height, txtformat); | 3308 | id, width, height, txtformat); |
3200 | refresh_rates_buf[0] = 0; | 3309 | refresh_rates_buf[0] = 0; |
3201 | refresh_rates = *(u16 *)(par->lcd_table+62); | 3310 | refresh_rates = *(u16 *)(par->lcd_table+62); |
3202 | m = 1; | 3311 | m = 1; |
3203 | f = 0; | 3312 | f = 0; |
3204 | for (i=0;i<16;i++) { | 3313 | for (i = 0; i < 16; i++) { |
3205 | if (refresh_rates & m) { | 3314 | if (refresh_rates & m) { |
3206 | if (f == 0) { | 3315 | if (f == 0) { |
3207 | sprintf(strbuf, "%d", lcd_refresh_rates[i]); | 3316 | sprintf(strbuf, "%d", |
3317 | lcd_refresh_rates[i]); | ||
3208 | f++; | 3318 | f++; |
3209 | } else { | 3319 | } else { |
3210 | sprintf(strbuf, ",%d", lcd_refresh_rates[i]); | 3320 | sprintf(strbuf, ",%d", |
3321 | lcd_refresh_rates[i]); | ||
3211 | } | 3322 | } |
3212 | strcat(refresh_rates_buf,strbuf); | 3323 | strcat(refresh_rates_buf, strbuf); |
3213 | } | 3324 | } |
3214 | m = m << 1; | 3325 | m = m << 1; |
3215 | } | 3326 | } |
@@ -3217,7 +3328,8 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) | |||
3217 | PRINTKI(" supports refresh rates [%s], default %d Hz\n", | 3328 | PRINTKI(" supports refresh rates [%s], default %d Hz\n", |
3218 | refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); | 3329 | refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); |
3219 | par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; | 3330 | par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; |
3220 | /* We now need to determine the crtc parameters for the | 3331 | /* |
3332 | * We now need to determine the crtc parameters for the | ||
3221 | * LCD monitor. This is tricky, because they are not stored | 3333 | * LCD monitor. This is tricky, because they are not stored |
3222 | * individually in the BIOS. Instead, the BIOS contains a | 3334 | * individually in the BIOS. Instead, the BIOS contains a |
3223 | * table of display modes that work for this monitor. | 3335 | * table of display modes that work for this monitor. |
@@ -3352,7 +3464,9 @@ static int __devinit init_from_bios(struct atyfb_par *par) | |||
3352 | } | 3464 | } |
3353 | #endif /* __i386__ */ | 3465 | #endif /* __i386__ */ |
3354 | 3466 | ||
3355 | static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr) | 3467 | static int __devinit atyfb_setup_generic(struct pci_dev *pdev, |
3468 | struct fb_info *info, | ||
3469 | unsigned long addr) | ||
3356 | { | 3470 | { |
3357 | struct atyfb_par *par = info->par; | 3471 | struct atyfb_par *par = info->par; |
3358 | u16 tmp; | 3472 | u16 tmp; |
@@ -3399,10 +3513,12 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *i | |||
3399 | goto atyfb_setup_generic_fail; | 3513 | goto atyfb_setup_generic_fail; |
3400 | } | 3514 | } |
3401 | 3515 | ||
3402 | if((ret = correct_chipset(par))) | 3516 | ret = correct_chipset(par); |
3517 | if (ret) | ||
3403 | goto atyfb_setup_generic_fail; | 3518 | goto atyfb_setup_generic_fail; |
3404 | #ifdef __i386__ | 3519 | #ifdef __i386__ |
3405 | if((ret = init_from_bios(par))) | 3520 | ret = init_from_bios(par); |
3521 | if (ret) | ||
3406 | goto atyfb_setup_generic_fail; | 3522 | goto atyfb_setup_generic_fail; |
3407 | #endif | 3523 | #endif |
3408 | if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN)) | 3524 | if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN)) |
@@ -3427,7 +3543,8 @@ atyfb_setup_generic_fail: | |||
3427 | 3543 | ||
3428 | #endif /* !__sparc__ */ | 3544 | #endif /* !__sparc__ */ |
3429 | 3545 | ||
3430 | static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3546 | static int __devinit atyfb_pci_probe(struct pci_dev *pdev, |
3547 | const struct pci_device_id *ent) | ||
3431 | { | 3548 | { |
3432 | unsigned long addr, res_start, res_size; | 3549 | unsigned long addr, res_start, res_size; |
3433 | struct fb_info *info; | 3550 | struct fb_info *info; |
@@ -3452,10 +3569,10 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi | |||
3452 | /* Reserve space */ | 3569 | /* Reserve space */ |
3453 | res_start = rp->start; | 3570 | res_start = rp->start; |
3454 | res_size = rp->end - rp->start + 1; | 3571 | res_size = rp->end - rp->start + 1; |
3455 | if (!request_mem_region (res_start, res_size, "atyfb")) | 3572 | if (!request_mem_region(res_start, res_size, "atyfb")) |
3456 | return -EBUSY; | 3573 | return -EBUSY; |
3457 | 3574 | ||
3458 | /* Allocate framebuffer */ | 3575 | /* Allocate framebuffer */ |
3459 | info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev); | 3576 | info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev); |
3460 | if (!info) { | 3577 | if (!info) { |
3461 | PRINTKE("atyfb_pci_probe() can't alloc fb_info\n"); | 3578 | PRINTKE("atyfb_pci_probe() can't alloc fb_info\n"); |
@@ -3502,6 +3619,11 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi | |||
3502 | par->mmap_map[1].prot_flag = _PAGE_E; | 3619 | par->mmap_map[1].prot_flag = _PAGE_E; |
3503 | #endif /* __sparc__ */ | 3620 | #endif /* __sparc__ */ |
3504 | 3621 | ||
3622 | mutex_lock(&reboot_lock); | ||
3623 | if (!reboot_info) | ||
3624 | reboot_info = info; | ||
3625 | mutex_unlock(&reboot_lock); | ||
3626 | |||
3505 | return 0; | 3627 | return 0; |
3506 | 3628 | ||
3507 | err_release_io: | 3629 | err_release_io: |
@@ -3538,7 +3660,8 @@ static int __init atyfb_atari_probe(void) | |||
3538 | for (m64_num = 0; m64_num < mach64_count; m64_num++) { | 3660 | for (m64_num = 0; m64_num < mach64_count; m64_num++) { |
3539 | if (!phys_vmembase[m64_num] || !phys_size[m64_num] || | 3661 | if (!phys_vmembase[m64_num] || !phys_size[m64_num] || |
3540 | !phys_guiregbase[m64_num]) { | 3662 | !phys_guiregbase[m64_num]) { |
3541 | PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num); | 3663 | PRINTKI("phys_*[%d] parameters not set => " |
3664 | "returning early. \n", m64_num); | ||
3542 | continue; | 3665 | continue; |
3543 | } | 3666 | } |
3544 | 3667 | ||
@@ -3554,8 +3677,8 @@ static int __init atyfb_atari_probe(void) | |||
3554 | par->irq = (unsigned int) -1; /* something invalid */ | 3677 | par->irq = (unsigned int) -1; /* something invalid */ |
3555 | 3678 | ||
3556 | /* | 3679 | /* |
3557 | * Map the video memory (physical address given) to somewhere in the | 3680 | * Map the video memory (physical address given) |
3558 | * kernel address space. | 3681 | * to somewhere in the kernel address space. |
3559 | */ | 3682 | */ |
3560 | info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); | 3683 | info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); |
3561 | info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */ | 3684 | info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */ |
@@ -3614,8 +3737,8 @@ static void __devexit atyfb_remove(struct fb_info *info) | |||
3614 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 3737 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
3615 | 3738 | ||
3616 | /* restore video mode */ | 3739 | /* restore video mode */ |
3617 | aty_set_crtc(par, &saved_crtc); | 3740 | aty_set_crtc(par, &par->saved_crtc); |
3618 | par->pll_ops->set_pll(info, &saved_pll); | 3741 | par->pll_ops->set_pll(info, &par->saved_pll); |
3619 | 3742 | ||
3620 | unregister_framebuffer(info); | 3743 | unregister_framebuffer(info); |
3621 | 3744 | ||
@@ -3626,12 +3749,12 @@ static void __devexit atyfb_remove(struct fb_info *info) | |||
3626 | 3749 | ||
3627 | #ifdef CONFIG_MTRR | 3750 | #ifdef CONFIG_MTRR |
3628 | if (par->mtrr_reg >= 0) { | 3751 | if (par->mtrr_reg >= 0) { |
3629 | mtrr_del(par->mtrr_reg, 0, 0); | 3752 | mtrr_del(par->mtrr_reg, 0, 0); |
3630 | par->mtrr_reg = -1; | 3753 | par->mtrr_reg = -1; |
3631 | } | 3754 | } |
3632 | if (par->mtrr_aper >= 0) { | 3755 | if (par->mtrr_aper >= 0) { |
3633 | mtrr_del(par->mtrr_aper, 0, 0); | 3756 | mtrr_del(par->mtrr_aper, 0, 0); |
3634 | par->mtrr_aper = -1; | 3757 | par->mtrr_aper = -1; |
3635 | } | 3758 | } |
3636 | #endif | 3759 | #endif |
3637 | #ifndef __sparc__ | 3760 | #ifndef __sparc__ |
@@ -3661,6 +3784,11 @@ static void __devexit atyfb_pci_remove(struct pci_dev *pdev) | |||
3661 | { | 3784 | { |
3662 | struct fb_info *info = pci_get_drvdata(pdev); | 3785 | struct fb_info *info = pci_get_drvdata(pdev); |
3663 | 3786 | ||
3787 | mutex_lock(&reboot_lock); | ||
3788 | if (reboot_info == info) | ||
3789 | reboot_info = NULL; | ||
3790 | mutex_unlock(&reboot_lock); | ||
3791 | |||
3664 | atyfb_remove(info); | 3792 | atyfb_remove(info); |
3665 | } | 3793 | } |
3666 | 3794 | ||
@@ -3808,29 +3936,88 @@ static int __init atyfb_setup(char *options) | |||
3808 | } | 3936 | } |
3809 | #endif /* MODULE */ | 3937 | #endif /* MODULE */ |
3810 | 3938 | ||
3939 | static int atyfb_reboot_notify(struct notifier_block *nb, | ||
3940 | unsigned long code, void *unused) | ||
3941 | { | ||
3942 | struct atyfb_par *par; | ||
3943 | |||
3944 | if (code != SYS_RESTART) | ||
3945 | return NOTIFY_DONE; | ||
3946 | |||
3947 | mutex_lock(&reboot_lock); | ||
3948 | |||
3949 | if (!reboot_info) | ||
3950 | goto out; | ||
3951 | |||
3952 | if (!lock_fb_info(reboot_info)) | ||
3953 | goto out; | ||
3954 | |||
3955 | par = reboot_info->par; | ||
3956 | |||
3957 | /* | ||
3958 | * HP OmniBook 500's BIOS doesn't like the state of the | ||
3959 | * hardware after atyfb has been used. Restore the hardware | ||
3960 | * to the original state to allow successful reboots. | ||
3961 | */ | ||
3962 | aty_set_crtc(par, &par->saved_crtc); | ||
3963 | par->pll_ops->set_pll(reboot_info, &par->saved_pll); | ||
3964 | |||
3965 | unlock_fb_info(reboot_info); | ||
3966 | out: | ||
3967 | mutex_unlock(&reboot_lock); | ||
3968 | |||
3969 | return NOTIFY_DONE; | ||
3970 | } | ||
3971 | |||
3972 | static struct notifier_block atyfb_reboot_notifier = { | ||
3973 | .notifier_call = atyfb_reboot_notify, | ||
3974 | }; | ||
3975 | |||
3976 | static const struct dmi_system_id atyfb_reboot_ids[] = { | ||
3977 | { | ||
3978 | .ident = "HP OmniBook 500", | ||
3979 | .matches = { | ||
3980 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
3981 | DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"), | ||
3982 | DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"), | ||
3983 | }, | ||
3984 | }, | ||
3985 | |||
3986 | { } | ||
3987 | }; | ||
3988 | |||
3811 | static int __init atyfb_init(void) | 3989 | static int __init atyfb_init(void) |
3812 | { | 3990 | { |
3813 | int err1 = 1, err2 = 1; | 3991 | int err1 = 1, err2 = 1; |
3814 | #ifndef MODULE | 3992 | #ifndef MODULE |
3815 | char *option = NULL; | 3993 | char *option = NULL; |
3816 | 3994 | ||
3817 | if (fb_get_options("atyfb", &option)) | 3995 | if (fb_get_options("atyfb", &option)) |
3818 | return -ENODEV; | 3996 | return -ENODEV; |
3819 | atyfb_setup(option); | 3997 | atyfb_setup(option); |
3820 | #endif | 3998 | #endif |
3821 | 3999 | ||
3822 | #ifdef CONFIG_PCI | 4000 | #ifdef CONFIG_PCI |
3823 | err1 = pci_register_driver(&atyfb_driver); | 4001 | err1 = pci_register_driver(&atyfb_driver); |
3824 | #endif | 4002 | #endif |
3825 | #ifdef CONFIG_ATARI | 4003 | #ifdef CONFIG_ATARI |
3826 | err2 = atyfb_atari_probe(); | 4004 | err2 = atyfb_atari_probe(); |
3827 | #endif | 4005 | #endif |
3828 | 4006 | ||
3829 | return (err1 && err2) ? -ENODEV : 0; | 4007 | if (err1 && err2) |
4008 | return -ENODEV; | ||
4009 | |||
4010 | if (dmi_check_system(atyfb_reboot_ids)) | ||
4011 | register_reboot_notifier(&atyfb_reboot_notifier); | ||
4012 | |||
4013 | return 0; | ||
3830 | } | 4014 | } |
3831 | 4015 | ||
3832 | static void __exit atyfb_exit(void) | 4016 | static void __exit atyfb_exit(void) |
3833 | { | 4017 | { |
4018 | if (dmi_check_system(atyfb_reboot_ids)) | ||
4019 | unregister_reboot_notifier(&atyfb_reboot_notifier); | ||
4020 | |||
3834 | #ifdef CONFIG_PCI | 4021 | #ifdef CONFIG_PCI |
3835 | pci_unregister_driver(&atyfb_driver); | 4022 | pci_unregister_driver(&atyfb_driver); |
3836 | #endif | 4023 | #endif |
@@ -3852,8 +4039,7 @@ MODULE_PARM_DESC(mclk, "int: override memory clock"); | |||
3852 | module_param(xclk, int, 0); | 4039 | module_param(xclk, int, 0); |
3853 | MODULE_PARM_DESC(xclk, "int: override accelerated engine clock"); | 4040 | MODULE_PARM_DESC(xclk, "int: override accelerated engine clock"); |
3854 | module_param(comp_sync, int, 0); | 4041 | module_param(comp_sync, int, 0); |
3855 | MODULE_PARM_DESC(comp_sync, | 4042 | MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)"); |
3856 | "Set composite sync signal to low (0) or high (1)"); | ||
3857 | module_param(mode, charp, 0); | 4043 | module_param(mode, charp, 0); |
3858 | MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); | 4044 | MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); |
3859 | #ifdef CONFIG_MTRR | 4045 | #ifdef CONFIG_MTRR |
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c index 0cc9724e61a2..51fcc0a2c94a 100644 --- a/drivers/video/aty/mach64_accel.c +++ b/drivers/video/aty/mach64_accel.c | |||
@@ -63,14 +63,17 @@ static void reset_GTC_3D_engine(const struct atyfb_par *par) | |||
63 | void aty_init_engine(struct atyfb_par *par, struct fb_info *info) | 63 | void aty_init_engine(struct atyfb_par *par, struct fb_info *info) |
64 | { | 64 | { |
65 | u32 pitch_value; | 65 | u32 pitch_value; |
66 | u32 vxres; | ||
66 | 67 | ||
67 | /* determine modal information from global mode structure */ | 68 | /* determine modal information from global mode structure */ |
68 | pitch_value = info->var.xres_virtual; | 69 | pitch_value = info->fix.line_length / (info->var.bits_per_pixel / 8); |
70 | vxres = info->var.xres_virtual; | ||
69 | 71 | ||
70 | if (info->var.bits_per_pixel == 24) { | 72 | if (info->var.bits_per_pixel == 24) { |
71 | /* In 24 bpp, the engine is in 8 bpp - this requires that all */ | 73 | /* In 24 bpp, the engine is in 8 bpp - this requires that all */ |
72 | /* horizontal coordinates and widths must be adjusted */ | 74 | /* horizontal coordinates and widths must be adjusted */ |
73 | pitch_value *= 3; | 75 | pitch_value *= 3; |
76 | vxres *= 3; | ||
74 | } | 77 | } |
75 | 78 | ||
76 | /* On GTC (RagePro), we need to reset the 3D engine before */ | 79 | /* On GTC (RagePro), we need to reset the 3D engine before */ |
@@ -133,7 +136,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) | |||
133 | aty_st_le32(SC_LEFT, 0, par); | 136 | aty_st_le32(SC_LEFT, 0, par); |
134 | aty_st_le32(SC_TOP, 0, par); | 137 | aty_st_le32(SC_TOP, 0, par); |
135 | aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); | 138 | aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); |
136 | aty_st_le32(SC_RIGHT, pitch_value - 1, par); | 139 | aty_st_le32(SC_RIGHT, vxres - 1, par); |
137 | 140 | ||
138 | /* set background color to minimum value (usually BLACK) */ | 141 | /* set background color to minimum value (usually BLACK) */ |
139 | aty_st_le32(DP_BKGD_CLR, 0, par); | 142 | aty_st_le32(DP_BKGD_CLR, 0, par); |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 378f27745a1d..a699aab63820 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -715,8 +715,11 @@ int au1100fb_setup(char *options) | |||
715 | } | 715 | } |
716 | /* Mode option (only option that start with digit) */ | 716 | /* Mode option (only option that start with digit) */ |
717 | else if (isdigit(this_opt[0])) { | 717 | else if (isdigit(this_opt[0])) { |
718 | mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL); | 718 | mode = kstrdup(this_opt, GFP_KERNEL); |
719 | strncpy(mode, this_opt, strlen(this_opt) + 1); | 719 | if (!mode) { |
720 | print_err("memory allocation failed"); | ||
721 | return -ENOMEM; | ||
722 | } | ||
720 | } | 723 | } |
721 | /* Unsupported option */ | 724 | /* Unsupported option */ |
722 | else { | 725 | else { |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index f9d19be05540..09bfa9662e4d 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -31,6 +31,13 @@ config LCD_CORGI | |||
31 | Say y here to support the LCD panels usually found on SHARP | 31 | Say y here to support the LCD panels usually found on SHARP |
32 | corgi (C7x0) and spitz (Cxx00) models. | 32 | corgi (C7x0) and spitz (Cxx00) models. |
33 | 33 | ||
34 | config LCD_LMS283GF05 | ||
35 | tristate "Samsung LMS283GF05 LCD" | ||
36 | depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO | ||
37 | help | ||
38 | SPI driver for Samsung LMS283GF05. This provides basic support | ||
39 | for powering the LCD up/down through a sysfs interface. | ||
40 | |||
34 | config LCD_LTV350QV | 41 | config LCD_LTV350QV |
35 | tristate "Samsung LTV350QV LCD Panel" | 42 | tristate "Samsung LTV350QV LCD Panel" |
36 | depends on LCD_CLASS_DEVICE && SPI_MASTER | 43 | depends on LCD_CLASS_DEVICE && SPI_MASTER |
@@ -110,7 +117,7 @@ config BACKLIGHT_CLASS_DEVICE | |||
110 | config BACKLIGHT_ATMEL_LCDC | 117 | config BACKLIGHT_ATMEL_LCDC |
111 | bool "Atmel LCDC Contrast-as-Backlight control" | 118 | bool "Atmel LCDC Contrast-as-Backlight control" |
112 | depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL | 119 | depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL |
113 | default y if MACH_SAM9261EK || MACH_SAM9263EK | 120 | default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK |
114 | help | 121 | help |
115 | This provides a backlight control internal to the Atmel LCDC | 122 | This provides a backlight control internal to the Atmel LCDC |
116 | driver. If the LCD "contrast control" on your board is wired | 123 | driver. If the LCD "contrast control" on your board is wired |
@@ -229,3 +236,29 @@ config BACKLIGHT_SAHARA | |||
229 | help | 236 | help |
230 | If you have a Tabletkiosk Sahara Touch-iT, say y to enable the | 237 | If you have a Tabletkiosk Sahara Touch-iT, say y to enable the |
231 | backlight driver. | 238 | backlight driver. |
239 | |||
240 | config BACKLIGHT_WM831X | ||
241 | tristate "WM831x PMIC Backlight Driver" | ||
242 | depends on BACKLIGHT_CLASS_DEVICE && MFD_WM831X | ||
243 | help | ||
244 | If you have a backlight driven by the ISINK and DCDC of a | ||
245 | WM831x PMIC say y to enable the backlight driver for it. | ||
246 | |||
247 | config BACKLIGHT_ADX | ||
248 | tristate "Avionic Design Xanthos Backlight Driver" | ||
249 | depends on BACKLIGHT_CLASS_DEVICE && ARCH_PXA_ADX | ||
250 | default y | ||
251 | help | ||
252 | Say Y to enable the backlight driver on Avionic Design Xanthos-based | ||
253 | boards. | ||
254 | |||
255 | config BACKLIGHT_ADP5520 | ||
256 | tristate "Backlight Driver for ADP5520/ADP5501 using WLED" | ||
257 | depends on BACKLIGHT_CLASS_DEVICE && PMIC_ADP5520 | ||
258 | help | ||
259 | If you have a LCD backlight connected to the BST/BL_SNK output of | ||
260 | ADP5520 or ADP5501, say Y here to enable this driver. | ||
261 | |||
262 | To compile this driver as a module, choose M here: the module will | ||
263 | be called adp5520_bl. | ||
264 | |||
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 4eb178c1d684..9a405548874c 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o | 3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o |
4 | obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o | 4 | obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o |
5 | obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o | 5 | obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o |
6 | obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o | ||
6 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o | 7 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o |
7 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o | 8 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o |
8 | obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o | 9 | obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o |
@@ -24,4 +25,7 @@ obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o | |||
24 | obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o | 25 | obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o |
25 | obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o | 26 | obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o |
26 | obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o | 27 | obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o |
28 | obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o | ||
29 | obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o | ||
30 | obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o | ||
27 | 31 | ||
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c new file mode 100644 index 000000000000..ad05da5ba3c7 --- /dev/null +++ b/drivers/video/backlight/adp5520_bl.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | * Backlight driver for Analog Devices ADP5520/ADP5501 MFD PMICs | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/fb.h> | ||
13 | #include <linux/backlight.h> | ||
14 | #include <linux/mfd/adp5520.h> | ||
15 | |||
16 | struct adp5520_bl { | ||
17 | struct device *master; | ||
18 | struct adp5520_backlight_platfrom_data *pdata; | ||
19 | struct mutex lock; | ||
20 | unsigned long cached_daylight_max; | ||
21 | int id; | ||
22 | int current_brightness; | ||
23 | }; | ||
24 | |||
25 | static int adp5520_bl_set(struct backlight_device *bl, int brightness) | ||
26 | { | ||
27 | struct adp5520_bl *data = bl_get_data(bl); | ||
28 | struct device *master = data->master; | ||
29 | int ret = 0; | ||
30 | |||
31 | if (data->pdata->en_ambl_sens) { | ||
32 | if ((brightness > 0) && (brightness < ADP5020_MAX_BRIGHTNESS)) { | ||
33 | /* Disable Ambient Light auto adjust */ | ||
34 | ret |= adp5520_clr_bits(master, BL_CONTROL, | ||
35 | BL_AUTO_ADJ); | ||
36 | ret |= adp5520_write(master, DAYLIGHT_MAX, brightness); | ||
37 | } else { | ||
38 | /* | ||
39 | * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust | ||
40 | * restore daylight l3 sysfs brightness | ||
41 | */ | ||
42 | ret |= adp5520_write(master, DAYLIGHT_MAX, | ||
43 | data->cached_daylight_max); | ||
44 | ret |= adp5520_set_bits(master, BL_CONTROL, | ||
45 | BL_AUTO_ADJ); | ||
46 | } | ||
47 | } else { | ||
48 | ret |= adp5520_write(master, DAYLIGHT_MAX, brightness); | ||
49 | } | ||
50 | |||
51 | if (data->current_brightness && brightness == 0) | ||
52 | ret |= adp5520_set_bits(master, | ||
53 | MODE_STATUS, DIM_EN); | ||
54 | else if (data->current_brightness == 0 && brightness) | ||
55 | ret |= adp5520_clr_bits(master, | ||
56 | MODE_STATUS, DIM_EN); | ||
57 | |||
58 | if (!ret) | ||
59 | data->current_brightness = brightness; | ||
60 | |||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | static int adp5520_bl_update_status(struct backlight_device *bl) | ||
65 | { | ||
66 | int brightness = bl->props.brightness; | ||
67 | if (bl->props.power != FB_BLANK_UNBLANK) | ||
68 | brightness = 0; | ||
69 | |||
70 | if (bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
71 | brightness = 0; | ||
72 | |||
73 | return adp5520_bl_set(bl, brightness); | ||
74 | } | ||
75 | |||
76 | static int adp5520_bl_get_brightness(struct backlight_device *bl) | ||
77 | { | ||
78 | struct adp5520_bl *data = bl_get_data(bl); | ||
79 | int error; | ||
80 | uint8_t reg_val; | ||
81 | |||
82 | error = adp5520_read(data->master, BL_VALUE, ®_val); | ||
83 | |||
84 | return error ? data->current_brightness : reg_val; | ||
85 | } | ||
86 | |||
87 | static struct backlight_ops adp5520_bl_ops = { | ||
88 | .update_status = adp5520_bl_update_status, | ||
89 | .get_brightness = adp5520_bl_get_brightness, | ||
90 | }; | ||
91 | |||
92 | static int adp5520_bl_setup(struct backlight_device *bl) | ||
93 | { | ||
94 | struct adp5520_bl *data = bl_get_data(bl); | ||
95 | struct device *master = data->master; | ||
96 | struct adp5520_backlight_platfrom_data *pdata = data->pdata; | ||
97 | int ret = 0; | ||
98 | |||
99 | ret |= adp5520_write(master, DAYLIGHT_MAX, pdata->l1_daylight_max); | ||
100 | ret |= adp5520_write(master, DAYLIGHT_DIM, pdata->l1_daylight_dim); | ||
101 | |||
102 | if (pdata->en_ambl_sens) { | ||
103 | data->cached_daylight_max = pdata->l1_daylight_max; | ||
104 | ret |= adp5520_write(master, OFFICE_MAX, pdata->l2_office_max); | ||
105 | ret |= adp5520_write(master, OFFICE_DIM, pdata->l2_office_dim); | ||
106 | ret |= adp5520_write(master, DARK_MAX, pdata->l3_dark_max); | ||
107 | ret |= adp5520_write(master, DARK_DIM, pdata->l3_dark_dim); | ||
108 | ret |= adp5520_write(master, L2_TRIP, pdata->l2_trip); | ||
109 | ret |= adp5520_write(master, L2_HYS, pdata->l2_hyst); | ||
110 | ret |= adp5520_write(master, L3_TRIP, pdata->l3_trip); | ||
111 | ret |= adp5520_write(master, L3_HYS, pdata->l3_hyst); | ||
112 | ret |= adp5520_write(master, ALS_CMPR_CFG, | ||
113 | ALS_CMPR_CFG_VAL(pdata->abml_filt, L3_EN)); | ||
114 | } | ||
115 | |||
116 | ret |= adp5520_write(master, BL_CONTROL, | ||
117 | BL_CTRL_VAL(pdata->fade_led_law, pdata->en_ambl_sens)); | ||
118 | |||
119 | ret |= adp5520_write(master, BL_FADE, FADE_VAL(pdata->fade_in, | ||
120 | pdata->fade_out)); | ||
121 | |||
122 | ret |= adp5520_set_bits(master, MODE_STATUS, BL_EN | DIM_EN); | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | static ssize_t adp5520_show(struct device *dev, char *buf, int reg) | ||
128 | { | ||
129 | struct adp5520_bl *data = dev_get_drvdata(dev); | ||
130 | int error; | ||
131 | uint8_t reg_val; | ||
132 | |||
133 | mutex_lock(&data->lock); | ||
134 | error = adp5520_read(data->master, reg, ®_val); | ||
135 | mutex_unlock(&data->lock); | ||
136 | |||
137 | return sprintf(buf, "%u\n", reg_val); | ||
138 | } | ||
139 | |||
140 | static ssize_t adp5520_store(struct device *dev, const char *buf, | ||
141 | size_t count, int reg) | ||
142 | { | ||
143 | struct adp5520_bl *data = dev_get_drvdata(dev); | ||
144 | unsigned long val; | ||
145 | int ret; | ||
146 | |||
147 | ret = strict_strtoul(buf, 10, &val); | ||
148 | if (ret) | ||
149 | return ret; | ||
150 | |||
151 | mutex_lock(&data->lock); | ||
152 | adp5520_write(data->master, reg, val); | ||
153 | mutex_unlock(&data->lock); | ||
154 | |||
155 | return count; | ||
156 | } | ||
157 | |||
158 | static ssize_t adp5520_bl_dark_max_show(struct device *dev, | ||
159 | struct device_attribute *attr, char *buf) | ||
160 | { | ||
161 | return adp5520_show(dev, buf, DARK_MAX); | ||
162 | } | ||
163 | |||
164 | static ssize_t adp5520_bl_dark_max_store(struct device *dev, | ||
165 | struct device_attribute *attr, const char *buf, size_t count) | ||
166 | { | ||
167 | return adp5520_store(dev, buf, count, DARK_MAX); | ||
168 | } | ||
169 | static DEVICE_ATTR(dark_max, 0664, adp5520_bl_dark_max_show, | ||
170 | adp5520_bl_dark_max_store); | ||
171 | |||
172 | static ssize_t adp5520_bl_office_max_show(struct device *dev, | ||
173 | struct device_attribute *attr, char *buf) | ||
174 | { | ||
175 | return adp5520_show(dev, buf, OFFICE_MAX); | ||
176 | } | ||
177 | |||
178 | static ssize_t adp5520_bl_office_max_store(struct device *dev, | ||
179 | struct device_attribute *attr, const char *buf, size_t count) | ||
180 | { | ||
181 | return adp5520_store(dev, buf, count, OFFICE_MAX); | ||
182 | } | ||
183 | static DEVICE_ATTR(office_max, 0664, adp5520_bl_office_max_show, | ||
184 | adp5520_bl_office_max_store); | ||
185 | |||
186 | static ssize_t adp5520_bl_daylight_max_show(struct device *dev, | ||
187 | struct device_attribute *attr, char *buf) | ||
188 | { | ||
189 | return adp5520_show(dev, buf, DAYLIGHT_MAX); | ||
190 | } | ||
191 | |||
192 | static ssize_t adp5520_bl_daylight_max_store(struct device *dev, | ||
193 | struct device_attribute *attr, const char *buf, size_t count) | ||
194 | { | ||
195 | struct adp5520_bl *data = dev_get_drvdata(dev); | ||
196 | |||
197 | strict_strtoul(buf, 10, &data->cached_daylight_max); | ||
198 | return adp5520_store(dev, buf, count, DAYLIGHT_MAX); | ||
199 | } | ||
200 | static DEVICE_ATTR(daylight_max, 0664, adp5520_bl_daylight_max_show, | ||
201 | adp5520_bl_daylight_max_store); | ||
202 | |||
203 | static ssize_t adp5520_bl_dark_dim_show(struct device *dev, | ||
204 | struct device_attribute *attr, char *buf) | ||
205 | { | ||
206 | return adp5520_show(dev, buf, DARK_DIM); | ||
207 | } | ||
208 | |||
209 | static ssize_t adp5520_bl_dark_dim_store(struct device *dev, | ||
210 | struct device_attribute *attr, | ||
211 | const char *buf, size_t count) | ||
212 | { | ||
213 | return adp5520_store(dev, buf, count, DARK_DIM); | ||
214 | } | ||
215 | static DEVICE_ATTR(dark_dim, 0664, adp5520_bl_dark_dim_show, | ||
216 | adp5520_bl_dark_dim_store); | ||
217 | |||
218 | static ssize_t adp5520_bl_office_dim_show(struct device *dev, | ||
219 | struct device_attribute *attr, char *buf) | ||
220 | { | ||
221 | return adp5520_show(dev, buf, OFFICE_DIM); | ||
222 | } | ||
223 | |||
224 | static ssize_t adp5520_bl_office_dim_store(struct device *dev, | ||
225 | struct device_attribute *attr, | ||
226 | const char *buf, size_t count) | ||
227 | { | ||
228 | return adp5520_store(dev, buf, count, OFFICE_DIM); | ||
229 | } | ||
230 | static DEVICE_ATTR(office_dim, 0664, adp5520_bl_office_dim_show, | ||
231 | adp5520_bl_office_dim_store); | ||
232 | |||
233 | static ssize_t adp5520_bl_daylight_dim_show(struct device *dev, | ||
234 | struct device_attribute *attr, char *buf) | ||
235 | { | ||
236 | return adp5520_show(dev, buf, DAYLIGHT_DIM); | ||
237 | } | ||
238 | |||
239 | static ssize_t adp5520_bl_daylight_dim_store(struct device *dev, | ||
240 | struct device_attribute *attr, | ||
241 | const char *buf, size_t count) | ||
242 | { | ||
243 | return adp5520_store(dev, buf, count, DAYLIGHT_DIM); | ||
244 | } | ||
245 | static DEVICE_ATTR(daylight_dim, 0664, adp5520_bl_daylight_dim_show, | ||
246 | adp5520_bl_daylight_dim_store); | ||
247 | |||
248 | static struct attribute *adp5520_bl_attributes[] = { | ||
249 | &dev_attr_dark_max.attr, | ||
250 | &dev_attr_dark_dim.attr, | ||
251 | &dev_attr_office_max.attr, | ||
252 | &dev_attr_office_dim.attr, | ||
253 | &dev_attr_daylight_max.attr, | ||
254 | &dev_attr_daylight_dim.attr, | ||
255 | NULL | ||
256 | }; | ||
257 | |||
258 | static const struct attribute_group adp5520_bl_attr_group = { | ||
259 | .attrs = adp5520_bl_attributes, | ||
260 | }; | ||
261 | |||
262 | static int __devinit adp5520_bl_probe(struct platform_device *pdev) | ||
263 | { | ||
264 | struct backlight_device *bl; | ||
265 | struct adp5520_bl *data; | ||
266 | int ret = 0; | ||
267 | |||
268 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
269 | if (data == NULL) | ||
270 | return -ENOMEM; | ||
271 | |||
272 | data->master = pdev->dev.parent; | ||
273 | data->pdata = pdev->dev.platform_data; | ||
274 | |||
275 | if (data->pdata == NULL) { | ||
276 | dev_err(&pdev->dev, "missing platform data\n"); | ||
277 | kfree(data); | ||
278 | return -ENODEV; | ||
279 | } | ||
280 | |||
281 | data->id = pdev->id; | ||
282 | data->current_brightness = 0; | ||
283 | |||
284 | mutex_init(&data->lock); | ||
285 | |||
286 | bl = backlight_device_register(pdev->name, data->master, | ||
287 | data, &adp5520_bl_ops); | ||
288 | if (IS_ERR(bl)) { | ||
289 | dev_err(&pdev->dev, "failed to register backlight\n"); | ||
290 | kfree(data); | ||
291 | return PTR_ERR(bl); | ||
292 | } | ||
293 | |||
294 | bl->props.max_brightness = | ||
295 | bl->props.brightness = ADP5020_MAX_BRIGHTNESS; | ||
296 | |||
297 | if (data->pdata->en_ambl_sens) | ||
298 | ret = sysfs_create_group(&bl->dev.kobj, | ||
299 | &adp5520_bl_attr_group); | ||
300 | |||
301 | if (ret) { | ||
302 | dev_err(&pdev->dev, "failed to register sysfs\n"); | ||
303 | backlight_device_unregister(bl); | ||
304 | kfree(data); | ||
305 | } | ||
306 | |||
307 | platform_set_drvdata(pdev, bl); | ||
308 | ret |= adp5520_bl_setup(bl); | ||
309 | backlight_update_status(bl); | ||
310 | |||
311 | return ret; | ||
312 | } | ||
313 | |||
314 | static int __devexit adp5520_bl_remove(struct platform_device *pdev) | ||
315 | { | ||
316 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
317 | struct adp5520_bl *data = bl_get_data(bl); | ||
318 | |||
319 | adp5520_clr_bits(data->master, MODE_STATUS, BL_EN); | ||
320 | |||
321 | if (data->pdata->en_ambl_sens) | ||
322 | sysfs_remove_group(&bl->dev.kobj, | ||
323 | &adp5520_bl_attr_group); | ||
324 | |||
325 | backlight_device_unregister(bl); | ||
326 | kfree(data); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | #ifdef CONFIG_PM | ||
332 | static int adp5520_bl_suspend(struct platform_device *pdev, | ||
333 | pm_message_t state) | ||
334 | { | ||
335 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
336 | return adp5520_bl_set(bl, 0); | ||
337 | } | ||
338 | |||
339 | static int adp5520_bl_resume(struct platform_device *pdev) | ||
340 | { | ||
341 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
342 | |||
343 | backlight_update_status(bl); | ||
344 | return 0; | ||
345 | } | ||
346 | #else | ||
347 | #define adp5520_bl_suspend NULL | ||
348 | #define adp5520_bl_resume NULL | ||
349 | #endif | ||
350 | |||
351 | static struct platform_driver adp5520_bl_driver = { | ||
352 | .driver = { | ||
353 | .name = "adp5520-backlight", | ||
354 | .owner = THIS_MODULE, | ||
355 | }, | ||
356 | .probe = adp5520_bl_probe, | ||
357 | .remove = __devexit_p(adp5520_bl_remove), | ||
358 | .suspend = adp5520_bl_suspend, | ||
359 | .resume = adp5520_bl_resume, | ||
360 | }; | ||
361 | |||
362 | static int __init adp5520_bl_init(void) | ||
363 | { | ||
364 | return platform_driver_register(&adp5520_bl_driver); | ||
365 | } | ||
366 | module_init(adp5520_bl_init); | ||
367 | |||
368 | static void __exit adp5520_bl_exit(void) | ||
369 | { | ||
370 | platform_driver_unregister(&adp5520_bl_driver); | ||
371 | } | ||
372 | module_exit(adp5520_bl_exit); | ||
373 | |||
374 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
375 | MODULE_DESCRIPTION("ADP5520(01) Backlight Driver"); | ||
376 | MODULE_LICENSE("GPL"); | ||
377 | MODULE_ALIAS("platform:adp5520-backlight"); | ||
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c new file mode 100644 index 000000000000..2c3bdfc620b7 --- /dev/null +++ b/drivers/video/backlight/adx_bl.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/backlight/adx.c | ||
3 | * | ||
4 | * Copyright (C) 2009 Avionic Design GmbH | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * Written by Thierry Reding <thierry.reding@avionic-design.de> | ||
11 | */ | ||
12 | |||
13 | #include <linux/backlight.h> | ||
14 | #include <linux/fb.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | /* register definitions */ | ||
20 | #define ADX_BACKLIGHT_CONTROL 0x00 | ||
21 | #define ADX_BACKLIGHT_CONTROL_ENABLE (1 << 0) | ||
22 | #define ADX_BACKLIGHT_BRIGHTNESS 0x08 | ||
23 | #define ADX_BACKLIGHT_STATUS 0x10 | ||
24 | #define ADX_BACKLIGHT_ERROR 0x18 | ||
25 | |||
26 | struct adxbl { | ||
27 | void __iomem *base; | ||
28 | }; | ||
29 | |||
30 | static int adx_backlight_update_status(struct backlight_device *bldev) | ||
31 | { | ||
32 | struct adxbl *bl = bl_get_data(bldev); | ||
33 | u32 value; | ||
34 | |||
35 | value = bldev->props.brightness; | ||
36 | writel(value, bl->base + ADX_BACKLIGHT_BRIGHTNESS); | ||
37 | |||
38 | value = readl(bl->base + ADX_BACKLIGHT_CONTROL); | ||
39 | |||
40 | if (bldev->props.state & BL_CORE_FBBLANK) | ||
41 | value &= ~ADX_BACKLIGHT_CONTROL_ENABLE; | ||
42 | else | ||
43 | value |= ADX_BACKLIGHT_CONTROL_ENABLE; | ||
44 | |||
45 | writel(value, bl->base + ADX_BACKLIGHT_CONTROL); | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static int adx_backlight_get_brightness(struct backlight_device *bldev) | ||
51 | { | ||
52 | struct adxbl *bl = bl_get_data(bldev); | ||
53 | u32 brightness; | ||
54 | |||
55 | brightness = readl(bl->base + ADX_BACKLIGHT_BRIGHTNESS); | ||
56 | return brightness & 0xff; | ||
57 | } | ||
58 | |||
59 | static int adx_backlight_check_fb(struct fb_info *fb) | ||
60 | { | ||
61 | return 1; | ||
62 | } | ||
63 | |||
64 | static struct backlight_ops adx_backlight_ops = { | ||
65 | .options = 0, | ||
66 | .update_status = adx_backlight_update_status, | ||
67 | .get_brightness = adx_backlight_get_brightness, | ||
68 | .check_fb = adx_backlight_check_fb, | ||
69 | }; | ||
70 | |||
71 | static int __devinit adx_backlight_probe(struct platform_device *pdev) | ||
72 | { | ||
73 | struct backlight_device *bldev; | ||
74 | struct resource *res; | ||
75 | struct adxbl *bl; | ||
76 | int ret = 0; | ||
77 | |||
78 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
79 | if (!res) { | ||
80 | ret = -ENXIO; | ||
81 | goto out; | ||
82 | } | ||
83 | |||
84 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
85 | resource_size(res), res->name); | ||
86 | if (!res) { | ||
87 | ret = -ENXIO; | ||
88 | goto out; | ||
89 | } | ||
90 | |||
91 | bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL); | ||
92 | if (!bl) { | ||
93 | ret = -ENOMEM; | ||
94 | goto out; | ||
95 | } | ||
96 | |||
97 | bl->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
98 | resource_size(res)); | ||
99 | if (!bl->base) { | ||
100 | ret = -ENXIO; | ||
101 | goto out; | ||
102 | } | ||
103 | |||
104 | bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl, | ||
105 | &adx_backlight_ops); | ||
106 | if (!bldev) { | ||
107 | ret = -ENOMEM; | ||
108 | goto out; | ||
109 | } | ||
110 | |||
111 | bldev->props.max_brightness = 0xff; | ||
112 | bldev->props.brightness = 0xff; | ||
113 | bldev->props.power = FB_BLANK_UNBLANK; | ||
114 | |||
115 | platform_set_drvdata(pdev, bldev); | ||
116 | |||
117 | out: | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | static int __devexit adx_backlight_remove(struct platform_device *pdev) | ||
122 | { | ||
123 | struct backlight_device *bldev; | ||
124 | int ret = 0; | ||
125 | |||
126 | bldev = platform_get_drvdata(pdev); | ||
127 | bldev->props.power = FB_BLANK_UNBLANK; | ||
128 | bldev->props.brightness = 0xff; | ||
129 | backlight_update_status(bldev); | ||
130 | backlight_device_unregister(bldev); | ||
131 | platform_set_drvdata(pdev, NULL); | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | #ifdef CONFIG_PM | ||
137 | static int adx_backlight_suspend(struct platform_device *pdev, | ||
138 | pm_message_t state) | ||
139 | { | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int adx_backlight_resume(struct platform_device *pdev) | ||
144 | { | ||
145 | return 0; | ||
146 | } | ||
147 | #else | ||
148 | #define adx_backlight_suspend NULL | ||
149 | #define adx_backlight_resume NULL | ||
150 | #endif | ||
151 | |||
152 | static struct platform_driver adx_backlight_driver = { | ||
153 | .probe = adx_backlight_probe, | ||
154 | .remove = __devexit_p(adx_backlight_remove), | ||
155 | .suspend = adx_backlight_suspend, | ||
156 | .resume = adx_backlight_resume, | ||
157 | .driver = { | ||
158 | .name = "adx-backlight", | ||
159 | .owner = THIS_MODULE, | ||
160 | }, | ||
161 | }; | ||
162 | |||
163 | static int __init adx_backlight_init(void) | ||
164 | { | ||
165 | return platform_driver_register(&adx_backlight_driver); | ||
166 | } | ||
167 | |||
168 | static void __exit adx_backlight_exit(void) | ||
169 | { | ||
170 | platform_driver_unregister(&adx_backlight_driver); | ||
171 | } | ||
172 | |||
173 | module_init(adx_backlight_init); | ||
174 | module_exit(adx_backlight_exit); | ||
175 | |||
176 | MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); | ||
177 | MODULE_DESCRIPTION("Avionic Design Xanthos Backlight Driver"); | ||
178 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 157057c79ca3..6615ac7fa60a 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -73,6 +73,27 @@ static inline void backlight_unregister_fb(struct backlight_device *bd) | |||
73 | } | 73 | } |
74 | #endif /* CONFIG_FB */ | 74 | #endif /* CONFIG_FB */ |
75 | 75 | ||
76 | static void backlight_generate_event(struct backlight_device *bd, | ||
77 | enum backlight_update_reason reason) | ||
78 | { | ||
79 | char *envp[2]; | ||
80 | |||
81 | switch (reason) { | ||
82 | case BACKLIGHT_UPDATE_SYSFS: | ||
83 | envp[0] = "SOURCE=sysfs"; | ||
84 | break; | ||
85 | case BACKLIGHT_UPDATE_HOTKEY: | ||
86 | envp[0] = "SOURCE=hotkey"; | ||
87 | break; | ||
88 | default: | ||
89 | envp[0] = "SOURCE=unknown"; | ||
90 | break; | ||
91 | } | ||
92 | envp[1] = NULL; | ||
93 | kobject_uevent_env(&bd->dev.kobj, KOBJ_CHANGE, envp); | ||
94 | sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); | ||
95 | } | ||
96 | |||
76 | static ssize_t backlight_show_power(struct device *dev, | 97 | static ssize_t backlight_show_power(struct device *dev, |
77 | struct device_attribute *attr,char *buf) | 98 | struct device_attribute *attr,char *buf) |
78 | { | 99 | { |
@@ -142,6 +163,8 @@ static ssize_t backlight_store_brightness(struct device *dev, | |||
142 | } | 163 | } |
143 | mutex_unlock(&bd->ops_lock); | 164 | mutex_unlock(&bd->ops_lock); |
144 | 165 | ||
166 | backlight_generate_event(bd, BACKLIGHT_UPDATE_SYSFS); | ||
167 | |||
145 | return rc; | 168 | return rc; |
146 | } | 169 | } |
147 | 170 | ||
@@ -214,6 +237,25 @@ static struct device_attribute bl_device_attributes[] = { | |||
214 | }; | 237 | }; |
215 | 238 | ||
216 | /** | 239 | /** |
240 | * backlight_force_update - tell the backlight subsystem that hardware state | ||
241 | * has changed | ||
242 | * @bd: the backlight device to update | ||
243 | * | ||
244 | * Updates the internal state of the backlight in response to a hardware event, | ||
245 | * and generate a uevent to notify userspace | ||
246 | */ | ||
247 | void backlight_force_update(struct backlight_device *bd, | ||
248 | enum backlight_update_reason reason) | ||
249 | { | ||
250 | mutex_lock(&bd->ops_lock); | ||
251 | if (bd->ops && bd->ops->get_brightness) | ||
252 | bd->props.brightness = bd->ops->get_brightness(bd); | ||
253 | mutex_unlock(&bd->ops_lock); | ||
254 | backlight_generate_event(bd, reason); | ||
255 | } | ||
256 | EXPORT_SYMBOL(backlight_force_update); | ||
257 | |||
258 | /** | ||
217 | * backlight_device_register - create and register a new object of | 259 | * backlight_device_register - create and register a new object of |
218 | * backlight_device class. | 260 | * backlight_device class. |
219 | * @name: the name of the new object(must be the same as the name of the | 261 | * @name: the name of the new object(must be the same as the name of the |
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index f8a4bb20f41a..96774949cd30 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c | |||
@@ -433,8 +433,9 @@ static int corgi_bl_update_status(struct backlight_device *bd) | |||
433 | 433 | ||
434 | if (corgibl_flags & CORGIBL_SUSPENDED) | 434 | if (corgibl_flags & CORGIBL_SUSPENDED) |
435 | intensity = 0; | 435 | intensity = 0; |
436 | if (corgibl_flags & CORGIBL_BATTLOW) | 436 | |
437 | intensity &= lcd->limit_mask; | 437 | if ((corgibl_flags & CORGIBL_BATTLOW) && intensity > lcd->limit_mask) |
438 | intensity = lcd->limit_mask; | ||
438 | 439 | ||
439 | return corgi_bl_set_intensity(lcd, intensity); | 440 | return corgi_bl_set_intensity(lcd, intensity); |
440 | } | 441 | } |
@@ -639,3 +640,4 @@ module_exit(corgi_lcd_exit); | |||
639 | MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00"); | 640 | MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00"); |
640 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); | 641 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); |
641 | MODULE_LICENSE("GPL"); | 642 | MODULE_LICENSE("GPL"); |
643 | MODULE_ALIAS("spi:corgi-lcd"); | ||
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 93bb4340cc64..701a1081e199 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c | |||
@@ -154,34 +154,38 @@ static int da903x_backlight_remove(struct platform_device *pdev) | |||
154 | } | 154 | } |
155 | 155 | ||
156 | #ifdef CONFIG_PM | 156 | #ifdef CONFIG_PM |
157 | static int da903x_backlight_suspend(struct platform_device *pdev, | 157 | static int da903x_backlight_suspend(struct device *dev) |
158 | pm_message_t state) | ||
159 | { | 158 | { |
159 | struct platform_device *pdev = to_platform_device(dev); | ||
160 | struct backlight_device *bl = platform_get_drvdata(pdev); | 160 | struct backlight_device *bl = platform_get_drvdata(pdev); |
161 | return da903x_backlight_set(bl, 0); | 161 | return da903x_backlight_set(bl, 0); |
162 | } | 162 | } |
163 | 163 | ||
164 | static int da903x_backlight_resume(struct platform_device *pdev) | 164 | static int da903x_backlight_resume(struct device *dev) |
165 | { | 165 | { |
166 | struct platform_device *pdev = to_platform_device(dev); | ||
166 | struct backlight_device *bl = platform_get_drvdata(pdev); | 167 | struct backlight_device *bl = platform_get_drvdata(pdev); |
167 | 168 | ||
168 | backlight_update_status(bl); | 169 | backlight_update_status(bl); |
169 | return 0; | 170 | return 0; |
170 | } | 171 | } |
171 | #else | 172 | |
172 | #define da903x_backlight_suspend NULL | 173 | static struct dev_pm_ops da903x_backlight_pm_ops = { |
173 | #define da903x_backlight_resume NULL | 174 | .suspend = da903x_backlight_suspend, |
175 | .resume = da903x_backlight_resume, | ||
176 | }; | ||
174 | #endif | 177 | #endif |
175 | 178 | ||
176 | static struct platform_driver da903x_backlight_driver = { | 179 | static struct platform_driver da903x_backlight_driver = { |
177 | .driver = { | 180 | .driver = { |
178 | .name = "da903x-backlight", | 181 | .name = "da903x-backlight", |
179 | .owner = THIS_MODULE, | 182 | .owner = THIS_MODULE, |
183 | #ifdef CONFIG_PM | ||
184 | .pm = &da903x_backlight_pm_ops, | ||
185 | #endif | ||
180 | }, | 186 | }, |
181 | .probe = da903x_backlight_probe, | 187 | .probe = da903x_backlight_probe, |
182 | .remove = da903x_backlight_remove, | 188 | .remove = da903x_backlight_remove, |
183 | .suspend = da903x_backlight_suspend, | ||
184 | .resume = da903x_backlight_resume, | ||
185 | }; | 189 | }; |
186 | 190 | ||
187 | static int __init da903x_backlight_init(void) | 191 | static int __init da903x_backlight_init(void) |
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index 5be55a20d8c7..7fb4eefff80d 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c | |||
@@ -103,7 +103,7 @@ static struct backlight_ops hp680bl_ops = { | |||
103 | .update_status = hp680bl_set_intensity, | 103 | .update_status = hp680bl_set_intensity, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static int __init hp680bl_probe(struct platform_device *pdev) | 106 | static int __devinit hp680bl_probe(struct platform_device *pdev) |
107 | { | 107 | { |
108 | struct backlight_device *bd; | 108 | struct backlight_device *bd; |
109 | 109 | ||
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index c3ebb6b41ce1..7aed2565c1bd 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c | |||
@@ -72,7 +72,7 @@ static int jornada_bl_update_status(struct backlight_device *bd) | |||
72 | if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) { | 72 | if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) { |
73 | printk(KERN_INFO "bl : failed to set brightness\n"); | 73 | printk(KERN_INFO "bl : failed to set brightness\n"); |
74 | ret = -ETIMEDOUT; | 74 | ret = -ETIMEDOUT; |
75 | goto out | 75 | goto out; |
76 | } | 76 | } |
77 | 77 | ||
78 | /* at this point we expect that the mcu has accepted | 78 | /* at this point we expect that the mcu has accepted |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index b6449470106c..a482dd7b0311 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -56,7 +56,7 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
56 | 56 | ||
57 | static int lcd_register_fb(struct lcd_device *ld) | 57 | static int lcd_register_fb(struct lcd_device *ld) |
58 | { | 58 | { |
59 | memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif)); | 59 | memset(&ld->fb_notif, 0, sizeof(ld->fb_notif)); |
60 | ld->fb_notif.notifier_call = fb_notifier_callback; | 60 | ld->fb_notif.notifier_call = fb_notifier_callback; |
61 | return fb_register_client(&ld->fb_notif); | 61 | return fb_register_client(&ld->fb_notif); |
62 | } | 62 | } |
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c new file mode 100644 index 000000000000..447b542a20ca --- /dev/null +++ b/drivers/video/backlight/lms283gf05.c | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * lms283gf05.c -- support for Samsung LMS283GF05 LCD | ||
3 | * | ||
4 | * Copyright (c) 2009 Marek Vasut <marek.vasut@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/device.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/lcd.h> | ||
16 | |||
17 | #include <linux/spi/spi.h> | ||
18 | #include <linux/spi/lms283gf05.h> | ||
19 | |||
20 | struct lms283gf05_state { | ||
21 | struct spi_device *spi; | ||
22 | struct lcd_device *ld; | ||
23 | }; | ||
24 | |||
25 | struct lms283gf05_seq { | ||
26 | unsigned char reg; | ||
27 | unsigned short value; | ||
28 | unsigned char delay; | ||
29 | }; | ||
30 | |||
31 | /* Magic sequences supplied by manufacturer, for details refer to datasheet */ | ||
32 | static struct lms283gf05_seq disp_initseq[] = { | ||
33 | /* REG, VALUE, DELAY */ | ||
34 | { 0x07, 0x0000, 0 }, | ||
35 | { 0x13, 0x0000, 10 }, | ||
36 | |||
37 | { 0x11, 0x3004, 0 }, | ||
38 | { 0x14, 0x200F, 0 }, | ||
39 | { 0x10, 0x1a20, 0 }, | ||
40 | { 0x13, 0x0040, 50 }, | ||
41 | |||
42 | { 0x13, 0x0060, 0 }, | ||
43 | { 0x13, 0x0070, 200 }, | ||
44 | |||
45 | { 0x01, 0x0127, 0 }, | ||
46 | { 0x02, 0x0700, 0 }, | ||
47 | { 0x03, 0x1030, 0 }, | ||
48 | { 0x08, 0x0208, 0 }, | ||
49 | { 0x0B, 0x0620, 0 }, | ||
50 | { 0x0C, 0x0110, 0 }, | ||
51 | { 0x30, 0x0120, 0 }, | ||
52 | { 0x31, 0x0127, 0 }, | ||
53 | { 0x32, 0x0000, 0 }, | ||
54 | { 0x33, 0x0503, 0 }, | ||
55 | { 0x34, 0x0727, 0 }, | ||
56 | { 0x35, 0x0124, 0 }, | ||
57 | { 0x36, 0x0706, 0 }, | ||
58 | { 0x37, 0x0701, 0 }, | ||
59 | { 0x38, 0x0F00, 0 }, | ||
60 | { 0x39, 0x0F00, 0 }, | ||
61 | { 0x40, 0x0000, 0 }, | ||
62 | { 0x41, 0x0000, 0 }, | ||
63 | { 0x42, 0x013f, 0 }, | ||
64 | { 0x43, 0x0000, 0 }, | ||
65 | { 0x44, 0x013f, 0 }, | ||
66 | { 0x45, 0x0000, 0 }, | ||
67 | { 0x46, 0xef00, 0 }, | ||
68 | { 0x47, 0x013f, 0 }, | ||
69 | { 0x48, 0x0000, 0 }, | ||
70 | { 0x07, 0x0015, 30 }, | ||
71 | |||
72 | { 0x07, 0x0017, 0 }, | ||
73 | |||
74 | { 0x20, 0x0000, 0 }, | ||
75 | { 0x21, 0x0000, 0 }, | ||
76 | { 0x22, 0x0000, 0 } | ||
77 | }; | ||
78 | |||
79 | static struct lms283gf05_seq disp_pdwnseq[] = { | ||
80 | { 0x07, 0x0016, 30 }, | ||
81 | |||
82 | { 0x07, 0x0004, 0 }, | ||
83 | { 0x10, 0x0220, 20 }, | ||
84 | |||
85 | { 0x13, 0x0060, 50 }, | ||
86 | |||
87 | { 0x13, 0x0040, 50 }, | ||
88 | |||
89 | { 0x13, 0x0000, 0 }, | ||
90 | { 0x10, 0x0000, 0 } | ||
91 | }; | ||
92 | |||
93 | |||
94 | static void lms283gf05_reset(unsigned long gpio, bool inverted) | ||
95 | { | ||
96 | gpio_set_value(gpio, !inverted); | ||
97 | mdelay(100); | ||
98 | gpio_set_value(gpio, inverted); | ||
99 | mdelay(20); | ||
100 | gpio_set_value(gpio, !inverted); | ||
101 | mdelay(20); | ||
102 | } | ||
103 | |||
104 | static void lms283gf05_toggle(struct spi_device *spi, | ||
105 | struct lms283gf05_seq *seq, int sz) | ||
106 | { | ||
107 | char buf[3]; | ||
108 | int i; | ||
109 | |||
110 | for (i = 0; i < sz; i++) { | ||
111 | buf[0] = 0x74; | ||
112 | buf[1] = 0x00; | ||
113 | buf[2] = seq[i].reg; | ||
114 | spi_write(spi, buf, 3); | ||
115 | |||
116 | buf[0] = 0x76; | ||
117 | buf[1] = seq[i].value >> 8; | ||
118 | buf[2] = seq[i].value & 0xff; | ||
119 | spi_write(spi, buf, 3); | ||
120 | |||
121 | mdelay(seq[i].delay); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static int lms283gf05_power_set(struct lcd_device *ld, int power) | ||
126 | { | ||
127 | struct lms283gf05_state *st = lcd_get_data(ld); | ||
128 | struct spi_device *spi = st->spi; | ||
129 | struct lms283gf05_pdata *pdata = spi->dev.platform_data; | ||
130 | |||
131 | if (power) { | ||
132 | if (pdata) | ||
133 | lms283gf05_reset(pdata->reset_gpio, | ||
134 | pdata->reset_inverted); | ||
135 | lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq)); | ||
136 | } else { | ||
137 | lms283gf05_toggle(spi, disp_pdwnseq, ARRAY_SIZE(disp_pdwnseq)); | ||
138 | if (pdata) | ||
139 | gpio_set_value(pdata->reset_gpio, | ||
140 | pdata->reset_inverted); | ||
141 | } | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static struct lcd_ops lms_ops = { | ||
147 | .set_power = lms283gf05_power_set, | ||
148 | .get_power = NULL, | ||
149 | }; | ||
150 | |||
151 | static int __devinit lms283gf05_probe(struct spi_device *spi) | ||
152 | { | ||
153 | struct lms283gf05_state *st; | ||
154 | struct lms283gf05_pdata *pdata = spi->dev.platform_data; | ||
155 | struct lcd_device *ld; | ||
156 | int ret = 0; | ||
157 | |||
158 | if (pdata != NULL) { | ||
159 | ret = gpio_request(pdata->reset_gpio, "LMS285GF05 RESET"); | ||
160 | if (ret) | ||
161 | return ret; | ||
162 | |||
163 | ret = gpio_direction_output(pdata->reset_gpio, | ||
164 | !pdata->reset_inverted); | ||
165 | if (ret) | ||
166 | goto err; | ||
167 | } | ||
168 | |||
169 | st = kzalloc(sizeof(struct lms283gf05_state), GFP_KERNEL); | ||
170 | if (st == NULL) { | ||
171 | dev_err(&spi->dev, "No memory for device state\n"); | ||
172 | ret = -ENOMEM; | ||
173 | goto err; | ||
174 | } | ||
175 | |||
176 | ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops); | ||
177 | if (IS_ERR(ld)) { | ||
178 | ret = PTR_ERR(ld); | ||
179 | goto err2; | ||
180 | } | ||
181 | |||
182 | st->spi = spi; | ||
183 | st->ld = ld; | ||
184 | |||
185 | dev_set_drvdata(&spi->dev, st); | ||
186 | |||
187 | /* kick in the LCD */ | ||
188 | if (pdata) | ||
189 | lms283gf05_reset(pdata->reset_gpio, pdata->reset_inverted); | ||
190 | lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq)); | ||
191 | |||
192 | return 0; | ||
193 | |||
194 | err2: | ||
195 | kfree(st); | ||
196 | err: | ||
197 | if (pdata != NULL) | ||
198 | gpio_free(pdata->reset_gpio); | ||
199 | |||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | static int __devexit lms283gf05_remove(struct spi_device *spi) | ||
204 | { | ||
205 | struct lms283gf05_state *st = dev_get_drvdata(&spi->dev); | ||
206 | struct lms283gf05_pdata *pdata = st->spi->dev.platform_data; | ||
207 | |||
208 | lcd_device_unregister(st->ld); | ||
209 | |||
210 | if (pdata != NULL) | ||
211 | gpio_free(pdata->reset_gpio); | ||
212 | |||
213 | kfree(st); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static struct spi_driver lms283gf05_driver = { | ||
219 | .driver = { | ||
220 | .name = "lms283gf05", | ||
221 | .owner = THIS_MODULE, | ||
222 | }, | ||
223 | .probe = lms283gf05_probe, | ||
224 | .remove = __devexit_p(lms283gf05_remove), | ||
225 | }; | ||
226 | |||
227 | static __init int lms283gf05_init(void) | ||
228 | { | ||
229 | return spi_register_driver(&lms283gf05_driver); | ||
230 | } | ||
231 | |||
232 | static __exit void lms283gf05_exit(void) | ||
233 | { | ||
234 | spi_unregister_driver(&lms283gf05_driver); | ||
235 | } | ||
236 | |||
237 | module_init(lms283gf05_init); | ||
238 | module_exit(lms283gf05_exit); | ||
239 | |||
240 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); | ||
241 | MODULE_DESCRIPTION("LCD283GF05 LCD"); | ||
242 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 2eb206bf73e6..4631ca8fa4a4 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c | |||
@@ -328,3 +328,4 @@ module_exit(ltv350qv_exit); | |||
328 | MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); | 328 | MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); |
329 | MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver"); | 329 | MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver"); |
330 | MODULE_LICENSE("GPL"); | 330 | MODULE_LICENSE("GPL"); |
331 | MODULE_ALIAS("spi:ltv350qv"); | ||
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 3bb4c0a50c62..9edb8d7c295f 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c | |||
@@ -166,6 +166,15 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { | |||
166 | }, | 166 | }, |
167 | { | 167 | { |
168 | .callback = mbp_dmi_match, | 168 | .callback = mbp_dmi_match, |
169 | .ident = "MacBookAir 1,1", | ||
170 | .matches = { | ||
171 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
172 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir1,1"), | ||
173 | }, | ||
174 | .driver_data = (void *)&intel_chipset_data, | ||
175 | }, | ||
176 | { | ||
177 | .callback = mbp_dmi_match, | ||
169 | .ident = "MacBook 5,1", | 178 | .ident = "MacBook 5,1", |
170 | .matches = { | 179 | .matches = { |
171 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 180 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), |
@@ -175,6 +184,15 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { | |||
175 | }, | 184 | }, |
176 | { | 185 | { |
177 | .callback = mbp_dmi_match, | 186 | .callback = mbp_dmi_match, |
187 | .ident = "MacBook 5,2", | ||
188 | .matches = { | ||
189 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
190 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"), | ||
191 | }, | ||
192 | .driver_data = (void *)&nvidia_chipset_data, | ||
193 | }, | ||
194 | { | ||
195 | .callback = mbp_dmi_match, | ||
178 | .ident = "MacBookAir 2,1", | 196 | .ident = "MacBookAir 2,1", |
179 | .matches = { | 197 | .matches = { |
180 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 198 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), |
@@ -191,6 +209,24 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { | |||
191 | }, | 209 | }, |
192 | .driver_data = (void *)&nvidia_chipset_data, | 210 | .driver_data = (void *)&nvidia_chipset_data, |
193 | }, | 211 | }, |
212 | { | ||
213 | .callback = mbp_dmi_match, | ||
214 | .ident = "MacBookPro 5,2", | ||
215 | .matches = { | ||
216 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
217 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,2"), | ||
218 | }, | ||
219 | .driver_data = (void *)&nvidia_chipset_data, | ||
220 | }, | ||
221 | { | ||
222 | .callback = mbp_dmi_match, | ||
223 | .ident = "MacBookPro 5,5", | ||
224 | .matches = { | ||
225 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
226 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"), | ||
227 | }, | ||
228 | .driver_data = (void *)&nvidia_chipset_data, | ||
229 | }, | ||
194 | { } | 230 | { } |
195 | }; | 231 | }; |
196 | 232 | ||
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index e641584e212e..887166267443 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
@@ -145,6 +145,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev, | |||
145 | struct backlight_device *bl = platform_get_drvdata(pdev); | 145 | struct backlight_device *bl = platform_get_drvdata(pdev); |
146 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); | 146 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); |
147 | 147 | ||
148 | if (pb->notify) | ||
149 | pb->notify(0); | ||
148 | pwm_config(pb->pwm, 0, pb->period); | 150 | pwm_config(pb->pwm, 0, pb->period); |
149 | pwm_disable(pb->pwm); | 151 | pwm_disable(pb->pwm); |
150 | return 0; | 152 | return 0; |
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index 1dae7f8f3c6b..bbfb502add67 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c | |||
@@ -356,7 +356,7 @@ static int __devinit tdo24m_probe(struct spi_device *spi) | |||
356 | lcd->power = FB_BLANK_POWERDOWN; | 356 | lcd->power = FB_BLANK_POWERDOWN; |
357 | lcd->mode = MODE_VGA; /* default to VGA */ | 357 | lcd->mode = MODE_VGA; /* default to VGA */ |
358 | 358 | ||
359 | lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL)); | 359 | lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, GFP_KERNEL); |
360 | if (lcd->buf == NULL) { | 360 | if (lcd->buf == NULL) { |
361 | kfree(lcd); | 361 | kfree(lcd); |
362 | return -ENOMEM; | 362 | return -ENOMEM; |
@@ -472,3 +472,4 @@ module_exit(tdo24m_exit); | |||
472 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); | 472 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); |
473 | MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel"); | 473 | MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel"); |
474 | MODULE_LICENSE("GPL"); | 474 | MODULE_LICENSE("GPL"); |
475 | MODULE_ALIAS("spi:tdo24m"); | ||
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index b7fbc75a62fc..50ec17dfc517 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c | |||
@@ -300,4 +300,4 @@ module_exit(tosa_lcd_exit); | |||
300 | MODULE_AUTHOR("Dmitry Baryshkov"); | 300 | MODULE_AUTHOR("Dmitry Baryshkov"); |
301 | MODULE_LICENSE("GPL v2"); | 301 | MODULE_LICENSE("GPL v2"); |
302 | MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); | 302 | MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); |
303 | 303 | MODULE_ALIAS("spi:tosa-lcd"); | |
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c index 8e653b8a6f17..b49063c831e7 100644 --- a/drivers/video/backlight/vgg2432a4.c +++ b/drivers/video/backlight/vgg2432a4.c | |||
@@ -280,5 +280,4 @@ module_exit(vgg2432a4_exit); | |||
280 | MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); | 280 | MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); |
281 | MODULE_DESCRIPTION("VGG2432A4 LCD Driver"); | 281 | MODULE_DESCRIPTION("VGG2432A4 LCD Driver"); |
282 | MODULE_LICENSE("GPL v2"); | 282 | MODULE_LICENSE("GPL v2"); |
283 | 283 | MODULE_ALIAS("spi:VGG2432A4"); | |
284 | |||
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c new file mode 100644 index 000000000000..467bdb7efb23 --- /dev/null +++ b/drivers/video/backlight/wm831x_bl.c | |||
@@ -0,0 +1,250 @@ | |||
1 | /* | ||
2 | * Backlight driver for Wolfson Microelectronics WM831x PMICs | ||
3 | * | ||
4 | * Copyright 2009 Wolfson Microelectonics plc | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/fb.h> | ||
15 | #include <linux/backlight.h> | ||
16 | |||
17 | #include <linux/mfd/wm831x/core.h> | ||
18 | #include <linux/mfd/wm831x/pdata.h> | ||
19 | #include <linux/mfd/wm831x/regulator.h> | ||
20 | |||
21 | struct wm831x_backlight_data { | ||
22 | struct wm831x *wm831x; | ||
23 | int isink_reg; | ||
24 | int current_brightness; | ||
25 | }; | ||
26 | |||
27 | static int wm831x_backlight_set(struct backlight_device *bl, int brightness) | ||
28 | { | ||
29 | struct wm831x_backlight_data *data = bl_get_data(bl); | ||
30 | struct wm831x *wm831x = data->wm831x; | ||
31 | int power_up = !data->current_brightness && brightness; | ||
32 | int power_down = data->current_brightness && !brightness; | ||
33 | int ret; | ||
34 | |||
35 | if (power_up) { | ||
36 | /* Enable the ISINK */ | ||
37 | ret = wm831x_set_bits(wm831x, data->isink_reg, | ||
38 | WM831X_CS1_ENA, WM831X_CS1_ENA); | ||
39 | if (ret < 0) | ||
40 | goto err; | ||
41 | |||
42 | /* Enable the DC-DC */ | ||
43 | ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, | ||
44 | WM831X_DC4_ENA, WM831X_DC4_ENA); | ||
45 | if (ret < 0) | ||
46 | goto err; | ||
47 | } | ||
48 | |||
49 | if (power_down) { | ||
50 | /* DCDC first */ | ||
51 | ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, | ||
52 | WM831X_DC4_ENA, 0); | ||
53 | if (ret < 0) | ||
54 | goto err; | ||
55 | |||
56 | /* ISINK */ | ||
57 | ret = wm831x_set_bits(wm831x, data->isink_reg, | ||
58 | WM831X_CS1_DRIVE | WM831X_CS1_ENA, 0); | ||
59 | if (ret < 0) | ||
60 | goto err; | ||
61 | } | ||
62 | |||
63 | /* Set the new brightness */ | ||
64 | ret = wm831x_set_bits(wm831x, data->isink_reg, | ||
65 | WM831X_CS1_ISEL_MASK, brightness); | ||
66 | if (ret < 0) | ||
67 | goto err; | ||
68 | |||
69 | if (power_up) { | ||
70 | /* Drive current through the ISINK */ | ||
71 | ret = wm831x_set_bits(wm831x, data->isink_reg, | ||
72 | WM831X_CS1_DRIVE, WM831X_CS1_DRIVE); | ||
73 | if (ret < 0) | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | data->current_brightness = brightness; | ||
78 | |||
79 | return 0; | ||
80 | |||
81 | err: | ||
82 | /* If we were in the middle of a power transition always shut down | ||
83 | * for safety. | ||
84 | */ | ||
85 | if (power_up || power_down) { | ||
86 | wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0); | ||
87 | wm831x_set_bits(wm831x, data->isink_reg, WM831X_CS1_ENA, 0); | ||
88 | } | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | static int wm831x_backlight_update_status(struct backlight_device *bl) | ||
94 | { | ||
95 | int brightness = bl->props.brightness; | ||
96 | |||
97 | if (bl->props.power != FB_BLANK_UNBLANK) | ||
98 | brightness = 0; | ||
99 | |||
100 | if (bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
101 | brightness = 0; | ||
102 | |||
103 | if (bl->props.state & BL_CORE_SUSPENDED) | ||
104 | brightness = 0; | ||
105 | |||
106 | return wm831x_backlight_set(bl, brightness); | ||
107 | } | ||
108 | |||
109 | static int wm831x_backlight_get_brightness(struct backlight_device *bl) | ||
110 | { | ||
111 | struct wm831x_backlight_data *data = bl_get_data(bl); | ||
112 | return data->current_brightness; | ||
113 | } | ||
114 | |||
115 | static struct backlight_ops wm831x_backlight_ops = { | ||
116 | .options = BL_CORE_SUSPENDRESUME, | ||
117 | .update_status = wm831x_backlight_update_status, | ||
118 | .get_brightness = wm831x_backlight_get_brightness, | ||
119 | }; | ||
120 | |||
121 | static int wm831x_backlight_probe(struct platform_device *pdev) | ||
122 | { | ||
123 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | ||
124 | struct wm831x_pdata *wm831x_pdata; | ||
125 | struct wm831x_backlight_pdata *pdata; | ||
126 | struct wm831x_backlight_data *data; | ||
127 | struct backlight_device *bl; | ||
128 | int ret, i, max_isel, isink_reg, dcdc_cfg; | ||
129 | |||
130 | /* We need platform data */ | ||
131 | if (pdev->dev.parent->platform_data) { | ||
132 | wm831x_pdata = pdev->dev.parent->platform_data; | ||
133 | pdata = wm831x_pdata->backlight; | ||
134 | } else { | ||
135 | pdata = NULL; | ||
136 | } | ||
137 | |||
138 | if (!pdata) { | ||
139 | dev_err(&pdev->dev, "No platform data supplied\n"); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | /* Figure out the maximum current we can use */ | ||
144 | for (i = 0; i < WM831X_ISINK_MAX_ISEL; i++) { | ||
145 | if (wm831x_isinkv_values[i] > pdata->max_uA) | ||
146 | break; | ||
147 | } | ||
148 | |||
149 | if (i == 0) { | ||
150 | dev_err(&pdev->dev, "Invalid max_uA: %duA\n", pdata->max_uA); | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | max_isel = i - 1; | ||
154 | |||
155 | if (pdata->max_uA != wm831x_isinkv_values[max_isel]) | ||
156 | dev_warn(&pdev->dev, | ||
157 | "Maximum current is %duA not %duA as requested\n", | ||
158 | wm831x_isinkv_values[max_isel], pdata->max_uA); | ||
159 | |||
160 | switch (pdata->isink) { | ||
161 | case 1: | ||
162 | isink_reg = WM831X_CURRENT_SINK_1; | ||
163 | dcdc_cfg = 0; | ||
164 | break; | ||
165 | case 2: | ||
166 | isink_reg = WM831X_CURRENT_SINK_2; | ||
167 | dcdc_cfg = WM831X_DC4_FBSRC; | ||
168 | break; | ||
169 | default: | ||
170 | dev_err(&pdev->dev, "Invalid ISINK %d\n", pdata->isink); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | |||
174 | /* Configure the ISINK to use for feedback */ | ||
175 | ret = wm831x_reg_unlock(wm831x); | ||
176 | if (ret < 0) | ||
177 | return ret; | ||
178 | |||
179 | ret = wm831x_set_bits(wm831x, WM831X_DC4_CONTROL, WM831X_DC4_FBSRC, | ||
180 | dcdc_cfg); | ||
181 | |||
182 | wm831x_reg_lock(wm831x); | ||
183 | if (ret < 0) | ||
184 | return ret; | ||
185 | |||
186 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
187 | if (data == NULL) | ||
188 | return -ENOMEM; | ||
189 | |||
190 | data->wm831x = wm831x; | ||
191 | data->current_brightness = 0; | ||
192 | data->isink_reg = isink_reg; | ||
193 | |||
194 | bl = backlight_device_register("wm831x", &pdev->dev, | ||
195 | data, &wm831x_backlight_ops); | ||
196 | if (IS_ERR(bl)) { | ||
197 | dev_err(&pdev->dev, "failed to register backlight\n"); | ||
198 | kfree(data); | ||
199 | return PTR_ERR(bl); | ||
200 | } | ||
201 | |||
202 | bl->props.max_brightness = max_isel; | ||
203 | bl->props.brightness = max_isel; | ||
204 | |||
205 | platform_set_drvdata(pdev, bl); | ||
206 | |||
207 | /* Disable the DCDC if it was started so we can bootstrap */ | ||
208 | wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0); | ||
209 | |||
210 | |||
211 | backlight_update_status(bl); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int wm831x_backlight_remove(struct platform_device *pdev) | ||
217 | { | ||
218 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
219 | struct wm831x_backlight_data *data = bl_get_data(bl); | ||
220 | |||
221 | backlight_device_unregister(bl); | ||
222 | kfree(data); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static struct platform_driver wm831x_backlight_driver = { | ||
227 | .driver = { | ||
228 | .name = "wm831x-backlight", | ||
229 | .owner = THIS_MODULE, | ||
230 | }, | ||
231 | .probe = wm831x_backlight_probe, | ||
232 | .remove = wm831x_backlight_remove, | ||
233 | }; | ||
234 | |||
235 | static int __init wm831x_backlight_init(void) | ||
236 | { | ||
237 | return platform_driver_register(&wm831x_backlight_driver); | ||
238 | } | ||
239 | module_init(wm831x_backlight_init); | ||
240 | |||
241 | static void __exit wm831x_backlight_exit(void) | ||
242 | { | ||
243 | platform_driver_unregister(&wm831x_backlight_driver); | ||
244 | } | ||
245 | module_exit(wm831x_backlight_exit); | ||
246 | |||
247 | MODULE_DESCRIPTION("Backlight Driver for WM831x PMICs"); | ||
248 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com"); | ||
249 | MODULE_LICENSE("GPL"); | ||
250 | MODULE_ALIAS("platform:wm831x-backlight"); | ||
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c index df03f3776dcc..79e5f40e6486 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/cfbcopyarea.c | |||
@@ -114,7 +114,7 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx, | |||
114 | d0 >>= right; | 114 | d0 >>= right; |
115 | } else if (src_idx+n <= bits) { | 115 | } else if (src_idx+n <= bits) { |
116 | // Single source word | 116 | // Single source word |
117 | d0 <<= left;; | 117 | d0 <<= left; |
118 | } else { | 118 | } else { |
119 | // 2 source words | 119 | // 2 source words |
120 | d1 = FB_READL(src + 1); | 120 | d1 = FB_READL(src + 1); |
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c index 7bad24ed04ef..108b89e09a80 100644 --- a/drivers/video/cobalt_lcdfb.c +++ b/drivers/video/cobalt_lcdfb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Cobalt server LCD frame buffer driver. | 2 | * Cobalt server LCD frame buffer driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/video/console/.gitignore b/drivers/video/console/.gitignore deleted file mode 100644 index 0c258b45439c..000000000000 --- a/drivers/video/console/.gitignore +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | # conmakehash generated file | ||
2 | promcon_tbl.c | ||
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 2f50a80b413e..fc7d9bbb548c 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -67,16 +67,9 @@ config SGI_NEWPORT_CONSOLE | |||
67 | 67 | ||
68 | # bool 'IODC console' CONFIG_IODC_CONSOLE | 68 | # bool 'IODC console' CONFIG_IODC_CONSOLE |
69 | 69 | ||
70 | config PROM_CONSOLE | ||
71 | bool "PROM console" | ||
72 | depends on SPARC | ||
73 | help | ||
74 | Say Y to build a console driver for Sun machines that uses the | ||
75 | terminal emulation built into their console PROMS. | ||
76 | |||
77 | config DUMMY_CONSOLE | 70 | config DUMMY_CONSOLE |
78 | bool | 71 | bool |
79 | depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y | 72 | depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y |
80 | default y | 73 | default y |
81 | 74 | ||
82 | config DUMMY_CONSOLE_COLUMNS | 75 | config DUMMY_CONSOLE_COLUMNS |
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index ac46cc3f6a2a..a862e9173ebe 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile | |||
@@ -22,7 +22,6 @@ font-objs += $(font-objs-y) | |||
22 | 22 | ||
23 | obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o | 23 | obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o |
24 | obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o | 24 | obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o |
25 | obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o | ||
26 | obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o | 25 | obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o |
27 | obj-$(CONFIG_VGA_CONSOLE) += vgacon.o | 26 | obj-$(CONFIG_VGA_CONSOLE) += vgacon.o |
28 | obj-$(CONFIG_MDA_CONSOLE) += mdacon.o | 27 | obj-$(CONFIG_MDA_CONSOLE) += mdacon.o |
@@ -40,14 +39,3 @@ obj-$(CONFIG_FB_STI) += sticore.o font.o | |||
40 | ifeq ($(CONFIG_USB_SISUSBVGA_CON),y) | 39 | ifeq ($(CONFIG_USB_SISUSBVGA_CON),y) |
41 | obj-$(CONFIG_USB_SISUSBVGA) += font.o | 40 | obj-$(CONFIG_USB_SISUSBVGA) += font.o |
42 | endif | 41 | endif |
43 | |||
44 | # Targets that kbuild needs to know about | ||
45 | targets := promcon_tbl.c | ||
46 | |||
47 | quiet_cmd_conmakehash = CNMKHSH $@ | ||
48 | cmd_conmakehash = scripts/conmakehash $< | \ | ||
49 | sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \ | ||
50 | -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@ | ||
51 | |||
52 | $(obj)/promcon_tbl.c: $(src)/prom.uni | ||
53 | $(call cmd,conmakehash) | ||
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 69864b1b3f9e..6b7c8fbc5495 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c | |||
@@ -25,7 +25,7 @@ static inline void update_attr(u8 *dst, u8 *src, int attribute, | |||
25 | struct vc_data *vc) | 25 | struct vc_data *vc) |
26 | { | 26 | { |
27 | int i, offset = (vc->vc_font.height < 10) ? 1 : 2; | 27 | int i, offset = (vc->vc_font.height < 10) ? 1 : 2; |
28 | int width = (vc->vc_font.width + 7) >> 3; | 28 | int width = DIV_ROUND_UP(vc->vc_font.width, 8); |
29 | unsigned int cellsize = vc->vc_font.height * width; | 29 | unsigned int cellsize = vc->vc_font.height * width; |
30 | u8 c; | 30 | u8 c; |
31 | 31 | ||
@@ -144,7 +144,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, | |||
144 | int fg, int bg) | 144 | int fg, int bg) |
145 | { | 145 | { |
146 | struct fb_image image; | 146 | struct fb_image image; |
147 | u32 width = (vc->vc_font.width + 7)/8; | 147 | u32 width = DIV_ROUND_UP(vc->vc_font.width, 8); |
148 | u32 cellsize = width * vc->vc_font.height; | 148 | u32 cellsize = width * vc->vc_font.height; |
149 | u32 maxcnt = info->pixmap.size/cellsize; | 149 | u32 maxcnt = info->pixmap.size/cellsize; |
150 | u32 scan_align = info->pixmap.scan_align - 1; | 150 | u32 scan_align = info->pixmap.scan_align - 1; |
@@ -173,7 +173,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, | |||
173 | cnt = count; | 173 | cnt = count; |
174 | 174 | ||
175 | image.width = vc->vc_font.width * cnt; | 175 | image.width = vc->vc_font.width * cnt; |
176 | pitch = ((image.width + 7) >> 3) + scan_align; | 176 | pitch = DIV_ROUND_UP(image.width, 8) + scan_align; |
177 | pitch &= ~scan_align; | 177 | pitch &= ~scan_align; |
178 | size = pitch * image.height + buf_align; | 178 | size = pitch * image.height + buf_align; |
179 | size &= ~buf_align; | 179 | size &= ~buf_align; |
@@ -239,7 +239,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, | |||
239 | struct fb_cursor cursor; | 239 | struct fb_cursor cursor; |
240 | struct fbcon_ops *ops = info->fbcon_par; | 240 | struct fbcon_ops *ops = info->fbcon_par; |
241 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; | 241 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; |
242 | int w = (vc->vc_font.width + 7) >> 3, c; | 242 | int w = DIV_ROUND_UP(vc->vc_font.width, 8), c; |
243 | int y = real_y(ops->p, vc->vc_y); | 243 | int y = real_y(ops->p, vc->vc_y); |
244 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); | 244 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); |
245 | int err = 1; | 245 | int err = 1; |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 471a9a60376a..3681c6a88212 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -114,6 +114,7 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1; | |||
114 | static int fbcon_is_default = 1; | 114 | static int fbcon_is_default = 1; |
115 | static int fbcon_has_exited; | 115 | static int fbcon_has_exited; |
116 | static int primary_device = -1; | 116 | static int primary_device = -1; |
117 | static int fbcon_has_console_bind; | ||
117 | 118 | ||
118 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY | 119 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY |
119 | static int map_override; | 120 | static int map_override; |
@@ -544,6 +545,8 @@ static int fbcon_takeover(int show_logo) | |||
544 | con2fb_map[i] = -1; | 545 | con2fb_map[i] = -1; |
545 | } | 546 | } |
546 | info_idx = -1; | 547 | info_idx = -1; |
548 | } else { | ||
549 | fbcon_has_console_bind = 1; | ||
547 | } | 550 | } |
548 | 551 | ||
549 | return err; | 552 | return err; |
@@ -725,7 +728,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, | |||
725 | int oldidx, int found) | 728 | int oldidx, int found) |
726 | { | 729 | { |
727 | struct fbcon_ops *ops = oldinfo->fbcon_par; | 730 | struct fbcon_ops *ops = oldinfo->fbcon_par; |
728 | int err = 0; | 731 | int err = 0, ret; |
729 | 732 | ||
730 | if (oldinfo->fbops->fb_release && | 733 | if (oldinfo->fbops->fb_release && |
731 | oldinfo->fbops->fb_release(oldinfo, 0)) { | 734 | oldinfo->fbops->fb_release(oldinfo, 0)) { |
@@ -752,8 +755,14 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, | |||
752 | newinfo in an undefined state. Thus, a call to | 755 | newinfo in an undefined state. Thus, a call to |
753 | fb_set_par() may be needed for the newinfo. | 756 | fb_set_par() may be needed for the newinfo. |
754 | */ | 757 | */ |
755 | if (newinfo->fbops->fb_set_par) | 758 | if (newinfo->fbops->fb_set_par) { |
756 | newinfo->fbops->fb_set_par(newinfo); | 759 | ret = newinfo->fbops->fb_set_par(newinfo); |
760 | |||
761 | if (ret) | ||
762 | printk(KERN_ERR "con2fb_release_oldinfo: " | ||
763 | "detected unhandled fb_set_par error, " | ||
764 | "error code %d\n", ret); | ||
765 | } | ||
757 | } | 766 | } |
758 | 767 | ||
759 | return err; | 768 | return err; |
@@ -763,11 +772,18 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, | |||
763 | int unit, int show_logo) | 772 | int unit, int show_logo) |
764 | { | 773 | { |
765 | struct fbcon_ops *ops = info->fbcon_par; | 774 | struct fbcon_ops *ops = info->fbcon_par; |
775 | int ret; | ||
766 | 776 | ||
767 | ops->currcon = fg_console; | 777 | ops->currcon = fg_console; |
768 | 778 | ||
769 | if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT)) | 779 | if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT)) { |
770 | info->fbops->fb_set_par(info); | 780 | ret = info->fbops->fb_set_par(info); |
781 | |||
782 | if (ret) | ||
783 | printk(KERN_ERR "con2fb_init_display: detected " | ||
784 | "unhandled fb_set_par error, " | ||
785 | "error code %d\n", ret); | ||
786 | } | ||
771 | 787 | ||
772 | ops->flags |= FBCON_FLAGS_INIT; | 788 | ops->flags |= FBCON_FLAGS_INIT; |
773 | ops->graphics = 0; | 789 | ops->graphics = 0; |
@@ -1006,7 +1022,7 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1006 | struct vc_data *svc = *default_mode; | 1022 | struct vc_data *svc = *default_mode; |
1007 | struct display *t, *p = &fb_display[vc->vc_num]; | 1023 | struct display *t, *p = &fb_display[vc->vc_num]; |
1008 | int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; | 1024 | int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; |
1009 | int cap; | 1025 | int cap, ret; |
1010 | 1026 | ||
1011 | if (info_idx == -1 || info == NULL) | 1027 | if (info_idx == -1 || info == NULL) |
1012 | return; | 1028 | return; |
@@ -1082,7 +1098,6 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1082 | new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); | 1098 | new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); |
1083 | new_cols /= vc->vc_font.width; | 1099 | new_cols /= vc->vc_font.width; |
1084 | new_rows /= vc->vc_font.height; | 1100 | new_rows /= vc->vc_font.height; |
1085 | vc_resize(vc, new_cols, new_rows); | ||
1086 | 1101 | ||
1087 | /* | 1102 | /* |
1088 | * We must always set the mode. The mode of the previous console | 1103 | * We must always set the mode. The mode of the previous console |
@@ -1093,8 +1108,15 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1093 | */ | 1108 | */ |
1094 | if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { | 1109 | if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { |
1095 | if (info->fbops->fb_set_par && | 1110 | if (info->fbops->fb_set_par && |
1096 | !(ops->flags & FBCON_FLAGS_INIT)) | 1111 | !(ops->flags & FBCON_FLAGS_INIT)) { |
1097 | info->fbops->fb_set_par(info); | 1112 | ret = info->fbops->fb_set_par(info); |
1113 | |||
1114 | if (ret) | ||
1115 | printk(KERN_ERR "fbcon_init: detected " | ||
1116 | "unhandled fb_set_par error, " | ||
1117 | "error code %d\n", ret); | ||
1118 | } | ||
1119 | |||
1098 | ops->flags |= FBCON_FLAGS_INIT; | 1120 | ops->flags |= FBCON_FLAGS_INIT; |
1099 | } | 1121 | } |
1100 | 1122 | ||
@@ -1111,10 +1133,11 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1111 | * vc_{cols,rows}, but we must not set those if we are only | 1133 | * vc_{cols,rows}, but we must not set those if we are only |
1112 | * resizing the console. | 1134 | * resizing the console. |
1113 | */ | 1135 | */ |
1114 | if (!init) { | 1136 | if (init) { |
1115 | vc->vc_cols = new_cols; | 1137 | vc->vc_cols = new_cols; |
1116 | vc->vc_rows = new_rows; | 1138 | vc->vc_rows = new_rows; |
1117 | } | 1139 | } else |
1140 | vc_resize(vc, new_cols, new_rows); | ||
1118 | 1141 | ||
1119 | if (logo) | 1142 | if (logo) |
1120 | fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); | 1143 | fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); |
@@ -2119,7 +2142,7 @@ static int fbcon_switch(struct vc_data *vc) | |||
2119 | struct fbcon_ops *ops; | 2142 | struct fbcon_ops *ops; |
2120 | struct display *p = &fb_display[vc->vc_num]; | 2143 | struct display *p = &fb_display[vc->vc_num]; |
2121 | struct fb_var_screeninfo var; | 2144 | struct fb_var_screeninfo var; |
2122 | int i, prev_console, charcnt = 256; | 2145 | int i, ret, prev_console, charcnt = 256; |
2123 | 2146 | ||
2124 | info = registered_fb[con2fb_map[vc->vc_num]]; | 2147 | info = registered_fb[con2fb_map[vc->vc_num]]; |
2125 | ops = info->fbcon_par; | 2148 | ops = info->fbcon_par; |
@@ -2174,8 +2197,14 @@ static int fbcon_switch(struct vc_data *vc) | |||
2174 | 2197 | ||
2175 | if (old_info != NULL && (old_info != info || | 2198 | if (old_info != NULL && (old_info != info || |
2176 | info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { | 2199 | info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { |
2177 | if (info->fbops->fb_set_par) | 2200 | if (info->fbops->fb_set_par) { |
2178 | info->fbops->fb_set_par(info); | 2201 | ret = info->fbops->fb_set_par(info); |
2202 | |||
2203 | if (ret) | ||
2204 | printk(KERN_ERR "fbcon_switch: detected " | ||
2205 | "unhandled fb_set_par error, " | ||
2206 | "error code %d\n", ret); | ||
2207 | } | ||
2179 | 2208 | ||
2180 | if (old_info != info) | 2209 | if (old_info != info) |
2181 | fbcon_del_cursor_timer(old_info); | 2210 | fbcon_del_cursor_timer(old_info); |
@@ -2282,14 +2311,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | |||
2282 | ops->graphics = 1; | 2311 | ops->graphics = 1; |
2283 | 2312 | ||
2284 | if (!blank) { | 2313 | if (!blank) { |
2285 | if (info->fbops->fb_save_state) | ||
2286 | info->fbops->fb_save_state(info); | ||
2287 | var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; | 2314 | var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; |
2288 | fb_set_var(info, &var); | 2315 | fb_set_var(info, &var); |
2289 | ops->graphics = 0; | 2316 | ops->graphics = 0; |
2290 | ops->var = info->var; | 2317 | ops->var = info->var; |
2291 | } else if (info->fbops->fb_restore_state) | 2318 | } |
2292 | info->fbops->fb_restore_state(info); | ||
2293 | } | 2319 | } |
2294 | 2320 | ||
2295 | if (!fbcon_is_inactive(vc, info)) { | 2321 | if (!fbcon_is_inactive(vc, info)) { |
@@ -2923,6 +2949,10 @@ static int fbcon_unbind(void) | |||
2923 | 2949 | ||
2924 | ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, | 2950 | ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, |
2925 | fbcon_is_default); | 2951 | fbcon_is_default); |
2952 | |||
2953 | if (!ret) | ||
2954 | fbcon_has_console_bind = 0; | ||
2955 | |||
2926 | return ret; | 2956 | return ret; |
2927 | } | 2957 | } |
2928 | #else | 2958 | #else |
@@ -2936,6 +2966,9 @@ static int fbcon_fb_unbind(int idx) | |||
2936 | { | 2966 | { |
2937 | int i, new_idx = -1, ret = 0; | 2967 | int i, new_idx = -1, ret = 0; |
2938 | 2968 | ||
2969 | if (!fbcon_has_console_bind) | ||
2970 | return 0; | ||
2971 | |||
2939 | for (i = first_fb_vc; i <= last_fb_vc; i++) { | 2972 | for (i = first_fb_vc; i <= last_fb_vc; i++) { |
2940 | if (con2fb_map[i] != idx && | 2973 | if (con2fb_map[i] != idx && |
2941 | con2fb_map[i] != -1) { | 2974 | con2fb_map[i] != -1) { |
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h index 75be5ce53dc5..e233444cda66 100644 --- a/drivers/video/console/fbcon_rotate.h +++ b/drivers/video/console/fbcon_rotate.h | |||
@@ -45,7 +45,7 @@ static inline void rotate_ud(const char *in, char *out, u32 width, u32 height) | |||
45 | width = (width + 7) & ~7; | 45 | width = (width + 7) & ~7; |
46 | 46 | ||
47 | for (i = 0; i < height; i++) { | 47 | for (i = 0; i < height; i++) { |
48 | for (j = 0; j < width; j++) { | 48 | for (j = 0; j < width - shift; j++) { |
49 | if (pattern_test_bit(j, i, width, in)) | 49 | if (pattern_test_bit(j, i, width, in)) |
50 | pattern_set_bit(width - (1 + j + shift), | 50 | pattern_set_bit(width - (1 + j + shift), |
51 | height - (1 + i), | 51 | height - (1 + i), |
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index d31b203bf654..3772433c49d1 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c | |||
@@ -216,7 +216,7 @@ static void newport_get_screensize(void) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | newport_xsize = newport_ysize = 0; | 218 | newport_xsize = newport_ysize = 0; |
219 | for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) { | 219 | for (i = 0; i < ARRAY_SIZE(linetable) - 1 && linetable[i + 1]; i += 2) { |
220 | cols = 0; | 220 | cols = 0; |
221 | newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]); | 221 | newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]); |
222 | npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | | 222 | npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | |
diff --git a/drivers/video/console/prom.uni b/drivers/video/console/prom.uni deleted file mode 100644 index 58f9c04ed9d3..000000000000 --- a/drivers/video/console/prom.uni +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | # | ||
2 | # Unicode mapping table for font in Sun PROM | ||
3 | # | ||
4 | # | ||
5 | 0x20-0x7e idem | ||
6 | 0xa0-0xff idem | ||
7 | # | ||
8 | 0x7c U+2502 | ||
9 | 0x2d U+2500 | ||
10 | 0x2b U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c | ||
11 | 0xa4 U+fffd | ||
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c deleted file mode 100644 index ae02e4eb18e7..000000000000 --- a/drivers/video/console/promcon.c +++ /dev/null | |||
@@ -1,598 +0,0 @@ | |||
1 | /* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $ | ||
2 | * Console driver utilizing PROM sun terminal emulation | ||
3 | * | ||
4 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | ||
5 | * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/console.h> | ||
16 | #include <linux/vt_kern.h> | ||
17 | #include <linux/selection.h> | ||
18 | #include <linux/fb.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kd.h> | ||
21 | |||
22 | #include <asm/oplib.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | |||
25 | static short pw = 80 - 1, ph = 34 - 1; | ||
26 | static short px, py; | ||
27 | static unsigned long promcon_uni_pagedir[2]; | ||
28 | |||
29 | extern u8 promfont_unicount[]; | ||
30 | extern u16 promfont_unitable[]; | ||
31 | |||
32 | #define PROMCON_COLOR 0 | ||
33 | |||
34 | #if PROMCON_COLOR | ||
35 | #define inverted(s) ((((s) & 0x7700) == 0x0700) ? 0 : 1) | ||
36 | #else | ||
37 | #define inverted(s) (((s) & 0x0800) ? 1 : 0) | ||
38 | #endif | ||
39 | |||
40 | static __inline__ void | ||
41 | promcon_puts(char *buf, int cnt) | ||
42 | { | ||
43 | prom_printf("%*.*s", cnt, cnt, buf); | ||
44 | } | ||
45 | |||
46 | static int | ||
47 | promcon_start(struct vc_data *conp, char *b) | ||
48 | { | ||
49 | unsigned short *s = (unsigned short *) | ||
50 | (conp->vc_origin + py * conp->vc_size_row + (px << 1)); | ||
51 | u16 cs; | ||
52 | |||
53 | cs = scr_readw(s); | ||
54 | if (px == pw) { | ||
55 | unsigned short *t = s - 1; | ||
56 | u16 ct = scr_readw(t); | ||
57 | |||
58 | if (inverted(cs) && inverted(ct)) | ||
59 | return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, | ||
60 | ct); | ||
61 | else if (inverted(cs)) | ||
62 | return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, | ||
63 | ct); | ||
64 | else if (inverted(ct)) | ||
65 | return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, | ||
66 | ct); | ||
67 | else | ||
68 | return sprintf(b, "\b%c\b\033[@%c", cs, ct); | ||
69 | } | ||
70 | |||
71 | if (inverted(cs)) | ||
72 | return sprintf(b, "\033[7m%c\033[m\b", cs); | ||
73 | else | ||
74 | return sprintf(b, "%c\b", cs); | ||
75 | } | ||
76 | |||
77 | static int | ||
78 | promcon_end(struct vc_data *conp, char *b) | ||
79 | { | ||
80 | unsigned short *s = (unsigned short *) | ||
81 | (conp->vc_origin + py * conp->vc_size_row + (px << 1)); | ||
82 | char *p = b; | ||
83 | u16 cs; | ||
84 | |||
85 | b += sprintf(b, "\033[%d;%dH", py + 1, px + 1); | ||
86 | |||
87 | cs = scr_readw(s); | ||
88 | if (px == pw) { | ||
89 | unsigned short *t = s - 1; | ||
90 | u16 ct = scr_readw(t); | ||
91 | |||
92 | if (inverted(cs) && inverted(ct)) | ||
93 | b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct); | ||
94 | else if (inverted(cs)) | ||
95 | b += sprintf(b, "\b%c\b\033[@%c", cs, ct); | ||
96 | else if (inverted(ct)) | ||
97 | b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct); | ||
98 | else | ||
99 | b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct); | ||
100 | return b - p; | ||
101 | } | ||
102 | |||
103 | if (inverted(cs)) | ||
104 | b += sprintf(b, "%c\b", cs); | ||
105 | else | ||
106 | b += sprintf(b, "\033[7m%c\033[m\b", cs); | ||
107 | return b - p; | ||
108 | } | ||
109 | |||
110 | const char *promcon_startup(void) | ||
111 | { | ||
112 | const char *display_desc = "PROM"; | ||
113 | int node; | ||
114 | char buf[40]; | ||
115 | |||
116 | node = prom_getchild(prom_root_node); | ||
117 | node = prom_searchsiblings(node, "options"); | ||
118 | if (prom_getproperty(node, "screen-#columns", buf, 40) != -1) { | ||
119 | pw = simple_strtoul(buf, NULL, 0); | ||
120 | if (pw < 10 || pw > 256) | ||
121 | pw = 80; | ||
122 | pw--; | ||
123 | } | ||
124 | if (prom_getproperty(node, "screen-#rows", buf, 40) != -1) { | ||
125 | ph = simple_strtoul(buf, NULL, 0); | ||
126 | if (ph < 10 || ph > 256) | ||
127 | ph = 34; | ||
128 | ph--; | ||
129 | } | ||
130 | promcon_puts("\033[H\033[J", 6); | ||
131 | return display_desc; | ||
132 | } | ||
133 | |||
134 | static void | ||
135 | promcon_init_unimap(struct vc_data *conp) | ||
136 | { | ||
137 | mm_segment_t old_fs = get_fs(); | ||
138 | struct unipair *p, *p1; | ||
139 | u16 *q; | ||
140 | int i, j, k; | ||
141 | |||
142 | p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL); | ||
143 | if (!p) return; | ||
144 | |||
145 | q = promfont_unitable; | ||
146 | p1 = p; | ||
147 | k = 0; | ||
148 | for (i = 0; i < 256; i++) | ||
149 | for (j = promfont_unicount[i]; j; j--) { | ||
150 | p1->unicode = *q++; | ||
151 | p1->fontpos = i; | ||
152 | p1++; | ||
153 | k++; | ||
154 | } | ||
155 | set_fs(KERNEL_DS); | ||
156 | con_clear_unimap(conp, NULL); | ||
157 | con_set_unimap(conp, k, p); | ||
158 | con_protect_unimap(conp, 1); | ||
159 | set_fs(old_fs); | ||
160 | kfree(p); | ||
161 | } | ||
162 | |||
163 | static void | ||
164 | promcon_init(struct vc_data *conp, int init) | ||
165 | { | ||
166 | unsigned long p; | ||
167 | |||
168 | conp->vc_can_do_color = PROMCON_COLOR; | ||
169 | if (init) { | ||
170 | conp->vc_cols = pw + 1; | ||
171 | conp->vc_rows = ph + 1; | ||
172 | } | ||
173 | p = *conp->vc_uni_pagedir_loc; | ||
174 | if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir || | ||
175 | !--conp->vc_uni_pagedir_loc[1]) | ||
176 | con_free_unimap(conp); | ||
177 | conp->vc_uni_pagedir_loc = promcon_uni_pagedir; | ||
178 | promcon_uni_pagedir[1]++; | ||
179 | if (!promcon_uni_pagedir[0] && p) { | ||
180 | promcon_init_unimap(conp); | ||
181 | } | ||
182 | if (!init) { | ||
183 | if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1) | ||
184 | vc_resize(conp, pw + 1, ph + 1); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | static void | ||
189 | promcon_deinit(struct vc_data *conp) | ||
190 | { | ||
191 | /* When closing the last console, reset video origin */ | ||
192 | if (!--promcon_uni_pagedir[1]) | ||
193 | con_free_unimap(conp); | ||
194 | conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir; | ||
195 | con_set_default_unimap(conp); | ||
196 | } | ||
197 | |||
198 | static int | ||
199 | promcon_switch(struct vc_data *conp) | ||
200 | { | ||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | static unsigned short * | ||
205 | promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp) | ||
206 | { | ||
207 | int cnt = pw + 1; | ||
208 | int attr = -1; | ||
209 | unsigned char *b = *bp; | ||
210 | |||
211 | while (cnt--) { | ||
212 | u16 c = scr_readw(s); | ||
213 | if (attr != inverted(c)) { | ||
214 | attr = inverted(c); | ||
215 | if (attr) { | ||
216 | strcpy (b, "\033[7m"); | ||
217 | b += 4; | ||
218 | } else { | ||
219 | strcpy (b, "\033[m"); | ||
220 | b += 3; | ||
221 | } | ||
222 | } | ||
223 | *b++ = c; | ||
224 | s++; | ||
225 | if (b - buf >= 224) { | ||
226 | promcon_puts(buf, b - buf); | ||
227 | b = buf; | ||
228 | } | ||
229 | } | ||
230 | *bp = b; | ||
231 | return s; | ||
232 | } | ||
233 | |||
234 | static void | ||
235 | promcon_putcs(struct vc_data *conp, const unsigned short *s, | ||
236 | int count, int y, int x) | ||
237 | { | ||
238 | unsigned char buf[256], *b = buf; | ||
239 | unsigned short attr = scr_readw(s); | ||
240 | unsigned char save; | ||
241 | int i, last = 0; | ||
242 | |||
243 | if (console_blanked) | ||
244 | return; | ||
245 | |||
246 | if (count <= 0) | ||
247 | return; | ||
248 | |||
249 | b += promcon_start(conp, b); | ||
250 | |||
251 | if (x + count >= pw + 1) { | ||
252 | if (count == 1) { | ||
253 | x -= 1; | ||
254 | save = scr_readw((unsigned short *)(conp->vc_origin | ||
255 | + y * conp->vc_size_row | ||
256 | + (x << 1))); | ||
257 | |||
258 | if (px != x || py != y) { | ||
259 | b += sprintf(b, "\033[%d;%dH", y + 1, x + 1); | ||
260 | px = x; | ||
261 | py = y; | ||
262 | } | ||
263 | |||
264 | if (inverted(attr)) | ||
265 | b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++)); | ||
266 | else | ||
267 | b += sprintf(b, "%c", scr_readw(s++)); | ||
268 | |||
269 | strcpy(b, "\b\033[@"); | ||
270 | b += 4; | ||
271 | |||
272 | if (inverted(save)) | ||
273 | b += sprintf(b, "\033[7m%c\033[m", save); | ||
274 | else | ||
275 | b += sprintf(b, "%c", save); | ||
276 | |||
277 | px++; | ||
278 | |||
279 | b += promcon_end(conp, b); | ||
280 | promcon_puts(buf, b - buf); | ||
281 | return; | ||
282 | } else { | ||
283 | last = 1; | ||
284 | count = pw - x - 1; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | if (inverted(attr)) { | ||
289 | strcpy(b, "\033[7m"); | ||
290 | b += 4; | ||
291 | } | ||
292 | |||
293 | if (px != x || py != y) { | ||
294 | b += sprintf(b, "\033[%d;%dH", y + 1, x + 1); | ||
295 | px = x; | ||
296 | py = y; | ||
297 | } | ||
298 | |||
299 | for (i = 0; i < count; i++) { | ||
300 | if (b - buf >= 224) { | ||
301 | promcon_puts(buf, b - buf); | ||
302 | b = buf; | ||
303 | } | ||
304 | *b++ = scr_readw(s++); | ||
305 | } | ||
306 | |||
307 | px += count; | ||
308 | |||
309 | if (last) { | ||
310 | save = scr_readw(s++); | ||
311 | b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save); | ||
312 | px++; | ||
313 | } | ||
314 | |||
315 | if (inverted(attr)) { | ||
316 | strcpy(b, "\033[m"); | ||
317 | b += 3; | ||
318 | } | ||
319 | |||
320 | b += promcon_end(conp, b); | ||
321 | promcon_puts(buf, b - buf); | ||
322 | } | ||
323 | |||
324 | static void | ||
325 | promcon_putc(struct vc_data *conp, int c, int y, int x) | ||
326 | { | ||
327 | unsigned short s; | ||
328 | |||
329 | if (console_blanked) | ||
330 | return; | ||
331 | |||
332 | scr_writew(c, &s); | ||
333 | promcon_putcs(conp, &s, 1, y, x); | ||
334 | } | ||
335 | |||
336 | static void | ||
337 | promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width) | ||
338 | { | ||
339 | unsigned char buf[256], *b = buf; | ||
340 | int i, j; | ||
341 | |||
342 | if (console_blanked) | ||
343 | return; | ||
344 | |||
345 | b += promcon_start(conp, b); | ||
346 | |||
347 | if (!sx && width == pw + 1) { | ||
348 | |||
349 | if (!sy && height == ph + 1) { | ||
350 | strcpy(b, "\033[H\033[J"); | ||
351 | b += 6; | ||
352 | b += promcon_end(conp, b); | ||
353 | promcon_puts(buf, b - buf); | ||
354 | return; | ||
355 | } else if (sy + height == ph + 1) { | ||
356 | b += sprintf(b, "\033[%dH\033[J", sy + 1); | ||
357 | b += promcon_end(conp, b); | ||
358 | promcon_puts(buf, b - buf); | ||
359 | return; | ||
360 | } | ||
361 | |||
362 | b += sprintf(b, "\033[%dH", sy + 1); | ||
363 | for (i = 1; i < height; i++) { | ||
364 | strcpy(b, "\033[K\n"); | ||
365 | b += 4; | ||
366 | } | ||
367 | |||
368 | strcpy(b, "\033[K"); | ||
369 | b += 3; | ||
370 | |||
371 | b += promcon_end(conp, b); | ||
372 | promcon_puts(buf, b - buf); | ||
373 | return; | ||
374 | |||
375 | } else if (sx + width == pw + 1) { | ||
376 | |||
377 | b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1); | ||
378 | for (i = 1; i < height; i++) { | ||
379 | strcpy(b, "\033[K\n"); | ||
380 | b += 4; | ||
381 | } | ||
382 | |||
383 | strcpy(b, "\033[K"); | ||
384 | b += 3; | ||
385 | |||
386 | b += promcon_end(conp, b); | ||
387 | promcon_puts(buf, b - buf); | ||
388 | return; | ||
389 | } | ||
390 | |||
391 | for (i = sy + 1; i <= sy + height; i++) { | ||
392 | b += sprintf(b, "\033[%d;%dH", i, sx + 1); | ||
393 | for (j = 0; j < width; j++) | ||
394 | *b++ = ' '; | ||
395 | if (b - buf + width >= 224) { | ||
396 | promcon_puts(buf, b - buf); | ||
397 | b = buf; | ||
398 | } | ||
399 | } | ||
400 | |||
401 | b += promcon_end(conp, b); | ||
402 | promcon_puts(buf, b - buf); | ||
403 | } | ||
404 | |||
405 | static void | ||
406 | promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx, | ||
407 | int height, int width) | ||
408 | { | ||
409 | char buf[256], *b = buf; | ||
410 | |||
411 | if (console_blanked) | ||
412 | return; | ||
413 | |||
414 | b += promcon_start(conp, b); | ||
415 | if (sy == dy && height == 1) { | ||
416 | if (dx > sx && dx + width == conp->vc_cols) | ||
417 | b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH", | ||
418 | sy + 1, sx + 1, dx - sx, py + 1, px + 1); | ||
419 | else if (dx < sx && sx + width == conp->vc_cols) | ||
420 | b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH", | ||
421 | dy + 1, dx + 1, sx - dx, py + 1, px + 1); | ||
422 | |||
423 | b += promcon_end(conp, b); | ||
424 | promcon_puts(buf, b - buf); | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * FIXME: What to do here??? | ||
430 | * Current console.c should not call it like that ever. | ||
431 | */ | ||
432 | prom_printf("\033[7mFIXME: bmove not handled\033[m\n"); | ||
433 | } | ||
434 | |||
435 | static void | ||
436 | promcon_cursor(struct vc_data *conp, int mode) | ||
437 | { | ||
438 | char buf[32], *b = buf; | ||
439 | |||
440 | switch (mode) { | ||
441 | case CM_ERASE: | ||
442 | break; | ||
443 | |||
444 | case CM_MOVE: | ||
445 | case CM_DRAW: | ||
446 | b += promcon_start(conp, b); | ||
447 | if (px != conp->vc_x || py != conp->vc_y) { | ||
448 | px = conp->vc_x; | ||
449 | py = conp->vc_y; | ||
450 | b += sprintf(b, "\033[%d;%dH", py + 1, px + 1); | ||
451 | } | ||
452 | promcon_puts(buf, b - buf); | ||
453 | break; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | static int | ||
458 | promcon_blank(struct vc_data *conp, int blank, int mode_switch) | ||
459 | { | ||
460 | if (blank) { | ||
461 | promcon_puts("\033[H\033[J\033[7m \033[m\b", 15); | ||
462 | return 0; | ||
463 | } else { | ||
464 | /* Let console.c redraw */ | ||
465 | return 1; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | static int | ||
470 | promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count) | ||
471 | { | ||
472 | unsigned char buf[256], *p = buf; | ||
473 | unsigned short *s; | ||
474 | int i; | ||
475 | |||
476 | if (console_blanked) | ||
477 | return 0; | ||
478 | |||
479 | p += promcon_start(conp, p); | ||
480 | |||
481 | switch (dir) { | ||
482 | case SM_UP: | ||
483 | if (b == ph + 1) { | ||
484 | p += sprintf(p, "\033[%dH\033[%dM", t + 1, count); | ||
485 | px = 0; | ||
486 | py = t; | ||
487 | p += promcon_end(conp, p); | ||
488 | promcon_puts(buf, p - buf); | ||
489 | break; | ||
490 | } | ||
491 | |||
492 | s = (unsigned short *)(conp->vc_origin | ||
493 | + (t + count) * conp->vc_size_row); | ||
494 | |||
495 | p += sprintf(p, "\033[%dH", t + 1); | ||
496 | |||
497 | for (i = t; i < b - count; i++) | ||
498 | s = promcon_repaint_line(s, buf, &p); | ||
499 | |||
500 | for (; i < b - 1; i++) { | ||
501 | strcpy(p, "\033[K\n"); | ||
502 | p += 4; | ||
503 | if (p - buf >= 224) { | ||
504 | promcon_puts(buf, p - buf); | ||
505 | p = buf; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | strcpy(p, "\033[K"); | ||
510 | p += 3; | ||
511 | |||
512 | p += promcon_end(conp, p); | ||
513 | promcon_puts(buf, p - buf); | ||
514 | break; | ||
515 | |||
516 | case SM_DOWN: | ||
517 | if (b == ph + 1) { | ||
518 | p += sprintf(p, "\033[%dH\033[%dL", t + 1, count); | ||
519 | px = 0; | ||
520 | py = t; | ||
521 | p += promcon_end(conp, p); | ||
522 | promcon_puts(buf, p - buf); | ||
523 | break; | ||
524 | } | ||
525 | |||
526 | s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row); | ||
527 | |||
528 | p += sprintf(p, "\033[%dH", t + 1); | ||
529 | |||
530 | for (i = t; i < t + count; i++) { | ||
531 | strcpy(p, "\033[K\n"); | ||
532 | p += 4; | ||
533 | if (p - buf >= 224) { | ||
534 | promcon_puts(buf, p - buf); | ||
535 | p = buf; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | for (; i < b; i++) | ||
540 | s = promcon_repaint_line(s, buf, &p); | ||
541 | |||
542 | p += promcon_end(conp, p); | ||
543 | promcon_puts(buf, p - buf); | ||
544 | break; | ||
545 | } | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | #if !(PROMCON_COLOR) | ||
551 | static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, | ||
552 | u8 _blink, u8 _underline, u8 _reverse, u8 _italic) | ||
553 | { | ||
554 | return (_reverse) ? 0xf : 0x7; | ||
555 | } | ||
556 | #endif | ||
557 | |||
558 | /* | ||
559 | * The console 'switch' structure for the VGA based console | ||
560 | */ | ||
561 | |||
562 | static int promcon_dummy(void) | ||
563 | { | ||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | #define DUMMY (void *) promcon_dummy | ||
568 | |||
569 | const struct consw prom_con = { | ||
570 | .owner = THIS_MODULE, | ||
571 | .con_startup = promcon_startup, | ||
572 | .con_init = promcon_init, | ||
573 | .con_deinit = promcon_deinit, | ||
574 | .con_clear = promcon_clear, | ||
575 | .con_putc = promcon_putc, | ||
576 | .con_putcs = promcon_putcs, | ||
577 | .con_cursor = promcon_cursor, | ||
578 | .con_scroll = promcon_scroll, | ||
579 | .con_bmove = promcon_bmove, | ||
580 | .con_switch = promcon_switch, | ||
581 | .con_blank = promcon_blank, | ||
582 | .con_set_palette = DUMMY, | ||
583 | .con_scrolldelta = DUMMY, | ||
584 | #if !(PROMCON_COLOR) | ||
585 | .con_build_attr = promcon_build_attr, | ||
586 | #endif | ||
587 | }; | ||
588 | |||
589 | void __init prom_con_init(void) | ||
590 | { | ||
591 | #ifdef CONFIG_DUMMY_CONSOLE | ||
592 | if (conswitchp == &dummy_con) | ||
593 | take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1); | ||
594 | else | ||
595 | #endif | ||
596 | if (conswitchp == &prom_con) | ||
597 | promcon_init_unimap(vc_cons[fg_console].d); | ||
598 | } | ||
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index ef7870f5ea08..857b3668b3ba 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c | |||
@@ -957,9 +957,14 @@ static int __devinit sticore_pci_init(struct pci_dev *pd, | |||
957 | #ifdef CONFIG_PCI | 957 | #ifdef CONFIG_PCI |
958 | unsigned long fb_base, rom_base; | 958 | unsigned long fb_base, rom_base; |
959 | unsigned int fb_len, rom_len; | 959 | unsigned int fb_len, rom_len; |
960 | int err; | ||
960 | struct sti_struct *sti; | 961 | struct sti_struct *sti; |
961 | 962 | ||
962 | pci_enable_device(pd); | 963 | err = pci_enable_device(pd); |
964 | if (err < 0) { | ||
965 | dev_err(&pd->dev, "Cannot enable PCI device\n"); | ||
966 | return err; | ||
967 | } | ||
963 | 968 | ||
964 | fb_base = pci_resource_start(pd, 0); | 969 | fb_base = pci_resource_start(pd, 0); |
965 | fb_len = pci_resource_len(pd, 0); | 970 | fb_len = pci_resource_len(pd, 0); |
@@ -1048,7 +1053,7 @@ static void __devinit sti_init_roms(void) | |||
1048 | 1053 | ||
1049 | /* Register drivers for native & PCI cards */ | 1054 | /* Register drivers for native & PCI cards */ |
1050 | register_parisc_driver(&pa_sti_driver); | 1055 | register_parisc_driver(&pa_sti_driver); |
1051 | pci_register_driver(&pci_sti_driver); | 1056 | WARN_ON(pci_register_driver(&pci_sti_driver)); |
1052 | 1057 | ||
1053 | /* if we didn't find the given default sti, take the first one */ | 1058 | /* if we didn't find the given default sti, take the first one */ |
1054 | if (!default_sti) | 1059 | if (!default_sti) |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 59d7d5ec17a4..da55ccaf4d55 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -180,7 +180,6 @@ static inline void vga_set_mem_top(struct vc_data *c) | |||
180 | } | 180 | } |
181 | 181 | ||
182 | #ifdef CONFIG_VGACON_SOFT_SCROLLBACK | 182 | #ifdef CONFIG_VGACON_SOFT_SCROLLBACK |
183 | #include <linux/slab.h> | ||
184 | /* software scrollback */ | 183 | /* software scrollback */ |
185 | static void *vgacon_scrollback; | 184 | static void *vgacon_scrollback; |
186 | static int vgacon_scrollback_tail; | 185 | static int vgacon_scrollback_tail; |
@@ -590,12 +589,14 @@ static void vgacon_init(struct vc_data *c, int init) | |||
590 | 589 | ||
591 | static void vgacon_deinit(struct vc_data *c) | 590 | static void vgacon_deinit(struct vc_data *c) |
592 | { | 591 | { |
593 | /* When closing the last console, reset video origin */ | 592 | /* When closing the active console, reset video origin */ |
594 | if (!--vgacon_uni_pagedir[1]) { | 593 | if (CON_IS_VISIBLE(c)) { |
595 | c->vc_visible_origin = vga_vram_base; | 594 | c->vc_visible_origin = vga_vram_base; |
596 | vga_set_mem_top(c); | 595 | vga_set_mem_top(c); |
597 | con_free_unimap(c); | ||
598 | } | 596 | } |
597 | |||
598 | if (!--vgacon_uni_pagedir[1]) | ||
599 | con_free_unimap(c); | ||
599 | c->vc_uni_pagedir_loc = &c->vc_uni_pagedir; | 600 | c->vc_uni_pagedir_loc = &c->vc_uni_pagedir; |
600 | con_set_default_unimap(c); | 601 | con_set_default_unimap(c); |
601 | } | 602 | } |
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c new file mode 100644 index 000000000000..035d56835b75 --- /dev/null +++ b/drivers/video/da8xx-fb.c | |||
@@ -0,0 +1,889 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 MontaVista Software Inc. | ||
3 | * Copyright (C) 2008-2009 Texas Instruments Inc | ||
4 | * | ||
5 | * Based on the LCD driver for TI Avalanche processors written by | ||
6 | * Ajay Singh and Shalom Hai. | ||
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 as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option)any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/fb.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <video/da8xx-fb.h> | ||
32 | |||
33 | #define DRIVER_NAME "da8xx_lcdc" | ||
34 | |||
35 | /* LCD Status Register */ | ||
36 | #define LCD_END_OF_FRAME0 BIT(8) | ||
37 | #define LCD_FIFO_UNDERFLOW BIT(5) | ||
38 | #define LCD_SYNC_LOST BIT(2) | ||
39 | |||
40 | /* LCD DMA Control Register */ | ||
41 | #define LCD_DMA_BURST_SIZE(x) ((x) << 4) | ||
42 | #define LCD_DMA_BURST_1 0x0 | ||
43 | #define LCD_DMA_BURST_2 0x1 | ||
44 | #define LCD_DMA_BURST_4 0x2 | ||
45 | #define LCD_DMA_BURST_8 0x3 | ||
46 | #define LCD_DMA_BURST_16 0x4 | ||
47 | #define LCD_END_OF_FRAME_INT_ENA BIT(2) | ||
48 | #define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0) | ||
49 | |||
50 | /* LCD Control Register */ | ||
51 | #define LCD_CLK_DIVISOR(x) ((x) << 8) | ||
52 | #define LCD_RASTER_MODE 0x01 | ||
53 | |||
54 | /* LCD Raster Control Register */ | ||
55 | #define LCD_PALETTE_LOAD_MODE(x) ((x) << 20) | ||
56 | #define PALETTE_AND_DATA 0x00 | ||
57 | #define PALETTE_ONLY 0x01 | ||
58 | |||
59 | #define LCD_MONO_8BIT_MODE BIT(9) | ||
60 | #define LCD_RASTER_ORDER BIT(8) | ||
61 | #define LCD_TFT_MODE BIT(7) | ||
62 | #define LCD_UNDERFLOW_INT_ENA BIT(6) | ||
63 | #define LCD_MONOCHROME_MODE BIT(1) | ||
64 | #define LCD_RASTER_ENABLE BIT(0) | ||
65 | #define LCD_TFT_ALT_ENABLE BIT(23) | ||
66 | #define LCD_STN_565_ENABLE BIT(24) | ||
67 | |||
68 | /* LCD Raster Timing 2 Register */ | ||
69 | #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) | ||
70 | #define LCD_AC_BIAS_FREQUENCY(x) ((x) << 8) | ||
71 | #define LCD_SYNC_CTRL BIT(25) | ||
72 | #define LCD_SYNC_EDGE BIT(24) | ||
73 | #define LCD_INVERT_PIXEL_CLOCK BIT(22) | ||
74 | #define LCD_INVERT_LINE_CLOCK BIT(21) | ||
75 | #define LCD_INVERT_FRAME_CLOCK BIT(20) | ||
76 | |||
77 | /* LCD Block */ | ||
78 | #define LCD_CTRL_REG 0x4 | ||
79 | #define LCD_STAT_REG 0x8 | ||
80 | #define LCD_RASTER_CTRL_REG 0x28 | ||
81 | #define LCD_RASTER_TIMING_0_REG 0x2C | ||
82 | #define LCD_RASTER_TIMING_1_REG 0x30 | ||
83 | #define LCD_RASTER_TIMING_2_REG 0x34 | ||
84 | #define LCD_DMA_CTRL_REG 0x40 | ||
85 | #define LCD_DMA_FRM_BUF_BASE_ADDR_0_REG 0x44 | ||
86 | #define LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG 0x48 | ||
87 | |||
88 | #define WSI_TIMEOUT 50 | ||
89 | #define PALETTE_SIZE 256 | ||
90 | #define LEFT_MARGIN 64 | ||
91 | #define RIGHT_MARGIN 64 | ||
92 | #define UPPER_MARGIN 32 | ||
93 | #define LOWER_MARGIN 32 | ||
94 | |||
95 | static resource_size_t da8xx_fb_reg_base; | ||
96 | static struct resource *lcdc_regs; | ||
97 | |||
98 | static inline unsigned int lcdc_read(unsigned int addr) | ||
99 | { | ||
100 | return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr)); | ||
101 | } | ||
102 | |||
103 | static inline void lcdc_write(unsigned int val, unsigned int addr) | ||
104 | { | ||
105 | __raw_writel(val, da8xx_fb_reg_base + (addr)); | ||
106 | } | ||
107 | |||
108 | struct da8xx_fb_par { | ||
109 | resource_size_t p_palette_base; | ||
110 | unsigned char *v_palette_base; | ||
111 | struct clk *lcdc_clk; | ||
112 | int irq; | ||
113 | unsigned short pseudo_palette[16]; | ||
114 | unsigned int databuf_sz; | ||
115 | unsigned int palette_sz; | ||
116 | }; | ||
117 | |||
118 | /* Variable Screen Information */ | ||
119 | static struct fb_var_screeninfo da8xx_fb_var __devinitdata = { | ||
120 | .xoffset = 0, | ||
121 | .yoffset = 0, | ||
122 | .transp = {0, 0, 0}, | ||
123 | .nonstd = 0, | ||
124 | .activate = 0, | ||
125 | .height = -1, | ||
126 | .width = -1, | ||
127 | .pixclock = 46666, /* 46us - AUO display */ | ||
128 | .accel_flags = 0, | ||
129 | .left_margin = LEFT_MARGIN, | ||
130 | .right_margin = RIGHT_MARGIN, | ||
131 | .upper_margin = UPPER_MARGIN, | ||
132 | .lower_margin = LOWER_MARGIN, | ||
133 | .sync = 0, | ||
134 | .vmode = FB_VMODE_NONINTERLACED | ||
135 | }; | ||
136 | |||
137 | static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = { | ||
138 | .id = "DA8xx FB Drv", | ||
139 | .type = FB_TYPE_PACKED_PIXELS, | ||
140 | .type_aux = 0, | ||
141 | .visual = FB_VISUAL_PSEUDOCOLOR, | ||
142 | .xpanstep = 1, | ||
143 | .ypanstep = 1, | ||
144 | .ywrapstep = 1, | ||
145 | .accel = FB_ACCEL_NONE | ||
146 | }; | ||
147 | |||
148 | struct da8xx_panel { | ||
149 | const char name[25]; /* Full name <vendor>_<model> */ | ||
150 | unsigned short width; | ||
151 | unsigned short height; | ||
152 | int hfp; /* Horizontal front porch */ | ||
153 | int hbp; /* Horizontal back porch */ | ||
154 | int hsw; /* Horizontal Sync Pulse Width */ | ||
155 | int vfp; /* Vertical front porch */ | ||
156 | int vbp; /* Vertical back porch */ | ||
157 | int vsw; /* Vertical Sync Pulse Width */ | ||
158 | int pxl_clk; /* Pixel clock */ | ||
159 | unsigned char invert_pxl_clk; /* Invert Pixel clock */ | ||
160 | }; | ||
161 | |||
162 | static struct da8xx_panel known_lcd_panels[] = { | ||
163 | /* Sharp LCD035Q3DG01 */ | ||
164 | [0] = { | ||
165 | .name = "Sharp_LCD035Q3DG01", | ||
166 | .width = 320, | ||
167 | .height = 240, | ||
168 | .hfp = 8, | ||
169 | .hbp = 6, | ||
170 | .hsw = 0, | ||
171 | .vfp = 2, | ||
172 | .vbp = 2, | ||
173 | .vsw = 0, | ||
174 | .pxl_clk = 0x10, | ||
175 | .invert_pxl_clk = 1, | ||
176 | }, | ||
177 | /* Sharp LK043T1DG01 */ | ||
178 | [1] = { | ||
179 | .name = "Sharp_LK043T1DG01", | ||
180 | .width = 480, | ||
181 | .height = 272, | ||
182 | .hfp = 2, | ||
183 | .hbp = 2, | ||
184 | .hsw = 41, | ||
185 | .vfp = 2, | ||
186 | .vbp = 2, | ||
187 | .vsw = 10, | ||
188 | .pxl_clk = 0x12, | ||
189 | .invert_pxl_clk = 0, | ||
190 | }, | ||
191 | }; | ||
192 | |||
193 | /* Disable the Raster Engine of the LCD Controller */ | ||
194 | static void lcd_disable_raster(struct da8xx_fb_par *par) | ||
195 | { | ||
196 | u32 reg; | ||
197 | |||
198 | reg = lcdc_read(LCD_RASTER_CTRL_REG); | ||
199 | if (reg & LCD_RASTER_ENABLE) | ||
200 | lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | ||
201 | } | ||
202 | |||
203 | static void lcd_blit(int load_mode, struct da8xx_fb_par *par) | ||
204 | { | ||
205 | u32 tmp = par->p_palette_base + par->databuf_sz - 4; | ||
206 | u32 reg; | ||
207 | |||
208 | /* Update the databuf in the hw. */ | ||
209 | lcdc_write(par->p_palette_base, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); | ||
210 | lcdc_write(tmp, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); | ||
211 | |||
212 | /* Start the DMA. */ | ||
213 | reg = lcdc_read(LCD_RASTER_CTRL_REG); | ||
214 | reg &= ~(3 << 20); | ||
215 | if (load_mode == LOAD_DATA) | ||
216 | reg |= LCD_PALETTE_LOAD_MODE(PALETTE_AND_DATA); | ||
217 | else if (load_mode == LOAD_PALETTE) | ||
218 | reg |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); | ||
219 | |||
220 | lcdc_write(reg, LCD_RASTER_CTRL_REG); | ||
221 | } | ||
222 | |||
223 | /* Configure the Burst Size of DMA */ | ||
224 | static int lcd_cfg_dma(int burst_size) | ||
225 | { | ||
226 | u32 reg; | ||
227 | |||
228 | reg = lcdc_read(LCD_DMA_CTRL_REG) & 0x00000001; | ||
229 | switch (burst_size) { | ||
230 | case 1: | ||
231 | reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1); | ||
232 | break; | ||
233 | case 2: | ||
234 | reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2); | ||
235 | break; | ||
236 | case 4: | ||
237 | reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4); | ||
238 | break; | ||
239 | case 8: | ||
240 | reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8); | ||
241 | break; | ||
242 | case 16: | ||
243 | reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16); | ||
244 | break; | ||
245 | default: | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | lcdc_write(reg, LCD_DMA_CTRL_REG); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static void lcd_cfg_ac_bias(int period, int transitions_per_int) | ||
254 | { | ||
255 | u32 reg; | ||
256 | |||
257 | /* Set the AC Bias Period and Number of Transisitons per Interrupt */ | ||
258 | reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & 0xFFF00000; | ||
259 | reg |= LCD_AC_BIAS_FREQUENCY(period) | | ||
260 | LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int); | ||
261 | lcdc_write(reg, LCD_RASTER_TIMING_2_REG); | ||
262 | } | ||
263 | |||
264 | static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width, | ||
265 | int front_porch) | ||
266 | { | ||
267 | u32 reg; | ||
268 | |||
269 | reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf; | ||
270 | reg |= ((back_porch & 0xff) << 24) | ||
271 | | ((front_porch & 0xff) << 16) | ||
272 | | ((pulse_width & 0x3f) << 10); | ||
273 | lcdc_write(reg, LCD_RASTER_TIMING_0_REG); | ||
274 | } | ||
275 | |||
276 | static void lcd_cfg_vertical_sync(int back_porch, int pulse_width, | ||
277 | int front_porch) | ||
278 | { | ||
279 | u32 reg; | ||
280 | |||
281 | reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff; | ||
282 | reg |= ((back_porch & 0xff) << 24) | ||
283 | | ((front_porch & 0xff) << 16) | ||
284 | | ((pulse_width & 0x3f) << 10); | ||
285 | lcdc_write(reg, LCD_RASTER_TIMING_1_REG); | ||
286 | } | ||
287 | |||
288 | static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) | ||
289 | { | ||
290 | u32 reg; | ||
291 | |||
292 | reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE | | ||
293 | LCD_MONO_8BIT_MODE | | ||
294 | LCD_MONOCHROME_MODE); | ||
295 | |||
296 | switch (cfg->p_disp_panel->panel_shade) { | ||
297 | case MONOCHROME: | ||
298 | reg |= LCD_MONOCHROME_MODE; | ||
299 | if (cfg->mono_8bit_mode) | ||
300 | reg |= LCD_MONO_8BIT_MODE; | ||
301 | break; | ||
302 | case COLOR_ACTIVE: | ||
303 | reg |= LCD_TFT_MODE; | ||
304 | if (cfg->tft_alt_mode) | ||
305 | reg |= LCD_TFT_ALT_ENABLE; | ||
306 | break; | ||
307 | |||
308 | case COLOR_PASSIVE: | ||
309 | if (cfg->stn_565_mode) | ||
310 | reg |= LCD_STN_565_ENABLE; | ||
311 | break; | ||
312 | |||
313 | default: | ||
314 | return -EINVAL; | ||
315 | } | ||
316 | |||
317 | /* enable additional interrupts here */ | ||
318 | reg |= LCD_UNDERFLOW_INT_ENA; | ||
319 | |||
320 | lcdc_write(reg, LCD_RASTER_CTRL_REG); | ||
321 | |||
322 | reg = lcdc_read(LCD_RASTER_TIMING_2_REG); | ||
323 | |||
324 | if (cfg->sync_ctrl) | ||
325 | reg |= LCD_SYNC_CTRL; | ||
326 | else | ||
327 | reg &= ~LCD_SYNC_CTRL; | ||
328 | |||
329 | if (cfg->sync_edge) | ||
330 | reg |= LCD_SYNC_EDGE; | ||
331 | else | ||
332 | reg &= ~LCD_SYNC_EDGE; | ||
333 | |||
334 | if (cfg->invert_line_clock) | ||
335 | reg |= LCD_INVERT_LINE_CLOCK; | ||
336 | else | ||
337 | reg &= ~LCD_INVERT_LINE_CLOCK; | ||
338 | |||
339 | if (cfg->invert_frm_clock) | ||
340 | reg |= LCD_INVERT_FRAME_CLOCK; | ||
341 | else | ||
342 | reg &= ~LCD_INVERT_FRAME_CLOCK; | ||
343 | |||
344 | lcdc_write(reg, LCD_RASTER_TIMING_2_REG); | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, | ||
350 | u32 bpp, u32 raster_order) | ||
351 | { | ||
352 | u32 bpl, reg; | ||
353 | |||
354 | /* Disable Dual Frame Buffer. */ | ||
355 | reg = lcdc_read(LCD_DMA_CTRL_REG); | ||
356 | lcdc_write(reg & ~LCD_DUAL_FRAME_BUFFER_ENABLE, | ||
357 | LCD_DMA_CTRL_REG); | ||
358 | /* Set the Panel Width */ | ||
359 | /* Pixels per line = (PPL + 1)*16 */ | ||
360 | /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/ | ||
361 | width &= 0x3f0; | ||
362 | reg = lcdc_read(LCD_RASTER_TIMING_0_REG); | ||
363 | reg &= 0xfffffc00; | ||
364 | reg |= ((width >> 4) - 1) << 4; | ||
365 | lcdc_write(reg, LCD_RASTER_TIMING_0_REG); | ||
366 | |||
367 | /* Set the Panel Height */ | ||
368 | reg = lcdc_read(LCD_RASTER_TIMING_1_REG); | ||
369 | reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00); | ||
370 | lcdc_write(reg, LCD_RASTER_TIMING_1_REG); | ||
371 | |||
372 | /* Set the Raster Order of the Frame Buffer */ | ||
373 | reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8); | ||
374 | if (raster_order) | ||
375 | reg |= LCD_RASTER_ORDER; | ||
376 | lcdc_write(reg, LCD_RASTER_CTRL_REG); | ||
377 | |||
378 | switch (bpp) { | ||
379 | case 1: | ||
380 | case 2: | ||
381 | case 4: | ||
382 | case 16: | ||
383 | par->palette_sz = 16 * 2; | ||
384 | break; | ||
385 | |||
386 | case 8: | ||
387 | par->palette_sz = 256 * 2; | ||
388 | break; | ||
389 | |||
390 | default: | ||
391 | return -EINVAL; | ||
392 | } | ||
393 | |||
394 | bpl = width * bpp / 8; | ||
395 | par->databuf_sz = height * bpl + par->palette_sz; | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
401 | unsigned blue, unsigned transp, | ||
402 | struct fb_info *info) | ||
403 | { | ||
404 | struct da8xx_fb_par *par = info->par; | ||
405 | unsigned short *palette = (unsigned short *)par->v_palette_base; | ||
406 | u_short pal; | ||
407 | |||
408 | if (regno > 255) | ||
409 | return 1; | ||
410 | |||
411 | if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) | ||
412 | return 1; | ||
413 | |||
414 | if (info->var.bits_per_pixel == 8) { | ||
415 | red >>= 4; | ||
416 | green >>= 8; | ||
417 | blue >>= 12; | ||
418 | |||
419 | pal = (red & 0x0f00); | ||
420 | pal |= (green & 0x00f0); | ||
421 | pal |= (blue & 0x000f); | ||
422 | |||
423 | palette[regno] = pal; | ||
424 | |||
425 | } else if ((info->var.bits_per_pixel == 16) && regno < 16) { | ||
426 | red >>= (16 - info->var.red.length); | ||
427 | red <<= info->var.red.offset; | ||
428 | |||
429 | green >>= (16 - info->var.green.length); | ||
430 | green <<= info->var.green.offset; | ||
431 | |||
432 | blue >>= (16 - info->var.blue.length); | ||
433 | blue <<= info->var.blue.offset; | ||
434 | |||
435 | par->pseudo_palette[regno] = red | green | blue; | ||
436 | |||
437 | palette[0] = 0x4000; | ||
438 | } | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | static void lcd_reset(struct da8xx_fb_par *par) | ||
444 | { | ||
445 | /* Disable the Raster if previously Enabled */ | ||
446 | if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE) | ||
447 | lcd_disable_raster(par); | ||
448 | |||
449 | /* DMA has to be disabled */ | ||
450 | lcdc_write(0, LCD_DMA_CTRL_REG); | ||
451 | lcdc_write(0, LCD_RASTER_CTRL_REG); | ||
452 | } | ||
453 | |||
454 | static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | ||
455 | struct da8xx_panel *panel) | ||
456 | { | ||
457 | u32 bpp; | ||
458 | int ret = 0; | ||
459 | |||
460 | lcd_reset(par); | ||
461 | |||
462 | /* Configure the LCD clock divisor. */ | ||
463 | lcdc_write(LCD_CLK_DIVISOR(panel->pxl_clk) | | ||
464 | (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); | ||
465 | |||
466 | if (panel->invert_pxl_clk) | ||
467 | lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | | ||
468 | LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG); | ||
469 | else | ||
470 | lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) & | ||
471 | ~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG); | ||
472 | |||
473 | /* Configure the DMA burst size. */ | ||
474 | ret = lcd_cfg_dma(cfg->dma_burst_sz); | ||
475 | if (ret < 0) | ||
476 | return ret; | ||
477 | |||
478 | /* Configure the AC bias properties. */ | ||
479 | lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt); | ||
480 | |||
481 | /* Configure the vertical and horizontal sync properties. */ | ||
482 | lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp); | ||
483 | lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp); | ||
484 | |||
485 | /* Configure for disply */ | ||
486 | ret = lcd_cfg_display(cfg); | ||
487 | if (ret < 0) | ||
488 | return ret; | ||
489 | |||
490 | if (QVGA != cfg->p_disp_panel->panel_type) | ||
491 | return -EINVAL; | ||
492 | |||
493 | if (cfg->bpp <= cfg->p_disp_panel->max_bpp && | ||
494 | cfg->bpp >= cfg->p_disp_panel->min_bpp) | ||
495 | bpp = cfg->bpp; | ||
496 | else | ||
497 | bpp = cfg->p_disp_panel->max_bpp; | ||
498 | if (bpp == 12) | ||
499 | bpp = 16; | ||
500 | ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width, | ||
501 | (unsigned int)panel->height, bpp, | ||
502 | cfg->raster_order); | ||
503 | if (ret < 0) | ||
504 | return ret; | ||
505 | |||
506 | /* Configure FDD */ | ||
507 | lcdc_write((lcdc_read(LCD_RASTER_CTRL_REG) & 0xfff00fff) | | ||
508 | (cfg->fdd << 12), LCD_RASTER_CTRL_REG); | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static irqreturn_t lcdc_irq_handler(int irq, void *arg) | ||
514 | { | ||
515 | u32 stat = lcdc_read(LCD_STAT_REG); | ||
516 | u32 reg; | ||
517 | |||
518 | if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { | ||
519 | reg = lcdc_read(LCD_RASTER_CTRL_REG); | ||
520 | lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | ||
521 | lcdc_write(stat, LCD_STAT_REG); | ||
522 | lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | ||
523 | } else | ||
524 | lcdc_write(stat, LCD_STAT_REG); | ||
525 | |||
526 | return IRQ_HANDLED; | ||
527 | } | ||
528 | |||
529 | static int fb_check_var(struct fb_var_screeninfo *var, | ||
530 | struct fb_info *info) | ||
531 | { | ||
532 | int err = 0; | ||
533 | |||
534 | switch (var->bits_per_pixel) { | ||
535 | case 1: | ||
536 | case 8: | ||
537 | var->red.offset = 0; | ||
538 | var->red.length = 8; | ||
539 | var->green.offset = 0; | ||
540 | var->green.length = 8; | ||
541 | var->blue.offset = 0; | ||
542 | var->blue.length = 8; | ||
543 | var->transp.offset = 0; | ||
544 | var->transp.length = 0; | ||
545 | break; | ||
546 | case 4: | ||
547 | var->red.offset = 0; | ||
548 | var->red.length = 4; | ||
549 | var->green.offset = 0; | ||
550 | var->green.length = 4; | ||
551 | var->blue.offset = 0; | ||
552 | var->blue.length = 4; | ||
553 | var->transp.offset = 0; | ||
554 | var->transp.length = 0; | ||
555 | break; | ||
556 | case 16: /* RGB 565 */ | ||
557 | var->red.offset = 0; | ||
558 | var->red.length = 5; | ||
559 | var->green.offset = 5; | ||
560 | var->green.length = 6; | ||
561 | var->blue.offset = 11; | ||
562 | var->blue.length = 5; | ||
563 | var->transp.offset = 0; | ||
564 | var->transp.length = 0; | ||
565 | break; | ||
566 | default: | ||
567 | err = -EINVAL; | ||
568 | } | ||
569 | |||
570 | var->red.msb_right = 0; | ||
571 | var->green.msb_right = 0; | ||
572 | var->blue.msb_right = 0; | ||
573 | var->transp.msb_right = 0; | ||
574 | return err; | ||
575 | } | ||
576 | |||
577 | static int __devexit fb_remove(struct platform_device *dev) | ||
578 | { | ||
579 | struct fb_info *info = dev_get_drvdata(&dev->dev); | ||
580 | |||
581 | if (info) { | ||
582 | struct da8xx_fb_par *par = info->par; | ||
583 | |||
584 | if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE) | ||
585 | lcd_disable_raster(par); | ||
586 | lcdc_write(0, LCD_RASTER_CTRL_REG); | ||
587 | |||
588 | /* disable DMA */ | ||
589 | lcdc_write(0, LCD_DMA_CTRL_REG); | ||
590 | |||
591 | unregister_framebuffer(info); | ||
592 | fb_dealloc_cmap(&info->cmap); | ||
593 | dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, | ||
594 | info->screen_base, | ||
595 | info->fix.smem_start); | ||
596 | free_irq(par->irq, par); | ||
597 | clk_disable(par->lcdc_clk); | ||
598 | clk_put(par->lcdc_clk); | ||
599 | framebuffer_release(info); | ||
600 | iounmap((void __iomem *)da8xx_fb_reg_base); | ||
601 | release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); | ||
602 | |||
603 | } | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static int fb_ioctl(struct fb_info *info, unsigned int cmd, | ||
608 | unsigned long arg) | ||
609 | { | ||
610 | struct lcd_sync_arg sync_arg; | ||
611 | |||
612 | switch (cmd) { | ||
613 | case FBIOGET_CONTRAST: | ||
614 | case FBIOPUT_CONTRAST: | ||
615 | case FBIGET_BRIGHTNESS: | ||
616 | case FBIPUT_BRIGHTNESS: | ||
617 | case FBIGET_COLOR: | ||
618 | case FBIPUT_COLOR: | ||
619 | return -ENOTTY; | ||
620 | case FBIPUT_HSYNC: | ||
621 | if (copy_from_user(&sync_arg, (char *)arg, | ||
622 | sizeof(struct lcd_sync_arg))) | ||
623 | return -EFAULT; | ||
624 | lcd_cfg_horizontal_sync(sync_arg.back_porch, | ||
625 | sync_arg.pulse_width, | ||
626 | sync_arg.front_porch); | ||
627 | break; | ||
628 | case FBIPUT_VSYNC: | ||
629 | if (copy_from_user(&sync_arg, (char *)arg, | ||
630 | sizeof(struct lcd_sync_arg))) | ||
631 | return -EFAULT; | ||
632 | lcd_cfg_vertical_sync(sync_arg.back_porch, | ||
633 | sync_arg.pulse_width, | ||
634 | sync_arg.front_porch); | ||
635 | break; | ||
636 | default: | ||
637 | return -EINVAL; | ||
638 | } | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | static struct fb_ops da8xx_fb_ops = { | ||
643 | .owner = THIS_MODULE, | ||
644 | .fb_check_var = fb_check_var, | ||
645 | .fb_setcolreg = fb_setcolreg, | ||
646 | .fb_ioctl = fb_ioctl, | ||
647 | .fb_fillrect = cfb_fillrect, | ||
648 | .fb_copyarea = cfb_copyarea, | ||
649 | .fb_imageblit = cfb_imageblit, | ||
650 | }; | ||
651 | |||
652 | static int __init fb_probe(struct platform_device *device) | ||
653 | { | ||
654 | struct da8xx_lcdc_platform_data *fb_pdata = | ||
655 | device->dev.platform_data; | ||
656 | struct lcd_ctrl_config *lcd_cfg; | ||
657 | struct da8xx_panel *lcdc_info; | ||
658 | struct fb_info *da8xx_fb_info; | ||
659 | struct clk *fb_clk = NULL; | ||
660 | struct da8xx_fb_par *par; | ||
661 | resource_size_t len; | ||
662 | int ret, i; | ||
663 | |||
664 | if (fb_pdata == NULL) { | ||
665 | dev_err(&device->dev, "Can not get platform data\n"); | ||
666 | return -ENOENT; | ||
667 | } | ||
668 | |||
669 | lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0); | ||
670 | if (!lcdc_regs) { | ||
671 | dev_err(&device->dev, | ||
672 | "Can not get memory resource for LCD controller\n"); | ||
673 | return -ENOENT; | ||
674 | } | ||
675 | |||
676 | len = resource_size(lcdc_regs); | ||
677 | |||
678 | lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name); | ||
679 | if (!lcdc_regs) | ||
680 | return -EBUSY; | ||
681 | |||
682 | da8xx_fb_reg_base = (resource_size_t)ioremap(lcdc_regs->start, len); | ||
683 | if (!da8xx_fb_reg_base) { | ||
684 | ret = -EBUSY; | ||
685 | goto err_request_mem; | ||
686 | } | ||
687 | |||
688 | fb_clk = clk_get(&device->dev, NULL); | ||
689 | if (IS_ERR(fb_clk)) { | ||
690 | dev_err(&device->dev, "Can not get device clock\n"); | ||
691 | ret = -ENODEV; | ||
692 | goto err_ioremap; | ||
693 | } | ||
694 | ret = clk_enable(fb_clk); | ||
695 | if (ret) | ||
696 | goto err_clk_put; | ||
697 | |||
698 | for (i = 0, lcdc_info = known_lcd_panels; | ||
699 | i < ARRAY_SIZE(known_lcd_panels); | ||
700 | i++, lcdc_info++) { | ||
701 | if (strcmp(fb_pdata->type, lcdc_info->name) == 0) | ||
702 | break; | ||
703 | } | ||
704 | |||
705 | if (i == ARRAY_SIZE(known_lcd_panels)) { | ||
706 | dev_err(&device->dev, "GLCD: No valid panel found\n"); | ||
707 | ret = -ENODEV; | ||
708 | goto err_clk_disable; | ||
709 | } else | ||
710 | dev_info(&device->dev, "GLCD: Found %s panel\n", | ||
711 | fb_pdata->type); | ||
712 | |||
713 | lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; | ||
714 | |||
715 | da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par), | ||
716 | &device->dev); | ||
717 | if (!da8xx_fb_info) { | ||
718 | dev_dbg(&device->dev, "Memory allocation failed for fb_info\n"); | ||
719 | ret = -ENOMEM; | ||
720 | goto err_clk_disable; | ||
721 | } | ||
722 | |||
723 | par = da8xx_fb_info->par; | ||
724 | |||
725 | if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { | ||
726 | dev_err(&device->dev, "lcd_init failed\n"); | ||
727 | ret = -EFAULT; | ||
728 | goto err_release_fb; | ||
729 | } | ||
730 | |||
731 | /* allocate frame buffer */ | ||
732 | da8xx_fb_info->screen_base = dma_alloc_coherent(NULL, | ||
733 | par->databuf_sz + PAGE_SIZE, | ||
734 | (resource_size_t *) | ||
735 | &da8xx_fb_info->fix.smem_start, | ||
736 | GFP_KERNEL | GFP_DMA); | ||
737 | |||
738 | if (!da8xx_fb_info->screen_base) { | ||
739 | dev_err(&device->dev, | ||
740 | "GLCD: kmalloc for frame buffer failed\n"); | ||
741 | ret = -EINVAL; | ||
742 | goto err_release_fb; | ||
743 | } | ||
744 | |||
745 | /* move palette base pointer by (PAGE_SIZE - palette_sz) bytes */ | ||
746 | par->v_palette_base = da8xx_fb_info->screen_base + | ||
747 | (PAGE_SIZE - par->palette_sz); | ||
748 | par->p_palette_base = da8xx_fb_info->fix.smem_start + | ||
749 | (PAGE_SIZE - par->palette_sz); | ||
750 | |||
751 | /* the rest of the frame buffer is pixel data */ | ||
752 | da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz; | ||
753 | da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz; | ||
754 | da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; | ||
755 | |||
756 | par->lcdc_clk = fb_clk; | ||
757 | |||
758 | par->irq = platform_get_irq(device, 0); | ||
759 | if (par->irq < 0) { | ||
760 | ret = -ENOENT; | ||
761 | goto err_release_fb_mem; | ||
762 | } | ||
763 | |||
764 | ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par); | ||
765 | if (ret) | ||
766 | goto err_release_fb_mem; | ||
767 | |||
768 | /* Initialize par */ | ||
769 | da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; | ||
770 | |||
771 | da8xx_fb_var.xres = lcdc_info->width; | ||
772 | da8xx_fb_var.xres_virtual = lcdc_info->width; | ||
773 | |||
774 | da8xx_fb_var.yres = lcdc_info->height; | ||
775 | da8xx_fb_var.yres_virtual = lcdc_info->height; | ||
776 | |||
777 | da8xx_fb_var.grayscale = | ||
778 | lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; | ||
779 | da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp; | ||
780 | |||
781 | da8xx_fb_var.hsync_len = lcdc_info->hsw; | ||
782 | da8xx_fb_var.vsync_len = lcdc_info->vsw; | ||
783 | |||
784 | /* Initialize fbinfo */ | ||
785 | da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT; | ||
786 | da8xx_fb_info->fix = da8xx_fb_fix; | ||
787 | da8xx_fb_info->var = da8xx_fb_var; | ||
788 | da8xx_fb_info->fbops = &da8xx_fb_ops; | ||
789 | da8xx_fb_info->pseudo_palette = par->pseudo_palette; | ||
790 | |||
791 | ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0); | ||
792 | if (ret) | ||
793 | goto err_free_irq; | ||
794 | |||
795 | /* First palette_sz byte of the frame buffer is the palette */ | ||
796 | da8xx_fb_info->cmap.len = par->palette_sz; | ||
797 | |||
798 | /* Flush the buffer to the screen. */ | ||
799 | lcd_blit(LOAD_DATA, par); | ||
800 | |||
801 | /* initialize var_screeninfo */ | ||
802 | da8xx_fb_var.activate = FB_ACTIVATE_FORCE; | ||
803 | fb_set_var(da8xx_fb_info, &da8xx_fb_var); | ||
804 | |||
805 | dev_set_drvdata(&device->dev, da8xx_fb_info); | ||
806 | /* Register the Frame Buffer */ | ||
807 | if (register_framebuffer(da8xx_fb_info) < 0) { | ||
808 | dev_err(&device->dev, | ||
809 | "GLCD: Frame Buffer Registration Failed!\n"); | ||
810 | ret = -EINVAL; | ||
811 | goto err_dealloc_cmap; | ||
812 | } | ||
813 | |||
814 | /* enable raster engine */ | ||
815 | lcdc_write(lcdc_read(LCD_RASTER_CTRL_REG) | | ||
816 | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | ||
817 | |||
818 | return 0; | ||
819 | |||
820 | err_dealloc_cmap: | ||
821 | fb_dealloc_cmap(&da8xx_fb_info->cmap); | ||
822 | |||
823 | err_free_irq: | ||
824 | free_irq(par->irq, par); | ||
825 | |||
826 | err_release_fb_mem: | ||
827 | dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, | ||
828 | da8xx_fb_info->screen_base, | ||
829 | da8xx_fb_info->fix.smem_start); | ||
830 | |||
831 | err_release_fb: | ||
832 | framebuffer_release(da8xx_fb_info); | ||
833 | |||
834 | err_clk_disable: | ||
835 | clk_disable(fb_clk); | ||
836 | |||
837 | err_clk_put: | ||
838 | clk_put(fb_clk); | ||
839 | |||
840 | err_ioremap: | ||
841 | iounmap((void __iomem *)da8xx_fb_reg_base); | ||
842 | |||
843 | err_request_mem: | ||
844 | release_mem_region(lcdc_regs->start, len); | ||
845 | |||
846 | return ret; | ||
847 | } | ||
848 | |||
849 | #ifdef CONFIG_PM | ||
850 | static int fb_suspend(struct platform_device *dev, pm_message_t state) | ||
851 | { | ||
852 | return -EBUSY; | ||
853 | } | ||
854 | static int fb_resume(struct platform_device *dev) | ||
855 | { | ||
856 | return -EBUSY; | ||
857 | } | ||
858 | #else | ||
859 | #define fb_suspend NULL | ||
860 | #define fb_resume NULL | ||
861 | #endif | ||
862 | |||
863 | static struct platform_driver da8xx_fb_driver = { | ||
864 | .probe = fb_probe, | ||
865 | .remove = fb_remove, | ||
866 | .suspend = fb_suspend, | ||
867 | .resume = fb_resume, | ||
868 | .driver = { | ||
869 | .name = DRIVER_NAME, | ||
870 | .owner = THIS_MODULE, | ||
871 | }, | ||
872 | }; | ||
873 | |||
874 | static int __init da8xx_fb_init(void) | ||
875 | { | ||
876 | return platform_driver_register(&da8xx_fb_driver); | ||
877 | } | ||
878 | |||
879 | static void __exit da8xx_fb_cleanup(void) | ||
880 | { | ||
881 | platform_driver_unregister(&da8xx_fb_driver); | ||
882 | } | ||
883 | |||
884 | module_init(da8xx_fb_init); | ||
885 | module_exit(da8xx_fb_cleanup); | ||
886 | |||
887 | MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx"); | ||
888 | MODULE_AUTHOR("Texas Instruments"); | ||
889 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c new file mode 100644 index 000000000000..bd9d46f95291 --- /dev/null +++ b/drivers/video/ep93xx-fb.c | |||
@@ -0,0 +1,646 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/ep93xx-fb.c | ||
3 | * | ||
4 | * Framebuffer support for the EP93xx series. | ||
5 | * | ||
6 | * Copyright (C) 2007 Bluewater Systems Ltd | ||
7 | * Author: Ryan Mallon <ryan@bluewatersys.com> | ||
8 | * | ||
9 | * Copyright (c) 2009 H Hartley Sweeten <hsweeten@visionengravers.com> | ||
10 | * | ||
11 | * Based on the Cirrus Logic ep93xxfb driver, and various other ep93xxfb | ||
12 | * drivers. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/fb.h> | ||
24 | |||
25 | #include <mach/fb.h> | ||
26 | |||
27 | /* Vertical Frame Timing Registers */ | ||
28 | #define EP93XXFB_VLINES_TOTAL 0x0000 /* SW locked */ | ||
29 | #define EP93XXFB_VSYNC 0x0004 /* SW locked */ | ||
30 | #define EP93XXFB_VACTIVE 0x0008 /* SW locked */ | ||
31 | #define EP93XXFB_VBLANK 0x0228 /* SW locked */ | ||
32 | #define EP93XXFB_VCLK 0x000c /* SW locked */ | ||
33 | |||
34 | /* Horizontal Frame Timing Registers */ | ||
35 | #define EP93XXFB_HCLKS_TOTAL 0x0010 /* SW locked */ | ||
36 | #define EP93XXFB_HSYNC 0x0014 /* SW locked */ | ||
37 | #define EP93XXFB_HACTIVE 0x0018 /* SW locked */ | ||
38 | #define EP93XXFB_HBLANK 0x022c /* SW locked */ | ||
39 | #define EP93XXFB_HCLK 0x001c /* SW locked */ | ||
40 | |||
41 | /* Frame Buffer Memory Configuration Registers */ | ||
42 | #define EP93XXFB_SCREEN_PAGE 0x0028 | ||
43 | #define EP93XXFB_SCREEN_HPAGE 0x002c | ||
44 | #define EP93XXFB_SCREEN_LINES 0x0030 | ||
45 | #define EP93XXFB_LINE_LENGTH 0x0034 | ||
46 | #define EP93XXFB_VLINE_STEP 0x0038 | ||
47 | #define EP93XXFB_LINE_CARRY 0x003c /* SW locked */ | ||
48 | #define EP93XXFB_EOL_OFFSET 0x0230 | ||
49 | |||
50 | /* Other Video Registers */ | ||
51 | #define EP93XXFB_BRIGHTNESS 0x0020 | ||
52 | #define EP93XXFB_ATTRIBS 0x0024 /* SW locked */ | ||
53 | #define EP93XXFB_SWLOCK 0x007c /* SW locked */ | ||
54 | #define EP93XXFB_AC_RATE 0x0214 | ||
55 | #define EP93XXFB_FIFO_LEVEL 0x0234 | ||
56 | #define EP93XXFB_PIXELMODE 0x0054 | ||
57 | #define EP93XXFB_PIXELMODE_32BPP (0x7 << 0) | ||
58 | #define EP93XXFB_PIXELMODE_24BPP (0x6 << 0) | ||
59 | #define EP93XXFB_PIXELMODE_16BPP (0x4 << 0) | ||
60 | #define EP93XXFB_PIXELMODE_8BPP (0x2 << 0) | ||
61 | #define EP93XXFB_PIXELMODE_SHIFT_1P_24B (0x0 << 3) | ||
62 | #define EP93XXFB_PIXELMODE_SHIFT_1P_18B (0x1 << 3) | ||
63 | #define EP93XXFB_PIXELMODE_COLOR_LUT (0x0 << 10) | ||
64 | #define EP93XXFB_PIXELMODE_COLOR_888 (0x4 << 10) | ||
65 | #define EP93XXFB_PIXELMODE_COLOR_555 (0x5 << 10) | ||
66 | #define EP93XXFB_PARL_IF_OUT 0x0058 | ||
67 | #define EP93XXFB_PARL_IF_IN 0x005c | ||
68 | |||
69 | /* Blink Control Registers */ | ||
70 | #define EP93XXFB_BLINK_RATE 0x0040 | ||
71 | #define EP93XXFB_BLINK_MASK 0x0044 | ||
72 | #define EP93XXFB_BLINK_PATTRN 0x0048 | ||
73 | #define EP93XXFB_PATTRN_MASK 0x004c | ||
74 | #define EP93XXFB_BKGRND_OFFSET 0x0050 | ||
75 | |||
76 | /* Hardware Cursor Registers */ | ||
77 | #define EP93XXFB_CURSOR_ADR_START 0x0060 | ||
78 | #define EP93XXFB_CURSOR_ADR_RESET 0x0064 | ||
79 | #define EP93XXFB_CURSOR_SIZE 0x0068 | ||
80 | #define EP93XXFB_CURSOR_COLOR1 0x006c | ||
81 | #define EP93XXFB_CURSOR_COLOR2 0x0070 | ||
82 | #define EP93XXFB_CURSOR_BLINK_COLOR1 0x021c | ||
83 | #define EP93XXFB_CURSOR_BLINK_COLOR2 0x0220 | ||
84 | #define EP93XXFB_CURSOR_XY_LOC 0x0074 | ||
85 | #define EP93XXFB_CURSOR_DSCAN_HY_LOC 0x0078 | ||
86 | #define EP93XXFB_CURSOR_BLINK_RATE_CTRL 0x0224 | ||
87 | |||
88 | /* LUT Registers */ | ||
89 | #define EP93XXFB_GRY_SCL_LUTR 0x0080 | ||
90 | #define EP93XXFB_GRY_SCL_LUTG 0x0280 | ||
91 | #define EP93XXFB_GRY_SCL_LUTB 0x0300 | ||
92 | #define EP93XXFB_LUT_SW_CONTROL 0x0218 | ||
93 | #define EP93XXFB_LUT_SW_CONTROL_SWTCH (1 << 0) | ||
94 | #define EP93XXFB_LUT_SW_CONTROL_SSTAT (1 << 1) | ||
95 | #define EP93XXFB_COLOR_LUT 0x0400 | ||
96 | |||
97 | /* Video Signature Registers */ | ||
98 | #define EP93XXFB_VID_SIG_RSLT_VAL 0x0200 | ||
99 | #define EP93XXFB_VID_SIG_CTRL 0x0204 | ||
100 | #define EP93XXFB_VSIG 0x0208 | ||
101 | #define EP93XXFB_HSIG 0x020c | ||
102 | #define EP93XXFB_SIG_CLR_STR 0x0210 | ||
103 | |||
104 | /* Minimum / Maximum resolutions supported */ | ||
105 | #define EP93XXFB_MIN_XRES 64 | ||
106 | #define EP93XXFB_MIN_YRES 64 | ||
107 | #define EP93XXFB_MAX_XRES 1024 | ||
108 | #define EP93XXFB_MAX_YRES 768 | ||
109 | |||
110 | struct ep93xx_fbi { | ||
111 | struct ep93xxfb_mach_info *mach_info; | ||
112 | struct clk *clk; | ||
113 | struct resource *res; | ||
114 | void __iomem *mmio_base; | ||
115 | unsigned int pseudo_palette[256]; | ||
116 | }; | ||
117 | |||
118 | static int check_screenpage_bug = 1; | ||
119 | module_param(check_screenpage_bug, int, 0644); | ||
120 | MODULE_PARM_DESC(check_screenpage_bug, | ||
121 | "Check for bit 27 screen page bug. Default = 1"); | ||
122 | |||
123 | static inline unsigned int ep93xxfb_readl(struct ep93xx_fbi *fbi, | ||
124 | unsigned int off) | ||
125 | { | ||
126 | return __raw_readl(fbi->mmio_base + off); | ||
127 | } | ||
128 | |||
129 | static inline void ep93xxfb_writel(struct ep93xx_fbi *fbi, | ||
130 | unsigned int val, unsigned int off) | ||
131 | { | ||
132 | __raw_writel(val, fbi->mmio_base + off); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * Write to one of the locked raster registers. | ||
137 | */ | ||
138 | static inline void ep93xxfb_out_locked(struct ep93xx_fbi *fbi, | ||
139 | unsigned int val, unsigned int reg) | ||
140 | { | ||
141 | /* | ||
142 | * We don't need a lock or delay here since the raster register | ||
143 | * block will remain unlocked until the next access. | ||
144 | */ | ||
145 | ep93xxfb_writel(fbi, 0xaa, EP93XXFB_SWLOCK); | ||
146 | ep93xxfb_writel(fbi, val, reg); | ||
147 | } | ||
148 | |||
149 | static void ep93xxfb_set_video_attribs(struct fb_info *info) | ||
150 | { | ||
151 | struct ep93xx_fbi *fbi = info->par; | ||
152 | unsigned int attribs; | ||
153 | |||
154 | attribs = EP93XXFB_ENABLE; | ||
155 | attribs |= fbi->mach_info->flags; | ||
156 | ep93xxfb_out_locked(fbi, attribs, EP93XXFB_ATTRIBS); | ||
157 | } | ||
158 | |||
159 | static int ep93xxfb_set_pixelmode(struct fb_info *info) | ||
160 | { | ||
161 | struct ep93xx_fbi *fbi = info->par; | ||
162 | unsigned int val; | ||
163 | |||
164 | info->var.transp.offset = 0; | ||
165 | info->var.transp.length = 0; | ||
166 | |||
167 | switch (info->var.bits_per_pixel) { | ||
168 | case 8: | ||
169 | val = EP93XXFB_PIXELMODE_8BPP | EP93XXFB_PIXELMODE_COLOR_LUT | | ||
170 | EP93XXFB_PIXELMODE_SHIFT_1P_18B; | ||
171 | |||
172 | info->var.red.offset = 0; | ||
173 | info->var.red.length = 8; | ||
174 | info->var.green.offset = 0; | ||
175 | info->var.green.length = 8; | ||
176 | info->var.blue.offset = 0; | ||
177 | info->var.blue.length = 8; | ||
178 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
179 | break; | ||
180 | |||
181 | case 16: | ||
182 | val = EP93XXFB_PIXELMODE_16BPP | EP93XXFB_PIXELMODE_COLOR_555 | | ||
183 | EP93XXFB_PIXELMODE_SHIFT_1P_18B; | ||
184 | |||
185 | info->var.red.offset = 11; | ||
186 | info->var.red.length = 5; | ||
187 | info->var.green.offset = 5; | ||
188 | info->var.green.length = 6; | ||
189 | info->var.blue.offset = 0; | ||
190 | info->var.blue.length = 5; | ||
191 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
192 | break; | ||
193 | |||
194 | case 24: | ||
195 | val = EP93XXFB_PIXELMODE_24BPP | EP93XXFB_PIXELMODE_COLOR_888 | | ||
196 | EP93XXFB_PIXELMODE_SHIFT_1P_24B; | ||
197 | |||
198 | info->var.red.offset = 16; | ||
199 | info->var.red.length = 8; | ||
200 | info->var.green.offset = 8; | ||
201 | info->var.green.length = 8; | ||
202 | info->var.blue.offset = 0; | ||
203 | info->var.blue.length = 8; | ||
204 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
205 | break; | ||
206 | |||
207 | case 32: | ||
208 | val = EP93XXFB_PIXELMODE_32BPP | EP93XXFB_PIXELMODE_COLOR_888 | | ||
209 | EP93XXFB_PIXELMODE_SHIFT_1P_24B; | ||
210 | |||
211 | info->var.red.offset = 16; | ||
212 | info->var.red.length = 8; | ||
213 | info->var.green.offset = 8; | ||
214 | info->var.green.length = 8; | ||
215 | info->var.blue.offset = 0; | ||
216 | info->var.blue.length = 8; | ||
217 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
218 | break; | ||
219 | |||
220 | default: | ||
221 | return -EINVAL; | ||
222 | } | ||
223 | |||
224 | ep93xxfb_writel(fbi, val, EP93XXFB_PIXELMODE); | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static void ep93xxfb_set_timing(struct fb_info *info) | ||
229 | { | ||
230 | struct ep93xx_fbi *fbi = info->par; | ||
231 | unsigned int vlines_total, hclks_total, start, stop; | ||
232 | |||
233 | vlines_total = info->var.yres + info->var.upper_margin + | ||
234 | info->var.lower_margin + info->var.vsync_len - 1; | ||
235 | |||
236 | hclks_total = info->var.xres + info->var.left_margin + | ||
237 | info->var.right_margin + info->var.hsync_len - 1; | ||
238 | |||
239 | ep93xxfb_out_locked(fbi, vlines_total, EP93XXFB_VLINES_TOTAL); | ||
240 | ep93xxfb_out_locked(fbi, hclks_total, EP93XXFB_HCLKS_TOTAL); | ||
241 | |||
242 | start = vlines_total; | ||
243 | stop = vlines_total - info->var.vsync_len; | ||
244 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VSYNC); | ||
245 | |||
246 | start = vlines_total - info->var.vsync_len - info->var.upper_margin; | ||
247 | stop = info->var.lower_margin - 1; | ||
248 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VBLANK); | ||
249 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VACTIVE); | ||
250 | |||
251 | start = vlines_total; | ||
252 | stop = vlines_total + 1; | ||
253 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VCLK); | ||
254 | |||
255 | start = hclks_total; | ||
256 | stop = hclks_total - info->var.hsync_len; | ||
257 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HSYNC); | ||
258 | |||
259 | start = hclks_total - info->var.hsync_len - info->var.left_margin; | ||
260 | stop = info->var.right_margin - 1; | ||
261 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HBLANK); | ||
262 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HACTIVE); | ||
263 | |||
264 | start = hclks_total; | ||
265 | stop = hclks_total; | ||
266 | ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HCLK); | ||
267 | |||
268 | ep93xxfb_out_locked(fbi, 0x0, EP93XXFB_LINE_CARRY); | ||
269 | } | ||
270 | |||
271 | static int ep93xxfb_set_par(struct fb_info *info) | ||
272 | { | ||
273 | struct ep93xx_fbi *fbi = info->par; | ||
274 | |||
275 | clk_set_rate(fbi->clk, 1000 * PICOS2KHZ(info->var.pixclock)); | ||
276 | |||
277 | ep93xxfb_set_timing(info); | ||
278 | |||
279 | info->fix.line_length = info->var.xres_virtual * | ||
280 | info->var.bits_per_pixel / 8; | ||
281 | |||
282 | ep93xxfb_writel(fbi, info->fix.smem_start, EP93XXFB_SCREEN_PAGE); | ||
283 | ep93xxfb_writel(fbi, info->var.yres - 1, EP93XXFB_SCREEN_LINES); | ||
284 | ep93xxfb_writel(fbi, ((info->var.xres * info->var.bits_per_pixel) | ||
285 | / 32) - 1, EP93XXFB_LINE_LENGTH); | ||
286 | ep93xxfb_writel(fbi, info->fix.line_length / 4, EP93XXFB_VLINE_STEP); | ||
287 | ep93xxfb_set_video_attribs(info); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int ep93xxfb_check_var(struct fb_var_screeninfo *var, | ||
292 | struct fb_info *info) | ||
293 | { | ||
294 | int err; | ||
295 | |||
296 | err = ep93xxfb_set_pixelmode(info); | ||
297 | if (err) | ||
298 | return err; | ||
299 | |||
300 | var->xres = max_t(unsigned int, var->xres, EP93XXFB_MIN_XRES); | ||
301 | var->xres = min_t(unsigned int, var->xres, EP93XXFB_MAX_XRES); | ||
302 | var->xres_virtual = max(var->xres_virtual, var->xres); | ||
303 | |||
304 | var->yres = max_t(unsigned int, var->yres, EP93XXFB_MIN_YRES); | ||
305 | var->yres = min_t(unsigned int, var->yres, EP93XXFB_MAX_YRES); | ||
306 | var->yres_virtual = max(var->yres_virtual, var->yres); | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int ep93xxfb_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
312 | { | ||
313 | unsigned int offset = vma->vm_pgoff << PAGE_SHIFT; | ||
314 | |||
315 | if (offset < info->fix.smem_len) { | ||
316 | return dma_mmap_writecombine(info->dev, vma, info->screen_base, | ||
317 | info->fix.smem_start, | ||
318 | info->fix.smem_len); | ||
319 | } | ||
320 | |||
321 | return -EINVAL; | ||
322 | } | ||
323 | |||
324 | static int ep93xxfb_blank(int blank_mode, struct fb_info *info) | ||
325 | { | ||
326 | struct ep93xx_fbi *fbi = info->par; | ||
327 | unsigned int attribs = ep93xxfb_readl(fbi, EP93XXFB_ATTRIBS); | ||
328 | |||
329 | if (blank_mode) { | ||
330 | if (fbi->mach_info->blank) | ||
331 | fbi->mach_info->blank(blank_mode, info); | ||
332 | ep93xxfb_out_locked(fbi, attribs & ~EP93XXFB_ENABLE, | ||
333 | EP93XXFB_ATTRIBS); | ||
334 | clk_disable(fbi->clk); | ||
335 | } else { | ||
336 | clk_enable(fbi->clk); | ||
337 | ep93xxfb_out_locked(fbi, attribs | EP93XXFB_ENABLE, | ||
338 | EP93XXFB_ATTRIBS); | ||
339 | if (fbi->mach_info->blank) | ||
340 | fbi->mach_info->blank(blank_mode, info); | ||
341 | } | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static inline int ep93xxfb_convert_color(int val, int width) | ||
347 | { | ||
348 | return ((val << width) + 0x7fff - val) >> 16; | ||
349 | } | ||
350 | |||
351 | static int ep93xxfb_setcolreg(unsigned int regno, unsigned int red, | ||
352 | unsigned int green, unsigned int blue, | ||
353 | unsigned int transp, struct fb_info *info) | ||
354 | { | ||
355 | struct ep93xx_fbi *fbi = info->par; | ||
356 | unsigned int *pal = info->pseudo_palette; | ||
357 | unsigned int ctrl, i, rgb, lut_current, lut_stat; | ||
358 | |||
359 | switch (info->fix.visual) { | ||
360 | case FB_VISUAL_PSEUDOCOLOR: | ||
361 | rgb = ((red & 0xff00) << 8) | (green & 0xff00) | | ||
362 | ((blue & 0xff00) >> 8); | ||
363 | |||
364 | pal[regno] = rgb; | ||
365 | ep93xxfb_writel(fbi, rgb, (EP93XXFB_COLOR_LUT + (regno << 2))); | ||
366 | ctrl = ep93xxfb_readl(fbi, EP93XXFB_LUT_SW_CONTROL); | ||
367 | lut_stat = !!(ctrl & EP93XXFB_LUT_SW_CONTROL_SSTAT); | ||
368 | lut_current = !!(ctrl & EP93XXFB_LUT_SW_CONTROL_SWTCH); | ||
369 | |||
370 | if (lut_stat == lut_current) { | ||
371 | for (i = 0; i < 256; i++) { | ||
372 | ep93xxfb_writel(fbi, pal[i], | ||
373 | EP93XXFB_COLOR_LUT + (i << 2)); | ||
374 | } | ||
375 | |||
376 | ep93xxfb_writel(fbi, | ||
377 | ctrl ^ EP93XXFB_LUT_SW_CONTROL_SWTCH, | ||
378 | EP93XXFB_LUT_SW_CONTROL); | ||
379 | } | ||
380 | break; | ||
381 | |||
382 | case FB_VISUAL_TRUECOLOR: | ||
383 | if (regno > 16) | ||
384 | return 1; | ||
385 | |||
386 | red = ep93xxfb_convert_color(red, info->var.red.length); | ||
387 | green = ep93xxfb_convert_color(green, info->var.green.length); | ||
388 | blue = ep93xxfb_convert_color(blue, info->var.blue.length); | ||
389 | transp = ep93xxfb_convert_color(transp, | ||
390 | info->var.transp.length); | ||
391 | |||
392 | pal[regno] = (red << info->var.red.offset) | | ||
393 | (green << info->var.green.offset) | | ||
394 | (blue << info->var.blue.offset) | | ||
395 | (transp << info->var.transp.offset); | ||
396 | break; | ||
397 | |||
398 | default: | ||
399 | return 1; | ||
400 | } | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static struct fb_ops ep93xxfb_ops = { | ||
406 | .owner = THIS_MODULE, | ||
407 | .fb_check_var = ep93xxfb_check_var, | ||
408 | .fb_set_par = ep93xxfb_set_par, | ||
409 | .fb_blank = ep93xxfb_blank, | ||
410 | .fb_fillrect = cfb_fillrect, | ||
411 | .fb_copyarea = cfb_copyarea, | ||
412 | .fb_imageblit = cfb_imageblit, | ||
413 | .fb_setcolreg = ep93xxfb_setcolreg, | ||
414 | .fb_mmap = ep93xxfb_mmap, | ||
415 | }; | ||
416 | |||
417 | static int __init ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info) | ||
418 | { | ||
419 | int i, fb_size = 0; | ||
420 | |||
421 | if (mach_info->num_modes == EP93XXFB_USE_MODEDB) { | ||
422 | fb_size = EP93XXFB_MAX_XRES * EP93XXFB_MAX_YRES * | ||
423 | mach_info->bpp / 8; | ||
424 | } else { | ||
425 | for (i = 0; i < mach_info->num_modes; i++) { | ||
426 | const struct fb_videomode *mode; | ||
427 | int size; | ||
428 | |||
429 | mode = &mach_info->modes[i]; | ||
430 | size = mode->xres * mode->yres * mach_info->bpp / 8; | ||
431 | if (size > fb_size) | ||
432 | fb_size = size; | ||
433 | } | ||
434 | } | ||
435 | |||
436 | return fb_size; | ||
437 | } | ||
438 | |||
439 | static int __init ep93xxfb_alloc_videomem(struct fb_info *info) | ||
440 | { | ||
441 | struct ep93xx_fbi *fbi = info->par; | ||
442 | char __iomem *virt_addr; | ||
443 | dma_addr_t phys_addr; | ||
444 | unsigned int fb_size; | ||
445 | |||
446 | fb_size = ep93xxfb_calc_fbsize(fbi->mach_info); | ||
447 | virt_addr = dma_alloc_writecombine(info->dev, fb_size, | ||
448 | &phys_addr, GFP_KERNEL); | ||
449 | if (!virt_addr) | ||
450 | return -ENOMEM; | ||
451 | |||
452 | /* | ||
453 | * There is a bug in the ep93xx framebuffer which causes problems | ||
454 | * if bit 27 of the physical address is set. | ||
455 | * See: http://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2 | ||
456 | * There does not seem to be any offical errata for this, but I | ||
457 | * have confirmed the problem exists on my hardware (ep9315) at | ||
458 | * least. | ||
459 | */ | ||
460 | if (check_screenpage_bug && phys_addr & (1 << 27)) { | ||
461 | dev_err(info->dev, "ep93xx framebuffer bug. phys addr (0x%x) " | ||
462 | "has bit 27 set: cannot init framebuffer\n", | ||
463 | phys_addr); | ||
464 | |||
465 | dma_free_coherent(info->dev, fb_size, virt_addr, phys_addr); | ||
466 | return -ENOMEM; | ||
467 | } | ||
468 | |||
469 | info->fix.smem_start = phys_addr; | ||
470 | info->fix.smem_len = fb_size; | ||
471 | info->screen_base = virt_addr; | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static void ep93xxfb_dealloc_videomem(struct fb_info *info) | ||
477 | { | ||
478 | if (info->screen_base) | ||
479 | dma_free_coherent(info->dev, info->fix.smem_len, | ||
480 | info->screen_base, info->fix.smem_start); | ||
481 | } | ||
482 | |||
483 | static int __init ep93xxfb_probe(struct platform_device *pdev) | ||
484 | { | ||
485 | struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data; | ||
486 | struct fb_info *info; | ||
487 | struct ep93xx_fbi *fbi; | ||
488 | struct resource *res; | ||
489 | char *video_mode; | ||
490 | int err; | ||
491 | |||
492 | if (!mach_info) | ||
493 | return -EINVAL; | ||
494 | |||
495 | info = framebuffer_alloc(sizeof(struct ep93xx_fbi), &pdev->dev); | ||
496 | if (!info) | ||
497 | return -ENOMEM; | ||
498 | |||
499 | info->dev = &pdev->dev; | ||
500 | platform_set_drvdata(pdev, info); | ||
501 | fbi = info->par; | ||
502 | fbi->mach_info = mach_info; | ||
503 | |||
504 | err = fb_alloc_cmap(&info->cmap, 256, 0); | ||
505 | if (err) | ||
506 | goto failed; | ||
507 | |||
508 | err = ep93xxfb_alloc_videomem(info); | ||
509 | if (err) | ||
510 | goto failed; | ||
511 | |||
512 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
513 | if (!res) { | ||
514 | err = -ENXIO; | ||
515 | goto failed; | ||
516 | } | ||
517 | |||
518 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
519 | if (!res) { | ||
520 | err = -EBUSY; | ||
521 | goto failed; | ||
522 | } | ||
523 | |||
524 | fbi->res = res; | ||
525 | fbi->mmio_base = ioremap(res->start, resource_size(res)); | ||
526 | if (!fbi->mmio_base) { | ||
527 | err = -ENXIO; | ||
528 | goto failed; | ||
529 | } | ||
530 | |||
531 | strcpy(info->fix.id, pdev->name); | ||
532 | info->fbops = &ep93xxfb_ops; | ||
533 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
534 | info->fix.accel = FB_ACCEL_NONE; | ||
535 | info->var.activate = FB_ACTIVATE_NOW; | ||
536 | info->var.vmode = FB_VMODE_NONINTERLACED; | ||
537 | info->flags = FBINFO_DEFAULT; | ||
538 | info->node = -1; | ||
539 | info->state = FBINFO_STATE_RUNNING; | ||
540 | info->pseudo_palette = &fbi->pseudo_palette; | ||
541 | |||
542 | fb_get_options("ep93xx-fb", &video_mode); | ||
543 | err = fb_find_mode(&info->var, info, video_mode, | ||
544 | fbi->mach_info->modes, fbi->mach_info->num_modes, | ||
545 | fbi->mach_info->default_mode, fbi->mach_info->bpp); | ||
546 | if (err == 0) { | ||
547 | dev_err(info->dev, "No suitable video mode found\n"); | ||
548 | err = -EINVAL; | ||
549 | goto failed; | ||
550 | } | ||
551 | |||
552 | if (mach_info->setup) { | ||
553 | err = mach_info->setup(pdev); | ||
554 | if (err) | ||
555 | return err; | ||
556 | } | ||
557 | |||
558 | err = ep93xxfb_check_var(&info->var, info); | ||
559 | if (err) | ||
560 | goto failed; | ||
561 | |||
562 | fbi->clk = clk_get(info->dev, NULL); | ||
563 | if (IS_ERR(fbi->clk)) { | ||
564 | err = PTR_ERR(fbi->clk); | ||
565 | fbi->clk = NULL; | ||
566 | goto failed; | ||
567 | } | ||
568 | |||
569 | ep93xxfb_set_par(info); | ||
570 | clk_enable(fbi->clk); | ||
571 | |||
572 | err = register_framebuffer(info); | ||
573 | if (err) | ||
574 | goto failed; | ||
575 | |||
576 | dev_info(info->dev, "registered. Mode = %dx%d-%d\n", | ||
577 | info->var.xres, info->var.yres, info->var.bits_per_pixel); | ||
578 | return 0; | ||
579 | |||
580 | failed: | ||
581 | if (fbi->clk) | ||
582 | clk_put(fbi->clk); | ||
583 | if (fbi->mmio_base) | ||
584 | iounmap(fbi->mmio_base); | ||
585 | if (fbi->res) | ||
586 | release_mem_region(fbi->res->start, resource_size(fbi->res)); | ||
587 | ep93xxfb_dealloc_videomem(info); | ||
588 | if (&info->cmap) | ||
589 | fb_dealloc_cmap(&info->cmap); | ||
590 | if (fbi->mach_info->teardown) | ||
591 | fbi->mach_info->teardown(pdev); | ||
592 | kfree(info); | ||
593 | platform_set_drvdata(pdev, NULL); | ||
594 | |||
595 | return err; | ||
596 | } | ||
597 | |||
598 | static int ep93xxfb_remove(struct platform_device *pdev) | ||
599 | { | ||
600 | struct fb_info *info = platform_get_drvdata(pdev); | ||
601 | struct ep93xx_fbi *fbi = info->par; | ||
602 | |||
603 | unregister_framebuffer(info); | ||
604 | clk_disable(fbi->clk); | ||
605 | clk_put(fbi->clk); | ||
606 | iounmap(fbi->mmio_base); | ||
607 | release_mem_region(fbi->res->start, resource_size(fbi->res)); | ||
608 | ep93xxfb_dealloc_videomem(info); | ||
609 | fb_dealloc_cmap(&info->cmap); | ||
610 | |||
611 | if (fbi->mach_info->teardown) | ||
612 | fbi->mach_info->teardown(pdev); | ||
613 | |||
614 | kfree(info); | ||
615 | platform_set_drvdata(pdev, NULL); | ||
616 | |||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static struct platform_driver ep93xxfb_driver = { | ||
621 | .probe = ep93xxfb_probe, | ||
622 | .remove = ep93xxfb_remove, | ||
623 | .driver = { | ||
624 | .name = "ep93xx-fb", | ||
625 | .owner = THIS_MODULE, | ||
626 | }, | ||
627 | }; | ||
628 | |||
629 | static int __devinit ep93xxfb_init(void) | ||
630 | { | ||
631 | return platform_driver_register(&ep93xxfb_driver); | ||
632 | } | ||
633 | |||
634 | static void __exit ep93xxfb_exit(void) | ||
635 | { | ||
636 | platform_driver_unregister(&ep93xxfb_driver); | ||
637 | } | ||
638 | |||
639 | module_init(ep93xxfb_init); | ||
640 | module_exit(ep93xxfb_exit); | ||
641 | |||
642 | MODULE_DESCRIPTION("EP93XX Framebuffer Driver"); | ||
643 | MODULE_ALIAS("platform:ep93xx-fb"); | ||
644 | MODULE_AUTHOR("Ryan Mallon <ryan&bluewatersys.com>, " | ||
645 | "H Hartley Sweeten <hsweeten@visionengravers.com"); | ||
646 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 0a7a6679ee6e..c27ab1ed9604 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c | |||
@@ -125,7 +125,7 @@ page_already_added: | |||
125 | return 0; | 125 | return 0; |
126 | } | 126 | } |
127 | 127 | ||
128 | static struct vm_operations_struct fb_deferred_io_vm_ops = { | 128 | static const struct vm_operations_struct fb_deferred_io_vm_ops = { |
129 | .fault = fb_deferred_io_fault, | 129 | .fault = fb_deferred_io_fault, |
130 | .page_mkwrite = fb_deferred_io_mkwrite, | 130 | .page_mkwrite = fb_deferred_io_mkwrite, |
131 | }; | 131 | }; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index f8a09bf8d0cd..99bbd282ce63 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/compat.h> | 16 | #include <linux/compat.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/major.h> | 20 | #include <linux/major.h> |
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -872,8 +871,8 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) | |||
872 | err = -EINVAL; | 871 | err = -EINVAL; |
873 | 872 | ||
874 | if (err || !info->fbops->fb_pan_display || | 873 | if (err || !info->fbops->fb_pan_display || |
875 | var->yoffset + yres > info->var.yres_virtual || | 874 | var->yoffset > info->var.yres_virtual - yres || |
876 | var->xoffset + info->var.xres > info->var.xres_virtual) | 875 | var->xoffset > info->var.xres_virtual - info->var.xres) |
877 | return -EINVAL; | 876 | return -EINVAL; |
878 | 877 | ||
879 | if ((err = info->fbops->fb_pan_display(var, info))) | 878 | if ((err = info->fbops->fb_pan_display(var, info))) |
@@ -955,6 +954,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
955 | goto done; | 954 | goto done; |
956 | 955 | ||
957 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { | 956 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { |
957 | struct fb_var_screeninfo old_var; | ||
958 | struct fb_videomode mode; | 958 | struct fb_videomode mode; |
959 | 959 | ||
960 | if (info->fbops->fb_get_caps) { | 960 | if (info->fbops->fb_get_caps) { |
@@ -964,10 +964,20 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
964 | goto done; | 964 | goto done; |
965 | } | 965 | } |
966 | 966 | ||
967 | old_var = info->var; | ||
967 | info->var = *var; | 968 | info->var = *var; |
968 | 969 | ||
969 | if (info->fbops->fb_set_par) | 970 | if (info->fbops->fb_set_par) { |
970 | info->fbops->fb_set_par(info); | 971 | ret = info->fbops->fb_set_par(info); |
972 | |||
973 | if (ret) { | ||
974 | info->var = old_var; | ||
975 | printk(KERN_WARNING "detected " | ||
976 | "fb_set_par error, " | ||
977 | "error code: %d\n", ret); | ||
978 | goto done; | ||
979 | } | ||
980 | } | ||
971 | 981 | ||
972 | fb_pan_display(info, &info->var); | 982 | fb_pan_display(info, &info->var); |
973 | fb_set_cmap(&info->cmap, info); | 983 | fb_set_cmap(&info->cmap, info); |
@@ -1310,8 +1320,6 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, | |||
1310 | 1320 | ||
1311 | static int | 1321 | static int |
1312 | fb_mmap(struct file *file, struct vm_area_struct * vma) | 1322 | fb_mmap(struct file *file, struct vm_area_struct * vma) |
1313 | __acquires(&info->lock) | ||
1314 | __releases(&info->lock) | ||
1315 | { | 1323 | { |
1316 | int fbidx = iminor(file->f_path.dentry->d_inode); | 1324 | int fbidx = iminor(file->f_path.dentry->d_inode); |
1317 | struct fb_info *info = registered_fb[fbidx]; | 1325 | struct fb_info *info = registered_fb[fbidx]; |
@@ -1325,16 +1333,14 @@ __releases(&info->lock) | |||
1325 | off = vma->vm_pgoff << PAGE_SHIFT; | 1333 | off = vma->vm_pgoff << PAGE_SHIFT; |
1326 | if (!fb) | 1334 | if (!fb) |
1327 | return -ENODEV; | 1335 | return -ENODEV; |
1336 | mutex_lock(&info->mm_lock); | ||
1328 | if (fb->fb_mmap) { | 1337 | if (fb->fb_mmap) { |
1329 | int res; | 1338 | int res; |
1330 | mutex_lock(&info->lock); | ||
1331 | res = fb->fb_mmap(info, vma); | 1339 | res = fb->fb_mmap(info, vma); |
1332 | mutex_unlock(&info->lock); | 1340 | mutex_unlock(&info->mm_lock); |
1333 | return res; | 1341 | return res; |
1334 | } | 1342 | } |
1335 | 1343 | ||
1336 | mutex_lock(&info->lock); | ||
1337 | |||
1338 | /* frame buffer memory */ | 1344 | /* frame buffer memory */ |
1339 | start = info->fix.smem_start; | 1345 | start = info->fix.smem_start; |
1340 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); | 1346 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); |
@@ -1342,13 +1348,13 @@ __releases(&info->lock) | |||
1342 | /* memory mapped io */ | 1348 | /* memory mapped io */ |
1343 | off -= len; | 1349 | off -= len; |
1344 | if (info->var.accel_flags) { | 1350 | if (info->var.accel_flags) { |
1345 | mutex_unlock(&info->lock); | 1351 | mutex_unlock(&info->mm_lock); |
1346 | return -EINVAL; | 1352 | return -EINVAL; |
1347 | } | 1353 | } |
1348 | start = info->fix.mmio_start; | 1354 | start = info->fix.mmio_start; |
1349 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); | 1355 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); |
1350 | } | 1356 | } |
1351 | mutex_unlock(&info->lock); | 1357 | mutex_unlock(&info->mm_lock); |
1352 | start &= PAGE_MASK; | 1358 | start &= PAGE_MASK; |
1353 | if ((vma->vm_end - vma->vm_start + off) > len) | 1359 | if ((vma->vm_end - vma->vm_start + off) > len) |
1354 | return -EINVAL; | 1360 | return -EINVAL; |
@@ -1518,6 +1524,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1518 | break; | 1524 | break; |
1519 | fb_info->node = i; | 1525 | fb_info->node = i; |
1520 | mutex_init(&fb_info->lock); | 1526 | mutex_init(&fb_info->lock); |
1527 | mutex_init(&fb_info->mm_lock); | ||
1521 | 1528 | ||
1522 | fb_info->dev = device_create(fb_class, fb_info->device, | 1529 | fb_info->dev = device_create(fb_class, fb_info->device, |
1523 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); | 1530 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); |
@@ -1793,7 +1800,7 @@ static int __init video_setup(char *options) | |||
1793 | global = 1; | 1800 | global = 1; |
1794 | } | 1801 | } |
1795 | 1802 | ||
1796 | if (!global && !strstr(options, "fb:")) { | 1803 | if (!global && !strchr(options, ':')) { |
1797 | fb_mode_option = options; | 1804 | fb_mode_option = options; |
1798 | global = 1; | 1805 | global = 1; |
1799 | } | 1806 | } |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 5c1a2c01778f..9ae9cd32bd06 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -256,8 +256,8 @@ static void fix_edid(unsigned char *edid, int fix) | |||
256 | 256 | ||
257 | static int edid_checksum(unsigned char *edid) | 257 | static int edid_checksum(unsigned char *edid) |
258 | { | 258 | { |
259 | unsigned char i, csum = 0, all_null = 0; | 259 | unsigned char csum = 0, all_null = 0; |
260 | int err = 0, fix = check_edid(edid); | 260 | int i, err = 0, fix = check_edid(edid); |
261 | 261 | ||
262 | if (fix) | 262 | if (fix) |
263 | fix_edid(edid, fix); | 263 | fix_edid(edid, fix); |
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index f153c581cbd7..72d68b3dc478 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -750,24 +750,26 @@ static void update_lcdc(struct fb_info *info) | |||
750 | static int map_video_memory(struct fb_info *info) | 750 | static int map_video_memory(struct fb_info *info) |
751 | { | 751 | { |
752 | phys_addr_t phys; | 752 | phys_addr_t phys; |
753 | u32 smem_len = info->fix.line_length * info->var.yres_virtual; | ||
753 | 754 | ||
754 | pr_debug("info->var.xres_virtual = %d\n", info->var.xres_virtual); | 755 | pr_debug("info->var.xres_virtual = %d\n", info->var.xres_virtual); |
755 | pr_debug("info->var.yres_virtual = %d\n", info->var.yres_virtual); | 756 | pr_debug("info->var.yres_virtual = %d\n", info->var.yres_virtual); |
756 | pr_debug("info->fix.line_length = %d\n", info->fix.line_length); | 757 | pr_debug("info->fix.line_length = %d\n", info->fix.line_length); |
758 | pr_debug("MAP_VIDEO_MEMORY: smem_len = %u\n", smem_len); | ||
757 | 759 | ||
758 | info->fix.smem_len = info->fix.line_length * info->var.yres_virtual; | 760 | info->screen_base = fsl_diu_alloc(smem_len, &phys); |
759 | pr_debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->fix.smem_len); | ||
760 | info->screen_base = fsl_diu_alloc(info->fix.smem_len, &phys); | ||
761 | if (info->screen_base == NULL) { | 761 | if (info->screen_base == NULL) { |
762 | printk(KERN_ERR "Unable to allocate fb memory\n"); | 762 | printk(KERN_ERR "Unable to allocate fb memory\n"); |
763 | return -ENOMEM; | 763 | return -ENOMEM; |
764 | } | 764 | } |
765 | mutex_lock(&info->mm_lock); | ||
765 | info->fix.smem_start = (unsigned long) phys; | 766 | info->fix.smem_start = (unsigned long) phys; |
767 | info->fix.smem_len = smem_len; | ||
768 | mutex_unlock(&info->mm_lock); | ||
766 | info->screen_size = info->fix.smem_len; | 769 | info->screen_size = info->fix.smem_len; |
767 | 770 | ||
768 | pr_debug("Allocated fb @ paddr=0x%08lx, size=%d.\n", | 771 | pr_debug("Allocated fb @ paddr=0x%08lx, size=%d.\n", |
769 | info->fix.smem_start, | 772 | info->fix.smem_start, info->fix.smem_len); |
770 | info->fix.smem_len); | ||
771 | pr_debug("screen base %p\n", info->screen_base); | 773 | pr_debug("screen base %p\n", info->screen_base); |
772 | 774 | ||
773 | return 0; | 775 | return 0; |
@@ -776,9 +778,11 @@ static int map_video_memory(struct fb_info *info) | |||
776 | static void unmap_video_memory(struct fb_info *info) | 778 | static void unmap_video_memory(struct fb_info *info) |
777 | { | 779 | { |
778 | fsl_diu_free(info->screen_base, info->fix.smem_len); | 780 | fsl_diu_free(info->screen_base, info->fix.smem_len); |
781 | mutex_lock(&info->mm_lock); | ||
779 | info->screen_base = NULL; | 782 | info->screen_base = NULL; |
780 | info->fix.smem_start = 0; | 783 | info->fix.smem_start = 0; |
781 | info->fix.smem_len = 0; | 784 | info->fix.smem_len = 0; |
785 | mutex_unlock(&info->mm_lock); | ||
782 | } | 786 | } |
783 | 787 | ||
784 | /* | 788 | /* |
@@ -1219,12 +1223,6 @@ static int __devinit install_fb(struct fb_info *info) | |||
1219 | return -EINVAL; | 1223 | return -EINVAL; |
1220 | } | 1224 | } |
1221 | 1225 | ||
1222 | if (fsl_diu_set_par(info)) { | ||
1223 | printk(KERN_ERR "fb_set_par failed"); | ||
1224 | fb_dealloc_cmap(&info->cmap); | ||
1225 | return -EINVAL; | ||
1226 | } | ||
1227 | |||
1228 | if (register_framebuffer(info) < 0) { | 1226 | if (register_framebuffer(info) < 0) { |
1229 | printk(KERN_ERR "register_framebuffer failed"); | 1227 | printk(KERN_ERR "register_framebuffer failed"); |
1230 | unmap_video_memory(info); | 1228 | unmap_video_memory(info); |
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 020db7fc9153..e7116a6d82d3 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c | |||
@@ -44,9 +44,6 @@ static struct fb_fix_screeninfo hitfb_fix __initdata = { | |||
44 | .accel = FB_ACCEL_NONE, | 44 | .accel = FB_ACCEL_NONE, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static u32 pseudo_palette[16]; | ||
48 | static struct fb_info fb_info; | ||
49 | |||
50 | static inline void hitfb_accel_wait(void) | 47 | static inline void hitfb_accel_wait(void) |
51 | { | 48 | { |
52 | while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ; | 49 | while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ; |
@@ -331,6 +328,8 @@ static struct fb_ops hitfb_ops = { | |||
331 | static int __init hitfb_probe(struct platform_device *dev) | 328 | static int __init hitfb_probe(struct platform_device *dev) |
332 | { | 329 | { |
333 | unsigned short lcdclor, ldr3, ldvndr; | 330 | unsigned short lcdclor, ldr3, ldvndr; |
331 | struct fb_info *info; | ||
332 | int ret; | ||
334 | 333 | ||
335 | if (fb_get_options("hitfb", NULL)) | 334 | if (fb_get_options("hitfb", NULL)) |
336 | return -ENODEV; | 335 | return -ENODEV; |
@@ -384,32 +383,53 @@ static int __init hitfb_probe(struct platform_device *dev) | |||
384 | break; | 383 | break; |
385 | } | 384 | } |
386 | 385 | ||
387 | fb_info.fbops = &hitfb_ops; | 386 | info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); |
388 | fb_info.var = hitfb_var; | 387 | if (unlikely(!info)) |
389 | fb_info.fix = hitfb_fix; | 388 | return -ENOMEM; |
390 | fb_info.pseudo_palette = pseudo_palette; | 389 | |
391 | fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | | 390 | info->fbops = &hitfb_ops; |
391 | info->var = hitfb_var; | ||
392 | info->fix = hitfb_fix; | ||
393 | info->pseudo_palette = info->par; | ||
394 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | | ||
392 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; | 395 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; |
393 | 396 | ||
394 | fb_info.screen_base = (void *)hitfb_fix.smem_start; | 397 | info->screen_base = (void *)hitfb_fix.smem_start; |
395 | 398 | ||
396 | fb_alloc_cmap(&fb_info.cmap, 256, 0); | 399 | ret = fb_alloc_cmap(&info->cmap, 256, 0); |
400 | if (unlikely(ret < 0)) | ||
401 | goto err_fb; | ||
397 | 402 | ||
398 | if (register_framebuffer(&fb_info) < 0) | 403 | ret = register_framebuffer(info); |
399 | return -EINVAL; | 404 | if (unlikely(ret < 0)) |
405 | goto err; | ||
406 | |||
407 | platform_set_drvdata(dev, info); | ||
400 | 408 | ||
401 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | 409 | printk(KERN_INFO "fb%d: %s frame buffer device\n", |
402 | fb_info.node, fb_info.fix.id); | 410 | info->node, info->fix.id); |
411 | |||
403 | return 0; | 412 | return 0; |
413 | |||
414 | err: | ||
415 | fb_dealloc_cmap(&info->cmap); | ||
416 | err_fb: | ||
417 | framebuffer_release(info); | ||
418 | return ret; | ||
404 | } | 419 | } |
405 | 420 | ||
406 | static int __exit hitfb_remove(struct platform_device *dev) | 421 | static int __exit hitfb_remove(struct platform_device *dev) |
407 | { | 422 | { |
408 | return unregister_framebuffer(&fb_info); | 423 | struct fb_info *info = platform_get_drvdata(dev); |
424 | |||
425 | unregister_framebuffer(info); | ||
426 | fb_dealloc_cmap(&info->cmap); | ||
427 | framebuffer_release(info); | ||
428 | |||
429 | return 0; | ||
409 | } | 430 | } |
410 | 431 | ||
411 | #ifdef CONFIG_PM | 432 | static int hitfb_suspend(struct device *dev) |
412 | static int hitfb_suspend(struct platform_device *dev, pm_message_t state) | ||
413 | { | 433 | { |
414 | u16 v; | 434 | u16 v; |
415 | 435 | ||
@@ -421,7 +441,7 @@ static int hitfb_suspend(struct platform_device *dev, pm_message_t state) | |||
421 | return 0; | 441 | return 0; |
422 | } | 442 | } |
423 | 443 | ||
424 | static int hitfb_resume(struct platform_device *dev) | 444 | static int hitfb_resume(struct device *dev) |
425 | { | 445 | { |
426 | u16 v; | 446 | u16 v; |
427 | 447 | ||
@@ -435,17 +455,19 @@ static int hitfb_resume(struct platform_device *dev) | |||
435 | 455 | ||
436 | return 0; | 456 | return 0; |
437 | } | 457 | } |
438 | #endif | 458 | |
459 | static struct dev_pm_ops hitfb_dev_pm_ops = { | ||
460 | .suspend = hitfb_suspend, | ||
461 | .resume = hitfb_resume, | ||
462 | }; | ||
439 | 463 | ||
440 | static struct platform_driver hitfb_driver = { | 464 | static struct platform_driver hitfb_driver = { |
441 | .probe = hitfb_probe, | 465 | .probe = hitfb_probe, |
442 | .remove = __exit_p(hitfb_remove), | 466 | .remove = __exit_p(hitfb_remove), |
443 | #ifdef CONFIG_PM | ||
444 | .suspend = hitfb_suspend, | ||
445 | .resume = hitfb_resume, | ||
446 | #endif | ||
447 | .driver = { | 467 | .driver = { |
448 | .name = "hitfb", | 468 | .name = "hitfb", |
469 | .owner = THIS_MODULE, | ||
470 | .pm = &hitfb_dev_pm_ops, | ||
449 | }, | 471 | }, |
450 | }; | 472 | }; |
451 | 473 | ||
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 2e940199fc89..5743ea25e818 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -1090,8 +1090,10 @@ static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | |||
1090 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | 1090 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); |
1091 | 1091 | ||
1092 | strcpy(fix->id, "I810"); | 1092 | strcpy(fix->id, "I810"); |
1093 | mutex_lock(&info->mm_lock); | ||
1093 | fix->smem_start = par->fb.physical; | 1094 | fix->smem_start = par->fb.physical; |
1094 | fix->smem_len = par->fb.size; | 1095 | fix->smem_len = par->fb.size; |
1096 | mutex_unlock(&info->mm_lock); | ||
1095 | fix->type = FB_TYPE_PACKED_PIXELS; | 1097 | fix->type = FB_TYPE_PACKED_PIXELS; |
1096 | fix->type_aux = 0; | 1098 | fix->type_aux = 0; |
1097 | fix->xpanstep = 8; | 1099 | fix->xpanstep = 8; |
@@ -2058,8 +2060,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev, | |||
2058 | 2060 | ||
2059 | fb_var_to_videomode(&mode, &info->var); | 2061 | fb_var_to_videomode(&mode, &info->var); |
2060 | fb_add_videomode(&mode, &info->modelist); | 2062 | fb_add_videomode(&mode, &info->modelist); |
2061 | encode_fix(&info->fix, info); | 2063 | |
2062 | |||
2063 | i810fb_init_ringbuffer(info); | 2064 | i810fb_init_ringbuffer(info); |
2064 | err = register_framebuffer(info); | 2065 | err = register_framebuffer(info); |
2065 | 2066 | ||
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 15a0ee6d8e23..66358fa825f3 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/math64.h> | 33 | #include <linux/math64.h> |
34 | 34 | ||
35 | #include <mach/imxfb.h> | 35 | #include <mach/imxfb.h> |
36 | #include <mach/hardware.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Complain if VAR is out of range. | 39 | * Complain if VAR is out of range. |
@@ -129,6 +130,10 @@ | |||
129 | #define LCDISR_EOF (1<<1) | 130 | #define LCDISR_EOF (1<<1) |
130 | #define LCDISR_BOF (1<<0) | 131 | #define LCDISR_BOF (1<<0) |
131 | 132 | ||
133 | /* Used fb-mode. Can be set on kernel command line, therefore file-static. */ | ||
134 | static const char *fb_mode; | ||
135 | |||
136 | |||
132 | /* | 137 | /* |
133 | * These are the bitfields for each | 138 | * These are the bitfields for each |
134 | * display depth that we support. | 139 | * display depth that we support. |
@@ -145,10 +150,6 @@ struct imxfb_info { | |||
145 | void __iomem *regs; | 150 | void __iomem *regs; |
146 | struct clk *clk; | 151 | struct clk *clk; |
147 | 152 | ||
148 | u_int max_bpp; | ||
149 | u_int max_xres; | ||
150 | u_int max_yres; | ||
151 | |||
152 | /* | 153 | /* |
153 | * These are the addresses we mapped | 154 | * These are the addresses we mapped |
154 | * the framebuffer memory region to. | 155 | * the framebuffer memory region to. |
@@ -172,6 +173,9 @@ struct imxfb_info { | |||
172 | cmap_static:1, | 173 | cmap_static:1, |
173 | unused:30; | 174 | unused:30; |
174 | 175 | ||
176 | struct imx_fb_videomode *mode; | ||
177 | int num_modes; | ||
178 | |||
175 | void (*lcd_power)(int); | 179 | void (*lcd_power)(int); |
176 | void (*backlight_power)(int); | 180 | void (*backlight_power)(int); |
177 | }; | 181 | }; |
@@ -298,6 +302,18 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
298 | return ret; | 302 | return ret; |
299 | } | 303 | } |
300 | 304 | ||
305 | static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi) | ||
306 | { | ||
307 | struct imx_fb_videomode *m; | ||
308 | int i; | ||
309 | |||
310 | for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) { | ||
311 | if (!strcmp(m->mode.name, fb_mode)) | ||
312 | return m; | ||
313 | } | ||
314 | return NULL; | ||
315 | } | ||
316 | |||
301 | /* | 317 | /* |
302 | * imxfb_check_var(): | 318 | * imxfb_check_var(): |
303 | * Round up in the following order: bits_per_pixel, xres, | 319 | * Round up in the following order: bits_per_pixel, xres, |
@@ -308,35 +324,81 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
308 | { | 324 | { |
309 | struct imxfb_info *fbi = info->par; | 325 | struct imxfb_info *fbi = info->par; |
310 | struct imxfb_rgb *rgb; | 326 | struct imxfb_rgb *rgb; |
327 | const struct imx_fb_videomode *imxfb_mode; | ||
328 | unsigned long lcd_clk; | ||
329 | unsigned long long tmp; | ||
330 | u32 pcr = 0; | ||
311 | 331 | ||
312 | if (var->xres < MIN_XRES) | 332 | if (var->xres < MIN_XRES) |
313 | var->xres = MIN_XRES; | 333 | var->xres = MIN_XRES; |
314 | if (var->yres < MIN_YRES) | 334 | if (var->yres < MIN_YRES) |
315 | var->yres = MIN_YRES; | 335 | var->yres = MIN_YRES; |
316 | if (var->xres > fbi->max_xres) | 336 | |
317 | var->xres = fbi->max_xres; | 337 | imxfb_mode = imxfb_find_mode(fbi); |
318 | if (var->yres > fbi->max_yres) | 338 | if (!imxfb_mode) |
319 | var->yres = fbi->max_yres; | 339 | return -EINVAL; |
320 | var->xres_virtual = max(var->xres_virtual, var->xres); | 340 | |
321 | var->yres_virtual = max(var->yres_virtual, var->yres); | 341 | var->xres = imxfb_mode->mode.xres; |
342 | var->yres = imxfb_mode->mode.yres; | ||
343 | var->bits_per_pixel = imxfb_mode->bpp; | ||
344 | var->pixclock = imxfb_mode->mode.pixclock; | ||
345 | var->hsync_len = imxfb_mode->mode.hsync_len; | ||
346 | var->left_margin = imxfb_mode->mode.left_margin; | ||
347 | var->right_margin = imxfb_mode->mode.right_margin; | ||
348 | var->vsync_len = imxfb_mode->mode.vsync_len; | ||
349 | var->upper_margin = imxfb_mode->mode.upper_margin; | ||
350 | var->lower_margin = imxfb_mode->mode.lower_margin; | ||
351 | var->sync = imxfb_mode->mode.sync; | ||
352 | var->xres_virtual = max(var->xres_virtual, var->xres); | ||
353 | var->yres_virtual = max(var->yres_virtual, var->yres); | ||
322 | 354 | ||
323 | pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); | 355 | pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); |
356 | |||
357 | lcd_clk = clk_get_rate(fbi->clk); | ||
358 | |||
359 | tmp = var->pixclock * (unsigned long long)lcd_clk; | ||
360 | |||
361 | do_div(tmp, 1000000); | ||
362 | |||
363 | if (do_div(tmp, 1000000) > 500000) | ||
364 | tmp++; | ||
365 | |||
366 | pcr = (unsigned int)tmp; | ||
367 | |||
368 | if (--pcr > 0x3F) { | ||
369 | pcr = 0x3F; | ||
370 | printk(KERN_WARNING "Must limit pixel clock to %luHz\n", | ||
371 | lcd_clk / pcr); | ||
372 | } | ||
373 | |||
324 | switch (var->bits_per_pixel) { | 374 | switch (var->bits_per_pixel) { |
325 | case 32: | 375 | case 32: |
376 | pcr |= PCR_BPIX_18; | ||
326 | rgb = &def_rgb_18; | 377 | rgb = &def_rgb_18; |
327 | break; | 378 | break; |
328 | case 16: | 379 | case 16: |
329 | default: | 380 | default: |
330 | if (fbi->pcr & PCR_TFT) | 381 | if (cpu_is_mx1()) |
382 | pcr |= PCR_BPIX_12; | ||
383 | else | ||
384 | pcr |= PCR_BPIX_16; | ||
385 | |||
386 | if (imxfb_mode->pcr & PCR_TFT) | ||
331 | rgb = &def_rgb_16_tft; | 387 | rgb = &def_rgb_16_tft; |
332 | else | 388 | else |
333 | rgb = &def_rgb_16_stn; | 389 | rgb = &def_rgb_16_stn; |
334 | break; | 390 | break; |
335 | case 8: | 391 | case 8: |
392 | pcr |= PCR_BPIX_8; | ||
336 | rgb = &def_rgb_8; | 393 | rgb = &def_rgb_8; |
337 | break; | 394 | break; |
338 | } | 395 | } |
339 | 396 | ||
397 | /* add sync polarities */ | ||
398 | pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25)); | ||
399 | |||
400 | fbi->pcr = pcr; | ||
401 | |||
340 | /* | 402 | /* |
341 | * Copy the RGB parameters for this display | 403 | * Copy the RGB parameters for this display |
342 | * from the machine specific parameters. | 404 | * from the machine specific parameters. |
@@ -393,10 +455,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) | |||
393 | 455 | ||
394 | writel(fbi->screen_dma, fbi->regs + LCDC_SSA); | 456 | writel(fbi->screen_dma, fbi->regs + LCDC_SSA); |
395 | 457 | ||
396 | /* physical screen start address */ | ||
397 | writel(VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4), | ||
398 | fbi->regs + LCDC_VPW); | ||
399 | |||
400 | /* panning offset 0 (0 pixel offset) */ | 458 | /* panning offset 0 (0 pixel offset) */ |
401 | writel(0x00000000, fbi->regs + LCDC_POS); | 459 | writel(0x00000000, fbi->regs + LCDC_POS); |
402 | 460 | ||
@@ -468,8 +526,6 @@ static struct fb_ops imxfb_ops = { | |||
468 | static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) | 526 | static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) |
469 | { | 527 | { |
470 | struct imxfb_info *fbi = info->par; | 528 | struct imxfb_info *fbi = info->par; |
471 | unsigned int pcr, lcd_clk; | ||
472 | unsigned long long tmp; | ||
473 | 529 | ||
474 | pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", | 530 | pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", |
475 | var->xres, var->hsync_len, | 531 | var->xres, var->hsync_len, |
@@ -505,6 +561,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf | |||
505 | info->fix.id, var->lower_margin); | 561 | info->fix.id, var->lower_margin); |
506 | #endif | 562 | #endif |
507 | 563 | ||
564 | /* physical screen start address */ | ||
565 | writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4), | ||
566 | fbi->regs + LCDC_VPW); | ||
567 | |||
508 | writel(HCR_H_WIDTH(var->hsync_len - 1) | | 568 | writel(HCR_H_WIDTH(var->hsync_len - 1) | |
509 | HCR_H_WAIT_1(var->right_margin - 1) | | 569 | HCR_H_WAIT_1(var->right_margin - 1) | |
510 | HCR_H_WAIT_2(var->left_margin - 3), | 570 | HCR_H_WAIT_2(var->left_margin - 3), |
@@ -518,22 +578,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf | |||
518 | writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), | 578 | writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), |
519 | fbi->regs + LCDC_SIZE); | 579 | fbi->regs + LCDC_SIZE); |
520 | 580 | ||
521 | lcd_clk = clk_get_rate(fbi->clk); | 581 | writel(fbi->pcr, fbi->regs + LCDC_PCR); |
522 | tmp = var->pixclock * (unsigned long long)lcd_clk; | ||
523 | do_div(tmp, 1000000); | ||
524 | if (do_div(tmp, 1000000) > 500000) | ||
525 | tmp++; | ||
526 | pcr = (unsigned int)tmp; | ||
527 | if (--pcr > 0x3F) { | ||
528 | pcr = 0x3F; | ||
529 | printk(KERN_WARNING "Must limit pixel clock to %uHz\n", | ||
530 | lcd_clk / pcr); | ||
531 | } | ||
532 | |||
533 | /* add sync polarities */ | ||
534 | pcr |= fbi->pcr & ~0x3F; | ||
535 | |||
536 | writel(pcr, fbi->regs + LCDC_PCR); | ||
537 | writel(fbi->pwmr, fbi->regs + LCDC_PWMR); | 582 | writel(fbi->pwmr, fbi->regs + LCDC_PWMR); |
538 | writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); | 583 | writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); |
539 | writel(fbi->dmacr, fbi->regs + LCDC_DMACR); | 584 | writel(fbi->dmacr, fbi->regs + LCDC_DMACR); |
@@ -575,6 +620,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) | |||
575 | struct imx_fb_platform_data *pdata = pdev->dev.platform_data; | 620 | struct imx_fb_platform_data *pdata = pdev->dev.platform_data; |
576 | struct fb_info *info = dev_get_drvdata(&pdev->dev); | 621 | struct fb_info *info = dev_get_drvdata(&pdev->dev); |
577 | struct imxfb_info *fbi = info->par; | 622 | struct imxfb_info *fbi = info->par; |
623 | struct imx_fb_videomode *m; | ||
624 | int i; | ||
578 | 625 | ||
579 | pr_debug("%s\n",__func__); | 626 | pr_debug("%s\n",__func__); |
580 | 627 | ||
@@ -603,35 +650,18 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) | |||
603 | info->fbops = &imxfb_ops; | 650 | info->fbops = &imxfb_ops; |
604 | info->flags = FBINFO_FLAG_DEFAULT | | 651 | info->flags = FBINFO_FLAG_DEFAULT | |
605 | FBINFO_READS_FAST; | 652 | FBINFO_READS_FAST; |
606 | |||
607 | fbi->max_xres = pdata->xres; | ||
608 | info->var.xres = pdata->xres; | ||
609 | info->var.xres_virtual = pdata->xres; | ||
610 | fbi->max_yres = pdata->yres; | ||
611 | info->var.yres = pdata->yres; | ||
612 | info->var.yres_virtual = pdata->yres; | ||
613 | fbi->max_bpp = pdata->bpp; | ||
614 | info->var.bits_per_pixel = pdata->bpp; | ||
615 | info->var.nonstd = pdata->nonstd; | ||
616 | info->var.pixclock = pdata->pixclock; | ||
617 | info->var.hsync_len = pdata->hsync_len; | ||
618 | info->var.left_margin = pdata->left_margin; | ||
619 | info->var.right_margin = pdata->right_margin; | ||
620 | info->var.vsync_len = pdata->vsync_len; | ||
621 | info->var.upper_margin = pdata->upper_margin; | ||
622 | info->var.lower_margin = pdata->lower_margin; | ||
623 | info->var.sync = pdata->sync; | ||
624 | info->var.grayscale = pdata->cmap_greyscale; | 653 | info->var.grayscale = pdata->cmap_greyscale; |
625 | fbi->cmap_inverse = pdata->cmap_inverse; | 654 | fbi->cmap_inverse = pdata->cmap_inverse; |
626 | fbi->cmap_static = pdata->cmap_static; | 655 | fbi->cmap_static = pdata->cmap_static; |
627 | fbi->pcr = pdata->pcr; | ||
628 | fbi->lscr1 = pdata->lscr1; | 656 | fbi->lscr1 = pdata->lscr1; |
629 | fbi->dmacr = pdata->dmacr; | 657 | fbi->dmacr = pdata->dmacr; |
630 | fbi->pwmr = pdata->pwmr; | 658 | fbi->pwmr = pdata->pwmr; |
631 | fbi->lcd_power = pdata->lcd_power; | 659 | fbi->lcd_power = pdata->lcd_power; |
632 | fbi->backlight_power = pdata->backlight_power; | 660 | fbi->backlight_power = pdata->backlight_power; |
633 | info->fix.smem_len = fbi->max_xres * fbi->max_yres * | 661 | |
634 | fbi->max_bpp / 8; | 662 | for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++) |
663 | info->fix.smem_len = max_t(size_t, info->fix.smem_len, | ||
664 | m->mode.xres * m->mode.yres * m->bpp / 8); | ||
635 | 665 | ||
636 | return 0; | 666 | return 0; |
637 | } | 667 | } |
@@ -642,9 +672,9 @@ static int __init imxfb_probe(struct platform_device *pdev) | |||
642 | struct fb_info *info; | 672 | struct fb_info *info; |
643 | struct imx_fb_platform_data *pdata; | 673 | struct imx_fb_platform_data *pdata; |
644 | struct resource *res; | 674 | struct resource *res; |
645 | int ret; | 675 | int ret, i; |
646 | 676 | ||
647 | printk("i.MX Framebuffer driver\n"); | 677 | dev_info(&pdev->dev, "i.MX Framebuffer driver\n"); |
648 | 678 | ||
649 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 679 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
650 | if (!res) | 680 | if (!res) |
@@ -662,6 +692,9 @@ static int __init imxfb_probe(struct platform_device *pdev) | |||
662 | 692 | ||
663 | fbi = info->par; | 693 | fbi = info->par; |
664 | 694 | ||
695 | if (!fb_mode) | ||
696 | fb_mode = pdata->mode[0].mode.name; | ||
697 | |||
665 | platform_set_drvdata(pdev, info); | 698 | platform_set_drvdata(pdev, info); |
666 | 699 | ||
667 | ret = imxfb_init_fbinfo(pdev); | 700 | ret = imxfb_init_fbinfo(pdev); |
@@ -677,14 +710,14 @@ static int __init imxfb_probe(struct platform_device *pdev) | |||
677 | 710 | ||
678 | fbi->clk = clk_get(&pdev->dev, NULL); | 711 | fbi->clk = clk_get(&pdev->dev, NULL); |
679 | if (IS_ERR(fbi->clk)) { | 712 | if (IS_ERR(fbi->clk)) { |
680 | ret = PTR_ERR(fbi->clk);; | 713 | ret = PTR_ERR(fbi->clk); |
681 | dev_err(&pdev->dev, "unable to get clock: %d\n", ret); | 714 | dev_err(&pdev->dev, "unable to get clock: %d\n", ret); |
682 | goto failed_getclock; | 715 | goto failed_getclock; |
683 | } | 716 | } |
684 | 717 | ||
685 | fbi->regs = ioremap(res->start, resource_size(res)); | 718 | fbi->regs = ioremap(res->start, resource_size(res)); |
686 | if (fbi->regs == NULL) { | 719 | if (fbi->regs == NULL) { |
687 | printk(KERN_ERR"Cannot map frame buffer registers\n"); | 720 | dev_err(&pdev->dev, "Cannot map frame buffer registers\n"); |
688 | goto failed_ioremap; | 721 | goto failed_ioremap; |
689 | } | 722 | } |
690 | 723 | ||
@@ -719,6 +752,13 @@ static int __init imxfb_probe(struct platform_device *pdev) | |||
719 | goto failed_platform_init; | 752 | goto failed_platform_init; |
720 | } | 753 | } |
721 | 754 | ||
755 | fbi->mode = pdata->mode; | ||
756 | fbi->num_modes = pdata->num_modes; | ||
757 | |||
758 | INIT_LIST_HEAD(&info->modelist); | ||
759 | for (i = 0; i < pdata->num_modes; i++) | ||
760 | fb_add_videomode(&pdata->mode[i].mode, &info->modelist); | ||
761 | |||
722 | /* | 762 | /* |
723 | * This makes sure that our colour bitfield | 763 | * This makes sure that our colour bitfield |
724 | * descriptors are correctly initialised. | 764 | * descriptors are correctly initialised. |
@@ -754,7 +794,7 @@ failed_map: | |||
754 | failed_getclock: | 794 | failed_getclock: |
755 | iounmap(fbi->regs); | 795 | iounmap(fbi->regs); |
756 | failed_ioremap: | 796 | failed_ioremap: |
757 | release_mem_region(res->start, res->end - res->start); | 797 | release_mem_region(res->start, resource_size(res)); |
758 | failed_req: | 798 | failed_req: |
759 | kfree(info->pseudo_palette); | 799 | kfree(info->pseudo_palette); |
760 | failed_init: | 800 | failed_init: |
@@ -785,7 +825,7 @@ static int __devexit imxfb_remove(struct platform_device *pdev) | |||
785 | framebuffer_release(info); | 825 | framebuffer_release(info); |
786 | 826 | ||
787 | iounmap(fbi->regs); | 827 | iounmap(fbi->regs); |
788 | release_mem_region(res->start, res->end - res->start + 1); | 828 | release_mem_region(res->start, resource_size(res)); |
789 | clk_disable(fbi->clk); | 829 | clk_disable(fbi->clk); |
790 | clk_put(fbi->clk); | 830 | clk_put(fbi->clk); |
791 | 831 | ||
@@ -811,8 +851,34 @@ static struct platform_driver imxfb_driver = { | |||
811 | }, | 851 | }, |
812 | }; | 852 | }; |
813 | 853 | ||
854 | static int imxfb_setup(void) | ||
855 | { | ||
856 | #ifndef MODULE | ||
857 | char *opt, *options = NULL; | ||
858 | |||
859 | if (fb_get_options("imxfb", &options)) | ||
860 | return -ENODEV; | ||
861 | |||
862 | if (!options || !*options) | ||
863 | return 0; | ||
864 | |||
865 | while ((opt = strsep(&options, ",")) != NULL) { | ||
866 | if (!*opt) | ||
867 | continue; | ||
868 | else | ||
869 | fb_mode = opt; | ||
870 | } | ||
871 | #endif | ||
872 | return 0; | ||
873 | } | ||
874 | |||
814 | int __init imxfb_init(void) | 875 | int __init imxfb_init(void) |
815 | { | 876 | { |
877 | int ret = imxfb_setup(); | ||
878 | |||
879 | if (ret < 0) | ||
880 | return ret; | ||
881 | |||
816 | return platform_driver_probe(&imxfb_driver, imxfb_probe); | 882 | return platform_driver_probe(&imxfb_driver, imxfb_probe); |
817 | } | 883 | } |
818 | 884 | ||
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c index d42346e7fdda..09f6e045d5be 100644 --- a/drivers/video/matrox/g450_pll.c +++ b/drivers/video/matrox/g450_pll.c | |||
@@ -25,16 +25,19 @@ static inline unsigned int g450_f2vco(unsigned char p, unsigned int fin) { | |||
25 | return (p & 0x40) ? fin : fin << ((p & 3) + 1); | 25 | return (p & 0x40) ? fin : fin << ((p & 3) + 1); |
26 | } | 26 | } |
27 | 27 | ||
28 | static unsigned int g450_mnp2vco(CPMINFO unsigned int mnp) { | 28 | static unsigned int g450_mnp2vco(const struct matrox_fb_info *minfo, |
29 | unsigned int mnp) | ||
30 | { | ||
29 | unsigned int m, n; | 31 | unsigned int m, n; |
30 | 32 | ||
31 | m = ((mnp >> 16) & 0x0FF) + 1; | 33 | m = ((mnp >> 16) & 0x0FF) + 1; |
32 | n = ((mnp >> 7) & 0x1FE) + 4; | 34 | n = ((mnp >> 7) & 0x1FE) + 4; |
33 | return (ACCESS_FBINFO(features).pll.ref_freq * n + (m >> 1)) / m; | 35 | return (minfo->features.pll.ref_freq * n + (m >> 1)) / m; |
34 | } | 36 | } |
35 | 37 | ||
36 | unsigned int g450_mnp2f(CPMINFO unsigned int mnp) { | 38 | unsigned int g450_mnp2f(const struct matrox_fb_info *minfo, unsigned int mnp) |
37 | return g450_vco2f(mnp, g450_mnp2vco(PMINFO mnp)); | 39 | { |
40 | return g450_vco2f(mnp, g450_mnp2vco(minfo, mnp)); | ||
38 | } | 41 | } |
39 | 42 | ||
40 | static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) { | 43 | static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) { |
@@ -49,7 +52,10 @@ static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) { | |||
49 | #define NO_MORE_MNP 0x01FFFFFF | 52 | #define NO_MORE_MNP 0x01FFFFFF |
50 | #define G450_MNP_FREQBITS (0xFFFFFF43) /* do not mask high byte so we'll catch NO_MORE_MNP */ | 53 | #define G450_MNP_FREQBITS (0xFFFFFF43) /* do not mask high byte so we'll catch NO_MORE_MNP */ |
51 | 54 | ||
52 | static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, unsigned int* fvco, unsigned int mnp) { | 55 | static unsigned int g450_nextpll(const struct matrox_fb_info *minfo, |
56 | const struct matrox_pll_limits *pi, | ||
57 | unsigned int *fvco, unsigned int mnp) | ||
58 | { | ||
53 | unsigned int m, n, p; | 59 | unsigned int m, n, p; |
54 | unsigned int tvco = *fvco; | 60 | unsigned int tvco = *fvco; |
55 | 61 | ||
@@ -90,12 +96,15 @@ static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, uns | |||
90 | } else { | 96 | } else { |
91 | m--; | 97 | m--; |
92 | } | 98 | } |
93 | n = ((tvco * (m+1) + ACCESS_FBINFO(features).pll.ref_freq) / (ACCESS_FBINFO(features).pll.ref_freq * 2)) - 2; | 99 | n = ((tvco * (m+1) + minfo->features.pll.ref_freq) / (minfo->features.pll.ref_freq * 2)) - 2; |
94 | } while (n < 0x03 || n > 0x7A); | 100 | } while (n < 0x03 || n > 0x7A); |
95 | return (m << 16) | (n << 8) | p; | 101 | return (m << 16) | (n << 8) | p; |
96 | } | 102 | } |
97 | 103 | ||
98 | static unsigned int g450_firstpll(CPMINFO const struct matrox_pll_limits* pi, unsigned int* vco, unsigned int fout) { | 104 | static unsigned int g450_firstpll(const struct matrox_fb_info *minfo, |
105 | const struct matrox_pll_limits *pi, | ||
106 | unsigned int *vco, unsigned int fout) | ||
107 | { | ||
99 | unsigned int p; | 108 | unsigned int p; |
100 | unsigned int vcomax; | 109 | unsigned int vcomax; |
101 | 110 | ||
@@ -121,88 +130,94 @@ static unsigned int g450_firstpll(CPMINFO const struct matrox_pll_limits* pi, un | |||
121 | } | 130 | } |
122 | *vco = tvco; | 131 | *vco = tvco; |
123 | } | 132 | } |
124 | return g450_nextpll(PMINFO pi, vco, 0xFF0000 | p); | 133 | return g450_nextpll(minfo, pi, vco, 0xFF0000 | p); |
125 | } | 134 | } |
126 | 135 | ||
127 | static inline unsigned int g450_setpll(CPMINFO unsigned int mnp, unsigned int pll) { | 136 | static inline unsigned int g450_setpll(const struct matrox_fb_info *minfo, |
137 | unsigned int mnp, unsigned int pll) | ||
138 | { | ||
128 | switch (pll) { | 139 | switch (pll) { |
129 | case M_PIXEL_PLL_A: | 140 | case M_PIXEL_PLL_A: |
130 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLAM, mnp >> 16); | 141 | matroxfb_DAC_out(minfo, M1064_XPIXPLLAM, mnp >> 16); |
131 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLAN, mnp >> 8); | 142 | matroxfb_DAC_out(minfo, M1064_XPIXPLLAN, mnp >> 8); |
132 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLAP, mnp); | 143 | matroxfb_DAC_out(minfo, M1064_XPIXPLLAP, mnp); |
133 | return M1064_XPIXPLLSTAT; | 144 | return M1064_XPIXPLLSTAT; |
134 | 145 | ||
135 | case M_PIXEL_PLL_B: | 146 | case M_PIXEL_PLL_B: |
136 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLBM, mnp >> 16); | 147 | matroxfb_DAC_out(minfo, M1064_XPIXPLLBM, mnp >> 16); |
137 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLBN, mnp >> 8); | 148 | matroxfb_DAC_out(minfo, M1064_XPIXPLLBN, mnp >> 8); |
138 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLBP, mnp); | 149 | matroxfb_DAC_out(minfo, M1064_XPIXPLLBP, mnp); |
139 | return M1064_XPIXPLLSTAT; | 150 | return M1064_XPIXPLLSTAT; |
140 | 151 | ||
141 | case M_PIXEL_PLL_C: | 152 | case M_PIXEL_PLL_C: |
142 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLCM, mnp >> 16); | 153 | matroxfb_DAC_out(minfo, M1064_XPIXPLLCM, mnp >> 16); |
143 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLCN, mnp >> 8); | 154 | matroxfb_DAC_out(minfo, M1064_XPIXPLLCN, mnp >> 8); |
144 | matroxfb_DAC_out(PMINFO M1064_XPIXPLLCP, mnp); | 155 | matroxfb_DAC_out(minfo, M1064_XPIXPLLCP, mnp); |
145 | return M1064_XPIXPLLSTAT; | 156 | return M1064_XPIXPLLSTAT; |
146 | 157 | ||
147 | case M_SYSTEM_PLL: | 158 | case M_SYSTEM_PLL: |
148 | matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLM, mnp >> 16); | 159 | matroxfb_DAC_out(minfo, DAC1064_XSYSPLLM, mnp >> 16); |
149 | matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLN, mnp >> 8); | 160 | matroxfb_DAC_out(minfo, DAC1064_XSYSPLLN, mnp >> 8); |
150 | matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLP, mnp); | 161 | matroxfb_DAC_out(minfo, DAC1064_XSYSPLLP, mnp); |
151 | return DAC1064_XSYSPLLSTAT; | 162 | return DAC1064_XSYSPLLSTAT; |
152 | 163 | ||
153 | case M_VIDEO_PLL: | 164 | case M_VIDEO_PLL: |
154 | matroxfb_DAC_out(PMINFO M1064_XVIDPLLM, mnp >> 16); | 165 | matroxfb_DAC_out(minfo, M1064_XVIDPLLM, mnp >> 16); |
155 | matroxfb_DAC_out(PMINFO M1064_XVIDPLLN, mnp >> 8); | 166 | matroxfb_DAC_out(minfo, M1064_XVIDPLLN, mnp >> 8); |
156 | matroxfb_DAC_out(PMINFO M1064_XVIDPLLP, mnp); | 167 | matroxfb_DAC_out(minfo, M1064_XVIDPLLP, mnp); |
157 | return M1064_XVIDPLLSTAT; | 168 | return M1064_XVIDPLLSTAT; |
158 | } | 169 | } |
159 | return 0; | 170 | return 0; |
160 | } | 171 | } |
161 | 172 | ||
162 | static inline unsigned int g450_cmppll(CPMINFO unsigned int mnp, unsigned int pll) { | 173 | static inline unsigned int g450_cmppll(const struct matrox_fb_info *minfo, |
174 | unsigned int mnp, unsigned int pll) | ||
175 | { | ||
163 | unsigned char m = mnp >> 16; | 176 | unsigned char m = mnp >> 16; |
164 | unsigned char n = mnp >> 8; | 177 | unsigned char n = mnp >> 8; |
165 | unsigned char p = mnp; | 178 | unsigned char p = mnp; |
166 | 179 | ||
167 | switch (pll) { | 180 | switch (pll) { |
168 | case M_PIXEL_PLL_A: | 181 | case M_PIXEL_PLL_A: |
169 | return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLAM) != m || | 182 | return (matroxfb_DAC_in(minfo, M1064_XPIXPLLAM) != m || |
170 | matroxfb_DAC_in(PMINFO M1064_XPIXPLLAN) != n || | 183 | matroxfb_DAC_in(minfo, M1064_XPIXPLLAN) != n || |
171 | matroxfb_DAC_in(PMINFO M1064_XPIXPLLAP) != p); | 184 | matroxfb_DAC_in(minfo, M1064_XPIXPLLAP) != p); |
172 | 185 | ||
173 | case M_PIXEL_PLL_B: | 186 | case M_PIXEL_PLL_B: |
174 | return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLBM) != m || | 187 | return (matroxfb_DAC_in(minfo, M1064_XPIXPLLBM) != m || |
175 | matroxfb_DAC_in(PMINFO M1064_XPIXPLLBN) != n || | 188 | matroxfb_DAC_in(minfo, M1064_XPIXPLLBN) != n || |
176 | matroxfb_DAC_in(PMINFO M1064_XPIXPLLBP) != p); | 189 | matroxfb_DAC_in(minfo, M1064_XPIXPLLBP) != p); |
177 | 190 | ||
178 | case M_PIXEL_PLL_C: | 191 | case M_PIXEL_PLL_C: |
179 | return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLCM) != m || | 192 | return (matroxfb_DAC_in(minfo, M1064_XPIXPLLCM) != m || |
180 | matroxfb_DAC_in(PMINFO M1064_XPIXPLLCN) != n || | 193 | matroxfb_DAC_in(minfo, M1064_XPIXPLLCN) != n || |
181 | matroxfb_DAC_in(PMINFO M1064_XPIXPLLCP) != p); | 194 | matroxfb_DAC_in(minfo, M1064_XPIXPLLCP) != p); |
182 | 195 | ||
183 | case M_SYSTEM_PLL: | 196 | case M_SYSTEM_PLL: |
184 | return (matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLM) != m || | 197 | return (matroxfb_DAC_in(minfo, DAC1064_XSYSPLLM) != m || |
185 | matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLN) != n || | 198 | matroxfb_DAC_in(minfo, DAC1064_XSYSPLLN) != n || |
186 | matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLP) != p); | 199 | matroxfb_DAC_in(minfo, DAC1064_XSYSPLLP) != p); |
187 | 200 | ||
188 | case M_VIDEO_PLL: | 201 | case M_VIDEO_PLL: |
189 | return (matroxfb_DAC_in(PMINFO M1064_XVIDPLLM) != m || | 202 | return (matroxfb_DAC_in(minfo, M1064_XVIDPLLM) != m || |
190 | matroxfb_DAC_in(PMINFO M1064_XVIDPLLN) != n || | 203 | matroxfb_DAC_in(minfo, M1064_XVIDPLLN) != n || |
191 | matroxfb_DAC_in(PMINFO M1064_XVIDPLLP) != p); | 204 | matroxfb_DAC_in(minfo, M1064_XVIDPLLP) != p); |
192 | } | 205 | } |
193 | return 1; | 206 | return 1; |
194 | } | 207 | } |
195 | 208 | ||
196 | static inline int g450_isplllocked(CPMINFO unsigned int regidx) { | 209 | static inline int g450_isplllocked(const struct matrox_fb_info *minfo, |
210 | unsigned int regidx) | ||
211 | { | ||
197 | unsigned int j; | 212 | unsigned int j; |
198 | 213 | ||
199 | for (j = 0; j < 1000; j++) { | 214 | for (j = 0; j < 1000; j++) { |
200 | if (matroxfb_DAC_in(PMINFO regidx) & 0x40) { | 215 | if (matroxfb_DAC_in(minfo, regidx) & 0x40) { |
201 | unsigned int r = 0; | 216 | unsigned int r = 0; |
202 | int i; | 217 | int i; |
203 | 218 | ||
204 | for (i = 0; i < 100; i++) { | 219 | for (i = 0; i < 100; i++) { |
205 | r += matroxfb_DAC_in(PMINFO regidx) & 0x40; | 220 | r += matroxfb_DAC_in(minfo, regidx) & 0x40; |
206 | } | 221 | } |
207 | return r >= (90 * 0x40); | 222 | return r >= (90 * 0x40); |
208 | } | 223 | } |
@@ -211,8 +226,10 @@ static inline int g450_isplllocked(CPMINFO unsigned int regidx) { | |||
211 | return 0; | 226 | return 0; |
212 | } | 227 | } |
213 | 228 | ||
214 | static int g450_testpll(CPMINFO unsigned int mnp, unsigned int pll) { | 229 | static int g450_testpll(const struct matrox_fb_info *minfo, unsigned int mnp, |
215 | return g450_isplllocked(PMINFO g450_setpll(PMINFO mnp, pll)); | 230 | unsigned int pll) |
231 | { | ||
232 | return g450_isplllocked(minfo, g450_setpll(minfo, mnp, pll)); | ||
216 | } | 233 | } |
217 | 234 | ||
218 | static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsigned int pll) { | 235 | static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsigned int pll) { |
@@ -225,13 +242,19 @@ static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsi | |||
225 | } | 242 | } |
226 | } | 243 | } |
227 | 244 | ||
228 | void matroxfb_g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll) { | 245 | void matroxfb_g450_setpll_cond(struct matrox_fb_info *minfo, unsigned int mnp, |
229 | if (g450_cmppll(PMINFO mnp, pll)) { | 246 | unsigned int pll) |
230 | g450_setpll(PMINFO mnp, pll); | 247 | { |
248 | if (g450_cmppll(minfo, mnp, pll)) { | ||
249 | g450_setpll(minfo, mnp, pll); | ||
231 | } | 250 | } |
232 | } | 251 | } |
233 | 252 | ||
234 | static inline unsigned int g450_findworkingpll(WPMINFO unsigned int pll, unsigned int* mnparray, unsigned int mnpcount) { | 253 | static inline unsigned int g450_findworkingpll(struct matrox_fb_info *minfo, |
254 | unsigned int pll, | ||
255 | unsigned int *mnparray, | ||
256 | unsigned int mnpcount) | ||
257 | { | ||
235 | unsigned int found = 0; | 258 | unsigned int found = 0; |
236 | unsigned int idx; | 259 | unsigned int idx; |
237 | unsigned int mnpfound = mnparray[0]; | 260 | unsigned int mnpfound = mnparray[0]; |
@@ -255,22 +278,22 @@ static inline unsigned int g450_findworkingpll(WPMINFO unsigned int pll, unsigne | |||
255 | while (sptr >= sarray) { | 278 | while (sptr >= sarray) { |
256 | unsigned int mnp = *sptr--; | 279 | unsigned int mnp = *sptr--; |
257 | 280 | ||
258 | if (g450_testpll(PMINFO mnp - 0x0300, pll) && | 281 | if (g450_testpll(minfo, mnp - 0x0300, pll) && |
259 | g450_testpll(PMINFO mnp + 0x0300, pll) && | 282 | g450_testpll(minfo, mnp + 0x0300, pll) && |
260 | g450_testpll(PMINFO mnp - 0x0200, pll) && | 283 | g450_testpll(minfo, mnp - 0x0200, pll) && |
261 | g450_testpll(PMINFO mnp + 0x0200, pll) && | 284 | g450_testpll(minfo, mnp + 0x0200, pll) && |
262 | g450_testpll(PMINFO mnp - 0x0100, pll) && | 285 | g450_testpll(minfo, mnp - 0x0100, pll) && |
263 | g450_testpll(PMINFO mnp + 0x0100, pll)) { | 286 | g450_testpll(minfo, mnp + 0x0100, pll)) { |
264 | if (g450_testpll(PMINFO mnp, pll)) { | 287 | if (g450_testpll(minfo, mnp, pll)) { |
265 | return mnp; | 288 | return mnp; |
266 | } | 289 | } |
267 | } else if (!found && g450_testpll(PMINFO mnp, pll)) { | 290 | } else if (!found && g450_testpll(minfo, mnp, pll)) { |
268 | mnpfound = mnp; | 291 | mnpfound = mnp; |
269 | found = 1; | 292 | found = 1; |
270 | } | 293 | } |
271 | } | 294 | } |
272 | } | 295 | } |
273 | g450_setpll(PMINFO mnpfound, pll); | 296 | g450_setpll(minfo, mnpfound, pll); |
274 | return mnpfound; | 297 | return mnpfound; |
275 | } | 298 | } |
276 | 299 | ||
@@ -283,7 +306,9 @@ static void g450_addcache(struct matrox_pll_cache* ci, unsigned int mnp_key, uns | |||
283 | ci->data[0].mnp_value = mnp_value; | 306 | ci->data[0].mnp_value = mnp_value; |
284 | } | 307 | } |
285 | 308 | ||
286 | static int g450_checkcache(WPMINFO struct matrox_pll_cache* ci, unsigned int mnp_key) { | 309 | static int g450_checkcache(struct matrox_fb_info *minfo, |
310 | struct matrox_pll_cache *ci, unsigned int mnp_key) | ||
311 | { | ||
287 | unsigned int i; | 312 | unsigned int i; |
288 | 313 | ||
289 | mnp_key &= G450_MNP_FREQBITS; | 314 | mnp_key &= G450_MNP_FREQBITS; |
@@ -303,8 +328,10 @@ static int g450_checkcache(WPMINFO struct matrox_pll_cache* ci, unsigned int mnp | |||
303 | return NO_MORE_MNP; | 328 | return NO_MORE_MNP; |
304 | } | 329 | } |
305 | 330 | ||
306 | static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | 331 | static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout, |
307 | unsigned int* mnparray, unsigned int* deltaarray) { | 332 | unsigned int pll, unsigned int *mnparray, |
333 | unsigned int *deltaarray) | ||
334 | { | ||
308 | unsigned int mnpcount; | 335 | unsigned int mnpcount; |
309 | unsigned int pixel_vco; | 336 | unsigned int pixel_vco; |
310 | const struct matrox_pll_limits* pi; | 337 | const struct matrox_pll_limits* pi; |
@@ -321,19 +348,19 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
321 | 348 | ||
322 | matroxfb_DAC_lock_irqsave(flags); | 349 | matroxfb_DAC_lock_irqsave(flags); |
323 | 350 | ||
324 | xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL); | 351 | xpwrctrl = matroxfb_DAC_in(minfo, M1064_XPWRCTRL); |
325 | matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN); | 352 | matroxfb_DAC_out(minfo, M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN); |
326 | mga_outb(M_SEQ_INDEX, M_SEQ1); | 353 | mga_outb(M_SEQ_INDEX, M_SEQ1); |
327 | mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF); | 354 | mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF); |
328 | tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL); | 355 | tmp = matroxfb_DAC_in(minfo, M1064_XPIXCLKCTRL); |
329 | tmp |= M1064_XPIXCLKCTRL_DIS; | 356 | tmp |= M1064_XPIXCLKCTRL_DIS; |
330 | if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) { | 357 | if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) { |
331 | tmp |= M1064_XPIXCLKCTRL_PLL_UP; | 358 | tmp |= M1064_XPIXCLKCTRL_PLL_UP; |
332 | } | 359 | } |
333 | matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); | 360 | matroxfb_DAC_out(minfo, M1064_XPIXCLKCTRL, tmp); |
334 | /* DVI PLL preferred for frequencies up to | 361 | /* DVI PLL preferred for frequencies up to |
335 | panel link max, standard PLL otherwise */ | 362 | panel link max, standard PLL otherwise */ |
336 | if (fout >= MINFO->max_pixel_clock_panellink) | 363 | if (fout >= minfo->max_pixel_clock_panellink) |
337 | tmp = 0; | 364 | tmp = 0; |
338 | else tmp = | 365 | else tmp = |
339 | M1064_XDVICLKCTRL_DVIDATAPATHSEL | | 366 | M1064_XDVICLKCTRL_DVIDATAPATHSEL | |
@@ -341,8 +368,8 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
341 | M1064_XDVICLKCTRL_C1DVICLKEN | | 368 | M1064_XDVICLKCTRL_C1DVICLKEN | |
342 | M1064_XDVICLKCTRL_DVILOOPCTL | | 369 | M1064_XDVICLKCTRL_DVILOOPCTL | |
343 | M1064_XDVICLKCTRL_P1LOOPBWDTCTL; | 370 | M1064_XDVICLKCTRL_P1LOOPBWDTCTL; |
344 | matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp); | 371 | matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp); |
345 | matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, | 372 | matroxfb_DAC_out(minfo, M1064_XPWRCTRL, |
346 | xpwrctrl); | 373 | xpwrctrl); |
347 | 374 | ||
348 | matroxfb_DAC_unlock_irqrestore(flags); | 375 | matroxfb_DAC_unlock_irqrestore(flags); |
@@ -363,20 +390,20 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
363 | } | 390 | } |
364 | mga_outb(M_MISC_REG, misc); | 391 | mga_outb(M_MISC_REG, misc); |
365 | } | 392 | } |
366 | pi = &ACCESS_FBINFO(limits.pixel); | 393 | pi = &minfo->limits.pixel; |
367 | ci = &ACCESS_FBINFO(cache.pixel); | 394 | ci = &minfo->cache.pixel; |
368 | break; | 395 | break; |
369 | case M_SYSTEM_PLL: | 396 | case M_SYSTEM_PLL: |
370 | { | 397 | { |
371 | u_int32_t opt; | 398 | u_int32_t opt; |
372 | 399 | ||
373 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &opt); | 400 | pci_read_config_dword(minfo->pcidev, PCI_OPTION_REG, &opt); |
374 | if (!(opt & 0x20)) { | 401 | if (!(opt & 0x20)) { |
375 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, opt | 0x20); | 402 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, opt | 0x20); |
376 | } | 403 | } |
377 | } | 404 | } |
378 | pi = &ACCESS_FBINFO(limits.system); | 405 | pi = &minfo->limits.system; |
379 | ci = &ACCESS_FBINFO(cache.system); | 406 | ci = &minfo->cache.system; |
380 | break; | 407 | break; |
381 | case M_VIDEO_PLL: | 408 | case M_VIDEO_PLL: |
382 | { | 409 | { |
@@ -385,18 +412,18 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
385 | unsigned long flags; | 412 | unsigned long flags; |
386 | 413 | ||
387 | matroxfb_DAC_lock_irqsave(flags); | 414 | matroxfb_DAC_lock_irqsave(flags); |
388 | tmp = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL); | 415 | tmp = matroxfb_DAC_in(minfo, M1064_XPWRCTRL); |
389 | if (!(tmp & 2)) { | 416 | if (!(tmp & 2)) { |
390 | matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, tmp | 2); | 417 | matroxfb_DAC_out(minfo, M1064_XPWRCTRL, tmp | 2); |
391 | } | 418 | } |
392 | 419 | ||
393 | mnp = matroxfb_DAC_in(PMINFO M1064_XPIXPLLCM) << 16; | 420 | mnp = matroxfb_DAC_in(minfo, M1064_XPIXPLLCM) << 16; |
394 | mnp |= matroxfb_DAC_in(PMINFO M1064_XPIXPLLCN) << 8; | 421 | mnp |= matroxfb_DAC_in(minfo, M1064_XPIXPLLCN) << 8; |
395 | pixel_vco = g450_mnp2vco(PMINFO mnp); | 422 | pixel_vco = g450_mnp2vco(minfo, mnp); |
396 | matroxfb_DAC_unlock_irqrestore(flags); | 423 | matroxfb_DAC_unlock_irqrestore(flags); |
397 | } | 424 | } |
398 | pi = &ACCESS_FBINFO(limits.video); | 425 | pi = &minfo->limits.video; |
399 | ci = &ACCESS_FBINFO(cache.video); | 426 | ci = &minfo->cache.video; |
400 | break; | 427 | break; |
401 | default: | 428 | default: |
402 | return -EINVAL; | 429 | return -EINVAL; |
@@ -407,12 +434,12 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
407 | unsigned int mnp; | 434 | unsigned int mnp; |
408 | unsigned int xvco; | 435 | unsigned int xvco; |
409 | 436 | ||
410 | for(mnp = g450_firstpll(PMINFO pi, &xvco, fout); mnp != NO_MORE_MNP; mnp = g450_nextpll(PMINFO pi, &xvco, mnp)) { | 437 | for (mnp = g450_firstpll(minfo, pi, &xvco, fout); mnp != NO_MORE_MNP; mnp = g450_nextpll(minfo, pi, &xvco, mnp)) { |
411 | unsigned int idx; | 438 | unsigned int idx; |
412 | unsigned int vco; | 439 | unsigned int vco; |
413 | unsigned int delta; | 440 | unsigned int delta; |
414 | 441 | ||
415 | vco = g450_mnp2vco(PMINFO mnp); | 442 | vco = g450_mnp2vco(minfo, mnp); |
416 | #if 0 | 443 | #if 0 |
417 | if (pll == M_VIDEO_PLL) { | 444 | if (pll == M_VIDEO_PLL) { |
418 | unsigned int big, small; | 445 | unsigned int big, small; |
@@ -444,7 +471,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
444 | * (freqs near VCOmin aren't as stable) | 471 | * (freqs near VCOmin aren't as stable) |
445 | */ | 472 | */ |
446 | if (delta == deltaarray[idx-1] | 473 | if (delta == deltaarray[idx-1] |
447 | && vco != g450_mnp2vco(PMINFO mnparray[idx-1]) | 474 | && vco != g450_mnp2vco(minfo, mnparray[idx-1]) |
448 | && vco < (pi->vcomin * 17 / 16)) { | 475 | && vco < (pi->vcomin * 17 / 16)) { |
449 | break; | 476 | break; |
450 | } | 477 | } |
@@ -468,14 +495,14 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
468 | unsigned int mnp; | 495 | unsigned int mnp; |
469 | 496 | ||
470 | matroxfb_DAC_lock_irqsave(flags); | 497 | matroxfb_DAC_lock_irqsave(flags); |
471 | mnp = g450_checkcache(PMINFO ci, mnparray[0]); | 498 | mnp = g450_checkcache(minfo, ci, mnparray[0]); |
472 | if (mnp != NO_MORE_MNP) { | 499 | if (mnp != NO_MORE_MNP) { |
473 | matroxfb_g450_setpll_cond(PMINFO mnp, pll); | 500 | matroxfb_g450_setpll_cond(minfo, mnp, pll); |
474 | } else { | 501 | } else { |
475 | mnp = g450_findworkingpll(PMINFO pll, mnparray, mnpcount); | 502 | mnp = g450_findworkingpll(minfo, pll, mnparray, mnpcount); |
476 | g450_addcache(ci, mnparray[0], mnp); | 503 | g450_addcache(ci, mnparray[0], mnp); |
477 | } | 504 | } |
478 | updatehwstate_clk(&ACCESS_FBINFO(hw), mnp, pll); | 505 | updatehwstate_clk(&minfo->hw, mnp, pll); |
479 | matroxfb_DAC_unlock_irqrestore(flags); | 506 | matroxfb_DAC_unlock_irqrestore(flags); |
480 | return mnp; | 507 | return mnp; |
481 | } | 508 | } |
@@ -485,14 +512,16 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
485 | * Currently there is 5(p) * 10(m) = 50 possible values. */ | 512 | * Currently there is 5(p) * 10(m) = 50 possible values. */ |
486 | #define MNP_TABLE_SIZE 64 | 513 | #define MNP_TABLE_SIZE 64 |
487 | 514 | ||
488 | int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll) { | 515 | int matroxfb_g450_setclk(struct matrox_fb_info *minfo, unsigned int fout, |
516 | unsigned int pll) | ||
517 | { | ||
489 | unsigned int* arr; | 518 | unsigned int* arr; |
490 | 519 | ||
491 | arr = kmalloc(sizeof(*arr) * MNP_TABLE_SIZE * 2, GFP_KERNEL); | 520 | arr = kmalloc(sizeof(*arr) * MNP_TABLE_SIZE * 2, GFP_KERNEL); |
492 | if (arr) { | 521 | if (arr) { |
493 | int r; | 522 | int r; |
494 | 523 | ||
495 | r = __g450_setclk(PMINFO fout, pll, arr, arr + MNP_TABLE_SIZE); | 524 | r = __g450_setclk(minfo, fout, pll, arr, arr + MNP_TABLE_SIZE); |
496 | kfree(arr); | 525 | kfree(arr); |
497 | return r; | 526 | return r; |
498 | } | 527 | } |
diff --git a/drivers/video/matrox/g450_pll.h b/drivers/video/matrox/g450_pll.h index c17ed74501e9..aac615d18440 100644 --- a/drivers/video/matrox/g450_pll.h +++ b/drivers/video/matrox/g450_pll.h | |||
@@ -3,8 +3,10 @@ | |||
3 | 3 | ||
4 | #include "matroxfb_base.h" | 4 | #include "matroxfb_base.h" |
5 | 5 | ||
6 | int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll); | 6 | int matroxfb_g450_setclk(struct matrox_fb_info *minfo, unsigned int fout, |
7 | unsigned int g450_mnp2f(CPMINFO unsigned int mnp); | 7 | unsigned int pll); |
8 | void matroxfb_g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll); | 8 | unsigned int g450_mnp2f(const struct matrox_fb_info *minfo, unsigned int mnp); |
9 | void matroxfb_g450_setpll_cond(struct matrox_fb_info *minfo, unsigned int mnp, | ||
10 | unsigned int pll); | ||
9 | 11 | ||
10 | #endif /* __G450_PLL_H__ */ | 12 | #endif /* __G450_PLL_H__ */ |
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c index c14e3e2212b3..f3728ab262f8 100644 --- a/drivers/video/matrox/i2c-matroxfb.c +++ b/drivers/video/matrox/i2c-matroxfb.c | |||
@@ -41,7 +41,7 @@ static int matroxfb_read_gpio(struct matrox_fb_info* minfo) { | |||
41 | int v; | 41 | int v; |
42 | 42 | ||
43 | matroxfb_DAC_lock_irqsave(flags); | 43 | matroxfb_DAC_lock_irqsave(flags); |
44 | v = matroxfb_DAC_in(PMINFO DAC_XGENIODATA); | 44 | v = matroxfb_DAC_in(minfo, DAC_XGENIODATA); |
45 | matroxfb_DAC_unlock_irqrestore(flags); | 45 | matroxfb_DAC_unlock_irqrestore(flags); |
46 | return v; | 46 | return v; |
47 | } | 47 | } |
@@ -51,10 +51,10 @@ static void matroxfb_set_gpio(struct matrox_fb_info* minfo, int mask, int val) { | |||
51 | int v; | 51 | int v; |
52 | 52 | ||
53 | matroxfb_DAC_lock_irqsave(flags); | 53 | matroxfb_DAC_lock_irqsave(flags); |
54 | v = (matroxfb_DAC_in(PMINFO DAC_XGENIOCTRL) & mask) | val; | 54 | v = (matroxfb_DAC_in(minfo, DAC_XGENIOCTRL) & mask) | val; |
55 | matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, v); | 55 | matroxfb_DAC_out(minfo, DAC_XGENIOCTRL, v); |
56 | /* We must reset GENIODATA very often... XFree plays with this register */ | 56 | /* We must reset GENIODATA very often... XFree plays with this register */ |
57 | matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0x00); | 57 | matroxfb_DAC_out(minfo, DAC_XGENIODATA, 0x00); |
58 | matroxfb_DAC_unlock_irqrestore(flags); | 58 | matroxfb_DAC_unlock_irqrestore(flags); |
59 | } | 59 | } |
60 | 60 | ||
@@ -112,7 +112,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, | |||
112 | i2c_set_adapdata(&b->adapter, b); | 112 | i2c_set_adapdata(&b->adapter, b); |
113 | b->adapter.class = class; | 113 | b->adapter.class = class; |
114 | b->adapter.algo_data = &b->bac; | 114 | b->adapter.algo_data = &b->bac; |
115 | b->adapter.dev.parent = &ACCESS_FBINFO(pcidev)->dev; | 115 | b->adapter.dev.parent = &minfo->pcidev->dev; |
116 | b->bac = matrox_i2c_algo_template; | 116 | b->bac = matrox_i2c_algo_template; |
117 | b->bac.data = b; | 117 | b->bac.data = b; |
118 | err = i2c_bit_add_bus(&b->adapter); | 118 | err = i2c_bit_add_bus(&b->adapter); |
@@ -149,11 +149,11 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) { | |||
149 | return NULL; | 149 | return NULL; |
150 | 150 | ||
151 | matroxfb_DAC_lock_irqsave(flags); | 151 | matroxfb_DAC_lock_irqsave(flags); |
152 | matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0xFF); | 152 | matroxfb_DAC_out(minfo, DAC_XGENIODATA, 0xFF); |
153 | matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0x00); | 153 | matroxfb_DAC_out(minfo, DAC_XGENIOCTRL, 0x00); |
154 | matroxfb_DAC_unlock_irqrestore(flags); | 154 | matroxfb_DAC_unlock_irqrestore(flags); |
155 | 155 | ||
156 | switch (ACCESS_FBINFO(chip)) { | 156 | switch (minfo->chip) { |
157 | case MGA_2064: | 157 | case MGA_2064: |
158 | case MGA_2164: | 158 | case MGA_2164: |
159 | err = i2c_bus_reg(&m2info->ddc1, minfo, | 159 | err = i2c_bus_reg(&m2info->ddc1, minfo, |
@@ -168,7 +168,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) { | |||
168 | } | 168 | } |
169 | if (err) | 169 | if (err) |
170 | goto fail_ddc1; | 170 | goto fail_ddc1; |
171 | if (ACCESS_FBINFO(devflags.dualhead)) { | 171 | if (minfo->devflags.dualhead) { |
172 | err = i2c_bus_reg(&m2info->ddc2, minfo, | 172 | err = i2c_bus_reg(&m2info->ddc2, minfo, |
173 | DDC2_DATA, DDC2_CLK, | 173 | DDC2_DATA, DDC2_CLK, |
174 | "DDC:fb%u #1", I2C_CLASS_DDC); | 174 | "DDC:fb%u #1", I2C_CLASS_DDC); |
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c index 0ce3b0a89798..f9fa0fd00292 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/matrox/matroxfb_DAC1064.c | |||
@@ -33,7 +33,11 @@ | |||
33 | #define DAC1064_OPT_MDIV2 0x00 | 33 | #define DAC1064_OPT_MDIV2 0x00 |
34 | #define DAC1064_OPT_RESERVED 0x10 | 34 | #define DAC1064_OPT_RESERVED 0x10 |
35 | 35 | ||
36 | static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) { | 36 | static void DAC1064_calcclock(const struct matrox_fb_info *minfo, |
37 | unsigned int freq, unsigned int fmax, | ||
38 | unsigned int *in, unsigned int *feed, | ||
39 | unsigned int *post) | ||
40 | { | ||
37 | unsigned int fvco; | 41 | unsigned int fvco; |
38 | unsigned int p; | 42 | unsigned int p; |
39 | 43 | ||
@@ -41,7 +45,7 @@ static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsi | |||
41 | 45 | ||
42 | /* only for devices older than G450 */ | 46 | /* only for devices older than G450 */ |
43 | 47 | ||
44 | fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p); | 48 | fvco = PLL_calcclock(minfo, freq, fmax, in, feed, &p); |
45 | 49 | ||
46 | p = (1 << p) - 1; | 50 | p = (1 << p) - 1; |
47 | if (fvco <= 100000) | 51 | if (fvco <= 100000) |
@@ -80,32 +84,35 @@ static const unsigned char MGA1064_DAC[] = { | |||
80 | 0x00, | 84 | 0x00, |
81 | 0x00, 0x00, 0xFF, 0xFF}; | 85 | 0x00, 0x00, 0xFF, 0xFF}; |
82 | 86 | ||
83 | static void DAC1064_setpclk(WPMINFO unsigned long fout) { | 87 | static void DAC1064_setpclk(struct matrox_fb_info *minfo, unsigned long fout) |
88 | { | ||
84 | unsigned int m, n, p; | 89 | unsigned int m, n, p; |
85 | 90 | ||
86 | DBG(__func__) | 91 | DBG(__func__) |
87 | 92 | ||
88 | DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p); | 93 | DAC1064_calcclock(minfo, fout, minfo->max_pixel_clock, &m, &n, &p); |
89 | ACCESS_FBINFO(hw).DACclk[0] = m; | 94 | minfo->hw.DACclk[0] = m; |
90 | ACCESS_FBINFO(hw).DACclk[1] = n; | 95 | minfo->hw.DACclk[1] = n; |
91 | ACCESS_FBINFO(hw).DACclk[2] = p; | 96 | minfo->hw.DACclk[2] = p; |
92 | } | 97 | } |
93 | 98 | ||
94 | static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) { | 99 | static void DAC1064_setmclk(struct matrox_fb_info *minfo, int oscinfo, |
100 | unsigned long fmem) | ||
101 | { | ||
95 | u_int32_t mx; | 102 | u_int32_t mx; |
96 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 103 | struct matrox_hw_state *hw = &minfo->hw; |
97 | 104 | ||
98 | DBG(__func__) | 105 | DBG(__func__) |
99 | 106 | ||
100 | if (ACCESS_FBINFO(devflags.noinit)) { | 107 | if (minfo->devflags.noinit) { |
101 | /* read MCLK and give up... */ | 108 | /* read MCLK and give up... */ |
102 | hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM); | 109 | hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM); |
103 | hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN); | 110 | hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN); |
104 | hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP); | 111 | hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP); |
105 | return; | 112 | return; |
106 | } | 113 | } |
107 | mx = hw->MXoptionReg | 0x00000004; | 114 | mx = hw->MXoptionReg | 0x00000004; |
108 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); | 115 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx); |
109 | mx &= ~0x000000BB; | 116 | mx &= ~0x000000BB; |
110 | if (oscinfo & DAC1064_OPT_GDIV1) | 117 | if (oscinfo & DAC1064_OPT_GDIV1) |
111 | mx |= 0x00000008; | 118 | mx |= 0x00000008; |
@@ -120,9 +127,9 @@ static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) { | |||
120 | 127 | ||
121 | /* powerup system PLL, select PCI clock */ | 128 | /* powerup system PLL, select PCI clock */ |
122 | mx |= 0x00000020; | 129 | mx |= 0x00000020; |
123 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); | 130 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx); |
124 | mx &= ~0x00000004; | 131 | mx &= ~0x00000004; |
125 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); | 132 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx); |
126 | 133 | ||
127 | /* !!! you must not access device if MCLK is not running !!! | 134 | /* !!! you must not access device if MCLK is not running !!! |
128 | Doing so cause immediate PCI lockup :-( Maybe they should | 135 | Doing so cause immediate PCI lockup :-( Maybe they should |
@@ -131,12 +138,12 @@ static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) { | |||
131 | perfect... */ | 138 | perfect... */ |
132 | /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not | 139 | /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not |
133 | select PLL... because of PLL can be stopped at this time) */ | 140 | select PLL... because of PLL can be stopped at this time) */ |
134 | DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p); | 141 | DAC1064_calcclock(minfo, fmem, minfo->max_pixel_clock, &m, &n, &p); |
135 | outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m); | 142 | outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3] = m); |
136 | outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n); | 143 | outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4] = n); |
137 | outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p); | 144 | outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5] = p); |
138 | for (clk = 65536; clk; --clk) { | 145 | for (clk = 65536; clk; --clk) { |
139 | if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40) | 146 | if (inDAC1064(minfo, DAC1064_XSYSPLLSTAT) & 0x40) |
140 | break; | 147 | break; |
141 | } | 148 | } |
142 | if (!clk) | 149 | if (!clk) |
@@ -147,29 +154,30 @@ static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) { | |||
147 | /* select specified system clock source */ | 154 | /* select specified system clock source */ |
148 | mx |= oscinfo & DAC1064_OPT_SCLK_MASK; | 155 | mx |= oscinfo & DAC1064_OPT_SCLK_MASK; |
149 | } | 156 | } |
150 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); | 157 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx); |
151 | mx &= ~0x00000004; | 158 | mx &= ~0x00000004; |
152 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); | 159 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx); |
153 | hw->MXoptionReg = mx; | 160 | hw->MXoptionReg = mx; |
154 | } | 161 | } |
155 | 162 | ||
156 | #ifdef CONFIG_FB_MATROX_G | 163 | #ifdef CONFIG_FB_MATROX_G |
157 | static void g450_set_plls(WPMINFO2) { | 164 | static void g450_set_plls(struct matrox_fb_info *minfo) |
165 | { | ||
158 | u_int32_t c2_ctl; | 166 | u_int32_t c2_ctl; |
159 | unsigned int pxc; | 167 | unsigned int pxc; |
160 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 168 | struct matrox_hw_state *hw = &minfo->hw; |
161 | int pixelmnp; | 169 | int pixelmnp; |
162 | int videomnp; | 170 | int videomnp; |
163 | 171 | ||
164 | c2_ctl = hw->crtc2.ctl & ~0x4007; /* Clear PLL + enable for CRTC2 */ | 172 | c2_ctl = hw->crtc2.ctl & ~0x4007; /* Clear PLL + enable for CRTC2 */ |
165 | c2_ctl |= 0x0001; /* Enable CRTC2 */ | 173 | c2_ctl |= 0x0001; /* Enable CRTC2 */ |
166 | hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */ | 174 | hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */ |
167 | pixelmnp = ACCESS_FBINFO(crtc1).mnp; | 175 | pixelmnp = minfo->crtc1.mnp; |
168 | videomnp = ACCESS_FBINFO(crtc2).mnp; | 176 | videomnp = minfo->crtc2.mnp; |
169 | if (videomnp < 0) { | 177 | if (videomnp < 0) { |
170 | c2_ctl &= ~0x0001; /* Disable CRTC2 */ | 178 | c2_ctl &= ~0x0001; /* Disable CRTC2 */ |
171 | hw->DACreg[POS1064_XPWRCTRL] &= ~0x10; /* Powerdown CRTC2 */ | 179 | hw->DACreg[POS1064_XPWRCTRL] &= ~0x10; /* Powerdown CRTC2 */ |
172 | } else if (ACCESS_FBINFO(crtc2).pixclock == ACCESS_FBINFO(features).pll.ref_freq) { | 180 | } else if (minfo->crtc2.pixclock == minfo->features.pll.ref_freq) { |
173 | c2_ctl |= 0x4002; /* Use reference directly */ | 181 | c2_ctl |= 0x4002; /* Use reference directly */ |
174 | } else if (videomnp == pixelmnp) { | 182 | } else if (videomnp == pixelmnp) { |
175 | c2_ctl |= 0x0004; /* Use pixel PLL */ | 183 | c2_ctl |= 0x0004; /* Use pixel PLL */ |
@@ -184,27 +192,27 @@ static void g450_set_plls(WPMINFO2) { | |||
184 | c2_ctl |= 0x0006; /* Use video PLL */ | 192 | c2_ctl |= 0x0006; /* Use video PLL */ |
185 | hw->DACreg[POS1064_XPWRCTRL] |= 0x02; | 193 | hw->DACreg[POS1064_XPWRCTRL] |= 0x02; |
186 | 194 | ||
187 | outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); | 195 | outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); |
188 | matroxfb_g450_setpll_cond(PMINFO videomnp, M_VIDEO_PLL); | 196 | matroxfb_g450_setpll_cond(minfo, videomnp, M_VIDEO_PLL); |
189 | } | 197 | } |
190 | 198 | ||
191 | hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP; | 199 | hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP; |
192 | if (pixelmnp >= 0) { | 200 | if (pixelmnp >= 0) { |
193 | hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP; | 201 | hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP; |
194 | 202 | ||
195 | outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); | 203 | outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); |
196 | matroxfb_g450_setpll_cond(PMINFO pixelmnp, M_PIXEL_PLL_C); | 204 | matroxfb_g450_setpll_cond(minfo, pixelmnp, M_PIXEL_PLL_C); |
197 | } | 205 | } |
198 | if (c2_ctl != hw->crtc2.ctl) { | 206 | if (c2_ctl != hw->crtc2.ctl) { |
199 | hw->crtc2.ctl = c2_ctl; | 207 | hw->crtc2.ctl = c2_ctl; |
200 | mga_outl(0x3C10, c2_ctl); | 208 | mga_outl(0x3C10, c2_ctl); |
201 | } | 209 | } |
202 | 210 | ||
203 | pxc = ACCESS_FBINFO(crtc1).pixclock; | 211 | pxc = minfo->crtc1.pixclock; |
204 | if (pxc == 0 || ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC2) { | 212 | if (pxc == 0 || minfo->outputs[2].src == MATROXFB_SRC_CRTC2) { |
205 | pxc = ACCESS_FBINFO(crtc2).pixclock; | 213 | pxc = minfo->crtc2.pixclock; |
206 | } | 214 | } |
207 | if (ACCESS_FBINFO(chip) == MGA_G550) { | 215 | if (minfo->chip == MGA_G550) { |
208 | if (pxc < 45000) { | 216 | if (pxc < 45000) { |
209 | hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-50 */ | 217 | hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-50 */ |
210 | } else if (pxc < 55000) { | 218 | } else if (pxc < 55000) { |
@@ -245,18 +253,19 @@ static void g450_set_plls(WPMINFO2) { | |||
245 | } | 253 | } |
246 | #endif | 254 | #endif |
247 | 255 | ||
248 | void DAC1064_global_init(WPMINFO2) { | 256 | void DAC1064_global_init(struct matrox_fb_info *minfo) |
249 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 257 | { |
258 | struct matrox_hw_state *hw = &minfo->hw; | ||
250 | 259 | ||
251 | hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK; | 260 | hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK; |
252 | hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN; | 261 | hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN; |
253 | hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL; | 262 | hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL; |
254 | #ifdef CONFIG_FB_MATROX_G | 263 | #ifdef CONFIG_FB_MATROX_G |
255 | if (ACCESS_FBINFO(devflags.g450dac)) { | 264 | if (minfo->devflags.g450dac) { |
256 | hw->DACreg[POS1064_XPWRCTRL] = 0x1F; /* powerup everything */ | 265 | hw->DACreg[POS1064_XPWRCTRL] = 0x1F; /* powerup everything */ |
257 | hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */ | 266 | hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */ |
258 | hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN; | 267 | hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN; |
259 | switch (ACCESS_FBINFO(outputs[0]).src) { | 268 | switch (minfo->outputs[0].src) { |
260 | case MATROXFB_SRC_CRTC1: | 269 | case MATROXFB_SRC_CRTC1: |
261 | case MATROXFB_SRC_CRTC2: | 270 | case MATROXFB_SRC_CRTC2: |
262 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */ | 271 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */ |
@@ -265,12 +274,12 @@ void DAC1064_global_init(WPMINFO2) { | |||
265 | hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN; | 274 | hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN; |
266 | break; | 275 | break; |
267 | } | 276 | } |
268 | switch (ACCESS_FBINFO(outputs[1]).src) { | 277 | switch (minfo->outputs[1].src) { |
269 | case MATROXFB_SRC_CRTC1: | 278 | case MATROXFB_SRC_CRTC1: |
270 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04; | 279 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04; |
271 | break; | 280 | break; |
272 | case MATROXFB_SRC_CRTC2: | 281 | case MATROXFB_SRC_CRTC2: |
273 | if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_MONITOR) { | 282 | if (minfo->outputs[1].mode == MATROXFB_OUTPUT_MODE_MONITOR) { |
274 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08; | 283 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08; |
275 | } else { | 284 | } else { |
276 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C; | 285 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C; |
@@ -280,7 +289,7 @@ void DAC1064_global_init(WPMINFO2) { | |||
280 | hw->DACreg[POS1064_XPWRCTRL] &= ~0x01; /* Poweroff DAC2 */ | 289 | hw->DACreg[POS1064_XPWRCTRL] &= ~0x01; /* Poweroff DAC2 */ |
281 | break; | 290 | break; |
282 | } | 291 | } |
283 | switch (ACCESS_FBINFO(outputs[2]).src) { | 292 | switch (minfo->outputs[2].src) { |
284 | case MATROXFB_SRC_CRTC1: | 293 | case MATROXFB_SRC_CRTC1: |
285 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20; | 294 | hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20; |
286 | break; | 295 | break; |
@@ -299,55 +308,57 @@ void DAC1064_global_init(WPMINFO2) { | |||
299 | break; | 308 | break; |
300 | } | 309 | } |
301 | /* Now set timming related variables... */ | 310 | /* Now set timming related variables... */ |
302 | g450_set_plls(PMINFO2); | 311 | g450_set_plls(minfo); |
303 | } else | 312 | } else |
304 | #endif | 313 | #endif |
305 | { | 314 | { |
306 | if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) { | 315 | if (minfo->outputs[1].src == MATROXFB_SRC_CRTC1) { |
307 | hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT; | 316 | hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT; |
308 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12; | 317 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12; |
309 | } else if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) { | 318 | } else if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) { |
310 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12; | 319 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12; |
311 | } else if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) | 320 | } else if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1) |
312 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12; | 321 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12; |
313 | else | 322 | else |
314 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS; | 323 | hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS; |
315 | 324 | ||
316 | if (ACCESS_FBINFO(outputs[0]).src != MATROXFB_SRC_NONE) | 325 | if (minfo->outputs[0].src != MATROXFB_SRC_NONE) |
317 | hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN; | 326 | hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN; |
318 | } | 327 | } |
319 | } | 328 | } |
320 | 329 | ||
321 | void DAC1064_global_restore(WPMINFO2) { | 330 | void DAC1064_global_restore(struct matrox_fb_info *minfo) |
322 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 331 | { |
323 | 332 | struct matrox_hw_state *hw = &minfo->hw; | |
324 | outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); | 333 | |
325 | outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]); | 334 | outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); |
326 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) { | 335 | outDAC1064(minfo, M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]); |
327 | outDAC1064(PMINFO 0x20, 0x04); | 336 | if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) { |
328 | outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type)); | 337 | outDAC1064(minfo, 0x20, 0x04); |
329 | if (ACCESS_FBINFO(devflags.g450dac)) { | 338 | outDAC1064(minfo, 0x1F, minfo->devflags.dfp_type); |
330 | outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC); | 339 | if (minfo->devflags.g450dac) { |
331 | outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); | 340 | outDAC1064(minfo, M1064_XSYNCCTRL, 0xCC); |
332 | outDAC1064(PMINFO M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]); | 341 | outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); |
333 | outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]); | 342 | outDAC1064(minfo, M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]); |
343 | outDAC1064(minfo, M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]); | ||
334 | } | 344 | } |
335 | } | 345 | } |
336 | } | 346 | } |
337 | 347 | ||
338 | static int DAC1064_init_1(WPMINFO struct my_timming* m) { | 348 | static int DAC1064_init_1(struct matrox_fb_info *minfo, struct my_timming *m) |
339 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 349 | { |
350 | struct matrox_hw_state *hw = &minfo->hw; | ||
340 | 351 | ||
341 | DBG(__func__) | 352 | DBG(__func__) |
342 | 353 | ||
343 | memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs)); | 354 | memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs)); |
344 | switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { | 355 | switch (minfo->fbcon.var.bits_per_pixel) { |
345 | /* case 4: not supported by MGA1064 DAC */ | 356 | /* case 4: not supported by MGA1064 DAC */ |
346 | case 8: | 357 | case 8: |
347 | hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; | 358 | hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; |
348 | break; | 359 | break; |
349 | case 16: | 360 | case 16: |
350 | if (ACCESS_FBINFO(fbcon).var.green.length == 5) | 361 | if (minfo->fbcon.var.green.length == 5) |
351 | hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; | 362 | hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; |
352 | else | 363 | else |
353 | hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; | 364 | hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; |
@@ -361,22 +372,23 @@ static int DAC1064_init_1(WPMINFO struct my_timming* m) { | |||
361 | default: | 372 | default: |
362 | return 1; /* unsupported depth */ | 373 | return 1; /* unsupported depth */ |
363 | } | 374 | } |
364 | hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl); | 375 | hw->DACreg[POS1064_XVREFCTRL] = minfo->features.DAC1064.xvrefctrl; |
365 | hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK; | 376 | hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK; |
366 | hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN; | 377 | hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN; |
367 | hw->DACreg[POS1064_XCURADDL] = 0; | 378 | hw->DACreg[POS1064_XCURADDL] = 0; |
368 | hw->DACreg[POS1064_XCURADDH] = 0; | 379 | hw->DACreg[POS1064_XCURADDH] = 0; |
369 | 380 | ||
370 | DAC1064_global_init(PMINFO2); | 381 | DAC1064_global_init(minfo); |
371 | return 0; | 382 | return 0; |
372 | } | 383 | } |
373 | 384 | ||
374 | static int DAC1064_init_2(WPMINFO struct my_timming* m) { | 385 | static int DAC1064_init_2(struct matrox_fb_info *minfo, struct my_timming *m) |
375 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 386 | { |
387 | struct matrox_hw_state *hw = &minfo->hw; | ||
376 | 388 | ||
377 | DBG(__func__) | 389 | DBG(__func__) |
378 | 390 | ||
379 | if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 16) { /* 256 entries */ | 391 | if (minfo->fbcon.var.bits_per_pixel > 16) { /* 256 entries */ |
380 | int i; | 392 | int i; |
381 | 393 | ||
382 | for (i = 0; i < 256; i++) { | 394 | for (i = 0; i < 256; i++) { |
@@ -384,8 +396,8 @@ static int DAC1064_init_2(WPMINFO struct my_timming* m) { | |||
384 | hw->DACpal[i * 3 + 1] = i; | 396 | hw->DACpal[i * 3 + 1] = i; |
385 | hw->DACpal[i * 3 + 2] = i; | 397 | hw->DACpal[i * 3 + 2] = i; |
386 | } | 398 | } |
387 | } else if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 8) { | 399 | } else if (minfo->fbcon.var.bits_per_pixel > 8) { |
388 | if (ACCESS_FBINFO(fbcon).var.green.length == 5) { /* 0..31, 128..159 */ | 400 | if (minfo->fbcon.var.green.length == 5) { /* 0..31, 128..159 */ |
389 | int i; | 401 | int i; |
390 | 402 | ||
391 | for (i = 0; i < 32; i++) { | 403 | for (i = 0; i < 32; i++) { |
@@ -413,8 +425,9 @@ static int DAC1064_init_2(WPMINFO struct my_timming* m) { | |||
413 | return 0; | 425 | return 0; |
414 | } | 426 | } |
415 | 427 | ||
416 | static void DAC1064_restore_1(WPMINFO2) { | 428 | static void DAC1064_restore_1(struct matrox_fb_info *minfo) |
417 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 429 | { |
430 | struct matrox_hw_state *hw = &minfo->hw; | ||
418 | 431 | ||
419 | CRITFLAGS | 432 | CRITFLAGS |
420 | 433 | ||
@@ -422,28 +435,29 @@ static void DAC1064_restore_1(WPMINFO2) { | |||
422 | 435 | ||
423 | CRITBEGIN | 436 | CRITBEGIN |
424 | 437 | ||
425 | if ((inDAC1064(PMINFO DAC1064_XSYSPLLM) != hw->DACclk[3]) || | 438 | if ((inDAC1064(minfo, DAC1064_XSYSPLLM) != hw->DACclk[3]) || |
426 | (inDAC1064(PMINFO DAC1064_XSYSPLLN) != hw->DACclk[4]) || | 439 | (inDAC1064(minfo, DAC1064_XSYSPLLN) != hw->DACclk[4]) || |
427 | (inDAC1064(PMINFO DAC1064_XSYSPLLP) != hw->DACclk[5])) { | 440 | (inDAC1064(minfo, DAC1064_XSYSPLLP) != hw->DACclk[5])) { |
428 | outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]); | 441 | outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3]); |
429 | outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]); | 442 | outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4]); |
430 | outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]); | 443 | outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5]); |
431 | } | 444 | } |
432 | { | 445 | { |
433 | unsigned int i; | 446 | unsigned int i; |
434 | 447 | ||
435 | for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { | 448 | for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { |
436 | if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL)) | 449 | if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL)) |
437 | outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]); | 450 | outDAC1064(minfo, MGA1064_DAC_regs[i], hw->DACreg[i]); |
438 | } | 451 | } |
439 | } | 452 | } |
440 | 453 | ||
441 | DAC1064_global_restore(PMINFO2); | 454 | DAC1064_global_restore(minfo); |
442 | 455 | ||
443 | CRITEND | 456 | CRITEND |
444 | }; | 457 | }; |
445 | 458 | ||
446 | static void DAC1064_restore_2(WPMINFO2) { | 459 | static void DAC1064_restore_2(struct matrox_fb_info *minfo) |
460 | { | ||
447 | #ifdef DEBUG | 461 | #ifdef DEBUG |
448 | unsigned int i; | 462 | unsigned int i; |
449 | #endif | 463 | #endif |
@@ -453,12 +467,12 @@ static void DAC1064_restore_2(WPMINFO2) { | |||
453 | #ifdef DEBUG | 467 | #ifdef DEBUG |
454 | dprintk(KERN_DEBUG "DAC1064regs "); | 468 | dprintk(KERN_DEBUG "DAC1064regs "); |
455 | for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { | 469 | for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { |
456 | dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]); | 470 | dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], minfo->hw.DACreg[i]); |
457 | if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... "); | 471 | if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... "); |
458 | } | 472 | } |
459 | dprintk("\n" KERN_DEBUG "DAC1064clk "); | 473 | dprintk(KERN_DEBUG "DAC1064clk "); |
460 | for (i = 0; i < 6; i++) | 474 | for (i = 0; i < 6; i++) |
461 | dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]); | 475 | dprintk("C%02X=%02X ", i, minfo->hw.DACclk[i]); |
462 | dprintk("\n"); | 476 | dprintk("\n"); |
463 | #endif | 477 | #endif |
464 | } | 478 | } |
@@ -470,14 +484,14 @@ static int m1064_compute(void* out, struct my_timming* m) { | |||
470 | int tmout; | 484 | int tmout; |
471 | CRITFLAGS | 485 | CRITFLAGS |
472 | 486 | ||
473 | DAC1064_setpclk(PMINFO m->pixclock); | 487 | DAC1064_setpclk(minfo, m->pixclock); |
474 | 488 | ||
475 | CRITBEGIN | 489 | CRITBEGIN |
476 | 490 | ||
477 | for (i = 0; i < 3; i++) | 491 | for (i = 0; i < 3; i++) |
478 | outDAC1064(PMINFO M1064_XPIXPLLCM + i, ACCESS_FBINFO(hw).DACclk[i]); | 492 | outDAC1064(minfo, M1064_XPIXPLLCM + i, minfo->hw.DACclk[i]); |
479 | for (tmout = 500000; tmout; tmout--) { | 493 | for (tmout = 500000; tmout; tmout--) { |
480 | if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40) | 494 | if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40) |
481 | break; | 495 | break; |
482 | udelay(10); | 496 | udelay(10); |
483 | }; | 497 | }; |
@@ -500,9 +514,9 @@ static struct matrox_altout m1064 = { | |||
500 | static int g450_compute(void* out, struct my_timming* m) { | 514 | static int g450_compute(void* out, struct my_timming* m) { |
501 | #define minfo ((struct matrox_fb_info*)out) | 515 | #define minfo ((struct matrox_fb_info*)out) |
502 | if (m->mnp < 0) { | 516 | if (m->mnp < 0) { |
503 | m->mnp = matroxfb_g450_setclk(PMINFO m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); | 517 | m->mnp = matroxfb_g450_setclk(minfo, m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); |
504 | if (m->mnp >= 0) { | 518 | if (m->mnp >= 0) { |
505 | m->pixclock = g450_mnp2f(PMINFO m->mnp); | 519 | m->pixclock = g450_mnp2f(minfo, m->mnp); |
506 | } | 520 | } |
507 | } | 521 | } |
508 | #undef minfo | 522 | #undef minfo |
@@ -518,13 +532,14 @@ static struct matrox_altout g450out = { | |||
518 | #endif /* NEED_DAC1064 */ | 532 | #endif /* NEED_DAC1064 */ |
519 | 533 | ||
520 | #ifdef CONFIG_FB_MATROX_MYSTIQUE | 534 | #ifdef CONFIG_FB_MATROX_MYSTIQUE |
521 | static int MGA1064_init(WPMINFO struct my_timming* m) { | 535 | static int MGA1064_init(struct matrox_fb_info *minfo, struct my_timming *m) |
522 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 536 | { |
537 | struct matrox_hw_state *hw = &minfo->hw; | ||
523 | 538 | ||
524 | DBG(__func__) | 539 | DBG(__func__) |
525 | 540 | ||
526 | if (DAC1064_init_1(PMINFO m)) return 1; | 541 | if (DAC1064_init_1(minfo, m)) return 1; |
527 | if (matroxfb_vgaHWinit(PMINFO m)) return 1; | 542 | if (matroxfb_vgaHWinit(minfo, m)) return 1; |
528 | 543 | ||
529 | hw->MiscOutReg = 0xCB; | 544 | hw->MiscOutReg = 0xCB; |
530 | if (m->sync & FB_SYNC_HOR_HIGH_ACT) | 545 | if (m->sync & FB_SYNC_HOR_HIGH_ACT) |
@@ -534,20 +549,21 @@ static int MGA1064_init(WPMINFO struct my_timming* m) { | |||
534 | if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ | 549 | if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ |
535 | hw->CRTCEXT[3] |= 0x40; | 550 | hw->CRTCEXT[3] |= 0x40; |
536 | 551 | ||
537 | if (DAC1064_init_2(PMINFO m)) return 1; | 552 | if (DAC1064_init_2(minfo, m)) return 1; |
538 | return 0; | 553 | return 0; |
539 | } | 554 | } |
540 | #endif | 555 | #endif |
541 | 556 | ||
542 | #ifdef CONFIG_FB_MATROX_G | 557 | #ifdef CONFIG_FB_MATROX_G |
543 | static int MGAG100_init(WPMINFO struct my_timming* m) { | 558 | static int MGAG100_init(struct matrox_fb_info *minfo, struct my_timming *m) |
544 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 559 | { |
560 | struct matrox_hw_state *hw = &minfo->hw; | ||
545 | 561 | ||
546 | DBG(__func__) | 562 | DBG(__func__) |
547 | 563 | ||
548 | if (DAC1064_init_1(PMINFO m)) return 1; | 564 | if (DAC1064_init_1(minfo, m)) return 1; |
549 | hw->MXoptionReg &= ~0x2000; | 565 | hw->MXoptionReg &= ~0x2000; |
550 | if (matroxfb_vgaHWinit(PMINFO m)) return 1; | 566 | if (matroxfb_vgaHWinit(minfo, m)) return 1; |
551 | 567 | ||
552 | hw->MiscOutReg = 0xEF; | 568 | hw->MiscOutReg = 0xEF; |
553 | if (m->sync & FB_SYNC_HOR_HIGH_ACT) | 569 | if (m->sync & FB_SYNC_HOR_HIGH_ACT) |
@@ -557,27 +573,28 @@ static int MGAG100_init(WPMINFO struct my_timming* m) { | |||
557 | if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ | 573 | if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ |
558 | hw->CRTCEXT[3] |= 0x40; | 574 | hw->CRTCEXT[3] |= 0x40; |
559 | 575 | ||
560 | if (DAC1064_init_2(PMINFO m)) return 1; | 576 | if (DAC1064_init_2(minfo, m)) return 1; |
561 | return 0; | 577 | return 0; |
562 | } | 578 | } |
563 | #endif /* G */ | 579 | #endif /* G */ |
564 | 580 | ||
565 | #ifdef CONFIG_FB_MATROX_MYSTIQUE | 581 | #ifdef CONFIG_FB_MATROX_MYSTIQUE |
566 | static void MGA1064_ramdac_init(WPMINFO2) { | 582 | static void MGA1064_ramdac_init(struct matrox_fb_info *minfo) |
583 | { | ||
567 | 584 | ||
568 | DBG(__func__) | 585 | DBG(__func__) |
569 | 586 | ||
570 | /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */ | 587 | /* minfo->features.DAC1064.vco_freq_min = 120000; */ |
571 | ACCESS_FBINFO(features.pll.vco_freq_min) = 62000; | 588 | minfo->features.pll.vco_freq_min = 62000; |
572 | ACCESS_FBINFO(features.pll.ref_freq) = 14318; | 589 | minfo->features.pll.ref_freq = 14318; |
573 | ACCESS_FBINFO(features.pll.feed_div_min) = 100; | 590 | minfo->features.pll.feed_div_min = 100; |
574 | ACCESS_FBINFO(features.pll.feed_div_max) = 127; | 591 | minfo->features.pll.feed_div_max = 127; |
575 | ACCESS_FBINFO(features.pll.in_div_min) = 1; | 592 | minfo->features.pll.in_div_min = 1; |
576 | ACCESS_FBINFO(features.pll.in_div_max) = 31; | 593 | minfo->features.pll.in_div_max = 31; |
577 | ACCESS_FBINFO(features.pll.post_shift_max) = 3; | 594 | minfo->features.pll.post_shift_max = 3; |
578 | ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL; | 595 | minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_EXTERNAL; |
579 | /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */ | 596 | /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */ |
580 | DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333); | 597 | DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333); |
581 | } | 598 | } |
582 | #endif | 599 | #endif |
583 | 600 | ||
@@ -589,23 +606,25 @@ static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */ | |||
589 | static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */ | 606 | static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */ |
590 | #endif | 607 | #endif |
591 | 608 | ||
592 | static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) { | 609 | static void MGAG100_progPixClock(const struct matrox_fb_info *minfo, int flags, |
610 | int m, int n, int p) | ||
611 | { | ||
593 | int reg; | 612 | int reg; |
594 | int selClk; | 613 | int selClk; |
595 | int clk; | 614 | int clk; |
596 | 615 | ||
597 | DBG(__func__) | 616 | DBG(__func__) |
598 | 617 | ||
599 | outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS | | 618 | outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS | |
600 | M1064_XPIXCLKCTRL_PLL_UP); | 619 | M1064_XPIXCLKCTRL_PLL_UP); |
601 | switch (flags & 3) { | 620 | switch (flags & 3) { |
602 | case 0: reg = M1064_XPIXPLLAM; break; | 621 | case 0: reg = M1064_XPIXPLLAM; break; |
603 | case 1: reg = M1064_XPIXPLLBM; break; | 622 | case 1: reg = M1064_XPIXPLLBM; break; |
604 | default: reg = M1064_XPIXPLLCM; break; | 623 | default: reg = M1064_XPIXPLLCM; break; |
605 | } | 624 | } |
606 | outDAC1064(PMINFO reg++, m); | 625 | outDAC1064(minfo, reg++, m); |
607 | outDAC1064(PMINFO reg++, n); | 626 | outDAC1064(minfo, reg++, n); |
608 | outDAC1064(PMINFO reg, p); | 627 | outDAC1064(minfo, reg, p); |
609 | selClk = mga_inb(M_MISC_REG_READ) & ~0xC; | 628 | selClk = mga_inb(M_MISC_REG_READ) & ~0xC; |
610 | /* there should be flags & 0x03 & case 0/1/else */ | 629 | /* there should be flags & 0x03 & case 0/1/else */ |
611 | /* and we should first select source and after that we should wait for PLL */ | 630 | /* and we should first select source and after that we should wait for PLL */ |
@@ -617,61 +636,64 @@ static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) { | |||
617 | } | 636 | } |
618 | mga_outb(M_MISC_REG, selClk); | 637 | mga_outb(M_MISC_REG, selClk); |
619 | for (clk = 500000; clk; clk--) { | 638 | for (clk = 500000; clk; clk--) { |
620 | if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40) | 639 | if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40) |
621 | break; | 640 | break; |
622 | udelay(10); | 641 | udelay(10); |
623 | }; | 642 | }; |
624 | if (!clk) | 643 | if (!clk) |
625 | printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A'); | 644 | printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A'); |
626 | selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK; | 645 | selClk = inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK; |
627 | switch (flags & 0x0C) { | 646 | switch (flags & 0x0C) { |
628 | case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break; | 647 | case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break; |
629 | case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break; | 648 | case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break; |
630 | default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break; | 649 | default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break; |
631 | } | 650 | } |
632 | outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk); | 651 | outDAC1064(minfo, M1064_XPIXCLKCTRL, selClk); |
633 | outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS); | 652 | outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS); |
634 | } | 653 | } |
635 | 654 | ||
636 | static void MGAG100_setPixClock(CPMINFO int flags, int freq) { | 655 | static void MGAG100_setPixClock(const struct matrox_fb_info *minfo, int flags, |
656 | int freq) | ||
657 | { | ||
637 | unsigned int m, n, p; | 658 | unsigned int m, n, p; |
638 | 659 | ||
639 | DBG(__func__) | 660 | DBG(__func__) |
640 | 661 | ||
641 | DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p); | 662 | DAC1064_calcclock(minfo, freq, minfo->max_pixel_clock, &m, &n, &p); |
642 | MGAG100_progPixClock(PMINFO flags, m, n, p); | 663 | MGAG100_progPixClock(minfo, flags, m, n, p); |
643 | } | 664 | } |
644 | #endif | 665 | #endif |
645 | 666 | ||
646 | #ifdef CONFIG_FB_MATROX_MYSTIQUE | 667 | #ifdef CONFIG_FB_MATROX_MYSTIQUE |
647 | static int MGA1064_preinit(WPMINFO2) { | 668 | static int MGA1064_preinit(struct matrox_fb_info *minfo) |
669 | { | ||
648 | static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960, | 670 | static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960, |
649 | 1024, 1152, 1280, 1600, 1664, 1920, | 671 | 1024, 1152, 1280, 1600, 1664, 1920, |
650 | 2048, 0}; | 672 | 2048, 0}; |
651 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 673 | struct matrox_hw_state *hw = &minfo->hw; |
652 | 674 | ||
653 | DBG(__func__) | 675 | DBG(__func__) |
654 | 676 | ||
655 | /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ | 677 | /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */ |
656 | ACCESS_FBINFO(capable.text) = 1; | 678 | minfo->capable.text = 1; |
657 | ACCESS_FBINFO(capable.vxres) = vxres_mystique; | 679 | minfo->capable.vxres = vxres_mystique; |
658 | 680 | ||
659 | ACCESS_FBINFO(outputs[0]).output = &m1064; | 681 | minfo->outputs[0].output = &m1064; |
660 | ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; | 682 | minfo->outputs[0].src = minfo->outputs[0].default_src; |
661 | ACCESS_FBINFO(outputs[0]).data = MINFO; | 683 | minfo->outputs[0].data = minfo; |
662 | ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 684 | minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
663 | 685 | ||
664 | if (ACCESS_FBINFO(devflags.noinit)) | 686 | if (minfo->devflags.noinit) |
665 | return 0; /* do not modify settings */ | 687 | return 0; /* do not modify settings */ |
666 | hw->MXoptionReg &= 0xC0000100; | 688 | hw->MXoptionReg &= 0xC0000100; |
667 | hw->MXoptionReg |= 0x00094E20; | 689 | hw->MXoptionReg |= 0x00094E20; |
668 | if (ACCESS_FBINFO(devflags.novga)) | 690 | if (minfo->devflags.novga) |
669 | hw->MXoptionReg &= ~0x00000100; | 691 | hw->MXoptionReg &= ~0x00000100; |
670 | if (ACCESS_FBINFO(devflags.nobios)) | 692 | if (minfo->devflags.nobios) |
671 | hw->MXoptionReg &= ~0x40000000; | 693 | hw->MXoptionReg &= ~0x40000000; |
672 | if (ACCESS_FBINFO(devflags.nopciretry)) | 694 | if (minfo->devflags.nopciretry) |
673 | hw->MXoptionReg |= 0x20000000; | 695 | hw->MXoptionReg |= 0x20000000; |
674 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 696 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
675 | mga_setr(M_SEQ_INDEX, 0x01, 0x20); | 697 | mga_setr(M_SEQ_INDEX, 0x01, 0x20); |
676 | mga_outl(M_CTLWTST, 0x00000000); | 698 | mga_outl(M_CTLWTST, 0x00000000); |
677 | udelay(200); | 699 | udelay(200); |
@@ -681,101 +703,105 @@ static int MGA1064_preinit(WPMINFO2) { | |||
681 | return 0; | 703 | return 0; |
682 | } | 704 | } |
683 | 705 | ||
684 | static void MGA1064_reset(WPMINFO2) { | 706 | static void MGA1064_reset(struct matrox_fb_info *minfo) |
707 | { | ||
685 | 708 | ||
686 | DBG(__func__); | 709 | DBG(__func__); |
687 | 710 | ||
688 | MGA1064_ramdac_init(PMINFO2); | 711 | MGA1064_ramdac_init(minfo); |
689 | } | 712 | } |
690 | #endif | 713 | #endif |
691 | 714 | ||
692 | #ifdef CONFIG_FB_MATROX_G | 715 | #ifdef CONFIG_FB_MATROX_G |
693 | static void g450_mclk_init(WPMINFO2) { | 716 | static void g450_mclk_init(struct matrox_fb_info *minfo) |
717 | { | ||
694 | /* switch all clocks to PCI source */ | 718 | /* switch all clocks to PCI source */ |
695 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4); | 719 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4); |
696 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03); | 720 | pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3 & ~0x00300C03); |
697 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); | 721 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); |
698 | 722 | ||
699 | if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) || | 723 | if (((minfo->values.reg.opt3 & 0x000003) == 0x000003) || |
700 | ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) || | 724 | ((minfo->values.reg.opt3 & 0x000C00) == 0x000C00) || |
701 | ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) { | 725 | ((minfo->values.reg.opt3 & 0x300000) == 0x300000)) { |
702 | matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL); | 726 | matroxfb_g450_setclk(minfo, minfo->values.pll.video, M_VIDEO_PLL); |
703 | } else { | 727 | } else { |
704 | unsigned long flags; | 728 | unsigned long flags; |
705 | unsigned int pwr; | 729 | unsigned int pwr; |
706 | 730 | ||
707 | matroxfb_DAC_lock_irqsave(flags); | 731 | matroxfb_DAC_lock_irqsave(flags); |
708 | pwr = inDAC1064(PMINFO M1064_XPWRCTRL) & ~0x02; | 732 | pwr = inDAC1064(minfo, M1064_XPWRCTRL) & ~0x02; |
709 | outDAC1064(PMINFO M1064_XPWRCTRL, pwr); | 733 | outDAC1064(minfo, M1064_XPWRCTRL, pwr); |
710 | matroxfb_DAC_unlock_irqrestore(flags); | 734 | matroxfb_DAC_unlock_irqrestore(flags); |
711 | } | 735 | } |
712 | matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL); | 736 | matroxfb_g450_setclk(minfo, minfo->values.pll.system, M_SYSTEM_PLL); |
713 | 737 | ||
714 | /* switch clocks to their real PLL source(s) */ | 738 | /* switch clocks to their real PLL source(s) */ |
715 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4); | 739 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4); |
716 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3); | 740 | pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3); |
717 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); | 741 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); |
718 | 742 | ||
719 | } | 743 | } |
720 | 744 | ||
721 | static void g450_memory_init(WPMINFO2) { | 745 | static void g450_memory_init(struct matrox_fb_info *minfo) |
746 | { | ||
722 | /* disable memory refresh */ | 747 | /* disable memory refresh */ |
723 | ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000; | 748 | minfo->hw.MXoptionReg &= ~0x001F8000; |
724 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); | 749 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); |
725 | 750 | ||
726 | /* set memory interface parameters */ | 751 | /* set memory interface parameters */ |
727 | ACCESS_FBINFO(hw).MXoptionReg &= ~0x00207E00; | 752 | minfo->hw.MXoptionReg &= ~0x00207E00; |
728 | ACCESS_FBINFO(hw).MXoptionReg |= 0x00207E00 & ACCESS_FBINFO(values).reg.opt; | 753 | minfo->hw.MXoptionReg |= 0x00207E00 & minfo->values.reg.opt; |
729 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); | 754 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); |
730 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ACCESS_FBINFO(values).reg.opt2); | 755 | pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, minfo->values.reg.opt2); |
731 | 756 | ||
732 | mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); | 757 | mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); |
733 | 758 | ||
734 | /* first set up memory interface with disabled memory interface clocks */ | 759 | /* first set up memory interface with disabled memory interface clocks */ |
735 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc & ~0x80000000U); | 760 | pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc & ~0x80000000U); |
736 | mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); | 761 | mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); |
737 | mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess); | 762 | mga_outl(M_MACCESS, minfo->values.reg.maccess); |
738 | /* start memory clocks */ | 763 | /* start memory clocks */ |
739 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc | 0x80000000U); | 764 | pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc | 0x80000000U); |
740 | 765 | ||
741 | udelay(200); | 766 | udelay(200); |
742 | 767 | ||
743 | if (ACCESS_FBINFO(values).memory.ddr && (!ACCESS_FBINFO(values).memory.emrswen || !ACCESS_FBINFO(values).memory.dll)) { | 768 | if (minfo->values.memory.ddr && (!minfo->values.memory.emrswen || !minfo->values.memory.dll)) { |
744 | mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk & ~0x1000); | 769 | mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk & ~0x1000); |
745 | } | 770 | } |
746 | mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess | 0x8000); | 771 | mga_outl(M_MACCESS, minfo->values.reg.maccess | 0x8000); |
747 | 772 | ||
748 | udelay(200); | 773 | udelay(200); |
749 | 774 | ||
750 | ACCESS_FBINFO(hw).MXoptionReg |= 0x001F8000 & ACCESS_FBINFO(values).reg.opt; | 775 | minfo->hw.MXoptionReg |= 0x001F8000 & minfo->values.reg.opt; |
751 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); | 776 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); |
752 | 777 | ||
753 | /* value is written to memory chips only if old != new */ | 778 | /* value is written to memory chips only if old != new */ |
754 | mga_outl(M_PLNWT, 0); | 779 | mga_outl(M_PLNWT, 0); |
755 | mga_outl(M_PLNWT, ~0); | 780 | mga_outl(M_PLNWT, ~0); |
756 | 781 | ||
757 | if (ACCESS_FBINFO(values).reg.mctlwtst != ACCESS_FBINFO(values).reg.mctlwtst_core) { | 782 | if (minfo->values.reg.mctlwtst != minfo->values.reg.mctlwtst_core) { |
758 | mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst_core); | 783 | mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst_core); |
759 | } | 784 | } |
760 | 785 | ||
761 | } | 786 | } |
762 | 787 | ||
763 | static void g450_preinit(WPMINFO2) { | 788 | static void g450_preinit(struct matrox_fb_info *minfo) |
789 | { | ||
764 | u_int32_t c2ctl; | 790 | u_int32_t c2ctl; |
765 | u_int8_t curctl; | 791 | u_int8_t curctl; |
766 | u_int8_t c1ctl; | 792 | u_int8_t c1ctl; |
767 | 793 | ||
768 | /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */ | 794 | /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */ |
769 | ACCESS_FBINFO(hw).MXoptionReg &= 0xC0000100; | 795 | minfo->hw.MXoptionReg &= 0xC0000100; |
770 | ACCESS_FBINFO(hw).MXoptionReg |= 0x00000020; | 796 | minfo->hw.MXoptionReg |= 0x00000020; |
771 | if (ACCESS_FBINFO(devflags.novga)) | 797 | if (minfo->devflags.novga) |
772 | ACCESS_FBINFO(hw).MXoptionReg &= ~0x00000100; | 798 | minfo->hw.MXoptionReg &= ~0x00000100; |
773 | if (ACCESS_FBINFO(devflags.nobios)) | 799 | if (minfo->devflags.nobios) |
774 | ACCESS_FBINFO(hw).MXoptionReg &= ~0x40000000; | 800 | minfo->hw.MXoptionReg &= ~0x40000000; |
775 | if (ACCESS_FBINFO(devflags.nopciretry)) | 801 | if (minfo->devflags.nopciretry) |
776 | ACCESS_FBINFO(hw).MXoptionReg |= 0x20000000; | 802 | minfo->hw.MXoptionReg |= 0x20000000; |
777 | ACCESS_FBINFO(hw).MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x03400040; | 803 | minfo->hw.MXoptionReg |= minfo->values.reg.opt & 0x03400040; |
778 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); | 804 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); |
779 | 805 | ||
780 | /* Init system clocks */ | 806 | /* Init system clocks */ |
781 | 807 | ||
@@ -783,24 +809,24 @@ static void g450_preinit(WPMINFO2) { | |||
783 | c2ctl = mga_inl(M_C2CTL); | 809 | c2ctl = mga_inl(M_C2CTL); |
784 | mga_outl(M_C2CTL, c2ctl & ~1); | 810 | mga_outl(M_C2CTL, c2ctl & ~1); |
785 | /* stop cursor */ | 811 | /* stop cursor */ |
786 | curctl = inDAC1064(PMINFO M1064_XCURCTRL); | 812 | curctl = inDAC1064(minfo, M1064_XCURCTRL); |
787 | outDAC1064(PMINFO M1064_XCURCTRL, 0); | 813 | outDAC1064(minfo, M1064_XCURCTRL, 0); |
788 | /* stop crtc1 */ | 814 | /* stop crtc1 */ |
789 | c1ctl = mga_readr(M_SEQ_INDEX, 1); | 815 | c1ctl = mga_readr(M_SEQ_INDEX, 1); |
790 | mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20); | 816 | mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20); |
791 | 817 | ||
792 | g450_mclk_init(PMINFO2); | 818 | g450_mclk_init(minfo); |
793 | g450_memory_init(PMINFO2); | 819 | g450_memory_init(minfo); |
794 | 820 | ||
795 | /* set legacy VGA clock sources for DOSEmu or VMware... */ | 821 | /* set legacy VGA clock sources for DOSEmu or VMware... */ |
796 | matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A); | 822 | matroxfb_g450_setclk(minfo, 25175, M_PIXEL_PLL_A); |
797 | matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B); | 823 | matroxfb_g450_setclk(minfo, 28322, M_PIXEL_PLL_B); |
798 | 824 | ||
799 | /* restore crtc1 */ | 825 | /* restore crtc1 */ |
800 | mga_setr(M_SEQ_INDEX, 1, c1ctl); | 826 | mga_setr(M_SEQ_INDEX, 1, c1ctl); |
801 | 827 | ||
802 | /* restore cursor */ | 828 | /* restore cursor */ |
803 | outDAC1064(PMINFO M1064_XCURCTRL, curctl); | 829 | outDAC1064(minfo, M1064_XCURCTRL, curctl); |
804 | 830 | ||
805 | /* restore crtc2 */ | 831 | /* restore crtc2 */ |
806 | mga_outl(M_C2CTL, c2ctl); | 832 | mga_outl(M_C2CTL, c2ctl); |
@@ -808,11 +834,12 @@ static void g450_preinit(WPMINFO2) { | |||
808 | return; | 834 | return; |
809 | } | 835 | } |
810 | 836 | ||
811 | static int MGAG100_preinit(WPMINFO2) { | 837 | static int MGAG100_preinit(struct matrox_fb_info *minfo) |
838 | { | ||
812 | static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960, | 839 | static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960, |
813 | 1024, 1152, 1280, 1600, 1664, 1920, | 840 | 1024, 1152, 1280, 1600, 1664, 1920, |
814 | 2048, 0}; | 841 | 2048, 0}; |
815 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 842 | struct matrox_hw_state *hw = &minfo->hw; |
816 | 843 | ||
817 | u_int32_t reg50; | 844 | u_int32_t reg50; |
818 | #if 0 | 845 | #if 0 |
@@ -822,68 +849,68 @@ static int MGAG100_preinit(WPMINFO2) { | |||
822 | DBG(__func__) | 849 | DBG(__func__) |
823 | 850 | ||
824 | /* there are some instabilities if in_div > 19 && vco < 61000 */ | 851 | /* there are some instabilities if in_div > 19 && vco < 61000 */ |
825 | if (ACCESS_FBINFO(devflags.g450dac)) { | 852 | if (minfo->devflags.g450dac) { |
826 | ACCESS_FBINFO(features.pll.vco_freq_min) = 130000; /* my sample: >118 */ | 853 | minfo->features.pll.vco_freq_min = 130000; /* my sample: >118 */ |
827 | } else { | 854 | } else { |
828 | ACCESS_FBINFO(features.pll.vco_freq_min) = 62000; | 855 | minfo->features.pll.vco_freq_min = 62000; |
829 | } | 856 | } |
830 | if (!ACCESS_FBINFO(features.pll.ref_freq)) { | 857 | if (!minfo->features.pll.ref_freq) { |
831 | ACCESS_FBINFO(features.pll.ref_freq) = 27000; | 858 | minfo->features.pll.ref_freq = 27000; |
832 | } | 859 | } |
833 | ACCESS_FBINFO(features.pll.feed_div_min) = 7; | 860 | minfo->features.pll.feed_div_min = 7; |
834 | ACCESS_FBINFO(features.pll.feed_div_max) = 127; | 861 | minfo->features.pll.feed_div_max = 127; |
835 | ACCESS_FBINFO(features.pll.in_div_min) = 1; | 862 | minfo->features.pll.in_div_min = 1; |
836 | ACCESS_FBINFO(features.pll.in_div_max) = 31; | 863 | minfo->features.pll.in_div_max = 31; |
837 | ACCESS_FBINFO(features.pll.post_shift_max) = 3; | 864 | minfo->features.pll.post_shift_max = 3; |
838 | ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT; | 865 | minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_G100_DEFAULT; |
839 | /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ | 866 | /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */ |
840 | ACCESS_FBINFO(capable.text) = 1; | 867 | minfo->capable.text = 1; |
841 | ACCESS_FBINFO(capable.vxres) = vxres_g100; | 868 | minfo->capable.vxres = vxres_g100; |
842 | ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100 | 869 | minfo->capable.plnwt = minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100 |
843 | ? ACCESS_FBINFO(devflags.sgram) : 1; | 870 | ? minfo->devflags.sgram : 1; |
844 | 871 | ||
845 | #ifdef CONFIG_FB_MATROX_G | 872 | #ifdef CONFIG_FB_MATROX_G |
846 | if (ACCESS_FBINFO(devflags.g450dac)) { | 873 | if (minfo->devflags.g450dac) { |
847 | ACCESS_FBINFO(outputs[0]).output = &g450out; | 874 | minfo->outputs[0].output = &g450out; |
848 | } else | 875 | } else |
849 | #endif | 876 | #endif |
850 | { | 877 | { |
851 | ACCESS_FBINFO(outputs[0]).output = &m1064; | 878 | minfo->outputs[0].output = &m1064; |
852 | } | 879 | } |
853 | ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; | 880 | minfo->outputs[0].src = minfo->outputs[0].default_src; |
854 | ACCESS_FBINFO(outputs[0]).data = MINFO; | 881 | minfo->outputs[0].data = minfo; |
855 | ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 882 | minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
856 | 883 | ||
857 | if (ACCESS_FBINFO(devflags.g450dac)) { | 884 | if (minfo->devflags.g450dac) { |
858 | /* we must do this always, BIOS does not do it for us | 885 | /* we must do this always, BIOS does not do it for us |
859 | and accelerator dies without it */ | 886 | and accelerator dies without it */ |
860 | mga_outl(0x1C0C, 0); | 887 | mga_outl(0x1C0C, 0); |
861 | } | 888 | } |
862 | if (ACCESS_FBINFO(devflags.noinit)) | 889 | if (minfo->devflags.noinit) |
863 | return 0; | 890 | return 0; |
864 | if (ACCESS_FBINFO(devflags.g450dac)) { | 891 | if (minfo->devflags.g450dac) { |
865 | g450_preinit(PMINFO2); | 892 | g450_preinit(minfo); |
866 | return 0; | 893 | return 0; |
867 | } | 894 | } |
868 | hw->MXoptionReg &= 0xC0000100; | 895 | hw->MXoptionReg &= 0xC0000100; |
869 | hw->MXoptionReg |= 0x00000020; | 896 | hw->MXoptionReg |= 0x00000020; |
870 | if (ACCESS_FBINFO(devflags.novga)) | 897 | if (minfo->devflags.novga) |
871 | hw->MXoptionReg &= ~0x00000100; | 898 | hw->MXoptionReg &= ~0x00000100; |
872 | if (ACCESS_FBINFO(devflags.nobios)) | 899 | if (minfo->devflags.nobios) |
873 | hw->MXoptionReg &= ~0x40000000; | 900 | hw->MXoptionReg &= ~0x40000000; |
874 | if (ACCESS_FBINFO(devflags.nopciretry)) | 901 | if (minfo->devflags.nopciretry) |
875 | hw->MXoptionReg |= 0x20000000; | 902 | hw->MXoptionReg |= 0x20000000; |
876 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 903 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
877 | DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333); | 904 | DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333); |
878 | 905 | ||
879 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) { | 906 | if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100) { |
880 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50); | 907 | pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, ®50); |
881 | reg50 &= ~0x3000; | 908 | reg50 &= ~0x3000; |
882 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); | 909 | pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); |
883 | 910 | ||
884 | hw->MXoptionReg |= 0x1080; | 911 | hw->MXoptionReg |= 0x1080; |
885 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 912 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
886 | mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); | 913 | mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); |
887 | udelay(100); | 914 | udelay(100); |
888 | mga_outb(0x1C05, 0x00); | 915 | mga_outb(0x1C05, 0x00); |
889 | mga_outb(0x1C05, 0x80); | 916 | mga_outb(0x1C05, 0x80); |
@@ -893,68 +920,69 @@ static int MGAG100_preinit(WPMINFO2) { | |||
893 | udelay(100); | 920 | udelay(100); |
894 | reg50 &= ~0xFF; | 921 | reg50 &= ~0xFF; |
895 | reg50 |= 0x07; | 922 | reg50 |= 0x07; |
896 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); | 923 | pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); |
897 | /* it should help with G100 */ | 924 | /* it should help with G100 */ |
898 | mga_outb(M_GRAPHICS_INDEX, 6); | 925 | mga_outb(M_GRAPHICS_INDEX, 6); |
899 | mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4); | 926 | mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4); |
900 | mga_setr(M_EXTVGA_INDEX, 0x03, 0x81); | 927 | mga_setr(M_EXTVGA_INDEX, 0x03, 0x81); |
901 | mga_setr(M_EXTVGA_INDEX, 0x04, 0x00); | 928 | mga_setr(M_EXTVGA_INDEX, 0x04, 0x00); |
902 | mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA); | 929 | mga_writeb(minfo->video.vbase, 0x0000, 0xAA); |
903 | mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55); | 930 | mga_writeb(minfo->video.vbase, 0x0800, 0x55); |
904 | mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55); | 931 | mga_writeb(minfo->video.vbase, 0x4000, 0x55); |
905 | #if 0 | 932 | #if 0 |
906 | if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) { | 933 | if (mga_readb(minfo->video.vbase, 0x0000) != 0xAA) { |
907 | hw->MXoptionReg &= ~0x1000; | 934 | hw->MXoptionReg &= ~0x1000; |
908 | } | 935 | } |
909 | #endif | 936 | #endif |
910 | hw->MXoptionReg |= 0x00078020; | 937 | hw->MXoptionReg |= 0x00078020; |
911 | } else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) { | 938 | } else if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG200) { |
912 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50); | 939 | pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, ®50); |
913 | reg50 &= ~0x3000; | 940 | reg50 &= ~0x3000; |
914 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); | 941 | pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); |
915 | 942 | ||
916 | if (ACCESS_FBINFO(devflags.memtype) == -1) | 943 | if (minfo->devflags.memtype == -1) |
917 | hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00; | 944 | hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00; |
918 | else | 945 | else |
919 | hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10; | 946 | hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10; |
920 | if (ACCESS_FBINFO(devflags.sgram)) | 947 | if (minfo->devflags.sgram) |
921 | hw->MXoptionReg |= 0x4000; | 948 | hw->MXoptionReg |= 0x4000; |
922 | mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); | 949 | mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); |
923 | mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); | 950 | mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); |
924 | udelay(200); | 951 | udelay(200); |
925 | mga_outl(M_MACCESS, 0x00000000); | 952 | mga_outl(M_MACCESS, 0x00000000); |
926 | mga_outl(M_MACCESS, 0x00008000); | 953 | mga_outl(M_MACCESS, 0x00008000); |
927 | udelay(100); | 954 | udelay(100); |
928 | mga_outw(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); | 955 | mga_outw(M_MEMRDBK, minfo->values.reg.memrdbk); |
929 | hw->MXoptionReg |= 0x00078020; | 956 | hw->MXoptionReg |= 0x00078020; |
930 | } else { | 957 | } else { |
931 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50); | 958 | pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, ®50); |
932 | reg50 &= ~0x00000100; | 959 | reg50 &= ~0x00000100; |
933 | reg50 |= 0x00000000; | 960 | reg50 |= 0x00000000; |
934 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); | 961 | pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); |
935 | 962 | ||
936 | if (ACCESS_FBINFO(devflags.memtype) == -1) | 963 | if (minfo->devflags.memtype == -1) |
937 | hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00; | 964 | hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00; |
938 | else | 965 | else |
939 | hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10; | 966 | hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10; |
940 | if (ACCESS_FBINFO(devflags.sgram)) | 967 | if (minfo->devflags.sgram) |
941 | hw->MXoptionReg |= 0x4000; | 968 | hw->MXoptionReg |= 0x4000; |
942 | mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); | 969 | mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); |
943 | mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); | 970 | mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); |
944 | udelay(200); | 971 | udelay(200); |
945 | mga_outl(M_MACCESS, 0x00000000); | 972 | mga_outl(M_MACCESS, 0x00000000); |
946 | mga_outl(M_MACCESS, 0x00008000); | 973 | mga_outl(M_MACCESS, 0x00008000); |
947 | udelay(100); | 974 | udelay(100); |
948 | mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); | 975 | mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); |
949 | hw->MXoptionReg |= 0x00040020; | 976 | hw->MXoptionReg |= 0x00040020; |
950 | } | 977 | } |
951 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 978 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
952 | return 0; | 979 | return 0; |
953 | } | 980 | } |
954 | 981 | ||
955 | static void MGAG100_reset(WPMINFO2) { | 982 | static void MGAG100_reset(struct matrox_fb_info *minfo) |
983 | { | ||
956 | u_int8_t b; | 984 | u_int8_t b; |
957 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 985 | struct matrox_hw_state *hw = &minfo->hw; |
958 | 986 | ||
959 | DBG(__func__) | 987 | DBG(__func__) |
960 | 988 | ||
@@ -964,54 +992,55 @@ static void MGAG100_reset(WPMINFO2) { | |||
964 | 992 | ||
965 | find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */ | 993 | find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */ |
966 | pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b); | 994 | pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b); |
967 | if (b == ACCESS_FBINFO(pcidev)->bus->number) { | 995 | if (b == minfo->pcidev->bus->number) { |
968 | pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */ | 996 | pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */ |
969 | pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */ | 997 | pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */ |
970 | pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */ | 998 | pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */ |
971 | pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */ | 999 | pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */ |
972 | } | 1000 | } |
973 | #endif | 1001 | #endif |
974 | if (!ACCESS_FBINFO(devflags.noinit)) { | 1002 | if (!minfo->devflags.noinit) { |
975 | if (x7AF4 & 8) { | 1003 | if (x7AF4 & 8) { |
976 | hw->MXoptionReg |= 0x40; /* FIXME... */ | 1004 | hw->MXoptionReg |= 0x40; /* FIXME... */ |
977 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 1005 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
978 | } | 1006 | } |
979 | mga_setr(M_EXTVGA_INDEX, 0x06, 0x00); | 1007 | mga_setr(M_EXTVGA_INDEX, 0x06, 0x00); |
980 | } | 1008 | } |
981 | } | 1009 | } |
982 | if (ACCESS_FBINFO(devflags.g450dac)) { | 1010 | if (minfo->devflags.g450dac) { |
983 | /* either leave MCLK as is... or they were set in preinit */ | 1011 | /* either leave MCLK as is... or they were set in preinit */ |
984 | hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM); | 1012 | hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM); |
985 | hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN); | 1013 | hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN); |
986 | hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP); | 1014 | hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP); |
987 | } else { | 1015 | } else { |
988 | DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333); | 1016 | DAC1064_setmclk(minfo, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333); |
989 | } | 1017 | } |
990 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) { | 1018 | if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) { |
991 | if (ACCESS_FBINFO(devflags.dfp_type) == -1) { | 1019 | if (minfo->devflags.dfp_type == -1) { |
992 | ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F); | 1020 | minfo->devflags.dfp_type = inDAC1064(minfo, 0x1F); |
993 | } | 1021 | } |
994 | } | 1022 | } |
995 | if (ACCESS_FBINFO(devflags.noinit)) | 1023 | if (minfo->devflags.noinit) |
996 | return; | 1024 | return; |
997 | if (ACCESS_FBINFO(devflags.g450dac)) { | 1025 | if (minfo->devflags.g450dac) { |
998 | } else { | 1026 | } else { |
999 | MGAG100_setPixClock(PMINFO 4, 25175); | 1027 | MGAG100_setPixClock(minfo, 4, 25175); |
1000 | MGAG100_setPixClock(PMINFO 5, 28322); | 1028 | MGAG100_setPixClock(minfo, 5, 28322); |
1001 | if (x7AF4 & 0x10) { | 1029 | if (x7AF4 & 0x10) { |
1002 | b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1; | 1030 | b = inDAC1064(minfo, M1064_XGENIODATA) & ~1; |
1003 | outDAC1064(PMINFO M1064_XGENIODATA, b); | 1031 | outDAC1064(minfo, M1064_XGENIODATA, b); |
1004 | b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1; | 1032 | b = inDAC1064(minfo, M1064_XGENIOCTRL) | 1; |
1005 | outDAC1064(PMINFO M1064_XGENIOCTRL, b); | 1033 | outDAC1064(minfo, M1064_XGENIOCTRL, b); |
1006 | } | 1034 | } |
1007 | } | 1035 | } |
1008 | } | 1036 | } |
1009 | #endif | 1037 | #endif |
1010 | 1038 | ||
1011 | #ifdef CONFIG_FB_MATROX_MYSTIQUE | 1039 | #ifdef CONFIG_FB_MATROX_MYSTIQUE |
1012 | static void MGA1064_restore(WPMINFO2) { | 1040 | static void MGA1064_restore(struct matrox_fb_info *minfo) |
1041 | { | ||
1013 | int i; | 1042 | int i; |
1014 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 1043 | struct matrox_hw_state *hw = &minfo->hw; |
1015 | 1044 | ||
1016 | CRITFLAGS | 1045 | CRITFLAGS |
1017 | 1046 | ||
@@ -1019,25 +1048,26 @@ static void MGA1064_restore(WPMINFO2) { | |||
1019 | 1048 | ||
1020 | CRITBEGIN | 1049 | CRITBEGIN |
1021 | 1050 | ||
1022 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 1051 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
1023 | mga_outb(M_IEN, 0x00); | 1052 | mga_outb(M_IEN, 0x00); |
1024 | mga_outb(M_CACHEFLUSH, 0x00); | 1053 | mga_outb(M_CACHEFLUSH, 0x00); |
1025 | 1054 | ||
1026 | CRITEND | 1055 | CRITEND |
1027 | 1056 | ||
1028 | DAC1064_restore_1(PMINFO2); | 1057 | DAC1064_restore_1(minfo); |
1029 | matroxfb_vgaHWrestore(PMINFO2); | 1058 | matroxfb_vgaHWrestore(minfo); |
1030 | ACCESS_FBINFO(crtc1.panpos) = -1; | 1059 | minfo->crtc1.panpos = -1; |
1031 | for (i = 0; i < 6; i++) | 1060 | for (i = 0; i < 6; i++) |
1032 | mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); | 1061 | mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); |
1033 | DAC1064_restore_2(PMINFO2); | 1062 | DAC1064_restore_2(minfo); |
1034 | } | 1063 | } |
1035 | #endif | 1064 | #endif |
1036 | 1065 | ||
1037 | #ifdef CONFIG_FB_MATROX_G | 1066 | #ifdef CONFIG_FB_MATROX_G |
1038 | static void MGAG100_restore(WPMINFO2) { | 1067 | static void MGAG100_restore(struct matrox_fb_info *minfo) |
1068 | { | ||
1039 | int i; | 1069 | int i; |
1040 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 1070 | struct matrox_hw_state *hw = &minfo->hw; |
1041 | 1071 | ||
1042 | CRITFLAGS | 1072 | CRITFLAGS |
1043 | 1073 | ||
@@ -1045,19 +1075,17 @@ static void MGAG100_restore(WPMINFO2) { | |||
1045 | 1075 | ||
1046 | CRITBEGIN | 1076 | CRITBEGIN |
1047 | 1077 | ||
1048 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 1078 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
1049 | CRITEND | 1079 | CRITEND |
1050 | 1080 | ||
1051 | DAC1064_restore_1(PMINFO2); | 1081 | DAC1064_restore_1(minfo); |
1052 | matroxfb_vgaHWrestore(PMINFO2); | 1082 | matroxfb_vgaHWrestore(minfo); |
1053 | #ifdef CONFIG_FB_MATROX_32MB | 1083 | if (minfo->devflags.support32MB) |
1054 | if (ACCESS_FBINFO(devflags.support32MB)) | ||
1055 | mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]); | 1084 | mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]); |
1056 | #endif | 1085 | minfo->crtc1.panpos = -1; |
1057 | ACCESS_FBINFO(crtc1.panpos) = -1; | ||
1058 | for (i = 0; i < 6; i++) | 1086 | for (i = 0; i < 6; i++) |
1059 | mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); | 1087 | mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); |
1060 | DAC1064_restore_2(PMINFO2); | 1088 | DAC1064_restore_2(minfo); |
1061 | } | 1089 | } |
1062 | #endif | 1090 | #endif |
1063 | 1091 | ||
diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h index 7a98ce8043d7..c6ed7801efe2 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.h +++ b/drivers/video/matrox/matroxfb_DAC1064.h | |||
@@ -11,8 +11,8 @@ extern struct matrox_switch matrox_mystique; | |||
11 | extern struct matrox_switch matrox_G100; | 11 | extern struct matrox_switch matrox_G100; |
12 | #endif | 12 | #endif |
13 | #ifdef NEED_DAC1064 | 13 | #ifdef NEED_DAC1064 |
14 | void DAC1064_global_init(WPMINFO2); | 14 | void DAC1064_global_init(struct matrox_fb_info *minfo); |
15 | void DAC1064_global_restore(WPMINFO2); | 15 | void DAC1064_global_restore(struct matrox_fb_info *minfo); |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | #define M1064_INDEX 0x00 | 18 | #define M1064_INDEX 0x00 |
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c index 13524821e242..835aaaae6b96 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.c +++ b/drivers/video/matrox/matroxfb_Ti3026.c | |||
@@ -279,27 +279,31 @@ static const unsigned char MGADACbpp32[] = | |||
279 | TVP3026_XCOLKEYCTRL_ZOOM1, | 279 | TVP3026_XCOLKEYCTRL_ZOOM1, |
280 | 0x00, 0x00, TVP3026_XCURCTRL_DIS }; | 280 | 0x00, 0x00, TVP3026_XCURCTRL_DIS }; |
281 | 281 | ||
282 | static int Ti3026_calcclock(CPMINFO unsigned int freq, unsigned int fmax, int* in, int* feed, int* post) { | 282 | static int Ti3026_calcclock(const struct matrox_fb_info *minfo, |
283 | unsigned int freq, unsigned int fmax, int *in, | ||
284 | int *feed, int *post) | ||
285 | { | ||
283 | unsigned int fvco; | 286 | unsigned int fvco; |
284 | unsigned int lin, lfeed, lpost; | 287 | unsigned int lin, lfeed, lpost; |
285 | 288 | ||
286 | DBG(__func__) | 289 | DBG(__func__) |
287 | 290 | ||
288 | fvco = PLL_calcclock(PMINFO freq, fmax, &lin, &lfeed, &lpost); | 291 | fvco = PLL_calcclock(minfo, freq, fmax, &lin, &lfeed, &lpost); |
289 | fvco >>= (*post = lpost); | 292 | fvco >>= (*post = lpost); |
290 | *in = 64 - lin; | 293 | *in = 64 - lin; |
291 | *feed = 64 - lfeed; | 294 | *feed = 64 - lfeed; |
292 | return fvco; | 295 | return fvco; |
293 | } | 296 | } |
294 | 297 | ||
295 | static int Ti3026_setpclk(WPMINFO int clk) { | 298 | static int Ti3026_setpclk(struct matrox_fb_info *minfo, int clk) |
299 | { | ||
296 | unsigned int f_pll; | 300 | unsigned int f_pll; |
297 | unsigned int pixfeed, pixin, pixpost; | 301 | unsigned int pixfeed, pixin, pixpost; |
298 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 302 | struct matrox_hw_state *hw = &minfo->hw; |
299 | 303 | ||
300 | DBG(__func__) | 304 | DBG(__func__) |
301 | 305 | ||
302 | f_pll = Ti3026_calcclock(PMINFO clk, ACCESS_FBINFO(max_pixel_clock), &pixin, &pixfeed, &pixpost); | 306 | f_pll = Ti3026_calcclock(minfo, clk, minfo->max_pixel_clock, &pixin, &pixfeed, &pixpost); |
303 | 307 | ||
304 | hw->DACclk[0] = pixin | 0xC0; | 308 | hw->DACclk[0] = pixin | 0xC0; |
305 | hw->DACclk[1] = pixfeed; | 309 | hw->DACclk[1] = pixfeed; |
@@ -309,9 +313,9 @@ static int Ti3026_setpclk(WPMINFO int clk) { | |||
309 | unsigned int loopfeed, loopin, looppost, loopdiv, z; | 313 | unsigned int loopfeed, loopin, looppost, loopdiv, z; |
310 | unsigned int Bpp; | 314 | unsigned int Bpp; |
311 | 315 | ||
312 | Bpp = ACCESS_FBINFO(curr.final_bppShift); | 316 | Bpp = minfo->curr.final_bppShift; |
313 | 317 | ||
314 | if (ACCESS_FBINFO(fbcon).var.bits_per_pixel == 24) { | 318 | if (minfo->fbcon.var.bits_per_pixel == 24) { |
315 | loopfeed = 3; /* set lm to any possible value */ | 319 | loopfeed = 3; /* set lm to any possible value */ |
316 | loopin = 3 * 32 / Bpp; | 320 | loopin = 3 * 32 / Bpp; |
317 | } else { | 321 | } else { |
@@ -330,18 +334,18 @@ static int Ti3026_setpclk(WPMINFO int clk) { | |||
330 | looppost = 3; | 334 | looppost = 3; |
331 | loopdiv = z/16; | 335 | loopdiv = z/16; |
332 | } | 336 | } |
333 | if (ACCESS_FBINFO(fbcon).var.bits_per_pixel == 24) { | 337 | if (minfo->fbcon.var.bits_per_pixel == 24) { |
334 | hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; | 338 | hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; |
335 | hw->DACclk[4] = (65 - loopfeed) | 0x80; | 339 | hw->DACclk[4] = (65 - loopfeed) | 0x80; |
336 | if (ACCESS_FBINFO(accel.ramdac_rev) > 0x20) { | 340 | if (minfo->accel.ramdac_rev > 0x20) { |
337 | if (isInterleave(MINFO)) | 341 | if (isInterleave(minfo)) |
338 | hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3; | 342 | hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3; |
339 | else { | 343 | else { |
340 | hw->DACclk[4] &= ~0xC0; | 344 | hw->DACclk[4] &= ~0xC0; |
341 | hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3; | 345 | hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3; |
342 | } | 346 | } |
343 | } else { | 347 | } else { |
344 | if (isInterleave(MINFO)) | 348 | if (isInterleave(minfo)) |
345 | ; /* default... */ | 349 | ; /* default... */ |
346 | else { | 350 | else { |
347 | hw->DACclk[4] ^= 0xC0; /* change from 0x80 to 0x40 */ | 351 | hw->DACclk[4] ^= 0xC0; /* change from 0x80 to 0x40 */ |
@@ -349,7 +353,7 @@ static int Ti3026_setpclk(WPMINFO int clk) { | |||
349 | } | 353 | } |
350 | } | 354 | } |
351 | hw->DACclk[5] = looppost | 0xF8; | 355 | hw->DACclk[5] = looppost | 0xF8; |
352 | if (ACCESS_FBINFO(devflags.mga_24bpp_fix)) | 356 | if (minfo->devflags.mga_24bpp_fix) |
353 | hw->DACclk[5] ^= 0x40; | 357 | hw->DACclk[5] ^= 0x40; |
354 | } else { | 358 | } else { |
355 | hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; | 359 | hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; |
@@ -361,14 +365,15 @@ static int Ti3026_setpclk(WPMINFO int clk) { | |||
361 | return 0; | 365 | return 0; |
362 | } | 366 | } |
363 | 367 | ||
364 | static int Ti3026_init(WPMINFO struct my_timming* m) { | 368 | static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m) |
365 | u_int8_t muxctrl = isInterleave(MINFO) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT; | 369 | { |
366 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 370 | u_int8_t muxctrl = isInterleave(minfo) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT; |
371 | struct matrox_hw_state *hw = &minfo->hw; | ||
367 | 372 | ||
368 | DBG(__func__) | 373 | DBG(__func__) |
369 | 374 | ||
370 | memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg)); | 375 | memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg)); |
371 | switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { | 376 | switch (minfo->fbcon.var.bits_per_pixel) { |
372 | case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */ | 377 | case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */ |
373 | hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR; | 378 | hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR; |
374 | hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT; | 379 | hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT; |
@@ -383,7 +388,7 @@ static int Ti3026_init(WPMINFO struct my_timming* m) { | |||
383 | break; | 388 | break; |
384 | case 16: | 389 | case 16: |
385 | /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */ | 390 | /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */ |
386 | hw->DACreg[POS3026_XTRUECOLORCTRL] = (ACCESS_FBINFO(fbcon).var.green.length == 5)? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555 ) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565); | 391 | hw->DACreg[POS3026_XTRUECOLORCTRL] = (minfo->fbcon.var.green.length == 5) ? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565); |
387 | hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT; | 392 | hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT; |
388 | hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2; | 393 | hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2; |
389 | break; | 394 | break; |
@@ -400,7 +405,7 @@ static int Ti3026_init(WPMINFO struct my_timming* m) { | |||
400 | default: | 405 | default: |
401 | return 1; /* TODO: failed */ | 406 | return 1; /* TODO: failed */ |
402 | } | 407 | } |
403 | if (matroxfb_vgaHWinit(PMINFO m)) return 1; | 408 | if (matroxfb_vgaHWinit(minfo, m)) return 1; |
404 | 409 | ||
405 | /* set SYNC */ | 410 | /* set SYNC */ |
406 | hw->MiscOutReg = 0xCB; | 411 | hw->MiscOutReg = 0xCB; |
@@ -412,9 +417,9 @@ static int Ti3026_init(WPMINFO struct my_timming* m) { | |||
412 | hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN; | 417 | hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN; |
413 | 418 | ||
414 | /* set DELAY */ | 419 | /* set DELAY */ |
415 | if (ACCESS_FBINFO(video.len) < 0x400000) | 420 | if (minfo->video.len < 0x400000) |
416 | hw->CRTCEXT[3] |= 0x08; | 421 | hw->CRTCEXT[3] |= 0x08; |
417 | else if (ACCESS_FBINFO(video.len) > 0x400000) | 422 | else if (minfo->video.len > 0x400000) |
418 | hw->CRTCEXT[3] |= 0x10; | 423 | hw->CRTCEXT[3] |= 0x10; |
419 | 424 | ||
420 | /* set HWCURSOR */ | 425 | /* set HWCURSOR */ |
@@ -426,14 +431,15 @@ static int Ti3026_init(WPMINFO struct my_timming* m) { | |||
426 | 431 | ||
427 | /* set interleaving */ | 432 | /* set interleaving */ |
428 | hw->MXoptionReg &= ~0x00001000; | 433 | hw->MXoptionReg &= ~0x00001000; |
429 | if (isInterleave(MINFO)) hw->MXoptionReg |= 0x00001000; | 434 | if (isInterleave(minfo)) hw->MXoptionReg |= 0x00001000; |
430 | 435 | ||
431 | /* set DAC */ | 436 | /* set DAC */ |
432 | Ti3026_setpclk(PMINFO m->pixclock); | 437 | Ti3026_setpclk(minfo, m->pixclock); |
433 | return 0; | 438 | return 0; |
434 | } | 439 | } |
435 | 440 | ||
436 | static void ti3026_setMCLK(WPMINFO int fout){ | 441 | static void ti3026_setMCLK(struct matrox_fb_info *minfo, int fout) |
442 | { | ||
437 | unsigned int f_pll; | 443 | unsigned int f_pll; |
438 | unsigned int pclk_m, pclk_n, pclk_p; | 444 | unsigned int pclk_m, pclk_n, pclk_p; |
439 | unsigned int mclk_m, mclk_n, mclk_p; | 445 | unsigned int mclk_m, mclk_n, mclk_p; |
@@ -442,29 +448,29 @@ static void ti3026_setMCLK(WPMINFO int fout){ | |||
442 | 448 | ||
443 | DBG(__func__) | 449 | DBG(__func__) |
444 | 450 | ||
445 | f_pll = Ti3026_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &mclk_n, &mclk_m, &mclk_p); | 451 | f_pll = Ti3026_calcclock(minfo, fout, minfo->max_pixel_clock, &mclk_n, &mclk_m, &mclk_p); |
446 | 452 | ||
447 | /* save pclk */ | 453 | /* save pclk */ |
448 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC); | 454 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFC); |
449 | pclk_n = inTi3026(PMINFO TVP3026_XPIXPLLDATA); | 455 | pclk_n = inTi3026(minfo, TVP3026_XPIXPLLDATA); |
450 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFD); | 456 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFD); |
451 | pclk_m = inTi3026(PMINFO TVP3026_XPIXPLLDATA); | 457 | pclk_m = inTi3026(minfo, TVP3026_XPIXPLLDATA); |
452 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE); | 458 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFE); |
453 | pclk_p = inTi3026(PMINFO TVP3026_XPIXPLLDATA); | 459 | pclk_p = inTi3026(minfo, TVP3026_XPIXPLLDATA); |
454 | 460 | ||
455 | /* stop pclk */ | 461 | /* stop pclk */ |
456 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE); | 462 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFE); |
457 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00); | 463 | outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00); |
458 | 464 | ||
459 | /* set pclk to new mclk */ | 465 | /* set pclk to new mclk */ |
460 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC); | 466 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFC); |
461 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_n | 0xC0); | 467 | outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_n | 0xC0); |
462 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_m); | 468 | outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_m); |
463 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_p | 0xB0); | 469 | outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_p | 0xB0); |
464 | 470 | ||
465 | /* wait for PLL to lock */ | 471 | /* wait for PLL to lock */ |
466 | for (tmout = 500000; tmout; tmout--) { | 472 | for (tmout = 500000; tmout; tmout--) { |
467 | if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40) | 473 | if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40) |
468 | break; | 474 | break; |
469 | udelay(10); | 475 | udelay(10); |
470 | }; | 476 | }; |
@@ -472,23 +478,23 @@ static void ti3026_setMCLK(WPMINFO int fout){ | |||
472 | printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n"); | 478 | printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n"); |
473 | 479 | ||
474 | /* output pclk on mclk pin */ | 480 | /* output pclk on mclk pin */ |
475 | mclk_ctl = inTi3026(PMINFO TVP3026_XMEMPLLCTRL); | 481 | mclk_ctl = inTi3026(minfo, TVP3026_XMEMPLLCTRL); |
476 | outTi3026(PMINFO TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7); | 482 | outTi3026(minfo, TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7); |
477 | outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4); | 483 | outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4); |
478 | 484 | ||
479 | /* stop MCLK */ | 485 | /* stop MCLK */ |
480 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFB); | 486 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFB); |
481 | outTi3026(PMINFO TVP3026_XMEMPLLDATA, 0x00); | 487 | outTi3026(minfo, TVP3026_XMEMPLLDATA, 0x00); |
482 | 488 | ||
483 | /* set mclk to new freq */ | 489 | /* set mclk to new freq */ |
484 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xF3); | 490 | outTi3026(minfo, TVP3026_XPLLADDR, 0xF3); |
485 | outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_n | 0xC0); | 491 | outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_n | 0xC0); |
486 | outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_m); | 492 | outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_m); |
487 | outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_p | 0xB0); | 493 | outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_p | 0xB0); |
488 | 494 | ||
489 | /* wait for PLL to lock */ | 495 | /* wait for PLL to lock */ |
490 | for (tmout = 500000; tmout; tmout--) { | 496 | for (tmout = 500000; tmout; tmout--) { |
491 | if (inTi3026(PMINFO TVP3026_XMEMPLLDATA) & 0x40) | 497 | if (inTi3026(minfo, TVP3026_XMEMPLLDATA) & 0x40) |
492 | break; | 498 | break; |
493 | udelay(10); | 499 | udelay(10); |
494 | } | 500 | } |
@@ -496,7 +502,7 @@ static void ti3026_setMCLK(WPMINFO int fout){ | |||
496 | printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n"); | 502 | printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n"); |
497 | 503 | ||
498 | f_pll = f_pll * 333 / (10000 << mclk_p); | 504 | f_pll = f_pll * 333 / (10000 << mclk_p); |
499 | if (isMilleniumII(MINFO)) { | 505 | if (isMilleniumII(minfo)) { |
500 | rfhcnt = (f_pll - 128) / 256; | 506 | rfhcnt = (f_pll - 128) / 256; |
501 | if (rfhcnt > 15) | 507 | if (rfhcnt > 15) |
502 | rfhcnt = 15; | 508 | rfhcnt = 15; |
@@ -505,26 +511,26 @@ static void ti3026_setMCLK(WPMINFO int fout){ | |||
505 | if (rfhcnt > 15) | 511 | if (rfhcnt > 15) |
506 | rfhcnt = 0; | 512 | rfhcnt = 0; |
507 | } | 513 | } |
508 | ACCESS_FBINFO(hw).MXoptionReg = (ACCESS_FBINFO(hw).MXoptionReg & ~0x000F0000) | (rfhcnt << 16); | 514 | minfo->hw.MXoptionReg = (minfo->hw.MXoptionReg & ~0x000F0000) | (rfhcnt << 16); |
509 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); | 515 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); |
510 | 516 | ||
511 | /* output MCLK to MCLK pin */ | 517 | /* output MCLK to MCLK pin */ |
512 | outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL); | 518 | outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL); |
513 | outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4); | 519 | outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4); |
514 | 520 | ||
515 | /* stop PCLK */ | 521 | /* stop PCLK */ |
516 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE); | 522 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFE); |
517 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00); | 523 | outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00); |
518 | 524 | ||
519 | /* restore pclk */ | 525 | /* restore pclk */ |
520 | outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC); | 526 | outTi3026(minfo, TVP3026_XPLLADDR, 0xFC); |
521 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_n); | 527 | outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_n); |
522 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_m); | 528 | outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_m); |
523 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_p); | 529 | outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_p); |
524 | 530 | ||
525 | /* wait for PLL to lock */ | 531 | /* wait for PLL to lock */ |
526 | for (tmout = 500000; tmout; tmout--) { | 532 | for (tmout = 500000; tmout; tmout--) { |
527 | if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40) | 533 | if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40) |
528 | break; | 534 | break; |
529 | udelay(10); | 535 | udelay(10); |
530 | } | 536 | } |
@@ -532,26 +538,27 @@ static void ti3026_setMCLK(WPMINFO int fout){ | |||
532 | printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n"); | 538 | printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n"); |
533 | } | 539 | } |
534 | 540 | ||
535 | static void ti3026_ramdac_init(WPMINFO2) { | 541 | static void ti3026_ramdac_init(struct matrox_fb_info *minfo) |
536 | 542 | { | |
537 | DBG(__func__) | 543 | DBG(__func__) |
538 | 544 | ||
539 | ACCESS_FBINFO(features.pll.vco_freq_min) = 110000; | 545 | minfo->features.pll.vco_freq_min = 110000; |
540 | ACCESS_FBINFO(features.pll.ref_freq) = 114545; | 546 | minfo->features.pll.ref_freq = 114545; |
541 | ACCESS_FBINFO(features.pll.feed_div_min) = 2; | 547 | minfo->features.pll.feed_div_min = 2; |
542 | ACCESS_FBINFO(features.pll.feed_div_max) = 24; | 548 | minfo->features.pll.feed_div_max = 24; |
543 | ACCESS_FBINFO(features.pll.in_div_min) = 2; | 549 | minfo->features.pll.in_div_min = 2; |
544 | ACCESS_FBINFO(features.pll.in_div_max) = 63; | 550 | minfo->features.pll.in_div_max = 63; |
545 | ACCESS_FBINFO(features.pll.post_shift_max) = 3; | 551 | minfo->features.pll.post_shift_max = 3; |
546 | if (ACCESS_FBINFO(devflags.noinit)) | 552 | if (minfo->devflags.noinit) |
547 | return; | 553 | return; |
548 | ti3026_setMCLK(PMINFO 60000); | 554 | ti3026_setMCLK(minfo, 60000); |
549 | } | 555 | } |
550 | 556 | ||
551 | static void Ti3026_restore(WPMINFO2) { | 557 | static void Ti3026_restore(struct matrox_fb_info *minfo) |
558 | { | ||
552 | int i; | 559 | int i; |
553 | unsigned char progdac[6]; | 560 | unsigned char progdac[6]; |
554 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 561 | struct matrox_hw_state *hw = &minfo->hw; |
555 | CRITFLAGS | 562 | CRITFLAGS |
556 | 563 | ||
557 | DBG(__func__) | 564 | DBG(__func__) |
@@ -565,31 +572,31 @@ static void Ti3026_restore(WPMINFO2) { | |||
565 | 572 | ||
566 | CRITBEGIN | 573 | CRITBEGIN |
567 | 574 | ||
568 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 575 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
569 | 576 | ||
570 | CRITEND | 577 | CRITEND |
571 | 578 | ||
572 | matroxfb_vgaHWrestore(PMINFO2); | 579 | matroxfb_vgaHWrestore(minfo); |
573 | 580 | ||
574 | CRITBEGIN | 581 | CRITBEGIN |
575 | 582 | ||
576 | ACCESS_FBINFO(crtc1.panpos) = -1; | 583 | minfo->crtc1.panpos = -1; |
577 | for (i = 0; i < 6; i++) | 584 | for (i = 0; i < 6; i++) |
578 | mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); | 585 | mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); |
579 | 586 | ||
580 | for (i = 0; i < 21; i++) { | 587 | for (i = 0; i < 21; i++) { |
581 | outTi3026(PMINFO DACseq[i], hw->DACreg[i]); | 588 | outTi3026(minfo, DACseq[i], hw->DACreg[i]); |
582 | } | 589 | } |
583 | 590 | ||
584 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x00); | 591 | outTi3026(minfo, TVP3026_XPLLADDR, 0x00); |
585 | progdac[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); | 592 | progdac[0] = inTi3026(minfo, TVP3026_XPIXPLLDATA); |
586 | progdac[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); | 593 | progdac[3] = inTi3026(minfo, TVP3026_XLOOPPLLDATA); |
587 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x15); | 594 | outTi3026(minfo, TVP3026_XPLLADDR, 0x15); |
588 | progdac[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); | 595 | progdac[1] = inTi3026(minfo, TVP3026_XPIXPLLDATA); |
589 | progdac[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); | 596 | progdac[4] = inTi3026(minfo, TVP3026_XLOOPPLLDATA); |
590 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A); | 597 | outTi3026(minfo, TVP3026_XPLLADDR, 0x2A); |
591 | progdac[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); | 598 | progdac[2] = inTi3026(minfo, TVP3026_XPIXPLLDATA); |
592 | progdac[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); | 599 | progdac[5] = inTi3026(minfo, TVP3026_XLOOPPLLDATA); |
593 | 600 | ||
594 | CRITEND | 601 | CRITEND |
595 | if (memcmp(hw->DACclk, progdac, 6)) { | 602 | if (memcmp(hw->DACclk, progdac, 6)) { |
@@ -598,20 +605,20 @@ static void Ti3026_restore(WPMINFO2) { | |||
598 | /* Maybe even we should call schedule() ? */ | 605 | /* Maybe even we should call schedule() ? */ |
599 | 606 | ||
600 | CRITBEGIN | 607 | CRITBEGIN |
601 | outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]); | 608 | outTi3026(minfo, TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]); |
602 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A); | 609 | outTi3026(minfo, TVP3026_XPLLADDR, 0x2A); |
603 | outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0); | 610 | outTi3026(minfo, TVP3026_XLOOPPLLDATA, 0); |
604 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0); | 611 | outTi3026(minfo, TVP3026_XPIXPLLDATA, 0); |
605 | 612 | ||
606 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x00); | 613 | outTi3026(minfo, TVP3026_XPLLADDR, 0x00); |
607 | for (i = 0; i < 3; i++) | 614 | for (i = 0; i < 3; i++) |
608 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, hw->DACclk[i]); | 615 | outTi3026(minfo, TVP3026_XPIXPLLDATA, hw->DACclk[i]); |
609 | /* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */ | 616 | /* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */ |
610 | if (hw->MiscOutReg & 0x08) { | 617 | if (hw->MiscOutReg & 0x08) { |
611 | int tmout; | 618 | int tmout; |
612 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F); | 619 | outTi3026(minfo, TVP3026_XPLLADDR, 0x3F); |
613 | for (tmout = 500000; tmout; --tmout) { | 620 | for (tmout = 500000; tmout; --tmout) { |
614 | if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40) | 621 | if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40) |
615 | break; | 622 | break; |
616 | udelay(10); | 623 | udelay(10); |
617 | } | 624 | } |
@@ -624,18 +631,18 @@ static void Ti3026_restore(WPMINFO2) { | |||
624 | dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout); | 631 | dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout); |
625 | CRITBEGIN | 632 | CRITBEGIN |
626 | } | 633 | } |
627 | outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]); | 634 | outTi3026(minfo, TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]); |
628 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x00); | 635 | outTi3026(minfo, TVP3026_XPLLADDR, 0x00); |
629 | for (i = 3; i < 6; i++) | 636 | for (i = 3; i < 6; i++) |
630 | outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]); | 637 | outTi3026(minfo, TVP3026_XLOOPPLLDATA, hw->DACclk[i]); |
631 | CRITEND | 638 | CRITEND |
632 | if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) { | 639 | if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) { |
633 | int tmout; | 640 | int tmout; |
634 | 641 | ||
635 | CRITBEGIN | 642 | CRITBEGIN |
636 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F); | 643 | outTi3026(minfo, TVP3026_XPLLADDR, 0x3F); |
637 | for (tmout = 500000; tmout; --tmout) { | 644 | for (tmout = 500000; tmout; --tmout) { |
638 | if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40) | 645 | if (inTi3026(minfo, TVP3026_XLOOPPLLDATA) & 0x40) |
639 | break; | 646 | break; |
640 | udelay(10); | 647 | udelay(10); |
641 | } | 648 | } |
@@ -651,74 +658,75 @@ static void Ti3026_restore(WPMINFO2) { | |||
651 | dprintk(KERN_DEBUG "3026DACregs "); | 658 | dprintk(KERN_DEBUG "3026DACregs "); |
652 | for (i = 0; i < 21; i++) { | 659 | for (i = 0; i < 21; i++) { |
653 | dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]); | 660 | dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]); |
654 | if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... "); | 661 | if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... "); |
655 | } | 662 | } |
656 | dprintk("\n" KERN_DEBUG "DACclk "); | 663 | dprintk(KERN_DEBUG "DACclk "); |
657 | for (i = 0; i < 6; i++) | 664 | for (i = 0; i < 6; i++) |
658 | dprintk("C%02X=%02X ", i, hw->DACclk[i]); | 665 | dprintk("C%02X=%02X ", i, hw->DACclk[i]); |
659 | dprintk("\n"); | 666 | dprintk("\n"); |
660 | #endif | 667 | #endif |
661 | } | 668 | } |
662 | 669 | ||
663 | static void Ti3026_reset(WPMINFO2) { | 670 | static void Ti3026_reset(struct matrox_fb_info *minfo) |
664 | 671 | { | |
665 | DBG(__func__) | 672 | DBG(__func__) |
666 | 673 | ||
667 | ti3026_ramdac_init(PMINFO2); | 674 | ti3026_ramdac_init(minfo); |
668 | } | 675 | } |
669 | 676 | ||
670 | static struct matrox_altout ti3026_output = { | 677 | static struct matrox_altout ti3026_output = { |
671 | .name = "Primary output", | 678 | .name = "Primary output", |
672 | }; | 679 | }; |
673 | 680 | ||
674 | static int Ti3026_preinit(WPMINFO2) { | 681 | static int Ti3026_preinit(struct matrox_fb_info *minfo) |
682 | { | ||
675 | static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960, | 683 | static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960, |
676 | 1024, 1152, 1280, 1600, 1664, 1920, | 684 | 1024, 1152, 1280, 1600, 1664, 1920, |
677 | 2048, 0}; | 685 | 2048, 0}; |
678 | static const int vxres_mill1[] = { 640, 768, 800, 960, | 686 | static const int vxres_mill1[] = { 640, 768, 800, 960, |
679 | 1024, 1152, 1280, 1600, 1920, | 687 | 1024, 1152, 1280, 1600, 1920, |
680 | 2048, 0}; | 688 | 2048, 0}; |
681 | struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); | 689 | struct matrox_hw_state *hw = &minfo->hw; |
682 | 690 | ||
683 | DBG(__func__) | 691 | DBG(__func__) |
684 | 692 | ||
685 | ACCESS_FBINFO(millenium) = 1; | 693 | minfo->millenium = 1; |
686 | ACCESS_FBINFO(milleniumII) = (ACCESS_FBINFO(pcidev)->device != PCI_DEVICE_ID_MATROX_MIL); | 694 | minfo->milleniumII = (minfo->pcidev->device != PCI_DEVICE_ID_MATROX_MIL); |
687 | ACCESS_FBINFO(capable.cfb4) = 1; | 695 | minfo->capable.cfb4 = 1; |
688 | ACCESS_FBINFO(capable.text) = 1; /* isMilleniumII(MINFO); */ | 696 | minfo->capable.text = 1; /* isMilleniumII(minfo); */ |
689 | ACCESS_FBINFO(capable.vxres) = isMilleniumII(MINFO)?vxres_mill2:vxres_mill1; | 697 | minfo->capable.vxres = isMilleniumII(minfo) ? vxres_mill2 : vxres_mill1; |
690 | 698 | ||
691 | ACCESS_FBINFO(outputs[0]).data = MINFO; | 699 | minfo->outputs[0].data = minfo; |
692 | ACCESS_FBINFO(outputs[0]).output = &ti3026_output; | 700 | minfo->outputs[0].output = &ti3026_output; |
693 | ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; | 701 | minfo->outputs[0].src = minfo->outputs[0].default_src; |
694 | ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 702 | minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
695 | 703 | ||
696 | if (ACCESS_FBINFO(devflags.noinit)) | 704 | if (minfo->devflags.noinit) |
697 | return 0; | 705 | return 0; |
698 | /* preserve VGA I/O, BIOS and PPC */ | 706 | /* preserve VGA I/O, BIOS and PPC */ |
699 | hw->MXoptionReg &= 0xC0000100; | 707 | hw->MXoptionReg &= 0xC0000100; |
700 | hw->MXoptionReg |= 0x002C0000; | 708 | hw->MXoptionReg |= 0x002C0000; |
701 | if (ACCESS_FBINFO(devflags.novga)) | 709 | if (minfo->devflags.novga) |
702 | hw->MXoptionReg &= ~0x00000100; | 710 | hw->MXoptionReg &= ~0x00000100; |
703 | if (ACCESS_FBINFO(devflags.nobios)) | 711 | if (minfo->devflags.nobios) |
704 | hw->MXoptionReg &= ~0x40000000; | 712 | hw->MXoptionReg &= ~0x40000000; |
705 | if (ACCESS_FBINFO(devflags.nopciretry)) | 713 | if (minfo->devflags.nopciretry) |
706 | hw->MXoptionReg |= 0x20000000; | 714 | hw->MXoptionReg |= 0x20000000; |
707 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); | 715 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); |
708 | 716 | ||
709 | ACCESS_FBINFO(accel.ramdac_rev) = inTi3026(PMINFO TVP3026_XSILICONREV); | 717 | minfo->accel.ramdac_rev = inTi3026(minfo, TVP3026_XSILICONREV); |
710 | 718 | ||
711 | outTi3026(PMINFO TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED); | 719 | outTi3026(minfo, TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED); |
712 | outTi3026(PMINFO TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR); | 720 | outTi3026(minfo, TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR); |
713 | outTi3026(PMINFO TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA); | 721 | outTi3026(minfo, TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA); |
714 | 722 | ||
715 | outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A); | 723 | outTi3026(minfo, TVP3026_XPLLADDR, 0x2A); |
716 | outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0x00); | 724 | outTi3026(minfo, TVP3026_XLOOPPLLDATA, 0x00); |
717 | outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00); | 725 | outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00); |
718 | 726 | ||
719 | mga_outb(M_MISC_REG, 0x67); | 727 | mga_outb(M_MISC_REG, 0x67); |
720 | 728 | ||
721 | outTi3026(PMINFO TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL); | 729 | outTi3026(minfo, TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL); |
722 | 730 | ||
723 | mga_outl(M_RESET, 1); | 731 | mga_outl(M_RESET, 1); |
724 | udelay(250); | 732 | udelay(250); |
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c index 9c3aeee1cc4f..8335a6fe303e 100644 --- a/drivers/video/matrox/matroxfb_accel.c +++ b/drivers/video/matrox/matroxfb_accel.c | |||
@@ -81,7 +81,7 @@ | |||
81 | #include "matroxfb_Ti3026.h" | 81 | #include "matroxfb_Ti3026.h" |
82 | #include "matroxfb_misc.h" | 82 | #include "matroxfb_misc.h" |
83 | 83 | ||
84 | #define curr_ydstorg(x) ACCESS_FBINFO2(x, curr.ydstorg.pixels) | 84 | #define curr_ydstorg(x) ((x)->curr.ydstorg.pixels) |
85 | 85 | ||
86 | #define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l)) | 86 | #define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l)) |
87 | 87 | ||
@@ -107,7 +107,8 @@ static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* imag | |||
107 | static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect); | 107 | static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect); |
108 | static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area); | 108 | static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area); |
109 | 109 | ||
110 | void matrox_cfbX_init(WPMINFO2) { | 110 | void matrox_cfbX_init(struct matrox_fb_info *minfo) |
111 | { | ||
111 | u_int32_t maccess; | 112 | u_int32_t maccess; |
112 | u_int32_t mpitch; | 113 | u_int32_t mpitch; |
113 | u_int32_t mopmode; | 114 | u_int32_t mopmode; |
@@ -115,59 +116,59 @@ void matrox_cfbX_init(WPMINFO2) { | |||
115 | 116 | ||
116 | DBG(__func__) | 117 | DBG(__func__) |
117 | 118 | ||
118 | mpitch = ACCESS_FBINFO(fbcon).var.xres_virtual; | 119 | mpitch = minfo->fbcon.var.xres_virtual; |
119 | 120 | ||
120 | ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea; | 121 | minfo->fbops.fb_copyarea = cfb_copyarea; |
121 | ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect; | 122 | minfo->fbops.fb_fillrect = cfb_fillrect; |
122 | ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit; | 123 | minfo->fbops.fb_imageblit = cfb_imageblit; |
123 | ACCESS_FBINFO(fbops).fb_cursor = NULL; | 124 | minfo->fbops.fb_cursor = NULL; |
124 | 125 | ||
125 | accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT; | 126 | accel = (minfo->fbcon.var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT; |
126 | 127 | ||
127 | switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { | 128 | switch (minfo->fbcon.var.bits_per_pixel) { |
128 | case 4: maccess = 0x00000000; /* accelerate as 8bpp video */ | 129 | case 4: maccess = 0x00000000; /* accelerate as 8bpp video */ |
129 | mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */ | 130 | mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */ |
130 | mopmode = M_OPMODE_4BPP; | 131 | mopmode = M_OPMODE_4BPP; |
131 | matrox_cfb4_pal(ACCESS_FBINFO(cmap)); | 132 | matrox_cfb4_pal(minfo->cmap); |
132 | if (accel && !(mpitch & 1)) { | 133 | if (accel && !(mpitch & 1)) { |
133 | ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_cfb4_copyarea; | 134 | minfo->fbops.fb_copyarea = matroxfb_cfb4_copyarea; |
134 | ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_cfb4_fillrect; | 135 | minfo->fbops.fb_fillrect = matroxfb_cfb4_fillrect; |
135 | } | 136 | } |
136 | break; | 137 | break; |
137 | case 8: maccess = 0x00000000; | 138 | case 8: maccess = 0x00000000; |
138 | mopmode = M_OPMODE_8BPP; | 139 | mopmode = M_OPMODE_8BPP; |
139 | matrox_cfb8_pal(ACCESS_FBINFO(cmap)); | 140 | matrox_cfb8_pal(minfo->cmap); |
140 | if (accel) { | 141 | if (accel) { |
141 | ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; | 142 | minfo->fbops.fb_copyarea = matroxfb_copyarea; |
142 | ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; | 143 | minfo->fbops.fb_fillrect = matroxfb_fillrect; |
143 | ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; | 144 | minfo->fbops.fb_imageblit = matroxfb_imageblit; |
144 | } | 145 | } |
145 | break; | 146 | break; |
146 | case 16: if (ACCESS_FBINFO(fbcon).var.green.length == 5) | 147 | case 16: if (minfo->fbcon.var.green.length == 5) |
147 | maccess = 0xC0000001; | 148 | maccess = 0xC0000001; |
148 | else | 149 | else |
149 | maccess = 0x40000001; | 150 | maccess = 0x40000001; |
150 | mopmode = M_OPMODE_16BPP; | 151 | mopmode = M_OPMODE_16BPP; |
151 | if (accel) { | 152 | if (accel) { |
152 | ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; | 153 | minfo->fbops.fb_copyarea = matroxfb_copyarea; |
153 | ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; | 154 | minfo->fbops.fb_fillrect = matroxfb_fillrect; |
154 | ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; | 155 | minfo->fbops.fb_imageblit = matroxfb_imageblit; |
155 | } | 156 | } |
156 | break; | 157 | break; |
157 | case 24: maccess = 0x00000003; | 158 | case 24: maccess = 0x00000003; |
158 | mopmode = M_OPMODE_24BPP; | 159 | mopmode = M_OPMODE_24BPP; |
159 | if (accel) { | 160 | if (accel) { |
160 | ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; | 161 | minfo->fbops.fb_copyarea = matroxfb_copyarea; |
161 | ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; | 162 | minfo->fbops.fb_fillrect = matroxfb_fillrect; |
162 | ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; | 163 | minfo->fbops.fb_imageblit = matroxfb_imageblit; |
163 | } | 164 | } |
164 | break; | 165 | break; |
165 | case 32: maccess = 0x00000002; | 166 | case 32: maccess = 0x00000002; |
166 | mopmode = M_OPMODE_32BPP; | 167 | mopmode = M_OPMODE_32BPP; |
167 | if (accel) { | 168 | if (accel) { |
168 | ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; | 169 | minfo->fbops.fb_copyarea = matroxfb_copyarea; |
169 | ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; | 170 | minfo->fbops.fb_fillrect = matroxfb_fillrect; |
170 | ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; | 171 | minfo->fbops.fb_imageblit = matroxfb_imageblit; |
171 | } | 172 | } |
172 | break; | 173 | break; |
173 | default: maccess = 0x00000000; | 174 | default: maccess = 0x00000000; |
@@ -176,10 +177,10 @@ void matrox_cfbX_init(WPMINFO2) { | |||
176 | } | 177 | } |
177 | mga_fifo(8); | 178 | mga_fifo(8); |
178 | mga_outl(M_PITCH, mpitch); | 179 | mga_outl(M_PITCH, mpitch); |
179 | mga_outl(M_YDSTORG, curr_ydstorg(MINFO)); | 180 | mga_outl(M_YDSTORG, curr_ydstorg(minfo)); |
180 | if (ACCESS_FBINFO(capable.plnwt)) | 181 | if (minfo->capable.plnwt) |
181 | mga_outl(M_PLNWT, -1); | 182 | mga_outl(M_PLNWT, -1); |
182 | if (ACCESS_FBINFO(capable.srcorg)) { | 183 | if (minfo->capable.srcorg) { |
183 | mga_outl(M_SRCORG, 0); | 184 | mga_outl(M_SRCORG, 0); |
184 | mga_outl(M_DSTORG, 0); | 185 | mga_outl(M_DSTORG, 0); |
185 | } | 186 | } |
@@ -188,14 +189,16 @@ void matrox_cfbX_init(WPMINFO2) { | |||
188 | mga_outl(M_YTOP, 0); | 189 | mga_outl(M_YTOP, 0); |
189 | mga_outl(M_YBOT, 0x01FFFFFF); | 190 | mga_outl(M_YBOT, 0x01FFFFFF); |
190 | mga_outl(M_MACCESS, maccess); | 191 | mga_outl(M_MACCESS, maccess); |
191 | ACCESS_FBINFO(accel.m_dwg_rect) = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO; | 192 | minfo->accel.m_dwg_rect = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO; |
192 | if (isMilleniumII(MINFO)) ACCESS_FBINFO(accel.m_dwg_rect) |= M_DWG_TRANSC; | 193 | if (isMilleniumII(minfo)) minfo->accel.m_dwg_rect |= M_DWG_TRANSC; |
193 | ACCESS_FBINFO(accel.m_opmode) = mopmode; | 194 | minfo->accel.m_opmode = mopmode; |
194 | } | 195 | } |
195 | 196 | ||
196 | EXPORT_SYMBOL(matrox_cfbX_init); | 197 | EXPORT_SYMBOL(matrox_cfbX_init); |
197 | 198 | ||
198 | static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx, int height, int width) { | 199 | static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy, |
200 | int sx, int dy, int dx, int height, int width) | ||
201 | { | ||
199 | int start, end; | 202 | int start, end; |
200 | CRITFLAGS | 203 | CRITFLAGS |
201 | 204 | ||
@@ -209,7 +212,7 @@ static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx | |||
209 | M_DWG_BFCOL | M_DWG_REPLACE); | 212 | M_DWG_BFCOL | M_DWG_REPLACE); |
210 | mga_outl(M_AR5, vxres); | 213 | mga_outl(M_AR5, vxres); |
211 | width--; | 214 | width--; |
212 | start = sy*vxres+sx+curr_ydstorg(MINFO); | 215 | start = sy*vxres+sx+curr_ydstorg(minfo); |
213 | end = start+width; | 216 | end = start+width; |
214 | } else { | 217 | } else { |
215 | mga_fifo(3); | 218 | mga_fifo(3); |
@@ -217,7 +220,7 @@ static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx | |||
217 | mga_outl(M_SGN, 5); | 220 | mga_outl(M_SGN, 5); |
218 | mga_outl(M_AR5, -vxres); | 221 | mga_outl(M_AR5, -vxres); |
219 | width--; | 222 | width--; |
220 | end = (sy+height-1)*vxres+sx+curr_ydstorg(MINFO); | 223 | end = (sy+height-1)*vxres+sx+curr_ydstorg(minfo); |
221 | start = end+width; | 224 | start = end+width; |
222 | dy += height-1; | 225 | dy += height-1; |
223 | } | 226 | } |
@@ -231,7 +234,10 @@ static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx | |||
231 | CRITEND | 234 | CRITEND |
232 | } | 235 | } |
233 | 236 | ||
234 | static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, int dx, int height, int width) { | 237 | static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres, |
238 | int sy, int sx, int dy, int dx, int height, | ||
239 | int width) | ||
240 | { | ||
235 | int start, end; | 241 | int start, end; |
236 | CRITFLAGS | 242 | CRITFLAGS |
237 | 243 | ||
@@ -245,7 +251,7 @@ static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, in | |||
245 | M_DWG_BFCOL | M_DWG_REPLACE); | 251 | M_DWG_BFCOL | M_DWG_REPLACE); |
246 | mga_outl(M_AR5, vxres); | 252 | mga_outl(M_AR5, vxres); |
247 | width--; | 253 | width--; |
248 | start = sy*vxres+sx+curr_ydstorg(MINFO); | 254 | start = sy*vxres+sx+curr_ydstorg(minfo); |
249 | end = start+width; | 255 | end = start+width; |
250 | } else { | 256 | } else { |
251 | mga_fifo(3); | 257 | mga_fifo(3); |
@@ -253,7 +259,7 @@ static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, in | |||
253 | mga_outl(M_SGN, 5); | 259 | mga_outl(M_SGN, 5); |
254 | mga_outl(M_AR5, -vxres); | 260 | mga_outl(M_AR5, -vxres); |
255 | width--; | 261 | width--; |
256 | end = (sy+height-1)*vxres+sx+curr_ydstorg(MINFO); | 262 | end = (sy+height-1)*vxres+sx+curr_ydstorg(minfo); |
257 | start = end+width; | 263 | start = end+width; |
258 | dy += height-1; | 264 | dy += height-1; |
259 | } | 265 | } |
@@ -269,22 +275,23 @@ static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, in | |||
269 | } | 275 | } |
270 | 276 | ||
271 | static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area) { | 277 | static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area) { |
272 | MINFO_FROM_INFO(info); | 278 | struct matrox_fb_info *minfo = info2minfo(info); |
273 | 279 | ||
274 | if ((area->sx | area->dx | area->width) & 1) | 280 | if ((area->sx | area->dx | area->width) & 1) |
275 | cfb_copyarea(info, area); | 281 | cfb_copyarea(info, area); |
276 | else | 282 | else |
277 | matrox_accel_bmove_lin(PMINFO ACCESS_FBINFO(fbcon.var.xres_virtual) >> 1, area->sy, area->sx >> 1, area->dy, area->dx >> 1, area->height, area->width >> 1); | 283 | matrox_accel_bmove_lin(minfo, minfo->fbcon.var.xres_virtual >> 1, area->sy, area->sx >> 1, area->dy, area->dx >> 1, area->height, area->width >> 1); |
278 | } | 284 | } |
279 | 285 | ||
280 | static void matroxfb_copyarea(struct fb_info* info, const struct fb_copyarea* area) { | 286 | static void matroxfb_copyarea(struct fb_info* info, const struct fb_copyarea* area) { |
281 | MINFO_FROM_INFO(info); | 287 | struct matrox_fb_info *minfo = info2minfo(info); |
282 | 288 | ||
283 | matrox_accel_bmove(PMINFO ACCESS_FBINFO(fbcon.var.xres_virtual), area->sy, area->sx, area->dy, area->dx, area->height, area->width); | 289 | matrox_accel_bmove(minfo, minfo->fbcon.var.xres_virtual, area->sy, area->sx, area->dy, area->dx, area->height, area->width); |
284 | } | 290 | } |
285 | 291 | ||
286 | static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int height, | 292 | static void matroxfb_accel_clear(struct matrox_fb_info *minfo, u_int32_t color, |
287 | int width) { | 293 | int sy, int sx, int height, int width) |
294 | { | ||
288 | CRITFLAGS | 295 | CRITFLAGS |
289 | 296 | ||
290 | DBG(__func__) | 297 | DBG(__func__) |
@@ -292,7 +299,7 @@ static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int he | |||
292 | CRITBEGIN | 299 | CRITBEGIN |
293 | 300 | ||
294 | mga_fifo(5); | 301 | mga_fifo(5); |
295 | mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE); | 302 | mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE); |
296 | mga_outl(M_FCOL, color); | 303 | mga_outl(M_FCOL, color); |
297 | mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); | 304 | mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); |
298 | mga_ydstlen(sy, height); | 305 | mga_ydstlen(sy, height); |
@@ -302,16 +309,18 @@ static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int he | |||
302 | } | 309 | } |
303 | 310 | ||
304 | static void matroxfb_fillrect(struct fb_info* info, const struct fb_fillrect* rect) { | 311 | static void matroxfb_fillrect(struct fb_info* info, const struct fb_fillrect* rect) { |
305 | MINFO_FROM_INFO(info); | 312 | struct matrox_fb_info *minfo = info2minfo(info); |
306 | 313 | ||
307 | switch (rect->rop) { | 314 | switch (rect->rop) { |
308 | case ROP_COPY: | 315 | case ROP_COPY: |
309 | matroxfb_accel_clear(PMINFO ((u_int32_t*)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width); | 316 | matroxfb_accel_clear(minfo, ((u_int32_t *)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width); |
310 | break; | 317 | break; |
311 | } | 318 | } |
312 | } | 319 | } |
313 | 320 | ||
314 | static void matroxfb_cfb4_clear(WPMINFO u_int32_t bgx, int sy, int sx, int height, int width) { | 321 | static void matroxfb_cfb4_clear(struct matrox_fb_info *minfo, u_int32_t bgx, |
322 | int sy, int sx, int height, int width) | ||
323 | { | ||
315 | int whattodo; | 324 | int whattodo; |
316 | CRITFLAGS | 325 | CRITFLAGS |
317 | 326 | ||
@@ -333,16 +342,16 @@ static void matroxfb_cfb4_clear(WPMINFO u_int32_t bgx, int sy, int sx, int heigh | |||
333 | sx >>= 1; | 342 | sx >>= 1; |
334 | if (width) { | 343 | if (width) { |
335 | mga_fifo(5); | 344 | mga_fifo(5); |
336 | mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE2); | 345 | mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE2); |
337 | mga_outl(M_FCOL, bgx); | 346 | mga_outl(M_FCOL, bgx); |
338 | mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); | 347 | mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); |
339 | mga_outl(M_YDST, sy * ACCESS_FBINFO(fbcon).var.xres_virtual >> 6); | 348 | mga_outl(M_YDST, sy * minfo->fbcon.var.xres_virtual >> 6); |
340 | mga_outl(M_LEN | M_EXEC, height); | 349 | mga_outl(M_LEN | M_EXEC, height); |
341 | WaitTillIdle(); | 350 | WaitTillIdle(); |
342 | } | 351 | } |
343 | if (whattodo) { | 352 | if (whattodo) { |
344 | u_int32_t step = ACCESS_FBINFO(fbcon).var.xres_virtual >> 1; | 353 | u_int32_t step = minfo->fbcon.var.xres_virtual >> 1; |
345 | vaddr_t vbase = ACCESS_FBINFO(video.vbase); | 354 | vaddr_t vbase = minfo->video.vbase; |
346 | if (whattodo & 1) { | 355 | if (whattodo & 1) { |
347 | unsigned int uaddr = sy * step + sx - 1; | 356 | unsigned int uaddr = sy * step + sx - 1; |
348 | u_int32_t loop; | 357 | u_int32_t loop; |
@@ -367,17 +376,19 @@ static void matroxfb_cfb4_clear(WPMINFO u_int32_t bgx, int sy, int sx, int heigh | |||
367 | } | 376 | } |
368 | 377 | ||
369 | static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect) { | 378 | static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect) { |
370 | MINFO_FROM_INFO(info); | 379 | struct matrox_fb_info *minfo = info2minfo(info); |
371 | 380 | ||
372 | switch (rect->rop) { | 381 | switch (rect->rop) { |
373 | case ROP_COPY: | 382 | case ROP_COPY: |
374 | matroxfb_cfb4_clear(PMINFO ((u_int32_t*)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width); | 383 | matroxfb_cfb4_clear(minfo, ((u_int32_t *)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width); |
375 | break; | 384 | break; |
376 | } | 385 | } |
377 | } | 386 | } |
378 | 387 | ||
379 | static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx, | 388 | static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx, |
380 | const u_int8_t* chardata, int width, int height, int yy, int xx) { | 389 | u_int32_t bgx, const u_int8_t *chardata, |
390 | int width, int height, int yy, int xx) | ||
391 | { | ||
381 | u_int32_t step; | 392 | u_int32_t step; |
382 | u_int32_t ydstlen; | 393 | u_int32_t ydstlen; |
383 | u_int32_t xlen; | 394 | u_int32_t xlen; |
@@ -412,7 +423,7 @@ static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx, | |||
412 | mga_outl(M_FCOL, fgx); | 423 | mga_outl(M_FCOL, fgx); |
413 | mga_outl(M_BCOL, bgx); | 424 | mga_outl(M_BCOL, bgx); |
414 | fxbndry = ((xx + width - 1) << 16) | xx; | 425 | fxbndry = ((xx + width - 1) << 16) | xx; |
415 | mmio = ACCESS_FBINFO(mmio.vbase); | 426 | mmio = minfo->mmio.vbase; |
416 | 427 | ||
417 | mga_fifo(6); | 428 | mga_fifo(6); |
418 | mga_writel(mmio, M_FXBNDRY, fxbndry); | 429 | mga_writel(mmio, M_FXBNDRY, fxbndry); |
@@ -467,7 +478,7 @@ static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx, | |||
467 | 478 | ||
468 | 479 | ||
469 | static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* image) { | 480 | static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* image) { |
470 | MINFO_FROM_INFO(info); | 481 | struct matrox_fb_info *minfo = info2minfo(info); |
471 | 482 | ||
472 | DBG_HEAVY(__func__); | 483 | DBG_HEAVY(__func__); |
473 | 484 | ||
@@ -476,7 +487,7 @@ static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* imag | |||
476 | 487 | ||
477 | fgx = ((u_int32_t*)info->pseudo_palette)[image->fg_color]; | 488 | fgx = ((u_int32_t*)info->pseudo_palette)[image->fg_color]; |
478 | bgx = ((u_int32_t*)info->pseudo_palette)[image->bg_color]; | 489 | bgx = ((u_int32_t*)info->pseudo_palette)[image->bg_color]; |
479 | matroxfb_1bpp_imageblit(PMINFO fgx, bgx, image->data, image->width, image->height, image->dy, image->dx); | 490 | matroxfb_1bpp_imageblit(minfo, fgx, bgx, image->data, image->width, image->height, image->dy, image->dx); |
480 | } else { | 491 | } else { |
481 | /* Danger! image->depth is useless: logo painting code always | 492 | /* Danger! image->depth is useless: logo painting code always |
482 | passes framebuffer color depth here, although logo data are | 493 | passes framebuffer color depth here, although logo data are |
diff --git a/drivers/video/matrox/matroxfb_accel.h b/drivers/video/matrox/matroxfb_accel.h index f40c314b4c30..1e418e62c22d 100644 --- a/drivers/video/matrox/matroxfb_accel.h +++ b/drivers/video/matrox/matroxfb_accel.h | |||
@@ -3,6 +3,6 @@ | |||
3 | 3 | ||
4 | #include "matroxfb_base.h" | 4 | #include "matroxfb_base.h" |
5 | 5 | ||
6 | void matrox_cfbX_init(WPMINFO2); | 6 | void matrox_cfbX_init(struct matrox_fb_info *minfo); |
7 | 7 | ||
8 | #endif | 8 | #endif |
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 8e7a275df50c..7064fb4427b6 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c | |||
@@ -154,21 +154,22 @@ static struct fb_var_screeninfo vesafb_defined = { | |||
154 | 154 | ||
155 | 155 | ||
156 | /* --------------------------------------------------------------------- */ | 156 | /* --------------------------------------------------------------------- */ |
157 | static void update_crtc2(WPMINFO unsigned int pos) { | 157 | static void update_crtc2(struct matrox_fb_info *minfo, unsigned int pos) |
158 | struct matroxfb_dh_fb_info* info = ACCESS_FBINFO(crtc2.info); | 158 | { |
159 | struct matroxfb_dh_fb_info *info = minfo->crtc2.info; | ||
159 | 160 | ||
160 | /* Make sure that displays are compatible */ | 161 | /* Make sure that displays are compatible */ |
161 | if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) | 162 | if (info && (info->fbcon.var.bits_per_pixel == minfo->fbcon.var.bits_per_pixel) |
162 | && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) | 163 | && (info->fbcon.var.xres_virtual == minfo->fbcon.var.xres_virtual) |
163 | && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) | 164 | && (info->fbcon.var.green.length == minfo->fbcon.var.green.length) |
164 | ) { | 165 | ) { |
165 | switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { | 166 | switch (minfo->fbcon.var.bits_per_pixel) { |
166 | case 16: | 167 | case 16: |
167 | case 32: | 168 | case 32: |
168 | pos = pos * 8; | 169 | pos = pos * 8; |
169 | if (info->interlaced) { | 170 | if (info->interlaced) { |
170 | mga_outl(0x3C2C, pos); | 171 | mga_outl(0x3C2C, pos); |
171 | mga_outl(0x3C28, pos + ACCESS_FBINFO(fbcon).var.xres_virtual * ACCESS_FBINFO(fbcon).var.bits_per_pixel / 8); | 172 | mga_outl(0x3C28, pos + minfo->fbcon.var.xres_virtual * minfo->fbcon.var.bits_per_pixel / 8); |
172 | } else { | 173 | } else { |
173 | mga_outl(0x3C28, pos); | 174 | mga_outl(0x3C28, pos); |
174 | } | 175 | } |
@@ -177,17 +178,18 @@ static void update_crtc2(WPMINFO unsigned int pos) { | |||
177 | } | 178 | } |
178 | } | 179 | } |
179 | 180 | ||
180 | static void matroxfb_crtc1_panpos(WPMINFO2) { | 181 | static void matroxfb_crtc1_panpos(struct matrox_fb_info *minfo) |
181 | if (ACCESS_FBINFO(crtc1.panpos) >= 0) { | 182 | { |
183 | if (minfo->crtc1.panpos >= 0) { | ||
182 | unsigned long flags; | 184 | unsigned long flags; |
183 | int panpos; | 185 | int panpos; |
184 | 186 | ||
185 | matroxfb_DAC_lock_irqsave(flags); | 187 | matroxfb_DAC_lock_irqsave(flags); |
186 | panpos = ACCESS_FBINFO(crtc1.panpos); | 188 | panpos = minfo->crtc1.panpos; |
187 | if (panpos >= 0) { | 189 | if (panpos >= 0) { |
188 | unsigned int extvga_reg; | 190 | unsigned int extvga_reg; |
189 | 191 | ||
190 | ACCESS_FBINFO(crtc1.panpos) = -1; /* No update pending anymore */ | 192 | minfo->crtc1.panpos = -1; /* No update pending anymore */ |
191 | extvga_reg = mga_inb(M_EXTVGA_INDEX); | 193 | extvga_reg = mga_inb(M_EXTVGA_INDEX); |
192 | mga_setr(M_EXTVGA_INDEX, 0x00, panpos); | 194 | mga_setr(M_EXTVGA_INDEX, 0x00, panpos); |
193 | if (extvga_reg != 0x00) { | 195 | if (extvga_reg != 0x00) { |
@@ -202,39 +204,39 @@ static irqreturn_t matrox_irq(int irq, void *dev_id) | |||
202 | { | 204 | { |
203 | u_int32_t status; | 205 | u_int32_t status; |
204 | int handled = 0; | 206 | int handled = 0; |
205 | 207 | struct matrox_fb_info *minfo = dev_id; | |
206 | MINFO_FROM(dev_id); | ||
207 | 208 | ||
208 | status = mga_inl(M_STATUS); | 209 | status = mga_inl(M_STATUS); |
209 | 210 | ||
210 | if (status & 0x20) { | 211 | if (status & 0x20) { |
211 | mga_outl(M_ICLEAR, 0x20); | 212 | mga_outl(M_ICLEAR, 0x20); |
212 | ACCESS_FBINFO(crtc1.vsync.cnt)++; | 213 | minfo->crtc1.vsync.cnt++; |
213 | matroxfb_crtc1_panpos(PMINFO2); | 214 | matroxfb_crtc1_panpos(minfo); |
214 | wake_up_interruptible(&ACCESS_FBINFO(crtc1.vsync.wait)); | 215 | wake_up_interruptible(&minfo->crtc1.vsync.wait); |
215 | handled = 1; | 216 | handled = 1; |
216 | } | 217 | } |
217 | if (status & 0x200) { | 218 | if (status & 0x200) { |
218 | mga_outl(M_ICLEAR, 0x200); | 219 | mga_outl(M_ICLEAR, 0x200); |
219 | ACCESS_FBINFO(crtc2.vsync.cnt)++; | 220 | minfo->crtc2.vsync.cnt++; |
220 | wake_up_interruptible(&ACCESS_FBINFO(crtc2.vsync.wait)); | 221 | wake_up_interruptible(&minfo->crtc2.vsync.wait); |
221 | handled = 1; | 222 | handled = 1; |
222 | } | 223 | } |
223 | return IRQ_RETVAL(handled); | 224 | return IRQ_RETVAL(handled); |
224 | } | 225 | } |
225 | 226 | ||
226 | int matroxfb_enable_irq(WPMINFO int reenable) { | 227 | int matroxfb_enable_irq(struct matrox_fb_info *minfo, int reenable) |
228 | { | ||
227 | u_int32_t bm; | 229 | u_int32_t bm; |
228 | 230 | ||
229 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) | 231 | if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) |
230 | bm = 0x220; | 232 | bm = 0x220; |
231 | else | 233 | else |
232 | bm = 0x020; | 234 | bm = 0x020; |
233 | 235 | ||
234 | if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) { | 236 | if (!test_and_set_bit(0, &minfo->irq_flags)) { |
235 | if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq, | 237 | if (request_irq(minfo->pcidev->irq, matrox_irq, |
236 | IRQF_SHARED, "matroxfb", MINFO)) { | 238 | IRQF_SHARED, "matroxfb", minfo)) { |
237 | clear_bit(0, &ACCESS_FBINFO(irq_flags)); | 239 | clear_bit(0, &minfo->irq_flags); |
238 | return -EINVAL; | 240 | return -EINVAL; |
239 | } | 241 | } |
240 | /* Clear any pending field interrupts */ | 242 | /* Clear any pending field interrupts */ |
@@ -252,37 +254,39 @@ int matroxfb_enable_irq(WPMINFO int reenable) { | |||
252 | return 0; | 254 | return 0; |
253 | } | 255 | } |
254 | 256 | ||
255 | static void matroxfb_disable_irq(WPMINFO2) { | 257 | static void matroxfb_disable_irq(struct matrox_fb_info *minfo) |
256 | if (test_and_clear_bit(0, &ACCESS_FBINFO(irq_flags))) { | 258 | { |
259 | if (test_and_clear_bit(0, &minfo->irq_flags)) { | ||
257 | /* Flush pending pan-at-vbl request... */ | 260 | /* Flush pending pan-at-vbl request... */ |
258 | matroxfb_crtc1_panpos(PMINFO2); | 261 | matroxfb_crtc1_panpos(minfo); |
259 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) | 262 | if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) |
260 | mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220); | 263 | mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220); |
261 | else | 264 | else |
262 | mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20); | 265 | mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20); |
263 | free_irq(ACCESS_FBINFO(pcidev)->irq, MINFO); | 266 | free_irq(minfo->pcidev->irq, minfo); |
264 | } | 267 | } |
265 | } | 268 | } |
266 | 269 | ||
267 | int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { | 270 | int matroxfb_wait_for_sync(struct matrox_fb_info *minfo, u_int32_t crtc) |
271 | { | ||
268 | struct matrox_vsync *vs; | 272 | struct matrox_vsync *vs; |
269 | unsigned int cnt; | 273 | unsigned int cnt; |
270 | int ret; | 274 | int ret; |
271 | 275 | ||
272 | switch (crtc) { | 276 | switch (crtc) { |
273 | case 0: | 277 | case 0: |
274 | vs = &ACCESS_FBINFO(crtc1.vsync); | 278 | vs = &minfo->crtc1.vsync; |
275 | break; | 279 | break; |
276 | case 1: | 280 | case 1: |
277 | if (ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG400) { | 281 | if (minfo->devflags.accelerator != FB_ACCEL_MATROX_MGAG400) { |
278 | return -ENODEV; | 282 | return -ENODEV; |
279 | } | 283 | } |
280 | vs = &ACCESS_FBINFO(crtc2.vsync); | 284 | vs = &minfo->crtc2.vsync; |
281 | break; | 285 | break; |
282 | default: | 286 | default: |
283 | return -ENODEV; | 287 | return -ENODEV; |
284 | } | 288 | } |
285 | ret = matroxfb_enable_irq(PMINFO 0); | 289 | ret = matroxfb_enable_irq(minfo, 0); |
286 | if (ret) { | 290 | if (ret) { |
287 | return ret; | 291 | return ret; |
288 | } | 292 | } |
@@ -293,7 +297,7 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { | |||
293 | return ret; | 297 | return ret; |
294 | } | 298 | } |
295 | if (ret == 0) { | 299 | if (ret == 0) { |
296 | matroxfb_enable_irq(PMINFO 1); | 300 | matroxfb_enable_irq(minfo, 1); |
297 | return -ETIMEDOUT; | 301 | return -ETIMEDOUT; |
298 | } | 302 | } |
299 | return 0; | 303 | return 0; |
@@ -301,12 +305,12 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { | |||
301 | 305 | ||
302 | /* --------------------------------------------------------------------- */ | 306 | /* --------------------------------------------------------------------- */ |
303 | 307 | ||
304 | static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { | 308 | static void matrox_pan_var(struct matrox_fb_info *minfo, |
309 | struct fb_var_screeninfo *var) | ||
310 | { | ||
305 | unsigned int pos; | 311 | unsigned int pos; |
306 | unsigned short p0, p1, p2; | 312 | unsigned short p0, p1, p2; |
307 | #ifdef CONFIG_FB_MATROX_32MB | ||
308 | unsigned int p3; | 313 | unsigned int p3; |
309 | #endif | ||
310 | int vbl; | 314 | int vbl; |
311 | unsigned long flags; | 315 | unsigned long flags; |
312 | 316 | ||
@@ -314,47 +318,44 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { | |||
314 | 318 | ||
315 | DBG(__func__) | 319 | DBG(__func__) |
316 | 320 | ||
317 | if (ACCESS_FBINFO(dead)) | 321 | if (minfo->dead) |
318 | return; | 322 | return; |
319 | 323 | ||
320 | ACCESS_FBINFO(fbcon).var.xoffset = var->xoffset; | 324 | minfo->fbcon.var.xoffset = var->xoffset; |
321 | ACCESS_FBINFO(fbcon).var.yoffset = var->yoffset; | 325 | minfo->fbcon.var.yoffset = var->yoffset; |
322 | pos = (ACCESS_FBINFO(fbcon).var.yoffset * ACCESS_FBINFO(fbcon).var.xres_virtual + ACCESS_FBINFO(fbcon).var.xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32; | 326 | pos = (minfo->fbcon.var.yoffset * minfo->fbcon.var.xres_virtual + minfo->fbcon.var.xoffset) * minfo->curr.final_bppShift / 32; |
323 | pos += ACCESS_FBINFO(curr.ydstorg.chunks); | 327 | pos += minfo->curr.ydstorg.chunks; |
324 | p0 = ACCESS_FBINFO(hw).CRTC[0x0D] = pos & 0xFF; | 328 | p0 = minfo->hw.CRTC[0x0D] = pos & 0xFF; |
325 | p1 = ACCESS_FBINFO(hw).CRTC[0x0C] = (pos & 0xFF00) >> 8; | 329 | p1 = minfo->hw.CRTC[0x0C] = (pos & 0xFF00) >> 8; |
326 | p2 = ACCESS_FBINFO(hw).CRTCEXT[0] = (ACCESS_FBINFO(hw).CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); | 330 | p2 = minfo->hw.CRTCEXT[0] = (minfo->hw.CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); |
327 | #ifdef CONFIG_FB_MATROX_32MB | 331 | p3 = minfo->hw.CRTCEXT[8] = pos >> 21; |
328 | p3 = ACCESS_FBINFO(hw).CRTCEXT[8] = pos >> 21; | ||
329 | #endif | ||
330 | 332 | ||
331 | /* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */ | 333 | /* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */ |
332 | vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(PMINFO 0) == 0); | 334 | vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(minfo, 0) == 0); |
333 | 335 | ||
334 | CRITBEGIN | 336 | CRITBEGIN |
335 | 337 | ||
336 | matroxfb_DAC_lock_irqsave(flags); | 338 | matroxfb_DAC_lock_irqsave(flags); |
337 | mga_setr(M_CRTC_INDEX, 0x0D, p0); | 339 | mga_setr(M_CRTC_INDEX, 0x0D, p0); |
338 | mga_setr(M_CRTC_INDEX, 0x0C, p1); | 340 | mga_setr(M_CRTC_INDEX, 0x0C, p1); |
339 | #ifdef CONFIG_FB_MATROX_32MB | 341 | if (minfo->devflags.support32MB) |
340 | if (ACCESS_FBINFO(devflags.support32MB)) | ||
341 | mga_setr(M_EXTVGA_INDEX, 0x08, p3); | 342 | mga_setr(M_EXTVGA_INDEX, 0x08, p3); |
342 | #endif | ||
343 | if (vbl) { | 343 | if (vbl) { |
344 | ACCESS_FBINFO(crtc1.panpos) = p2; | 344 | minfo->crtc1.panpos = p2; |
345 | } else { | 345 | } else { |
346 | /* Abort any pending change */ | 346 | /* Abort any pending change */ |
347 | ACCESS_FBINFO(crtc1.panpos) = -1; | 347 | minfo->crtc1.panpos = -1; |
348 | mga_setr(M_EXTVGA_INDEX, 0x00, p2); | 348 | mga_setr(M_EXTVGA_INDEX, 0x00, p2); |
349 | } | 349 | } |
350 | matroxfb_DAC_unlock_irqrestore(flags); | 350 | matroxfb_DAC_unlock_irqrestore(flags); |
351 | 351 | ||
352 | update_crtc2(PMINFO pos); | 352 | update_crtc2(minfo, pos); |
353 | 353 | ||
354 | CRITEND | 354 | CRITEND |
355 | } | 355 | } |
356 | 356 | ||
357 | static void matroxfb_remove(WPMINFO int dummy) { | 357 | static void matroxfb_remove(struct matrox_fb_info *minfo, int dummy) |
358 | { | ||
358 | /* Currently we are holding big kernel lock on all dead & usecount updates. | 359 | /* Currently we are holding big kernel lock on all dead & usecount updates. |
359 | * Destroy everything after all users release it. Especially do not unregister | 360 | * Destroy everything after all users release it. Especially do not unregister |
360 | * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check | 361 | * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check |
@@ -363,25 +364,23 @@ static void matroxfb_remove(WPMINFO int dummy) { | |||
363 | * write data without causing too much damage... | 364 | * write data without causing too much damage... |
364 | */ | 365 | */ |
365 | 366 | ||
366 | ACCESS_FBINFO(dead) = 1; | 367 | minfo->dead = 1; |
367 | if (ACCESS_FBINFO(usecount)) { | 368 | if (minfo->usecount) { |
368 | /* destroy it later */ | 369 | /* destroy it later */ |
369 | return; | 370 | return; |
370 | } | 371 | } |
371 | matroxfb_unregister_device(MINFO); | 372 | matroxfb_unregister_device(minfo); |
372 | unregister_framebuffer(&ACCESS_FBINFO(fbcon)); | 373 | unregister_framebuffer(&minfo->fbcon); |
373 | matroxfb_g450_shutdown(PMINFO2); | 374 | matroxfb_g450_shutdown(minfo); |
374 | #ifdef CONFIG_MTRR | 375 | #ifdef CONFIG_MTRR |
375 | if (ACCESS_FBINFO(mtrr.vram_valid)) | 376 | if (minfo->mtrr.vram_valid) |
376 | mtrr_del(ACCESS_FBINFO(mtrr.vram), ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len)); | 377 | mtrr_del(minfo->mtrr.vram, minfo->video.base, minfo->video.len); |
377 | #endif | 378 | #endif |
378 | mga_iounmap(ACCESS_FBINFO(mmio.vbase)); | 379 | mga_iounmap(minfo->mmio.vbase); |
379 | mga_iounmap(ACCESS_FBINFO(video.vbase)); | 380 | mga_iounmap(minfo->video.vbase); |
380 | release_mem_region(ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len_maximum)); | 381 | release_mem_region(minfo->video.base, minfo->video.len_maximum); |
381 | release_mem_region(ACCESS_FBINFO(mmio.base), 16384); | 382 | release_mem_region(minfo->mmio.base, 16384); |
382 | #ifdef CONFIG_FB_MATROX_MULTIHEAD | ||
383 | kfree(minfo); | 383 | kfree(minfo); |
384 | #endif | ||
385 | } | 384 | } |
386 | 385 | ||
387 | /* | 386 | /* |
@@ -390,48 +389,50 @@ static void matroxfb_remove(WPMINFO int dummy) { | |||
390 | 389 | ||
391 | static int matroxfb_open(struct fb_info *info, int user) | 390 | static int matroxfb_open(struct fb_info *info, int user) |
392 | { | 391 | { |
393 | MINFO_FROM_INFO(info); | 392 | struct matrox_fb_info *minfo = info2minfo(info); |
394 | 393 | ||
395 | DBG_LOOP(__func__) | 394 | DBG_LOOP(__func__) |
396 | 395 | ||
397 | if (ACCESS_FBINFO(dead)) { | 396 | if (minfo->dead) { |
398 | return -ENXIO; | 397 | return -ENXIO; |
399 | } | 398 | } |
400 | ACCESS_FBINFO(usecount)++; | 399 | minfo->usecount++; |
401 | if (user) { | 400 | if (user) { |
402 | ACCESS_FBINFO(userusecount)++; | 401 | minfo->userusecount++; |
403 | } | 402 | } |
404 | return(0); | 403 | return(0); |
405 | } | 404 | } |
406 | 405 | ||
407 | static int matroxfb_release(struct fb_info *info, int user) | 406 | static int matroxfb_release(struct fb_info *info, int user) |
408 | { | 407 | { |
409 | MINFO_FROM_INFO(info); | 408 | struct matrox_fb_info *minfo = info2minfo(info); |
410 | 409 | ||
411 | DBG_LOOP(__func__) | 410 | DBG_LOOP(__func__) |
412 | 411 | ||
413 | if (user) { | 412 | if (user) { |
414 | if (0 == --ACCESS_FBINFO(userusecount)) { | 413 | if (0 == --minfo->userusecount) { |
415 | matroxfb_disable_irq(PMINFO2); | 414 | matroxfb_disable_irq(minfo); |
416 | } | 415 | } |
417 | } | 416 | } |
418 | if (!(--ACCESS_FBINFO(usecount)) && ACCESS_FBINFO(dead)) { | 417 | if (!(--minfo->usecount) && minfo->dead) { |
419 | matroxfb_remove(PMINFO 0); | 418 | matroxfb_remove(minfo, 0); |
420 | } | 419 | } |
421 | return(0); | 420 | return(0); |
422 | } | 421 | } |
423 | 422 | ||
424 | static int matroxfb_pan_display(struct fb_var_screeninfo *var, | 423 | static int matroxfb_pan_display(struct fb_var_screeninfo *var, |
425 | struct fb_info* info) { | 424 | struct fb_info* info) { |
426 | MINFO_FROM_INFO(info); | 425 | struct matrox_fb_info *minfo = info2minfo(info); |
427 | 426 | ||
428 | DBG(__func__) | 427 | DBG(__func__) |
429 | 428 | ||
430 | matrox_pan_var(PMINFO var); | 429 | matrox_pan_var(minfo, var); |
431 | return 0; | 430 | return 0; |
432 | } | 431 | } |
433 | 432 | ||
434 | static int matroxfb_get_final_bppShift(CPMINFO int bpp) { | 433 | static int matroxfb_get_final_bppShift(const struct matrox_fb_info *minfo, |
434 | int bpp) | ||
435 | { | ||
435 | int bppshft2; | 436 | int bppshft2; |
436 | 437 | ||
437 | DBG(__func__) | 438 | DBG(__func__) |
@@ -440,14 +441,16 @@ static int matroxfb_get_final_bppShift(CPMINFO int bpp) { | |||
440 | if (!bppshft2) { | 441 | if (!bppshft2) { |
441 | return 8; | 442 | return 8; |
442 | } | 443 | } |
443 | if (isInterleave(MINFO)) | 444 | if (isInterleave(minfo)) |
444 | bppshft2 >>= 1; | 445 | bppshft2 >>= 1; |
445 | if (ACCESS_FBINFO(devflags.video64bits)) | 446 | if (minfo->devflags.video64bits) |
446 | bppshft2 >>= 1; | 447 | bppshft2 >>= 1; |
447 | return bppshft2; | 448 | return bppshft2; |
448 | } | 449 | } |
449 | 450 | ||
450 | static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) { | 451 | static int matroxfb_test_and_set_rounding(const struct matrox_fb_info *minfo, |
452 | int xres, int bpp) | ||
453 | { | ||
451 | int over; | 454 | int over; |
452 | int rounding; | 455 | int rounding; |
453 | 456 | ||
@@ -465,11 +468,11 @@ static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) { | |||
465 | break; | 468 | break; |
466 | default: rounding = 16; | 469 | default: rounding = 16; |
467 | /* on G400, 16 really does not work */ | 470 | /* on G400, 16 really does not work */ |
468 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) | 471 | if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) |
469 | rounding = 32; | 472 | rounding = 32; |
470 | break; | 473 | break; |
471 | } | 474 | } |
472 | if (isInterleave(MINFO)) { | 475 | if (isInterleave(minfo)) { |
473 | rounding *= 2; | 476 | rounding *= 2; |
474 | } | 477 | } |
475 | over = xres % rounding; | 478 | over = xres % rounding; |
@@ -478,7 +481,9 @@ static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) { | |||
478 | return xres; | 481 | return xres; |
479 | } | 482 | } |
480 | 483 | ||
481 | static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) { | 484 | static int matroxfb_pitch_adjust(const struct matrox_fb_info *minfo, int xres, |
485 | int bpp) | ||
486 | { | ||
482 | const int* width; | 487 | const int* width; |
483 | int xres_new; | 488 | int xres_new; |
484 | 489 | ||
@@ -486,18 +491,18 @@ static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) { | |||
486 | 491 | ||
487 | if (!bpp) return xres; | 492 | if (!bpp) return xres; |
488 | 493 | ||
489 | width = ACCESS_FBINFO(capable.vxres); | 494 | width = minfo->capable.vxres; |
490 | 495 | ||
491 | if (ACCESS_FBINFO(devflags.precise_width)) { | 496 | if (minfo->devflags.precise_width) { |
492 | while (*width) { | 497 | while (*width) { |
493 | if ((*width >= xres) && (matroxfb_test_and_set_rounding(PMINFO *width, bpp) == *width)) { | 498 | if ((*width >= xres) && (matroxfb_test_and_set_rounding(minfo, *width, bpp) == *width)) { |
494 | break; | 499 | break; |
495 | } | 500 | } |
496 | width++; | 501 | width++; |
497 | } | 502 | } |
498 | xres_new = *width; | 503 | xres_new = *width; |
499 | } else { | 504 | } else { |
500 | xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp); | 505 | xres_new = matroxfb_test_and_set_rounding(minfo, xres, bpp); |
501 | } | 506 | } |
502 | return xres_new; | 507 | return xres_new; |
503 | } | 508 | } |
@@ -524,7 +529,10 @@ static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) { | |||
524 | return 16; /* return something reasonable... or panic()? */ | 529 | return 16; /* return something reasonable... or panic()? */ |
525 | } | 530 | } |
526 | 531 | ||
527 | static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visual, int *video_cmap_len, unsigned int* ydstorg) { | 532 | static int matroxfb_decode_var(const struct matrox_fb_info *minfo, |
533 | struct fb_var_screeninfo *var, int *visual, | ||
534 | int *video_cmap_len, unsigned int* ydstorg) | ||
535 | { | ||
528 | struct RGBT { | 536 | struct RGBT { |
529 | unsigned char bpp; | 537 | unsigned char bpp; |
530 | struct { | 538 | struct { |
@@ -551,7 +559,7 @@ static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visua | |||
551 | DBG(__func__) | 559 | DBG(__func__) |
552 | 560 | ||
553 | switch (bpp) { | 561 | switch (bpp) { |
554 | case 4: if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL; | 562 | case 4: if (!minfo->capable.cfb4) return -EINVAL; |
555 | break; | 563 | break; |
556 | case 8: break; | 564 | case 8: break; |
557 | case 16: break; | 565 | case 16: break; |
@@ -560,13 +568,13 @@ static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visua | |||
560 | default: return -EINVAL; | 568 | default: return -EINVAL; |
561 | } | 569 | } |
562 | *ydstorg = 0; | 570 | *ydstorg = 0; |
563 | vramlen = ACCESS_FBINFO(video.len_usable); | 571 | vramlen = minfo->video.len_usable; |
564 | if (var->yres_virtual < var->yres) | 572 | if (var->yres_virtual < var->yres) |
565 | var->yres_virtual = var->yres; | 573 | var->yres_virtual = var->yres; |
566 | if (var->xres_virtual < var->xres) | 574 | if (var->xres_virtual < var->xres) |
567 | var->xres_virtual = var->xres; | 575 | var->xres_virtual = var->xres; |
568 | 576 | ||
569 | var->xres_virtual = matroxfb_pitch_adjust(PMINFO var->xres_virtual, bpp); | 577 | var->xres_virtual = matroxfb_pitch_adjust(minfo, var->xres_virtual, bpp); |
570 | memlen = var->xres_virtual * bpp * var->yres_virtual / 8; | 578 | memlen = var->xres_virtual * bpp * var->yres_virtual / 8; |
571 | if (memlen > vramlen) { | 579 | if (memlen > vramlen) { |
572 | var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp); | 580 | var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp); |
@@ -575,7 +583,7 @@ static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visua | |||
575 | /* There is hardware bug that no line can cross 4MB boundary */ | 583 | /* There is hardware bug that no line can cross 4MB boundary */ |
576 | /* give up for CFB24, it is impossible to easy workaround it */ | 584 | /* give up for CFB24, it is impossible to easy workaround it */ |
577 | /* for other try to do something */ | 585 | /* for other try to do something */ |
578 | if (!ACCESS_FBINFO(capable.cross4MB) && (memlen > 0x400000)) { | 586 | if (!minfo->capable.cross4MB && (memlen > 0x400000)) { |
579 | if (bpp == 24) { | 587 | if (bpp == 24) { |
580 | /* sorry */ | 588 | /* sorry */ |
581 | } else { | 589 | } else { |
@@ -644,9 +652,7 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
644 | unsigned blue, unsigned transp, | 652 | unsigned blue, unsigned transp, |
645 | struct fb_info *fb_info) | 653 | struct fb_info *fb_info) |
646 | { | 654 | { |
647 | #ifdef CONFIG_FB_MATROX_MULTIHEAD | ||
648 | struct matrox_fb_info* minfo = container_of(fb_info, struct matrox_fb_info, fbcon); | 655 | struct matrox_fb_info* minfo = container_of(fb_info, struct matrox_fb_info, fbcon); |
649 | #endif | ||
650 | 656 | ||
651 | DBG(__func__) | 657 | DBG(__func__) |
652 | 658 | ||
@@ -657,20 +663,20 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
657 | * != 0 for invalid regno. | 663 | * != 0 for invalid regno. |
658 | */ | 664 | */ |
659 | 665 | ||
660 | if (regno >= ACCESS_FBINFO(curr.cmap_len)) | 666 | if (regno >= minfo->curr.cmap_len) |
661 | return 1; | 667 | return 1; |
662 | 668 | ||
663 | if (ACCESS_FBINFO(fbcon).var.grayscale) { | 669 | if (minfo->fbcon.var.grayscale) { |
664 | /* gray = 0.30*R + 0.59*G + 0.11*B */ | 670 | /* gray = 0.30*R + 0.59*G + 0.11*B */ |
665 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | 671 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; |
666 | } | 672 | } |
667 | 673 | ||
668 | red = CNVT_TOHW(red, ACCESS_FBINFO(fbcon).var.red.length); | 674 | red = CNVT_TOHW(red, minfo->fbcon.var.red.length); |
669 | green = CNVT_TOHW(green, ACCESS_FBINFO(fbcon).var.green.length); | 675 | green = CNVT_TOHW(green, minfo->fbcon.var.green.length); |
670 | blue = CNVT_TOHW(blue, ACCESS_FBINFO(fbcon).var.blue.length); | 676 | blue = CNVT_TOHW(blue, minfo->fbcon.var.blue.length); |
671 | transp = CNVT_TOHW(transp, ACCESS_FBINFO(fbcon).var.transp.length); | 677 | transp = CNVT_TOHW(transp, minfo->fbcon.var.transp.length); |
672 | 678 | ||
673 | switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { | 679 | switch (minfo->fbcon.var.bits_per_pixel) { |
674 | case 4: | 680 | case 4: |
675 | case 8: | 681 | case 8: |
676 | mga_outb(M_DAC_REG, regno); | 682 | mga_outb(M_DAC_REG, regno); |
@@ -683,30 +689,30 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
683 | break; | 689 | break; |
684 | { | 690 | { |
685 | u_int16_t col = | 691 | u_int16_t col = |
686 | (red << ACCESS_FBINFO(fbcon).var.red.offset) | | 692 | (red << minfo->fbcon.var.red.offset) | |
687 | (green << ACCESS_FBINFO(fbcon).var.green.offset) | | 693 | (green << minfo->fbcon.var.green.offset) | |
688 | (blue << ACCESS_FBINFO(fbcon).var.blue.offset) | | 694 | (blue << minfo->fbcon.var.blue.offset) | |
689 | (transp << ACCESS_FBINFO(fbcon).var.transp.offset); /* for 1:5:5:5 */ | 695 | (transp << minfo->fbcon.var.transp.offset); /* for 1:5:5:5 */ |
690 | ACCESS_FBINFO(cmap[regno]) = col | (col << 16); | 696 | minfo->cmap[regno] = col | (col << 16); |
691 | } | 697 | } |
692 | break; | 698 | break; |
693 | case 24: | 699 | case 24: |
694 | case 32: | 700 | case 32: |
695 | if (regno >= 16) | 701 | if (regno >= 16) |
696 | break; | 702 | break; |
697 | ACCESS_FBINFO(cmap[regno]) = | 703 | minfo->cmap[regno] = |
698 | (red << ACCESS_FBINFO(fbcon).var.red.offset) | | 704 | (red << minfo->fbcon.var.red.offset) | |
699 | (green << ACCESS_FBINFO(fbcon).var.green.offset) | | 705 | (green << minfo->fbcon.var.green.offset) | |
700 | (blue << ACCESS_FBINFO(fbcon).var.blue.offset) | | 706 | (blue << minfo->fbcon.var.blue.offset) | |
701 | (transp << ACCESS_FBINFO(fbcon).var.transp.offset); /* 8:8:8:8 */ | 707 | (transp << minfo->fbcon.var.transp.offset); /* 8:8:8:8 */ |
702 | break; | 708 | break; |
703 | } | 709 | } |
704 | return 0; | 710 | return 0; |
705 | } | 711 | } |
706 | 712 | ||
707 | static void matroxfb_init_fix(WPMINFO2) | 713 | static void matroxfb_init_fix(struct matrox_fb_info *minfo) |
708 | { | 714 | { |
709 | struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; | 715 | struct fb_fix_screeninfo *fix = &minfo->fbcon.fix; |
710 | DBG(__func__) | 716 | DBG(__func__) |
711 | 717 | ||
712 | strcpy(fix->id,"MATROX"); | 718 | strcpy(fix->id,"MATROX"); |
@@ -714,18 +720,20 @@ static void matroxfb_init_fix(WPMINFO2) | |||
714 | fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */ | 720 | fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */ |
715 | fix->ypanstep = 1; | 721 | fix->ypanstep = 1; |
716 | fix->ywrapstep = 0; | 722 | fix->ywrapstep = 0; |
717 | fix->mmio_start = ACCESS_FBINFO(mmio.base); | 723 | fix->mmio_start = minfo->mmio.base; |
718 | fix->mmio_len = ACCESS_FBINFO(mmio.len); | 724 | fix->mmio_len = minfo->mmio.len; |
719 | fix->accel = ACCESS_FBINFO(devflags.accelerator); | 725 | fix->accel = minfo->devflags.accelerator; |
720 | } | 726 | } |
721 | 727 | ||
722 | static void matroxfb_update_fix(WPMINFO2) | 728 | static void matroxfb_update_fix(struct matrox_fb_info *minfo) |
723 | { | 729 | { |
724 | struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; | 730 | struct fb_fix_screeninfo *fix = &minfo->fbcon.fix; |
725 | DBG(__func__) | 731 | DBG(__func__) |
726 | 732 | ||
727 | fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); | 733 | mutex_lock(&minfo->fbcon.mm_lock); |
728 | fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); | 734 | fix->smem_start = minfo->video.base + minfo->curr.ydstorg.bytes; |
735 | fix->smem_len = minfo->video.len_usable - minfo->curr.ydstorg.bytes; | ||
736 | mutex_unlock(&minfo->fbcon.mm_lock); | ||
729 | } | 737 | } |
730 | 738 | ||
731 | static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 739 | static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
@@ -734,12 +742,12 @@ static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf | |||
734 | int visual; | 742 | int visual; |
735 | int cmap_len; | 743 | int cmap_len; |
736 | unsigned int ydstorg; | 744 | unsigned int ydstorg; |
737 | MINFO_FROM_INFO(info); | 745 | struct matrox_fb_info *minfo = info2minfo(info); |
738 | 746 | ||
739 | if (ACCESS_FBINFO(dead)) { | 747 | if (minfo->dead) { |
740 | return -ENXIO; | 748 | return -ENXIO; |
741 | } | 749 | } |
742 | if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0) | 750 | if ((err = matroxfb_decode_var(minfo, var, &visual, &cmap_len, &ydstorg)) != 0) |
743 | return err; | 751 | return err; |
744 | return 0; | 752 | return 0; |
745 | } | 753 | } |
@@ -751,35 +759,35 @@ static int matroxfb_set_par(struct fb_info *info) | |||
751 | int cmap_len; | 759 | int cmap_len; |
752 | unsigned int ydstorg; | 760 | unsigned int ydstorg; |
753 | struct fb_var_screeninfo *var; | 761 | struct fb_var_screeninfo *var; |
754 | MINFO_FROM_INFO(info); | 762 | struct matrox_fb_info *minfo = info2minfo(info); |
755 | 763 | ||
756 | DBG(__func__) | 764 | DBG(__func__) |
757 | 765 | ||
758 | if (ACCESS_FBINFO(dead)) { | 766 | if (minfo->dead) { |
759 | return -ENXIO; | 767 | return -ENXIO; |
760 | } | 768 | } |
761 | 769 | ||
762 | var = &info->var; | 770 | var = &info->var; |
763 | if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0) | 771 | if ((err = matroxfb_decode_var(minfo, var, &visual, &cmap_len, &ydstorg)) != 0) |
764 | return err; | 772 | return err; |
765 | ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg; | 773 | minfo->fbcon.screen_base = vaddr_va(minfo->video.vbase) + ydstorg; |
766 | matroxfb_update_fix(PMINFO2); | 774 | matroxfb_update_fix(minfo); |
767 | ACCESS_FBINFO(fbcon).fix.visual = visual; | 775 | minfo->fbcon.fix.visual = visual; |
768 | ACCESS_FBINFO(fbcon).fix.type = FB_TYPE_PACKED_PIXELS; | 776 | minfo->fbcon.fix.type = FB_TYPE_PACKED_PIXELS; |
769 | ACCESS_FBINFO(fbcon).fix.type_aux = 0; | 777 | minfo->fbcon.fix.type_aux = 0; |
770 | ACCESS_FBINFO(fbcon).fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3; | 778 | minfo->fbcon.fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3; |
771 | { | 779 | { |
772 | unsigned int pos; | 780 | unsigned int pos; |
773 | 781 | ||
774 | ACCESS_FBINFO(curr.cmap_len) = cmap_len; | 782 | minfo->curr.cmap_len = cmap_len; |
775 | ydstorg += ACCESS_FBINFO(devflags.ydstorg); | 783 | ydstorg += minfo->devflags.ydstorg; |
776 | ACCESS_FBINFO(curr.ydstorg.bytes) = ydstorg; | 784 | minfo->curr.ydstorg.bytes = ydstorg; |
777 | ACCESS_FBINFO(curr.ydstorg.chunks) = ydstorg >> (isInterleave(MINFO)?3:2); | 785 | minfo->curr.ydstorg.chunks = ydstorg >> (isInterleave(minfo) ? 3 : 2); |
778 | if (var->bits_per_pixel == 4) | 786 | if (var->bits_per_pixel == 4) |
779 | ACCESS_FBINFO(curr.ydstorg.pixels) = ydstorg; | 787 | minfo->curr.ydstorg.pixels = ydstorg; |
780 | else | 788 | else |
781 | ACCESS_FBINFO(curr.ydstorg.pixels) = (ydstorg * 8) / var->bits_per_pixel; | 789 | minfo->curr.ydstorg.pixels = (ydstorg * 8) / var->bits_per_pixel; |
782 | ACCESS_FBINFO(curr.final_bppShift) = matroxfb_get_final_bppShift(PMINFO var->bits_per_pixel); | 790 | minfo->curr.final_bppShift = matroxfb_get_final_bppShift(minfo, var->bits_per_pixel); |
783 | { struct my_timming mt; | 791 | { struct my_timming mt; |
784 | struct matrox_hw_state* hw; | 792 | struct matrox_hw_state* hw; |
785 | int out; | 793 | int out; |
@@ -795,54 +803,55 @@ static int matroxfb_set_par(struct fb_info *info) | |||
795 | default: mt.delay = 31 + 8; break; | 803 | default: mt.delay = 31 + 8; break; |
796 | } | 804 | } |
797 | 805 | ||
798 | hw = &ACCESS_FBINFO(hw); | 806 | hw = &minfo->hw; |
799 | 807 | ||
800 | down_read(&ACCESS_FBINFO(altout).lock); | 808 | down_read(&minfo->altout.lock); |
801 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 809 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
802 | if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && | 810 | if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 && |
803 | ACCESS_FBINFO(outputs[out]).output->compute) { | 811 | minfo->outputs[out].output->compute) { |
804 | ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt); | 812 | minfo->outputs[out].output->compute(minfo->outputs[out].data, &mt); |
805 | } | 813 | } |
806 | } | 814 | } |
807 | up_read(&ACCESS_FBINFO(altout).lock); | 815 | up_read(&minfo->altout.lock); |
808 | ACCESS_FBINFO(crtc1).pixclock = mt.pixclock; | 816 | minfo->crtc1.pixclock = mt.pixclock; |
809 | ACCESS_FBINFO(crtc1).mnp = mt.mnp; | 817 | minfo->crtc1.mnp = mt.mnp; |
810 | ACCESS_FBINFO(hw_switch->init(PMINFO &mt)); | 818 | minfo->hw_switch->init(minfo, &mt); |
811 | pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32; | 819 | pos = (var->yoffset * var->xres_virtual + var->xoffset) * minfo->curr.final_bppShift / 32; |
812 | pos += ACCESS_FBINFO(curr.ydstorg.chunks); | 820 | pos += minfo->curr.ydstorg.chunks; |
813 | 821 | ||
814 | hw->CRTC[0x0D] = pos & 0xFF; | 822 | hw->CRTC[0x0D] = pos & 0xFF; |
815 | hw->CRTC[0x0C] = (pos & 0xFF00) >> 8; | 823 | hw->CRTC[0x0C] = (pos & 0xFF00) >> 8; |
816 | hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); | 824 | hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); |
817 | hw->CRTCEXT[8] = pos >> 21; | 825 | hw->CRTCEXT[8] = pos >> 21; |
818 | ACCESS_FBINFO(hw_switch->restore(PMINFO2)); | 826 | minfo->hw_switch->restore(minfo); |
819 | update_crtc2(PMINFO pos); | 827 | update_crtc2(minfo, pos); |
820 | down_read(&ACCESS_FBINFO(altout).lock); | 828 | down_read(&minfo->altout.lock); |
821 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 829 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
822 | if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && | 830 | if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 && |
823 | ACCESS_FBINFO(outputs[out]).output->program) { | 831 | minfo->outputs[out].output->program) { |
824 | ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data); | 832 | minfo->outputs[out].output->program(minfo->outputs[out].data); |
825 | } | 833 | } |
826 | } | 834 | } |
827 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 835 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
828 | if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && | 836 | if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 && |
829 | ACCESS_FBINFO(outputs[out]).output->start) { | 837 | minfo->outputs[out].output->start) { |
830 | ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data); | 838 | minfo->outputs[out].output->start(minfo->outputs[out].data); |
831 | } | 839 | } |
832 | } | 840 | } |
833 | up_read(&ACCESS_FBINFO(altout).lock); | 841 | up_read(&minfo->altout.lock); |
834 | matrox_cfbX_init(PMINFO2); | 842 | matrox_cfbX_init(minfo); |
835 | } | 843 | } |
836 | } | 844 | } |
837 | ACCESS_FBINFO(initialized) = 1; | 845 | minfo->initialized = 1; |
838 | return 0; | 846 | return 0; |
839 | } | 847 | } |
840 | 848 | ||
841 | static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank) | 849 | static int matroxfb_get_vblank(struct matrox_fb_info *minfo, |
850 | struct fb_vblank *vblank) | ||
842 | { | 851 | { |
843 | unsigned int sts1; | 852 | unsigned int sts1; |
844 | 853 | ||
845 | matroxfb_enable_irq(PMINFO 0); | 854 | matroxfb_enable_irq(minfo, 0); |
846 | memset(vblank, 0, sizeof(*vblank)); | 855 | memset(vblank, 0, sizeof(*vblank)); |
847 | vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC | | 856 | vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC | |
848 | FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK; | 857 | FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK; |
@@ -855,13 +864,13 @@ static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank) | |||
855 | vblank->flags |= FB_VBLANK_HBLANKING; | 864 | vblank->flags |= FB_VBLANK_HBLANKING; |
856 | if (sts1 & 8) | 865 | if (sts1 & 8) |
857 | vblank->flags |= FB_VBLANK_VSYNCING; | 866 | vblank->flags |= FB_VBLANK_VSYNCING; |
858 | if (vblank->vcount >= ACCESS_FBINFO(fbcon).var.yres) | 867 | if (vblank->vcount >= minfo->fbcon.var.yres) |
859 | vblank->flags |= FB_VBLANK_VBLANKING; | 868 | vblank->flags |= FB_VBLANK_VBLANKING; |
860 | if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { | 869 | if (test_bit(0, &minfo->irq_flags)) { |
861 | vblank->flags |= FB_VBLANK_HAVE_COUNT; | 870 | vblank->flags |= FB_VBLANK_HAVE_COUNT; |
862 | /* Only one writer, aligned int value... | 871 | /* Only one writer, aligned int value... |
863 | it should work without lock and without atomic_t */ | 872 | it should work without lock and without atomic_t */ |
864 | vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; | 873 | vblank->count = minfo->crtc1.vsync.cnt; |
865 | } | 874 | } |
866 | return 0; | 875 | return 0; |
867 | } | 876 | } |
@@ -874,11 +883,11 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
874 | unsigned int cmd, unsigned long arg) | 883 | unsigned int cmd, unsigned long arg) |
875 | { | 884 | { |
876 | void __user *argp = (void __user *)arg; | 885 | void __user *argp = (void __user *)arg; |
877 | MINFO_FROM_INFO(info); | 886 | struct matrox_fb_info *minfo = info2minfo(info); |
878 | 887 | ||
879 | DBG(__func__) | 888 | DBG(__func__) |
880 | 889 | ||
881 | if (ACCESS_FBINFO(dead)) { | 890 | if (minfo->dead) { |
882 | return -ENXIO; | 891 | return -ENXIO; |
883 | } | 892 | } |
884 | 893 | ||
@@ -888,7 +897,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
888 | struct fb_vblank vblank; | 897 | struct fb_vblank vblank; |
889 | int err; | 898 | int err; |
890 | 899 | ||
891 | err = matroxfb_get_vblank(PMINFO &vblank); | 900 | err = matroxfb_get_vblank(minfo, &vblank); |
892 | if (err) | 901 | if (err) |
893 | return err; | 902 | return err; |
894 | if (copy_to_user(argp, &vblank, sizeof(vblank))) | 903 | if (copy_to_user(argp, &vblank, sizeof(vblank))) |
@@ -902,7 +911,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
902 | if (get_user(crt, (u_int32_t __user *)arg)) | 911 | if (get_user(crt, (u_int32_t __user *)arg)) |
903 | return -EFAULT; | 912 | return -EFAULT; |
904 | 913 | ||
905 | return matroxfb_wait_for_sync(PMINFO crt); | 914 | return matroxfb_wait_for_sync(minfo, crt); |
906 | } | 915 | } |
907 | case MATROXFB_SET_OUTPUT_MODE: | 916 | case MATROXFB_SET_OUTPUT_MODE: |
908 | { | 917 | { |
@@ -914,8 +923,8 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
914 | return -EFAULT; | 923 | return -EFAULT; |
915 | if (mom.output >= MATROXFB_MAX_OUTPUTS) | 924 | if (mom.output >= MATROXFB_MAX_OUTPUTS) |
916 | return -ENXIO; | 925 | return -ENXIO; |
917 | down_read(&ACCESS_FBINFO(altout.lock)); | 926 | down_read(&minfo->altout.lock); |
918 | oproc = ACCESS_FBINFO(outputs[mom.output]).output; | 927 | oproc = minfo->outputs[mom.output].output; |
919 | if (!oproc) { | 928 | if (!oproc) { |
920 | val = -ENXIO; | 929 | val = -ENXIO; |
921 | } else if (!oproc->verifymode) { | 930 | } else if (!oproc->verifymode) { |
@@ -925,18 +934,18 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
925 | val = -EINVAL; | 934 | val = -EINVAL; |
926 | } | 935 | } |
927 | } else { | 936 | } else { |
928 | val = oproc->verifymode(ACCESS_FBINFO(outputs[mom.output]).data, mom.mode); | 937 | val = oproc->verifymode(minfo->outputs[mom.output].data, mom.mode); |
929 | } | 938 | } |
930 | if (!val) { | 939 | if (!val) { |
931 | if (ACCESS_FBINFO(outputs[mom.output]).mode != mom.mode) { | 940 | if (minfo->outputs[mom.output].mode != mom.mode) { |
932 | ACCESS_FBINFO(outputs[mom.output]).mode = mom.mode; | 941 | minfo->outputs[mom.output].mode = mom.mode; |
933 | val = 1; | 942 | val = 1; |
934 | } | 943 | } |
935 | } | 944 | } |
936 | up_read(&ACCESS_FBINFO(altout.lock)); | 945 | up_read(&minfo->altout.lock); |
937 | if (val != 1) | 946 | if (val != 1) |
938 | return val; | 947 | return val; |
939 | switch (ACCESS_FBINFO(outputs[mom.output]).src) { | 948 | switch (minfo->outputs[mom.output].src) { |
940 | case MATROXFB_SRC_CRTC1: | 949 | case MATROXFB_SRC_CRTC1: |
941 | matroxfb_set_par(info); | 950 | matroxfb_set_par(info); |
942 | break; | 951 | break; |
@@ -944,11 +953,11 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
944 | { | 953 | { |
945 | struct matroxfb_dh_fb_info* crtc2; | 954 | struct matroxfb_dh_fb_info* crtc2; |
946 | 955 | ||
947 | down_read(&ACCESS_FBINFO(crtc2.lock)); | 956 | down_read(&minfo->crtc2.lock); |
948 | crtc2 = ACCESS_FBINFO(crtc2.info); | 957 | crtc2 = minfo->crtc2.info; |
949 | if (crtc2) | 958 | if (crtc2) |
950 | crtc2->fbcon.fbops->fb_set_par(&crtc2->fbcon); | 959 | crtc2->fbcon.fbops->fb_set_par(&crtc2->fbcon); |
951 | up_read(&ACCESS_FBINFO(crtc2.lock)); | 960 | up_read(&minfo->crtc2.lock); |
952 | } | 961 | } |
953 | break; | 962 | break; |
954 | } | 963 | } |
@@ -964,15 +973,15 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
964 | return -EFAULT; | 973 | return -EFAULT; |
965 | if (mom.output >= MATROXFB_MAX_OUTPUTS) | 974 | if (mom.output >= MATROXFB_MAX_OUTPUTS) |
966 | return -ENXIO; | 975 | return -ENXIO; |
967 | down_read(&ACCESS_FBINFO(altout.lock)); | 976 | down_read(&minfo->altout.lock); |
968 | oproc = ACCESS_FBINFO(outputs[mom.output]).output; | 977 | oproc = minfo->outputs[mom.output].output; |
969 | if (!oproc) { | 978 | if (!oproc) { |
970 | val = -ENXIO; | 979 | val = -ENXIO; |
971 | } else { | 980 | } else { |
972 | mom.mode = ACCESS_FBINFO(outputs[mom.output]).mode; | 981 | mom.mode = minfo->outputs[mom.output].mode; |
973 | val = 0; | 982 | val = 0; |
974 | } | 983 | } |
975 | up_read(&ACCESS_FBINFO(altout.lock)); | 984 | up_read(&minfo->altout.lock); |
976 | if (val) | 985 | if (val) |
977 | return val; | 986 | return val; |
978 | if (copy_to_user(argp, &mom, sizeof(mom))) | 987 | if (copy_to_user(argp, &mom, sizeof(mom))) |
@@ -991,9 +1000,9 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
991 | if (tmp & (1 << i)) { | 1000 | if (tmp & (1 << i)) { |
992 | if (i >= MATROXFB_MAX_OUTPUTS) | 1001 | if (i >= MATROXFB_MAX_OUTPUTS) |
993 | return -ENXIO; | 1002 | return -ENXIO; |
994 | if (!ACCESS_FBINFO(outputs[i]).output) | 1003 | if (!minfo->outputs[i].output) |
995 | return -ENXIO; | 1004 | return -ENXIO; |
996 | switch (ACCESS_FBINFO(outputs[i]).src) { | 1005 | switch (minfo->outputs[i].src) { |
997 | case MATROXFB_SRC_NONE: | 1006 | case MATROXFB_SRC_NONE: |
998 | case MATROXFB_SRC_CRTC1: | 1007 | case MATROXFB_SRC_CRTC1: |
999 | break; | 1008 | break; |
@@ -1002,12 +1011,12 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1002 | } | 1011 | } |
1003 | } | 1012 | } |
1004 | } | 1013 | } |
1005 | if (ACCESS_FBINFO(devflags.panellink)) { | 1014 | if (minfo->devflags.panellink) { |
1006 | if (tmp & MATROXFB_OUTPUT_CONN_DFP) { | 1015 | if (tmp & MATROXFB_OUTPUT_CONN_DFP) { |
1007 | if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY) | 1016 | if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY) |
1008 | return -EINVAL; | 1017 | return -EINVAL; |
1009 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { | 1018 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { |
1010 | if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC2) { | 1019 | if (minfo->outputs[i].src == MATROXFB_SRC_CRTC2) { |
1011 | return -EBUSY; | 1020 | return -EBUSY; |
1012 | } | 1021 | } |
1013 | } | 1022 | } |
@@ -1016,13 +1025,13 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1016 | changes = 0; | 1025 | changes = 0; |
1017 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { | 1026 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { |
1018 | if (tmp & (1 << i)) { | 1027 | if (tmp & (1 << i)) { |
1019 | if (ACCESS_FBINFO(outputs[i]).src != MATROXFB_SRC_CRTC1) { | 1028 | if (minfo->outputs[i].src != MATROXFB_SRC_CRTC1) { |
1020 | changes = 1; | 1029 | changes = 1; |
1021 | ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_CRTC1; | 1030 | minfo->outputs[i].src = MATROXFB_SRC_CRTC1; |
1022 | } | 1031 | } |
1023 | } else if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { | 1032 | } else if (minfo->outputs[i].src == MATROXFB_SRC_CRTC1) { |
1024 | changes = 1; | 1033 | changes = 1; |
1025 | ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_NONE; | 1034 | minfo->outputs[i].src = MATROXFB_SRC_NONE; |
1026 | } | 1035 | } |
1027 | } | 1036 | } |
1028 | if (!changes) | 1037 | if (!changes) |
@@ -1036,7 +1045,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1036 | int i; | 1045 | int i; |
1037 | 1046 | ||
1038 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { | 1047 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { |
1039 | if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { | 1048 | if (minfo->outputs[i].src == MATROXFB_SRC_CRTC1) { |
1040 | conn |= 1 << i; | 1049 | conn |= 1 << i; |
1041 | } | 1050 | } |
1042 | } | 1051 | } |
@@ -1050,8 +1059,8 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1050 | int i; | 1059 | int i; |
1051 | 1060 | ||
1052 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { | 1061 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { |
1053 | if (ACCESS_FBINFO(outputs[i]).output) { | 1062 | if (minfo->outputs[i].output) { |
1054 | switch (ACCESS_FBINFO(outputs[i]).src) { | 1063 | switch (minfo->outputs[i].src) { |
1055 | case MATROXFB_SRC_NONE: | 1064 | case MATROXFB_SRC_NONE: |
1056 | case MATROXFB_SRC_CRTC1: | 1065 | case MATROXFB_SRC_CRTC1: |
1057 | conn |= 1 << i; | 1066 | conn |= 1 << i; |
@@ -1059,7 +1068,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1059 | } | 1068 | } |
1060 | } | 1069 | } |
1061 | } | 1070 | } |
1062 | if (ACCESS_FBINFO(devflags.panellink)) { | 1071 | if (minfo->devflags.panellink) { |
1063 | if (conn & MATROXFB_OUTPUT_CONN_DFP) | 1072 | if (conn & MATROXFB_OUTPUT_CONN_DFP) |
1064 | conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY; | 1073 | conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY; |
1065 | if (conn & MATROXFB_OUTPUT_CONN_SECONDARY) | 1074 | if (conn & MATROXFB_OUTPUT_CONN_SECONDARY) |
@@ -1075,7 +1084,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1075 | int i; | 1084 | int i; |
1076 | 1085 | ||
1077 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { | 1086 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { |
1078 | if (ACCESS_FBINFO(outputs[i]).output) { | 1087 | if (minfo->outputs[i].output) { |
1079 | conn |= 1 << i; | 1088 | conn |= 1 << i; |
1080 | } | 1089 | } |
1081 | } | 1090 | } |
@@ -1090,7 +1099,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1090 | memset(&r, 0, sizeof(r)); | 1099 | memset(&r, 0, sizeof(r)); |
1091 | strcpy(r.driver, "matroxfb"); | 1100 | strcpy(r.driver, "matroxfb"); |
1092 | strcpy(r.card, "Matrox"); | 1101 | strcpy(r.card, "Matrox"); |
1093 | sprintf(r.bus_info, "PCI:%s", pci_name(ACCESS_FBINFO(pcidev))); | 1102 | sprintf(r.bus_info, "PCI:%s", pci_name(minfo->pcidev)); |
1094 | r.version = KERNEL_VERSION(1,0,0); | 1103 | r.version = KERNEL_VERSION(1,0,0); |
1095 | r.capabilities = V4L2_CAP_VIDEO_OUTPUT; | 1104 | r.capabilities = V4L2_CAP_VIDEO_OUTPUT; |
1096 | if (copy_to_user(argp, &r, sizeof(r))) | 1105 | if (copy_to_user(argp, &r, sizeof(r))) |
@@ -1106,15 +1115,15 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1106 | if (copy_from_user(&qctrl, argp, sizeof(qctrl))) | 1115 | if (copy_from_user(&qctrl, argp, sizeof(qctrl))) |
1107 | return -EFAULT; | 1116 | return -EFAULT; |
1108 | 1117 | ||
1109 | down_read(&ACCESS_FBINFO(altout).lock); | 1118 | down_read(&minfo->altout.lock); |
1110 | if (!ACCESS_FBINFO(outputs[1]).output) { | 1119 | if (!minfo->outputs[1].output) { |
1111 | err = -ENXIO; | 1120 | err = -ENXIO; |
1112 | } else if (ACCESS_FBINFO(outputs[1]).output->getqueryctrl) { | 1121 | } else if (minfo->outputs[1].output->getqueryctrl) { |
1113 | err = ACCESS_FBINFO(outputs[1]).output->getqueryctrl(ACCESS_FBINFO(outputs[1]).data, &qctrl); | 1122 | err = minfo->outputs[1].output->getqueryctrl(minfo->outputs[1].data, &qctrl); |
1114 | } else { | 1123 | } else { |
1115 | err = -EINVAL; | 1124 | err = -EINVAL; |
1116 | } | 1125 | } |
1117 | up_read(&ACCESS_FBINFO(altout).lock); | 1126 | up_read(&minfo->altout.lock); |
1118 | if (err >= 0 && | 1127 | if (err >= 0 && |
1119 | copy_to_user(argp, &qctrl, sizeof(qctrl))) | 1128 | copy_to_user(argp, &qctrl, sizeof(qctrl))) |
1120 | return -EFAULT; | 1129 | return -EFAULT; |
@@ -1128,15 +1137,15 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1128 | if (copy_from_user(&ctrl, argp, sizeof(ctrl))) | 1137 | if (copy_from_user(&ctrl, argp, sizeof(ctrl))) |
1129 | return -EFAULT; | 1138 | return -EFAULT; |
1130 | 1139 | ||
1131 | down_read(&ACCESS_FBINFO(altout).lock); | 1140 | down_read(&minfo->altout.lock); |
1132 | if (!ACCESS_FBINFO(outputs[1]).output) { | 1141 | if (!minfo->outputs[1].output) { |
1133 | err = -ENXIO; | 1142 | err = -ENXIO; |
1134 | } else if (ACCESS_FBINFO(outputs[1]).output->getctrl) { | 1143 | } else if (minfo->outputs[1].output->getctrl) { |
1135 | err = ACCESS_FBINFO(outputs[1]).output->getctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); | 1144 | err = minfo->outputs[1].output->getctrl(minfo->outputs[1].data, &ctrl); |
1136 | } else { | 1145 | } else { |
1137 | err = -EINVAL; | 1146 | err = -EINVAL; |
1138 | } | 1147 | } |
1139 | up_read(&ACCESS_FBINFO(altout).lock); | 1148 | up_read(&minfo->altout.lock); |
1140 | if (err >= 0 && | 1149 | if (err >= 0 && |
1141 | copy_to_user(argp, &ctrl, sizeof(ctrl))) | 1150 | copy_to_user(argp, &ctrl, sizeof(ctrl))) |
1142 | return -EFAULT; | 1151 | return -EFAULT; |
@@ -1151,15 +1160,15 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1151 | if (copy_from_user(&ctrl, argp, sizeof(ctrl))) | 1160 | if (copy_from_user(&ctrl, argp, sizeof(ctrl))) |
1152 | return -EFAULT; | 1161 | return -EFAULT; |
1153 | 1162 | ||
1154 | down_read(&ACCESS_FBINFO(altout).lock); | 1163 | down_read(&minfo->altout.lock); |
1155 | if (!ACCESS_FBINFO(outputs[1]).output) { | 1164 | if (!minfo->outputs[1].output) { |
1156 | err = -ENXIO; | 1165 | err = -ENXIO; |
1157 | } else if (ACCESS_FBINFO(outputs[1]).output->setctrl) { | 1166 | } else if (minfo->outputs[1].output->setctrl) { |
1158 | err = ACCESS_FBINFO(outputs[1]).output->setctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); | 1167 | err = minfo->outputs[1].output->setctrl(minfo->outputs[1].data, &ctrl); |
1159 | } else { | 1168 | } else { |
1160 | err = -EINVAL; | 1169 | err = -EINVAL; |
1161 | } | 1170 | } |
1162 | up_read(&ACCESS_FBINFO(altout).lock); | 1171 | up_read(&minfo->altout.lock); |
1163 | return err; | 1172 | return err; |
1164 | } | 1173 | } |
1165 | } | 1174 | } |
@@ -1173,11 +1182,11 @@ static int matroxfb_blank(int blank, struct fb_info *info) | |||
1173 | int seq; | 1182 | int seq; |
1174 | int crtc; | 1183 | int crtc; |
1175 | CRITFLAGS | 1184 | CRITFLAGS |
1176 | MINFO_FROM_INFO(info); | 1185 | struct matrox_fb_info *minfo = info2minfo(info); |
1177 | 1186 | ||
1178 | DBG(__func__) | 1187 | DBG(__func__) |
1179 | 1188 | ||
1180 | if (ACCESS_FBINFO(dead)) | 1189 | if (minfo->dead) |
1181 | return 1; | 1190 | return 1; |
1182 | 1191 | ||
1183 | switch (blank) { | 1192 | switch (blank) { |
@@ -1279,7 +1288,9 @@ static char outputs[8]; /* "matrox:outputs:xxx" */ | |||
1279 | static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */ | 1288 | static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */ |
1280 | #endif | 1289 | #endif |
1281 | 1290 | ||
1282 | static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSize){ | 1291 | static int matroxfb_getmemory(struct matrox_fb_info *minfo, |
1292 | unsigned int maxSize, unsigned int *realSize) | ||
1293 | { | ||
1283 | vaddr_t vm; | 1294 | vaddr_t vm; |
1284 | unsigned int offs; | 1295 | unsigned int offs; |
1285 | unsigned int offs2; | 1296 | unsigned int offs2; |
@@ -1289,7 +1300,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi | |||
1289 | 1300 | ||
1290 | DBG(__func__) | 1301 | DBG(__func__) |
1291 | 1302 | ||
1292 | vm = ACCESS_FBINFO(video.vbase); | 1303 | vm = minfo->video.vbase; |
1293 | maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */ | 1304 | maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */ |
1294 | /* at least 2MB */ | 1305 | /* at least 2MB */ |
1295 | if (maxSize < 0x0200000) return 0; | 1306 | if (maxSize < 0x0200000) return 0; |
@@ -1321,7 +1332,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi | |||
1321 | 1332 | ||
1322 | *realSize = offs - 0x100000; | 1333 | *realSize = offs - 0x100000; |
1323 | #ifdef CONFIG_FB_MATROX_MILLENIUM | 1334 | #ifdef CONFIG_FB_MATROX_MILLENIUM |
1324 | ACCESS_FBINFO(interleave) = !(!isMillenium(MINFO) || ((offs - 0x100000) & 0x3FFFFF)); | 1335 | minfo->interleave = !(!isMillenium(minfo) || ((offs - 0x100000) & 0x3FFFFF)); |
1325 | #endif | 1336 | #endif |
1326 | return 1; | 1337 | return 1; |
1327 | } | 1338 | } |
@@ -1343,13 +1354,9 @@ static struct video_board vbMystique = {0x0800000, 0x0800000, FB_ACCEL_MATROX_M | |||
1343 | #ifdef CONFIG_FB_MATROX_G | 1354 | #ifdef CONFIG_FB_MATROX_G |
1344 | static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100}; | 1355 | static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100}; |
1345 | static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100}; | 1356 | static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100}; |
1346 | #ifdef CONFIG_FB_MATROX_32MB | ||
1347 | /* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for | 1357 | /* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for |
1348 | whole 32MB */ | 1358 | whole 32MB */ |
1349 | static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100}; | 1359 | static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100}; |
1350 | #else | ||
1351 | static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100}; | ||
1352 | #endif | ||
1353 | #endif | 1360 | #endif |
1354 | 1361 | ||
1355 | #define DEVF_VIDEO64BIT 0x0001 | 1362 | #define DEVF_VIDEO64BIT 0x0001 |
@@ -1556,16 +1563,17 @@ static struct fb_videomode defaultmode = { | |||
1556 | 1563 | ||
1557 | static int hotplug = 0; | 1564 | static int hotplug = 0; |
1558 | 1565 | ||
1559 | static void setDefaultOutputs(WPMINFO2) { | 1566 | static void setDefaultOutputs(struct matrox_fb_info *minfo) |
1567 | { | ||
1560 | unsigned int i; | 1568 | unsigned int i; |
1561 | const char* ptr; | 1569 | const char* ptr; |
1562 | 1570 | ||
1563 | ACCESS_FBINFO(outputs[0]).default_src = MATROXFB_SRC_CRTC1; | 1571 | minfo->outputs[0].default_src = MATROXFB_SRC_CRTC1; |
1564 | if (ACCESS_FBINFO(devflags.g450dac)) { | 1572 | if (minfo->devflags.g450dac) { |
1565 | ACCESS_FBINFO(outputs[1]).default_src = MATROXFB_SRC_CRTC1; | 1573 | minfo->outputs[1].default_src = MATROXFB_SRC_CRTC1; |
1566 | ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; | 1574 | minfo->outputs[2].default_src = MATROXFB_SRC_CRTC1; |
1567 | } else if (dfp) { | 1575 | } else if (dfp) { |
1568 | ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; | 1576 | minfo->outputs[2].default_src = MATROXFB_SRC_CRTC1; |
1569 | } | 1577 | } |
1570 | ptr = outputs; | 1578 | ptr = outputs; |
1571 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { | 1579 | for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { |
@@ -1575,11 +1583,11 @@ static void setDefaultOutputs(WPMINFO2) { | |||
1575 | break; | 1583 | break; |
1576 | } | 1584 | } |
1577 | if (c == '0') { | 1585 | if (c == '0') { |
1578 | ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_NONE; | 1586 | minfo->outputs[i].default_src = MATROXFB_SRC_NONE; |
1579 | } else if (c == '1') { | 1587 | } else if (c == '1') { |
1580 | ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC1; | 1588 | minfo->outputs[i].default_src = MATROXFB_SRC_CRTC1; |
1581 | } else if (c == '2' && ACCESS_FBINFO(devflags.crtc2)) { | 1589 | } else if (c == '2' && minfo->devflags.crtc2) { |
1582 | ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC2; | 1590 | minfo->outputs[i].default_src = MATROXFB_SRC_CRTC2; |
1583 | } else { | 1591 | } else { |
1584 | printk(KERN_ERR "matroxfb: Unknown outputs setting\n"); | 1592 | printk(KERN_ERR "matroxfb: Unknown outputs setting\n"); |
1585 | break; | 1593 | break; |
@@ -1589,7 +1597,8 @@ static void setDefaultOutputs(WPMINFO2) { | |||
1589 | outputs[0] = 0; | 1597 | outputs[0] = 0; |
1590 | } | 1598 | } |
1591 | 1599 | ||
1592 | static int initMatrox2(WPMINFO struct board* b){ | 1600 | static int initMatrox2(struct matrox_fb_info *minfo, struct board *b) |
1601 | { | ||
1593 | unsigned long ctrlptr_phys = 0; | 1602 | unsigned long ctrlptr_phys = 0; |
1594 | unsigned long video_base_phys = 0; | 1603 | unsigned long video_base_phys = 0; |
1595 | unsigned int memsize; | 1604 | unsigned int memsize; |
@@ -1605,58 +1614,56 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1605 | /* set default values... */ | 1614 | /* set default values... */ |
1606 | vesafb_defined.accel_flags = FB_ACCELF_TEXT; | 1615 | vesafb_defined.accel_flags = FB_ACCELF_TEXT; |
1607 | 1616 | ||
1608 | ACCESS_FBINFO(hw_switch) = b->base->lowlevel; | 1617 | minfo->hw_switch = b->base->lowlevel; |
1609 | ACCESS_FBINFO(devflags.accelerator) = b->base->accelID; | 1618 | minfo->devflags.accelerator = b->base->accelID; |
1610 | ACCESS_FBINFO(max_pixel_clock) = b->maxclk; | 1619 | minfo->max_pixel_clock = b->maxclk; |
1611 | 1620 | ||
1612 | printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name); | 1621 | printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name); |
1613 | ACCESS_FBINFO(capable.plnwt) = 1; | 1622 | minfo->capable.plnwt = 1; |
1614 | ACCESS_FBINFO(chip) = b->chip; | 1623 | minfo->chip = b->chip; |
1615 | ACCESS_FBINFO(capable.srcorg) = b->flags & DEVF_SRCORG; | 1624 | minfo->capable.srcorg = b->flags & DEVF_SRCORG; |
1616 | ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT; | 1625 | minfo->devflags.video64bits = b->flags & DEVF_VIDEO64BIT; |
1617 | if (b->flags & DEVF_TEXT4B) { | 1626 | if (b->flags & DEVF_TEXT4B) { |
1618 | ACCESS_FBINFO(devflags.vgastep) = 4; | 1627 | minfo->devflags.vgastep = 4; |
1619 | ACCESS_FBINFO(devflags.textmode) = 4; | 1628 | minfo->devflags.textmode = 4; |
1620 | ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; | 1629 | minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP16; |
1621 | } else if (b->flags & DEVF_TEXT16B) { | 1630 | } else if (b->flags & DEVF_TEXT16B) { |
1622 | ACCESS_FBINFO(devflags.vgastep) = 16; | 1631 | minfo->devflags.vgastep = 16; |
1623 | ACCESS_FBINFO(devflags.textmode) = 1; | 1632 | minfo->devflags.textmode = 1; |
1624 | ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; | 1633 | minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP16; |
1625 | } else { | 1634 | } else { |
1626 | ACCESS_FBINFO(devflags.vgastep) = 8; | 1635 | minfo->devflags.vgastep = 8; |
1627 | ACCESS_FBINFO(devflags.textmode) = 1; | 1636 | minfo->devflags.textmode = 1; |
1628 | ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8; | 1637 | minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP8; |
1629 | } | 1638 | } |
1630 | #ifdef CONFIG_FB_MATROX_32MB | 1639 | minfo->devflags.support32MB = (b->flags & DEVF_SUPPORT32MB) != 0; |
1631 | ACCESS_FBINFO(devflags.support32MB) = (b->flags & DEVF_SUPPORT32MB) != 0; | 1640 | minfo->devflags.precise_width = !(b->flags & DEVF_ANY_VXRES); |
1632 | #endif | 1641 | minfo->devflags.crtc2 = (b->flags & DEVF_CRTC2) != 0; |
1633 | ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES); | 1642 | minfo->devflags.maven_capable = (b->flags & DEVF_MAVEN_CAPABLE) != 0; |
1634 | ACCESS_FBINFO(devflags.crtc2) = (b->flags & DEVF_CRTC2) != 0; | 1643 | minfo->devflags.dualhead = (b->flags & DEVF_DUALHEAD) != 0; |
1635 | ACCESS_FBINFO(devflags.maven_capable) = (b->flags & DEVF_MAVEN_CAPABLE) != 0; | 1644 | minfo->devflags.dfp_type = dfp_type; |
1636 | ACCESS_FBINFO(devflags.dualhead) = (b->flags & DEVF_DUALHEAD) != 0; | 1645 | minfo->devflags.g450dac = (b->flags & DEVF_G450DAC) != 0; |
1637 | ACCESS_FBINFO(devflags.dfp_type) = dfp_type; | 1646 | minfo->devflags.textstep = minfo->devflags.vgastep * minfo->devflags.textmode; |
1638 | ACCESS_FBINFO(devflags.g450dac) = (b->flags & DEVF_G450DAC) != 0; | 1647 | minfo->devflags.textvram = 65536 / minfo->devflags.textmode; |
1639 | ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); | 1648 | setDefaultOutputs(minfo); |
1640 | ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode); | ||
1641 | setDefaultOutputs(PMINFO2); | ||
1642 | if (b->flags & DEVF_PANELLINK_CAPABLE) { | 1649 | if (b->flags & DEVF_PANELLINK_CAPABLE) { |
1643 | ACCESS_FBINFO(outputs[2]).data = MINFO; | 1650 | minfo->outputs[2].data = minfo; |
1644 | ACCESS_FBINFO(outputs[2]).output = &panellink_output; | 1651 | minfo->outputs[2].output = &panellink_output; |
1645 | ACCESS_FBINFO(outputs[2]).src = ACCESS_FBINFO(outputs[2]).default_src; | 1652 | minfo->outputs[2].src = minfo->outputs[2].default_src; |
1646 | ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 1653 | minfo->outputs[2].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
1647 | ACCESS_FBINFO(devflags.panellink) = 1; | 1654 | minfo->devflags.panellink = 1; |
1648 | } | 1655 | } |
1649 | 1656 | ||
1650 | if (ACCESS_FBINFO(capable.cross4MB) < 0) | 1657 | if (minfo->capable.cross4MB < 0) |
1651 | ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB; | 1658 | minfo->capable.cross4MB = b->flags & DEVF_CROSS4MB; |
1652 | if (b->flags & DEVF_SWAPS) { | 1659 | if (b->flags & DEVF_SWAPS) { |
1653 | ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); | 1660 | ctrlptr_phys = pci_resource_start(minfo->pcidev, 1); |
1654 | video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); | 1661 | video_base_phys = pci_resource_start(minfo->pcidev, 0); |
1655 | ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_0; | 1662 | minfo->devflags.fbResource = PCI_BASE_ADDRESS_0; |
1656 | } else { | 1663 | } else { |
1657 | ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); | 1664 | ctrlptr_phys = pci_resource_start(minfo->pcidev, 0); |
1658 | video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); | 1665 | video_base_phys = pci_resource_start(minfo->pcidev, 1); |
1659 | ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_1; | 1666 | minfo->devflags.fbResource = PCI_BASE_ADDRESS_1; |
1660 | } | 1667 | } |
1661 | err = -EINVAL; | 1668 | err = -EINVAL; |
1662 | if (!ctrlptr_phys) { | 1669 | if (!ctrlptr_phys) { |
@@ -1674,7 +1681,7 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1674 | if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) { | 1681 | if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) { |
1675 | goto failCtrlMR; | 1682 | goto failCtrlMR; |
1676 | } | 1683 | } |
1677 | ACCESS_FBINFO(video.len_maximum) = memsize; | 1684 | minfo->video.len_maximum = memsize; |
1678 | /* convert mem (autodetect k, M) */ | 1685 | /* convert mem (autodetect k, M) */ |
1679 | if (mem < 1024) mem *= 1024; | 1686 | if (mem < 1024) mem *= 1024; |
1680 | if (mem < 0x00100000) mem *= 1024; | 1687 | if (mem < 0x00100000) mem *= 1024; |
@@ -1682,14 +1689,14 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1682 | if (mem && (mem < memsize)) | 1689 | if (mem && (mem < memsize)) |
1683 | memsize = mem; | 1690 | memsize = mem; |
1684 | err = -ENOMEM; | 1691 | err = -ENOMEM; |
1685 | if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &ACCESS_FBINFO(mmio.vbase))) { | 1692 | if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &minfo->mmio.vbase)) { |
1686 | printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys); | 1693 | printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys); |
1687 | goto failVideoMR; | 1694 | goto failVideoMR; |
1688 | } | 1695 | } |
1689 | ACCESS_FBINFO(mmio.base) = ctrlptr_phys; | 1696 | minfo->mmio.base = ctrlptr_phys; |
1690 | ACCESS_FBINFO(mmio.len) = 16384; | 1697 | minfo->mmio.len = 16384; |
1691 | ACCESS_FBINFO(video.base) = video_base_phys; | 1698 | minfo->video.base = video_base_phys; |
1692 | if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) { | 1699 | if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &minfo->video.vbase)) { |
1693 | printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", | 1700 | printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", |
1694 | video_base_phys, memsize); | 1701 | video_base_phys, memsize); |
1695 | goto failCtrlIO; | 1702 | goto failCtrlIO; |
@@ -1698,63 +1705,63 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1698 | u_int32_t cmd; | 1705 | u_int32_t cmd; |
1699 | u_int32_t mga_option; | 1706 | u_int32_t mga_option; |
1700 | 1707 | ||
1701 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &mga_option); | 1708 | pci_read_config_dword(minfo->pcidev, PCI_OPTION_REG, &mga_option); |
1702 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); | 1709 | pci_read_config_dword(minfo->pcidev, PCI_COMMAND, &cmd); |
1703 | mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ | 1710 | mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ |
1704 | mga_option |= MX_OPTION_BSWAP; | 1711 | mga_option |= MX_OPTION_BSWAP; |
1705 | /* disable palette snooping */ | 1712 | /* disable palette snooping */ |
1706 | cmd &= ~PCI_COMMAND_VGA_PALETTE; | 1713 | cmd &= ~PCI_COMMAND_VGA_PALETTE; |
1707 | if (pci_dev_present(intel_82437)) { | 1714 | if (pci_dev_present(intel_82437)) { |
1708 | if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { | 1715 | if (!(mga_option & 0x20000000) && !minfo->devflags.nopciretry) { |
1709 | printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); | 1716 | printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); |
1710 | } | 1717 | } |
1711 | mga_option |= 0x20000000; | 1718 | mga_option |= 0x20000000; |
1712 | ACCESS_FBINFO(devflags.nopciretry) = 1; | 1719 | minfo->devflags.nopciretry = 1; |
1713 | } | 1720 | } |
1714 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, cmd); | 1721 | pci_write_config_dword(minfo->pcidev, PCI_COMMAND, cmd); |
1715 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mga_option); | 1722 | pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mga_option); |
1716 | ACCESS_FBINFO(hw).MXoptionReg = mga_option; | 1723 | minfo->hw.MXoptionReg = mga_option; |
1717 | 1724 | ||
1718 | /* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */ | 1725 | /* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */ |
1719 | /* maybe preinit() candidate, but it is same... for all devices... at this time... */ | 1726 | /* maybe preinit() candidate, but it is same... for all devices... at this time... */ |
1720 | pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MGA_INDEX, 0x00003C00); | 1727 | pci_write_config_dword(minfo->pcidev, PCI_MGA_INDEX, 0x00003C00); |
1721 | } | 1728 | } |
1722 | 1729 | ||
1723 | err = -ENXIO; | 1730 | err = -ENXIO; |
1724 | matroxfb_read_pins(PMINFO2); | 1731 | matroxfb_read_pins(minfo); |
1725 | if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO2)) { | 1732 | if (minfo->hw_switch->preinit(minfo)) { |
1726 | goto failVideoIO; | 1733 | goto failVideoIO; |
1727 | } | 1734 | } |
1728 | 1735 | ||
1729 | err = -ENOMEM; | 1736 | err = -ENOMEM; |
1730 | if (!matroxfb_getmemory(PMINFO memsize, &ACCESS_FBINFO(video.len)) || !ACCESS_FBINFO(video.len)) { | 1737 | if (!matroxfb_getmemory(minfo, memsize, &minfo->video.len) || !minfo->video.len) { |
1731 | printk(KERN_ERR "matroxfb: cannot determine memory size\n"); | 1738 | printk(KERN_ERR "matroxfb: cannot determine memory size\n"); |
1732 | goto failVideoIO; | 1739 | goto failVideoIO; |
1733 | } | 1740 | } |
1734 | ACCESS_FBINFO(devflags.ydstorg) = 0; | 1741 | minfo->devflags.ydstorg = 0; |
1735 | 1742 | ||
1736 | ACCESS_FBINFO(video.base) = video_base_phys; | 1743 | minfo->video.base = video_base_phys; |
1737 | ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len); | 1744 | minfo->video.len_usable = minfo->video.len; |
1738 | if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable) | 1745 | if (minfo->video.len_usable > b->base->maxdisplayable) |
1739 | ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable; | 1746 | minfo->video.len_usable = b->base->maxdisplayable; |
1740 | #ifdef CONFIG_MTRR | 1747 | #ifdef CONFIG_MTRR |
1741 | if (mtrr) { | 1748 | if (mtrr) { |
1742 | ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1); | 1749 | minfo->mtrr.vram = mtrr_add(video_base_phys, minfo->video.len, MTRR_TYPE_WRCOMB, 1); |
1743 | ACCESS_FBINFO(mtrr.vram_valid) = 1; | 1750 | minfo->mtrr.vram_valid = 1; |
1744 | printk(KERN_INFO "matroxfb: MTRR's turned on\n"); | 1751 | printk(KERN_INFO "matroxfb: MTRR's turned on\n"); |
1745 | } | 1752 | } |
1746 | #endif /* CONFIG_MTRR */ | 1753 | #endif /* CONFIG_MTRR */ |
1747 | 1754 | ||
1748 | if (!ACCESS_FBINFO(devflags.novga)) | 1755 | if (!minfo->devflags.novga) |
1749 | request_region(0x3C0, 32, "matrox"); | 1756 | request_region(0x3C0, 32, "matrox"); |
1750 | matroxfb_g450_connect(PMINFO2); | 1757 | matroxfb_g450_connect(minfo); |
1751 | ACCESS_FBINFO(hw_switch->reset(PMINFO2)); | 1758 | minfo->hw_switch->reset(minfo); |
1752 | 1759 | ||
1753 | ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0; | 1760 | minfo->fbcon.monspecs.hfmin = 0; |
1754 | ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh; | 1761 | minfo->fbcon.monspecs.hfmax = fh; |
1755 | ACCESS_FBINFO(fbcon.monspecs.vfmin) = 0; | 1762 | minfo->fbcon.monspecs.vfmin = 0; |
1756 | ACCESS_FBINFO(fbcon.monspecs.vfmax) = fv; | 1763 | minfo->fbcon.monspecs.vfmax = fv; |
1757 | ACCESS_FBINFO(fbcon.monspecs.dpms) = 0; /* TBD */ | 1764 | minfo->fbcon.monspecs.dpms = 0; /* TBD */ |
1758 | 1765 | ||
1759 | /* static settings */ | 1766 | /* static settings */ |
1760 | vesafb_defined.red = colors[depth-1].red; | 1767 | vesafb_defined.red = colors[depth-1].red; |
@@ -1766,24 +1773,24 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1766 | if (noaccel) | 1773 | if (noaccel) |
1767 | vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT; | 1774 | vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT; |
1768 | 1775 | ||
1769 | ACCESS_FBINFO(fbops) = matroxfb_ops; | 1776 | minfo->fbops = matroxfb_ops; |
1770 | ACCESS_FBINFO(fbcon.fbops) = &ACCESS_FBINFO(fbops); | 1777 | minfo->fbcon.fbops = &minfo->fbops; |
1771 | ACCESS_FBINFO(fbcon.pseudo_palette) = ACCESS_FBINFO(cmap); | 1778 | minfo->fbcon.pseudo_palette = minfo->cmap; |
1772 | /* after __init time we are like module... no logo */ | 1779 | /* after __init time we are like module... no logo */ |
1773 | ACCESS_FBINFO(fbcon.flags) = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT; | 1780 | minfo->fbcon.flags = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT; |
1774 | ACCESS_FBINFO(fbcon.flags) |= FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */ | 1781 | minfo->fbcon.flags |= FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */ |
1775 | FBINFO_HWACCEL_COPYAREA | /* We have hw-assisted bmove */ | 1782 | FBINFO_HWACCEL_COPYAREA | /* We have hw-assisted bmove */ |
1776 | FBINFO_HWACCEL_FILLRECT | /* And fillrect */ | 1783 | FBINFO_HWACCEL_FILLRECT | /* And fillrect */ |
1777 | FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */ | 1784 | FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */ |
1778 | FBINFO_HWACCEL_XPAN | /* And we support both horizontal */ | 1785 | FBINFO_HWACCEL_XPAN | /* And we support both horizontal */ |
1779 | FBINFO_HWACCEL_YPAN; /* And vertical panning */ | 1786 | FBINFO_HWACCEL_YPAN; /* And vertical panning */ |
1780 | ACCESS_FBINFO(video.len_usable) &= PAGE_MASK; | 1787 | minfo->video.len_usable &= PAGE_MASK; |
1781 | fb_alloc_cmap(&ACCESS_FBINFO(fbcon.cmap), 256, 1); | 1788 | fb_alloc_cmap(&minfo->fbcon.cmap, 256, 1); |
1782 | 1789 | ||
1783 | #ifndef MODULE | 1790 | #ifndef MODULE |
1784 | /* mode database is marked __init!!! */ | 1791 | /* mode database is marked __init!!! */ |
1785 | if (!hotplug) { | 1792 | if (!hotplug) { |
1786 | fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL, | 1793 | fb_find_mode(&vesafb_defined, &minfo->fbcon, videomode[0] ? videomode : NULL, |
1787 | NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel); | 1794 | NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel); |
1788 | } | 1795 | } |
1789 | #endif /* !MODULE */ | 1796 | #endif /* !MODULE */ |
@@ -1872,53 +1879,52 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1872 | vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough | 1879 | vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough |
1873 | to yres_virtual * xres_virtual < 2^32 */ | 1880 | to yres_virtual * xres_virtual < 2^32 */ |
1874 | } | 1881 | } |
1875 | matroxfb_init_fix(PMINFO2); | 1882 | matroxfb_init_fix(minfo); |
1876 | ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)); | 1883 | minfo->fbcon.screen_base = vaddr_va(minfo->video.vbase); |
1877 | matroxfb_update_fix(PMINFO2); | ||
1878 | /* Normalize values (namely yres_virtual) */ | 1884 | /* Normalize values (namely yres_virtual) */ |
1879 | matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon)); | 1885 | matroxfb_check_var(&vesafb_defined, &minfo->fbcon); |
1880 | /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over | 1886 | /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over |
1881 | * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var, | 1887 | * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var, |
1882 | * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work | 1888 | * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work |
1883 | * anyway. But we at least tried... */ | 1889 | * anyway. But we at least tried... */ |
1884 | ACCESS_FBINFO(fbcon.var) = vesafb_defined; | 1890 | minfo->fbcon.var = vesafb_defined; |
1885 | err = -EINVAL; | 1891 | err = -EINVAL; |
1886 | 1892 | ||
1887 | printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n", | 1893 | printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n", |
1888 | vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, | 1894 | vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, |
1889 | vesafb_defined.xres_virtual, vesafb_defined.yres_virtual); | 1895 | vesafb_defined.xres_virtual, vesafb_defined.yres_virtual); |
1890 | printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n", | 1896 | printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n", |
1891 | ACCESS_FBINFO(video.base), vaddr_va(ACCESS_FBINFO(video.vbase)), ACCESS_FBINFO(video.len)); | 1897 | minfo->video.base, vaddr_va(minfo->video.vbase), minfo->video.len); |
1892 | 1898 | ||
1893 | /* We do not have to set currcon to 0... register_framebuffer do it for us on first console | 1899 | /* We do not have to set currcon to 0... register_framebuffer do it for us on first console |
1894 | * and we do not want currcon == 0 for subsequent framebuffers */ | 1900 | * and we do not want currcon == 0 for subsequent framebuffers */ |
1895 | 1901 | ||
1896 | ACCESS_FBINFO(fbcon).device = &ACCESS_FBINFO(pcidev)->dev; | 1902 | minfo->fbcon.device = &minfo->pcidev->dev; |
1897 | if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) { | 1903 | if (register_framebuffer(&minfo->fbcon) < 0) { |
1898 | goto failVideoIO; | 1904 | goto failVideoIO; |
1899 | } | 1905 | } |
1900 | printk("fb%d: %s frame buffer device\n", | 1906 | printk("fb%d: %s frame buffer device\n", |
1901 | ACCESS_FBINFO(fbcon.node), ACCESS_FBINFO(fbcon.fix.id)); | 1907 | minfo->fbcon.node, minfo->fbcon.fix.id); |
1902 | 1908 | ||
1903 | /* there is no console on this fb... but we have to initialize hardware | 1909 | /* there is no console on this fb... but we have to initialize hardware |
1904 | * until someone tells me what is proper thing to do */ | 1910 | * until someone tells me what is proper thing to do */ |
1905 | if (!ACCESS_FBINFO(initialized)) { | 1911 | if (!minfo->initialized) { |
1906 | printk(KERN_INFO "fb%d: initializing hardware\n", | 1912 | printk(KERN_INFO "fb%d: initializing hardware\n", |
1907 | ACCESS_FBINFO(fbcon.node)); | 1913 | minfo->fbcon.node); |
1908 | /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var | 1914 | /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var |
1909 | * already before, so register_framebuffer works correctly. */ | 1915 | * already before, so register_framebuffer works correctly. */ |
1910 | vesafb_defined.activate |= FB_ACTIVATE_FORCE; | 1916 | vesafb_defined.activate |= FB_ACTIVATE_FORCE; |
1911 | fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); | 1917 | fb_set_var(&minfo->fbcon, &vesafb_defined); |
1912 | } | 1918 | } |
1913 | 1919 | ||
1914 | return 0; | 1920 | return 0; |
1915 | failVideoIO:; | 1921 | failVideoIO:; |
1916 | matroxfb_g450_shutdown(PMINFO2); | 1922 | matroxfb_g450_shutdown(minfo); |
1917 | mga_iounmap(ACCESS_FBINFO(video.vbase)); | 1923 | mga_iounmap(minfo->video.vbase); |
1918 | failCtrlIO:; | 1924 | failCtrlIO:; |
1919 | mga_iounmap(ACCESS_FBINFO(mmio.vbase)); | 1925 | mga_iounmap(minfo->mmio.vbase); |
1920 | failVideoMR:; | 1926 | failVideoMR:; |
1921 | release_mem_region(video_base_phys, ACCESS_FBINFO(video.len_maximum)); | 1927 | release_mem_region(video_base_phys, minfo->video.len_maximum); |
1922 | failCtrlMR:; | 1928 | failCtrlMR:; |
1923 | release_mem_region(ctrlptr_phys, 16384); | 1929 | release_mem_region(ctrlptr_phys, 16384); |
1924 | fail:; | 1930 | fail:; |
@@ -1974,7 +1980,7 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv) { | |||
1974 | static void matroxfb_register_device(struct matrox_fb_info* minfo) { | 1980 | static void matroxfb_register_device(struct matrox_fb_info* minfo) { |
1975 | struct matroxfb_driver* drv; | 1981 | struct matroxfb_driver* drv; |
1976 | int i = 0; | 1982 | int i = 0; |
1977 | list_add(&ACCESS_FBINFO(next_fb), &matroxfb_list); | 1983 | list_add(&minfo->next_fb, &matroxfb_list); |
1978 | for (drv = matroxfb_driver_l(matroxfb_driver_list.next); | 1984 | for (drv = matroxfb_driver_l(matroxfb_driver_list.next); |
1979 | drv != matroxfb_driver_l(&matroxfb_driver_list); | 1985 | drv != matroxfb_driver_l(&matroxfb_driver_list); |
1980 | drv = matroxfb_driver_l(drv->node.next)) { | 1986 | drv = matroxfb_driver_l(drv->node.next)) { |
@@ -1994,7 +2000,7 @@ static void matroxfb_register_device(struct matrox_fb_info* minfo) { | |||
1994 | static void matroxfb_unregister_device(struct matrox_fb_info* minfo) { | 2000 | static void matroxfb_unregister_device(struct matrox_fb_info* minfo) { |
1995 | int i; | 2001 | int i; |
1996 | 2002 | ||
1997 | list_del(&ACCESS_FBINFO(next_fb)); | 2003 | list_del(&minfo->next_fb); |
1998 | for (i = 0; i < minfo->drivers_count; i++) { | 2004 | for (i = 0; i < minfo->drivers_count; i++) { |
1999 | struct matroxfb_driver* drv = minfo->drivers[i]; | 2005 | struct matroxfb_driver* drv = minfo->drivers[i]; |
2000 | 2006 | ||
@@ -2010,9 +2016,6 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm | |||
2010 | struct matrox_fb_info* minfo; | 2016 | struct matrox_fb_info* minfo; |
2011 | int err; | 2017 | int err; |
2012 | u_int32_t cmd; | 2018 | u_int32_t cmd; |
2013 | #ifndef CONFIG_FB_MATROX_MULTIHEAD | ||
2014 | static int registered = 0; | ||
2015 | #endif | ||
2016 | DBG(__func__) | 2019 | DBG(__func__) |
2017 | 2020 | ||
2018 | svid = pdev->subsystem_vendor; | 2021 | svid = pdev->subsystem_vendor; |
@@ -2036,67 +2039,57 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm | |||
2036 | return -1; | 2039 | return -1; |
2037 | } | 2040 | } |
2038 | 2041 | ||
2039 | #ifdef CONFIG_FB_MATROX_MULTIHEAD | ||
2040 | minfo = kmalloc(sizeof(*minfo), GFP_KERNEL); | 2042 | minfo = kmalloc(sizeof(*minfo), GFP_KERNEL); |
2041 | if (!minfo) | 2043 | if (!minfo) |
2042 | return -1; | 2044 | return -1; |
2043 | #else | 2045 | memset(minfo, 0, sizeof(*minfo)); |
2044 | if (registered) /* singlehead driver... */ | ||
2045 | return -1; | ||
2046 | minfo = &matroxfb_global_mxinfo; | ||
2047 | #endif | ||
2048 | memset(MINFO, 0, sizeof(*MINFO)); | ||
2049 | 2046 | ||
2050 | ACCESS_FBINFO(pcidev) = pdev; | 2047 | minfo->pcidev = pdev; |
2051 | ACCESS_FBINFO(dead) = 0; | 2048 | minfo->dead = 0; |
2052 | ACCESS_FBINFO(usecount) = 0; | 2049 | minfo->usecount = 0; |
2053 | ACCESS_FBINFO(userusecount) = 0; | 2050 | minfo->userusecount = 0; |
2054 | 2051 | ||
2055 | pci_set_drvdata(pdev, MINFO); | 2052 | pci_set_drvdata(pdev, minfo); |
2056 | /* DEVFLAGS */ | 2053 | /* DEVFLAGS */ |
2057 | ACCESS_FBINFO(devflags.memtype) = memtype; | 2054 | minfo->devflags.memtype = memtype; |
2058 | if (memtype != -1) | 2055 | if (memtype != -1) |
2059 | noinit = 0; | 2056 | noinit = 0; |
2060 | if (cmd & PCI_COMMAND_MEMORY) { | 2057 | if (cmd & PCI_COMMAND_MEMORY) { |
2061 | ACCESS_FBINFO(devflags.novga) = novga; | 2058 | minfo->devflags.novga = novga; |
2062 | ACCESS_FBINFO(devflags.nobios) = nobios; | 2059 | minfo->devflags.nobios = nobios; |
2063 | ACCESS_FBINFO(devflags.noinit) = noinit; | 2060 | minfo->devflags.noinit = noinit; |
2064 | /* subsequent heads always needs initialization and must not enable BIOS */ | 2061 | /* subsequent heads always needs initialization and must not enable BIOS */ |
2065 | novga = 1; | 2062 | novga = 1; |
2066 | nobios = 1; | 2063 | nobios = 1; |
2067 | noinit = 0; | 2064 | noinit = 0; |
2068 | } else { | 2065 | } else { |
2069 | ACCESS_FBINFO(devflags.novga) = 1; | 2066 | minfo->devflags.novga = 1; |
2070 | ACCESS_FBINFO(devflags.nobios) = 1; | 2067 | minfo->devflags.nobios = 1; |
2071 | ACCESS_FBINFO(devflags.noinit) = 0; | 2068 | minfo->devflags.noinit = 0; |
2072 | } | 2069 | } |
2073 | 2070 | ||
2074 | ACCESS_FBINFO(devflags.nopciretry) = no_pci_retry; | 2071 | minfo->devflags.nopciretry = no_pci_retry; |
2075 | ACCESS_FBINFO(devflags.mga_24bpp_fix) = inv24; | 2072 | minfo->devflags.mga_24bpp_fix = inv24; |
2076 | ACCESS_FBINFO(devflags.precise_width) = option_precise_width; | 2073 | minfo->devflags.precise_width = option_precise_width; |
2077 | ACCESS_FBINFO(devflags.sgram) = sgram; | 2074 | minfo->devflags.sgram = sgram; |
2078 | ACCESS_FBINFO(capable.cross4MB) = cross4MB; | 2075 | minfo->capable.cross4MB = cross4MB; |
2079 | 2076 | ||
2080 | spin_lock_init(&ACCESS_FBINFO(lock.DAC)); | 2077 | spin_lock_init(&minfo->lock.DAC); |
2081 | spin_lock_init(&ACCESS_FBINFO(lock.accel)); | 2078 | spin_lock_init(&minfo->lock.accel); |
2082 | init_rwsem(&ACCESS_FBINFO(crtc2.lock)); | 2079 | init_rwsem(&minfo->crtc2.lock); |
2083 | init_rwsem(&ACCESS_FBINFO(altout.lock)); | 2080 | init_rwsem(&minfo->altout.lock); |
2084 | ACCESS_FBINFO(irq_flags) = 0; | 2081 | mutex_init(&minfo->fbcon.mm_lock); |
2085 | init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); | 2082 | minfo->irq_flags = 0; |
2086 | init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); | 2083 | init_waitqueue_head(&minfo->crtc1.vsync.wait); |
2087 | ACCESS_FBINFO(crtc1.panpos) = -1; | 2084 | init_waitqueue_head(&minfo->crtc2.vsync.wait); |
2088 | 2085 | minfo->crtc1.panpos = -1; | |
2089 | err = initMatrox2(PMINFO b); | 2086 | |
2087 | err = initMatrox2(minfo, b); | ||
2090 | if (!err) { | 2088 | if (!err) { |
2091 | #ifndef CONFIG_FB_MATROX_MULTIHEAD | 2089 | matroxfb_register_device(minfo); |
2092 | registered = 1; | ||
2093 | #endif | ||
2094 | matroxfb_register_device(MINFO); | ||
2095 | return 0; | 2090 | return 0; |
2096 | } | 2091 | } |
2097 | #ifdef CONFIG_FB_MATROX_MULTIHEAD | ||
2098 | kfree(minfo); | 2092 | kfree(minfo); |
2099 | #endif | ||
2100 | return -1; | 2093 | return -1; |
2101 | } | 2094 | } |
2102 | 2095 | ||
@@ -2104,7 +2097,7 @@ static void pci_remove_matrox(struct pci_dev* pdev) { | |||
2104 | struct matrox_fb_info* minfo; | 2097 | struct matrox_fb_info* minfo; |
2105 | 2098 | ||
2106 | minfo = pci_get_drvdata(pdev); | 2099 | minfo = pci_get_drvdata(pdev); |
2107 | matroxfb_remove(PMINFO 1); | 2100 | matroxfb_remove(minfo, 1); |
2108 | } | 2101 | } |
2109 | 2102 | ||
2110 | static struct pci_device_id matroxfb_devices[] = { | 2103 | static struct pci_device_id matroxfb_devices[] = { |
@@ -2508,13 +2501,8 @@ module_param(inv24, int, 0); | |||
2508 | MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)"); | 2501 | MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)"); |
2509 | module_param(inverse, int, 0); | 2502 | module_param(inverse, int, 0); |
2510 | MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)"); | 2503 | MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)"); |
2511 | #ifdef CONFIG_FB_MATROX_MULTIHEAD | ||
2512 | module_param(dev, int, 0); | 2504 | module_param(dev, int, 0); |
2513 | MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)"); | 2505 | MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)"); |
2514 | #else | ||
2515 | module_param(dev, int, 0); | ||
2516 | MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=first working)"); | ||
2517 | #endif | ||
2518 | module_param(vesa, int, 0); | 2506 | module_param(vesa, int, 0); |
2519 | MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)"); | 2507 | MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)"); |
2520 | module_param(xres, int, 0); | 2508 | module_param(xres, int, 0); |
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index 95883236c0cd..f3a4e15672d9 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h | |||
@@ -54,9 +54,6 @@ | |||
54 | #include "../macmodes.h" | 54 | #include "../macmodes.h" |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | /* always compile support for 32MB... It cost almost nothing */ | ||
58 | #define CONFIG_FB_MATROX_32MB | ||
59 | |||
60 | #ifdef MATROXFB_DEBUG | 57 | #ifdef MATROXFB_DEBUG |
61 | 58 | ||
62 | #define DEBUG | 59 | #define DEBUG |
@@ -464,9 +461,7 @@ struct matrox_fb_info { | |||
464 | int nopciretry; | 461 | int nopciretry; |
465 | int noinit; | 462 | int noinit; |
466 | int sgram; | 463 | int sgram; |
467 | #ifdef CONFIG_FB_MATROX_32MB | ||
468 | int support32MB; | 464 | int support32MB; |
469 | #endif | ||
470 | 465 | ||
471 | int accelerator; | 466 | int accelerator; |
472 | int text_type_aux; | 467 | int text_type_aux; |
@@ -524,47 +519,11 @@ struct matrox_fb_info { | |||
524 | 519 | ||
525 | #define info2minfo(info) container_of(info, struct matrox_fb_info, fbcon) | 520 | #define info2minfo(info) container_of(info, struct matrox_fb_info, fbcon) |
526 | 521 | ||
527 | #ifdef CONFIG_FB_MATROX_MULTIHEAD | ||
528 | #define ACCESS_FBINFO2(info, x) (info->x) | ||
529 | #define ACCESS_FBINFO(x) ACCESS_FBINFO2(minfo,x) | ||
530 | |||
531 | #define MINFO minfo | ||
532 | |||
533 | #define WPMINFO2 struct matrox_fb_info* minfo | ||
534 | #define WPMINFO WPMINFO2 , | ||
535 | #define CPMINFO2 const struct matrox_fb_info* minfo | ||
536 | #define CPMINFO CPMINFO2 , | ||
537 | #define PMINFO2 minfo | ||
538 | #define PMINFO PMINFO2 , | ||
539 | |||
540 | #define MINFO_FROM(x) struct matrox_fb_info* minfo = x | ||
541 | #else | ||
542 | |||
543 | extern struct matrox_fb_info matroxfb_global_mxinfo; | ||
544 | |||
545 | #define ACCESS_FBINFO(x) (matroxfb_global_mxinfo.x) | ||
546 | #define ACCESS_FBINFO2(info, x) (matroxfb_global_mxinfo.x) | ||
547 | |||
548 | #define MINFO (&matroxfb_global_mxinfo) | ||
549 | |||
550 | #define WPMINFO2 void | ||
551 | #define WPMINFO | ||
552 | #define CPMINFO2 void | ||
553 | #define CPMINFO | ||
554 | #define PMINFO2 | ||
555 | #define PMINFO | ||
556 | |||
557 | #define MINFO_FROM(x) | ||
558 | |||
559 | #endif | ||
560 | |||
561 | #define MINFO_FROM_INFO(x) MINFO_FROM(info2minfo(x)) | ||
562 | |||
563 | struct matrox_switch { | 522 | struct matrox_switch { |
564 | int (*preinit)(WPMINFO2); | 523 | int (*preinit)(struct matrox_fb_info *minfo); |
565 | void (*reset)(WPMINFO2); | 524 | void (*reset)(struct matrox_fb_info *minfo); |
566 | int (*init)(WPMINFO struct my_timming*); | 525 | int (*init)(struct matrox_fb_info *minfo, struct my_timming*); |
567 | void (*restore)(WPMINFO2); | 526 | void (*restore)(struct matrox_fb_info *minfo); |
568 | }; | 527 | }; |
569 | 528 | ||
570 | struct matroxfb_driver { | 529 | struct matroxfb_driver { |
@@ -727,11 +686,11 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv); | |||
727 | #endif | 686 | #endif |
728 | #endif | 687 | #endif |
729 | 688 | ||
730 | #define mga_inb(addr) mga_readb(ACCESS_FBINFO(mmio.vbase), (addr)) | 689 | #define mga_inb(addr) mga_readb(minfo->mmio.vbase, (addr)) |
731 | #define mga_inl(addr) mga_readl(ACCESS_FBINFO(mmio.vbase), (addr)) | 690 | #define mga_inl(addr) mga_readl(minfo->mmio.vbase, (addr)) |
732 | #define mga_outb(addr,val) mga_writeb(ACCESS_FBINFO(mmio.vbase), (addr), (val)) | 691 | #define mga_outb(addr,val) mga_writeb(minfo->mmio.vbase, (addr), (val)) |
733 | #define mga_outw(addr,val) mga_writew(ACCESS_FBINFO(mmio.vbase), (addr), (val)) | 692 | #define mga_outw(addr,val) mga_writew(minfo->mmio.vbase, (addr), (val)) |
734 | #define mga_outl(addr,val) mga_writel(ACCESS_FBINFO(mmio.vbase), (addr), (val)) | 693 | #define mga_outl(addr,val) mga_writel(minfo->mmio.vbase, (addr), (val)) |
735 | #define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1)) | 694 | #define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1)) |
736 | #define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port)) | 695 | #define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port)) |
737 | 696 | ||
@@ -750,19 +709,20 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv); | |||
750 | #define isMilleniumII(x) (0) | 709 | #define isMilleniumII(x) (0) |
751 | #endif | 710 | #endif |
752 | 711 | ||
753 | #define matroxfb_DAC_lock() spin_lock(&ACCESS_FBINFO(lock.DAC)) | 712 | #define matroxfb_DAC_lock() spin_lock(&minfo->lock.DAC) |
754 | #define matroxfb_DAC_unlock() spin_unlock(&ACCESS_FBINFO(lock.DAC)) | 713 | #define matroxfb_DAC_unlock() spin_unlock(&minfo->lock.DAC) |
755 | #define matroxfb_DAC_lock_irqsave(flags) spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC),flags) | 714 | #define matroxfb_DAC_lock_irqsave(flags) spin_lock_irqsave(&minfo->lock.DAC, flags) |
756 | #define matroxfb_DAC_unlock_irqrestore(flags) spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC),flags) | 715 | #define matroxfb_DAC_unlock_irqrestore(flags) spin_unlock_irqrestore(&minfo->lock.DAC, flags) |
757 | extern void matroxfb_DAC_out(CPMINFO int reg, int val); | 716 | extern void matroxfb_DAC_out(const struct matrox_fb_info *minfo, int reg, |
758 | extern int matroxfb_DAC_in(CPMINFO int reg); | 717 | int val); |
718 | extern int matroxfb_DAC_in(const struct matrox_fb_info *minfo, int reg); | ||
759 | extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt); | 719 | extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt); |
760 | extern int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc); | 720 | extern int matroxfb_wait_for_sync(struct matrox_fb_info *minfo, u_int32_t crtc); |
761 | extern int matroxfb_enable_irq(WPMINFO int reenable); | 721 | extern int matroxfb_enable_irq(struct matrox_fb_info *minfo, int reenable); |
762 | 722 | ||
763 | #ifdef MATROXFB_USE_SPINLOCKS | 723 | #ifdef MATROXFB_USE_SPINLOCKS |
764 | #define CRITBEGIN spin_lock_irqsave(&ACCESS_FBINFO(lock.accel), critflags); | 724 | #define CRITBEGIN spin_lock_irqsave(&minfo->lock.accel, critflags); |
765 | #define CRITEND spin_unlock_irqrestore(&ACCESS_FBINFO(lock.accel), critflags); | 725 | #define CRITEND spin_unlock_irqrestore(&minfo->lock.accel, critflags); |
766 | #define CRITFLAGS unsigned long critflags; | 726 | #define CRITFLAGS unsigned long critflags; |
767 | #else | 727 | #else |
768 | #define CRITBEGIN | 728 | #define CRITBEGIN |
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c index 7ac4c5f6145d..78414baa5a54 100644 --- a/drivers/video/matrox/matroxfb_crtc2.c +++ b/drivers/video/matrox/matroxfb_crtc2.c | |||
@@ -65,7 +65,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, | |||
65 | unsigned int pos) { | 65 | unsigned int pos) { |
66 | u_int32_t tmp; | 66 | u_int32_t tmp; |
67 | u_int32_t datactl; | 67 | u_int32_t datactl; |
68 | MINFO_FROM(m2info->primary_dev); | 68 | struct matrox_fb_info *minfo = m2info->primary_dev; |
69 | 69 | ||
70 | switch (mode) { | 70 | switch (mode) { |
71 | case 15: | 71 | case 15: |
@@ -81,11 +81,11 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, | |||
81 | } | 81 | } |
82 | tmp |= 0x00000001; /* enable CRTC2 */ | 82 | tmp |= 0x00000001; /* enable CRTC2 */ |
83 | datactl = 0; | 83 | datactl = 0; |
84 | if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) { | 84 | if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) { |
85 | if (ACCESS_FBINFO(devflags.g450dac)) { | 85 | if (minfo->devflags.g450dac) { |
86 | tmp |= 0x00000006; /* source from secondary pixel PLL */ | 86 | tmp |= 0x00000006; /* source from secondary pixel PLL */ |
87 | /* no vidrst when in monitor mode */ | 87 | /* no vidrst when in monitor mode */ |
88 | if (ACCESS_FBINFO(outputs[1]).mode != MATROXFB_OUTPUT_MODE_MONITOR) { | 88 | if (minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) { |
89 | tmp |= 0xC0001000; /* Enable H/V vidrst */ | 89 | tmp |= 0xC0001000; /* Enable H/V vidrst */ |
90 | } | 90 | } |
91 | } else { | 91 | } else { |
@@ -93,11 +93,11 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, | |||
93 | tmp |= 0xC0000000; /* enable vvidrst & hvidrst */ | 93 | tmp |= 0xC0000000; /* enable vvidrst & hvidrst */ |
94 | /* MGA TVO is our clock source */ | 94 | /* MGA TVO is our clock source */ |
95 | } | 95 | } |
96 | } else if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) { | 96 | } else if (minfo->outputs[0].src == MATROXFB_SRC_CRTC2) { |
97 | tmp |= 0x00000004; /* source from pixclock */ | 97 | tmp |= 0x00000004; /* source from pixclock */ |
98 | /* PIXPLL is our clock source */ | 98 | /* PIXPLL is our clock source */ |
99 | } | 99 | } |
100 | if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) { | 100 | if (minfo->outputs[0].src == MATROXFB_SRC_CRTC2) { |
101 | tmp |= 0x00100000; /* connect CRTC2 to DAC */ | 101 | tmp |= 0x00100000; /* connect CRTC2 to DAC */ |
102 | } | 102 | } |
103 | if (mt->interlaced) { | 103 | if (mt->interlaced) { |
@@ -146,7 +146,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, | |||
146 | } | 146 | } |
147 | } | 147 | } |
148 | mga_outl(0x3C10, tmp); | 148 | mga_outl(0x3C10, tmp); |
149 | ACCESS_FBINFO(hw).crtc2.ctl = tmp; | 149 | minfo->hw.crtc2.ctl = tmp; |
150 | 150 | ||
151 | tmp = mt->VDisplay << 16; /* line compare */ | 151 | tmp = mt->VDisplay << 16; /* line compare */ |
152 | if (mt->sync & FB_SYNC_HOR_HIGH_ACT) | 152 | if (mt->sync & FB_SYNC_HOR_HIGH_ACT) |
@@ -157,10 +157,10 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, | |||
157 | } | 157 | } |
158 | 158 | ||
159 | static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) { | 159 | static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) { |
160 | MINFO_FROM(m2info->primary_dev); | 160 | struct matrox_fb_info *minfo = m2info->primary_dev; |
161 | 161 | ||
162 | mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */ | 162 | mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */ |
163 | ACCESS_FBINFO(hw).crtc2.ctl = 0x00000004; | 163 | minfo->hw.crtc2.ctl = 0x00000004; |
164 | } | 164 | } |
165 | 165 | ||
166 | static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info, | 166 | static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info, |
@@ -168,7 +168,7 @@ static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info, | |||
168 | unsigned int pos; | 168 | unsigned int pos; |
169 | unsigned int linelen; | 169 | unsigned int linelen; |
170 | unsigned int pixelsize; | 170 | unsigned int pixelsize; |
171 | MINFO_FROM(m2info->primary_dev); | 171 | struct matrox_fb_info *minfo = m2info->primary_dev; |
172 | 172 | ||
173 | m2info->fbcon.var.xoffset = var->xoffset; | 173 | m2info->fbcon.var.xoffset = var->xoffset; |
174 | m2info->fbcon.var.yoffset = var->yoffset; | 174 | m2info->fbcon.var.yoffset = var->yoffset; |
@@ -260,15 +260,15 @@ static int matroxfb_dh_decode_var(struct matroxfb_dh_fb_info* m2info, | |||
260 | 260 | ||
261 | static int matroxfb_dh_open(struct fb_info* info, int user) { | 261 | static int matroxfb_dh_open(struct fb_info* info, int user) { |
262 | #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) | 262 | #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) |
263 | MINFO_FROM(m2info->primary_dev); | 263 | struct matrox_fb_info *minfo = m2info->primary_dev; |
264 | 264 | ||
265 | if (MINFO) { | 265 | if (minfo) { |
266 | int err; | 266 | int err; |
267 | 267 | ||
268 | if (ACCESS_FBINFO(dead)) { | 268 | if (minfo->dead) { |
269 | return -ENXIO; | 269 | return -ENXIO; |
270 | } | 270 | } |
271 | err = ACCESS_FBINFO(fbops).fb_open(&ACCESS_FBINFO(fbcon), user); | 271 | err = minfo->fbops.fb_open(&minfo->fbcon, user); |
272 | if (err) { | 272 | if (err) { |
273 | return err; | 273 | return err; |
274 | } | 274 | } |
@@ -280,16 +280,21 @@ static int matroxfb_dh_open(struct fb_info* info, int user) { | |||
280 | static int matroxfb_dh_release(struct fb_info* info, int user) { | 280 | static int matroxfb_dh_release(struct fb_info* info, int user) { |
281 | #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) | 281 | #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) |
282 | int err = 0; | 282 | int err = 0; |
283 | MINFO_FROM(m2info->primary_dev); | 283 | struct matrox_fb_info *minfo = m2info->primary_dev; |
284 | 284 | ||
285 | if (MINFO) { | 285 | if (minfo) { |
286 | err = ACCESS_FBINFO(fbops).fb_release(&ACCESS_FBINFO(fbcon), user); | 286 | err = minfo->fbops.fb_release(&minfo->fbcon, user); |
287 | } | 287 | } |
288 | return err; | 288 | return err; |
289 | #undef m2info | 289 | #undef m2info |
290 | } | 290 | } |
291 | 291 | ||
292 | static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) { | 292 | /* |
293 | * This function is called before the register_framebuffer so | ||
294 | * no locking is needed. | ||
295 | */ | ||
296 | static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) | ||
297 | { | ||
293 | struct fb_fix_screeninfo *fix = &m2info->fbcon.fix; | 298 | struct fb_fix_screeninfo *fix = &m2info->fbcon.fix; |
294 | 299 | ||
295 | strcpy(fix->id, "MATROX DH"); | 300 | strcpy(fix->id, "MATROX DH"); |
@@ -321,7 +326,7 @@ static int matroxfb_dh_set_par(struct fb_info* info) { | |||
321 | int mode; | 326 | int mode; |
322 | int err; | 327 | int err; |
323 | struct fb_var_screeninfo* var = &info->var; | 328 | struct fb_var_screeninfo* var = &info->var; |
324 | MINFO_FROM(m2info->primary_dev); | 329 | struct matrox_fb_info *minfo = m2info->primary_dev; |
325 | 330 | ||
326 | if ((err = matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode)) != 0) | 331 | if ((err = matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode)) != 0) |
327 | return err; | 332 | return err; |
@@ -347,39 +352,39 @@ static int matroxfb_dh_set_par(struct fb_info* info) { | |||
347 | pos = (m2info->fbcon.var.yoffset * m2info->fbcon.var.xres_virtual + m2info->fbcon.var.xoffset) * m2info->fbcon.var.bits_per_pixel >> 3; | 352 | pos = (m2info->fbcon.var.yoffset * m2info->fbcon.var.xres_virtual + m2info->fbcon.var.xoffset) * m2info->fbcon.var.bits_per_pixel >> 3; |
348 | pos += m2info->video.offbase; | 353 | pos += m2info->video.offbase; |
349 | cnt = 0; | 354 | cnt = 0; |
350 | down_read(&ACCESS_FBINFO(altout).lock); | 355 | down_read(&minfo->altout.lock); |
351 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 356 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
352 | if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) { | 357 | if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) { |
353 | cnt++; | 358 | cnt++; |
354 | if (ACCESS_FBINFO(outputs[out]).output->compute) { | 359 | if (minfo->outputs[out].output->compute) { |
355 | ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt); | 360 | minfo->outputs[out].output->compute(minfo->outputs[out].data, &mt); |
356 | } | 361 | } |
357 | } | 362 | } |
358 | } | 363 | } |
359 | ACCESS_FBINFO(crtc2).pixclock = mt.pixclock; | 364 | minfo->crtc2.pixclock = mt.pixclock; |
360 | ACCESS_FBINFO(crtc2).mnp = mt.mnp; | 365 | minfo->crtc2.mnp = mt.mnp; |
361 | up_read(&ACCESS_FBINFO(altout).lock); | 366 | up_read(&minfo->altout.lock); |
362 | if (cnt) { | 367 | if (cnt) { |
363 | matroxfb_dh_restore(m2info, &mt, mode, pos); | 368 | matroxfb_dh_restore(m2info, &mt, mode, pos); |
364 | } else { | 369 | } else { |
365 | matroxfb_dh_disable(m2info); | 370 | matroxfb_dh_disable(m2info); |
366 | } | 371 | } |
367 | DAC1064_global_init(PMINFO2); | 372 | DAC1064_global_init(minfo); |
368 | DAC1064_global_restore(PMINFO2); | 373 | DAC1064_global_restore(minfo); |
369 | down_read(&ACCESS_FBINFO(altout).lock); | 374 | down_read(&minfo->altout.lock); |
370 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 375 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
371 | if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2 && | 376 | if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2 && |
372 | ACCESS_FBINFO(outputs[out]).output->program) { | 377 | minfo->outputs[out].output->program) { |
373 | ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data); | 378 | minfo->outputs[out].output->program(minfo->outputs[out].data); |
374 | } | 379 | } |
375 | } | 380 | } |
376 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 381 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
377 | if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2 && | 382 | if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2 && |
378 | ACCESS_FBINFO(outputs[out]).output->start) { | 383 | minfo->outputs[out].output->start) { |
379 | ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data); | 384 | minfo->outputs[out].output->start(minfo->outputs[out].data); |
380 | } | 385 | } |
381 | } | 386 | } |
382 | up_read(&ACCESS_FBINFO(altout).lock); | 387 | up_read(&minfo->altout.lock); |
383 | } | 388 | } |
384 | m2info->initialized = 1; | 389 | m2info->initialized = 1; |
385 | return 0; | 390 | return 0; |
@@ -394,9 +399,9 @@ static int matroxfb_dh_pan_display(struct fb_var_screeninfo* var, struct fb_info | |||
394 | } | 399 | } |
395 | 400 | ||
396 | static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) { | 401 | static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) { |
397 | MINFO_FROM(m2info->primary_dev); | 402 | struct matrox_fb_info *minfo = m2info->primary_dev; |
398 | 403 | ||
399 | matroxfb_enable_irq(PMINFO 0); | 404 | matroxfb_enable_irq(minfo, 0); |
400 | memset(vblank, 0, sizeof(*vblank)); | 405 | memset(vblank, 0, sizeof(*vblank)); |
401 | vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK; | 406 | vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK; |
402 | /* mask out reserved bits + field number (odd/even) */ | 407 | /* mask out reserved bits + field number (odd/even) */ |
@@ -404,11 +409,11 @@ static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, stru | |||
404 | /* compatibility stuff */ | 409 | /* compatibility stuff */ |
405 | if (vblank->vcount >= m2info->fbcon.var.yres) | 410 | if (vblank->vcount >= m2info->fbcon.var.yres) |
406 | vblank->flags |= FB_VBLANK_VBLANKING; | 411 | vblank->flags |= FB_VBLANK_VBLANKING; |
407 | if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { | 412 | if (test_bit(0, &minfo->irq_flags)) { |
408 | vblank->flags |= FB_VBLANK_HAVE_COUNT; | 413 | vblank->flags |= FB_VBLANK_HAVE_COUNT; |
409 | /* Only one writer, aligned int value... | 414 | /* Only one writer, aligned int value... |
410 | it should work without lock and without atomic_t */ | 415 | it should work without lock and without atomic_t */ |
411 | vblank->count = ACCESS_FBINFO(crtc2).vsync.cnt; | 416 | vblank->count = minfo->crtc2.vsync.cnt; |
412 | } | 417 | } |
413 | return 0; | 418 | return 0; |
414 | } | 419 | } |
@@ -418,7 +423,7 @@ static int matroxfb_dh_ioctl(struct fb_info *info, | |||
418 | unsigned long arg) | 423 | unsigned long arg) |
419 | { | 424 | { |
420 | #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) | 425 | #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) |
421 | MINFO_FROM(m2info->primary_dev); | 426 | struct matrox_fb_info *minfo = m2info->primary_dev; |
422 | 427 | ||
423 | DBG(__func__) | 428 | DBG(__func__) |
424 | 429 | ||
@@ -444,13 +449,13 @@ static int matroxfb_dh_ioctl(struct fb_info *info, | |||
444 | 449 | ||
445 | if (crt != 0) | 450 | if (crt != 0) |
446 | return -ENODEV; | 451 | return -ENODEV; |
447 | return matroxfb_wait_for_sync(PMINFO 1); | 452 | return matroxfb_wait_for_sync(minfo, 1); |
448 | } | 453 | } |
449 | case MATROXFB_SET_OUTPUT_MODE: | 454 | case MATROXFB_SET_OUTPUT_MODE: |
450 | case MATROXFB_GET_OUTPUT_MODE: | 455 | case MATROXFB_GET_OUTPUT_MODE: |
451 | case MATROXFB_GET_ALL_OUTPUTS: | 456 | case MATROXFB_GET_ALL_OUTPUTS: |
452 | { | 457 | { |
453 | return ACCESS_FBINFO(fbcon.fbops)->fb_ioctl(&ACCESS_FBINFO(fbcon), cmd, arg); | 458 | return minfo->fbcon.fbops->fb_ioctl(&minfo->fbcon, cmd, arg); |
454 | } | 459 | } |
455 | case MATROXFB_SET_OUTPUT_CONNECTION: | 460 | case MATROXFB_SET_OUTPUT_CONNECTION: |
456 | { | 461 | { |
@@ -464,9 +469,9 @@ static int matroxfb_dh_ioctl(struct fb_info *info, | |||
464 | if (tmp & (1 << out)) { | 469 | if (tmp & (1 << out)) { |
465 | if (out >= MATROXFB_MAX_OUTPUTS) | 470 | if (out >= MATROXFB_MAX_OUTPUTS) |
466 | return -ENXIO; | 471 | return -ENXIO; |
467 | if (!ACCESS_FBINFO(outputs[out]).output) | 472 | if (!minfo->outputs[out].output) |
468 | return -ENXIO; | 473 | return -ENXIO; |
469 | switch (ACCESS_FBINFO(outputs[out]).src) { | 474 | switch (minfo->outputs[out].src) { |
470 | case MATROXFB_SRC_NONE: | 475 | case MATROXFB_SRC_NONE: |
471 | case MATROXFB_SRC_CRTC2: | 476 | case MATROXFB_SRC_CRTC2: |
472 | break; | 477 | break; |
@@ -475,22 +480,22 @@ static int matroxfb_dh_ioctl(struct fb_info *info, | |||
475 | } | 480 | } |
476 | } | 481 | } |
477 | } | 482 | } |
478 | if (ACCESS_FBINFO(devflags.panellink)) { | 483 | if (minfo->devflags.panellink) { |
479 | if (tmp & MATROXFB_OUTPUT_CONN_DFP) | 484 | if (tmp & MATROXFB_OUTPUT_CONN_DFP) |
480 | return -EINVAL; | 485 | return -EINVAL; |
481 | if ((ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) && tmp) | 486 | if ((minfo->outputs[2].src == MATROXFB_SRC_CRTC1) && tmp) |
482 | return -EBUSY; | 487 | return -EBUSY; |
483 | } | 488 | } |
484 | changes = 0; | 489 | changes = 0; |
485 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 490 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
486 | if (tmp & (1 << out)) { | 491 | if (tmp & (1 << out)) { |
487 | if (ACCESS_FBINFO(outputs[out]).src != MATROXFB_SRC_CRTC2) { | 492 | if (minfo->outputs[out].src != MATROXFB_SRC_CRTC2) { |
488 | changes = 1; | 493 | changes = 1; |
489 | ACCESS_FBINFO(outputs[out]).src = MATROXFB_SRC_CRTC2; | 494 | minfo->outputs[out].src = MATROXFB_SRC_CRTC2; |
490 | } | 495 | } |
491 | } else if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) { | 496 | } else if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) { |
492 | changes = 1; | 497 | changes = 1; |
493 | ACCESS_FBINFO(outputs[out]).src = MATROXFB_SRC_NONE; | 498 | minfo->outputs[out].src = MATROXFB_SRC_NONE; |
494 | } | 499 | } |
495 | } | 500 | } |
496 | if (!changes) | 501 | if (!changes) |
@@ -504,7 +509,7 @@ static int matroxfb_dh_ioctl(struct fb_info *info, | |||
504 | int out; | 509 | int out; |
505 | 510 | ||
506 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 511 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
507 | if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) { | 512 | if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) { |
508 | conn |= 1 << out; | 513 | conn |= 1 << out; |
509 | } | 514 | } |
510 | } | 515 | } |
@@ -518,8 +523,8 @@ static int matroxfb_dh_ioctl(struct fb_info *info, | |||
518 | int out; | 523 | int out; |
519 | 524 | ||
520 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { | 525 | for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { |
521 | if (ACCESS_FBINFO(outputs[out]).output) { | 526 | if (minfo->outputs[out].output) { |
522 | switch (ACCESS_FBINFO(outputs[out]).src) { | 527 | switch (minfo->outputs[out].src) { |
523 | case MATROXFB_SRC_NONE: | 528 | case MATROXFB_SRC_NONE: |
524 | case MATROXFB_SRC_CRTC2: | 529 | case MATROXFB_SRC_CRTC2: |
525 | tmp |= 1 << out; | 530 | tmp |= 1 << out; |
@@ -527,9 +532,9 @@ static int matroxfb_dh_ioctl(struct fb_info *info, | |||
527 | } | 532 | } |
528 | } | 533 | } |
529 | } | 534 | } |
530 | if (ACCESS_FBINFO(devflags.panellink)) { | 535 | if (minfo->devflags.panellink) { |
531 | tmp &= ~MATROXFB_OUTPUT_CONN_DFP; | 536 | tmp &= ~MATROXFB_OUTPUT_CONN_DFP; |
532 | if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) { | 537 | if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1) { |
533 | tmp = 0; | 538 | tmp = 0; |
534 | } | 539 | } |
535 | } | 540 | } |
@@ -590,7 +595,9 @@ static struct fb_var_screeninfo matroxfb_dh_defined = { | |||
590 | 0, {0,0,0,0,0} | 595 | 0, {0,0,0,0,0} |
591 | }; | 596 | }; |
592 | 597 | ||
593 | static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) { | 598 | static int matroxfb_dh_regit(const struct matrox_fb_info *minfo, |
599 | struct matroxfb_dh_fb_info *m2info) | ||
600 | { | ||
594 | #define minfo (m2info->primary_dev) | 601 | #define minfo (m2info->primary_dev) |
595 | void* oldcrtc2; | 602 | void* oldcrtc2; |
596 | 603 | ||
@@ -606,21 +613,21 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) { | |||
606 | if (mem < 64*1024) | 613 | if (mem < 64*1024) |
607 | mem *= 1024; | 614 | mem *= 1024; |
608 | mem &= ~0x00000FFF; /* PAGE_MASK? */ | 615 | mem &= ~0x00000FFF; /* PAGE_MASK? */ |
609 | if (ACCESS_FBINFO(video.len_usable) + mem <= ACCESS_FBINFO(video.len)) | 616 | if (minfo->video.len_usable + mem <= minfo->video.len) |
610 | m2info->video.offbase = ACCESS_FBINFO(video.len) - mem; | 617 | m2info->video.offbase = minfo->video.len - mem; |
611 | else if (ACCESS_FBINFO(video.len) < mem) { | 618 | else if (minfo->video.len < mem) { |
612 | return -ENOMEM; | 619 | return -ENOMEM; |
613 | } else { /* check yres on first head... */ | 620 | } else { /* check yres on first head... */ |
614 | m2info->video.borrowed = mem; | 621 | m2info->video.borrowed = mem; |
615 | ACCESS_FBINFO(video.len_usable) -= mem; | 622 | minfo->video.len_usable -= mem; |
616 | m2info->video.offbase = ACCESS_FBINFO(video.len_usable); | 623 | m2info->video.offbase = minfo->video.len_usable; |
617 | } | 624 | } |
618 | m2info->video.base = ACCESS_FBINFO(video.base) + m2info->video.offbase; | 625 | m2info->video.base = minfo->video.base + m2info->video.offbase; |
619 | m2info->video.len = m2info->video.len_usable = m2info->video.len_maximum = mem; | 626 | m2info->video.len = m2info->video.len_usable = m2info->video.len_maximum = mem; |
620 | m2info->video.vbase.vaddr = vaddr_va(ACCESS_FBINFO(video.vbase)) + m2info->video.offbase; | 627 | m2info->video.vbase.vaddr = vaddr_va(minfo->video.vbase) + m2info->video.offbase; |
621 | m2info->mmio.base = ACCESS_FBINFO(mmio.base); | 628 | m2info->mmio.base = minfo->mmio.base; |
622 | m2info->mmio.vbase = ACCESS_FBINFO(mmio.vbase); | 629 | m2info->mmio.vbase = minfo->mmio.vbase; |
623 | m2info->mmio.len = ACCESS_FBINFO(mmio.len); | 630 | m2info->mmio.len = minfo->mmio.len; |
624 | 631 | ||
625 | matroxfb_dh_init_fix(m2info); | 632 | matroxfb_dh_init_fix(m2info); |
626 | if (register_framebuffer(&m2info->fbcon)) { | 633 | if (register_framebuffer(&m2info->fbcon)) { |
@@ -628,10 +635,10 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) { | |||
628 | } | 635 | } |
629 | if (!m2info->initialized) | 636 | if (!m2info->initialized) |
630 | fb_set_var(&m2info->fbcon, &matroxfb_dh_defined); | 637 | fb_set_var(&m2info->fbcon, &matroxfb_dh_defined); |
631 | down_write(&ACCESS_FBINFO(crtc2.lock)); | 638 | down_write(&minfo->crtc2.lock); |
632 | oldcrtc2 = ACCESS_FBINFO(crtc2.info); | 639 | oldcrtc2 = minfo->crtc2.info; |
633 | ACCESS_FBINFO(crtc2.info) = m2info; | 640 | minfo->crtc2.info = m2info; |
634 | up_write(&ACCESS_FBINFO(crtc2.lock)); | 641 | up_write(&minfo->crtc2.lock); |
635 | if (oldcrtc2) { | 642 | if (oldcrtc2) { |
636 | printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n", | 643 | printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n", |
637 | oldcrtc2); | 644 | oldcrtc2); |
@@ -644,12 +651,12 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) { | |||
644 | 651 | ||
645 | static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) { | 652 | static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) { |
646 | #define minfo (m2info->primary_dev) | 653 | #define minfo (m2info->primary_dev) |
647 | if (matroxfb_dh_regit(PMINFO m2info)) { | 654 | if (matroxfb_dh_regit(minfo, m2info)) { |
648 | printk(KERN_ERR "matroxfb_crtc2: secondary head failed to register\n"); | 655 | printk(KERN_ERR "matroxfb_crtc2: secondary head failed to register\n"); |
649 | return -1; | 656 | return -1; |
650 | } | 657 | } |
651 | printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n", | 658 | printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n", |
652 | ACCESS_FBINFO(fbcon.node), m2info->fbcon.node); | 659 | minfo->fbcon.node, m2info->fbcon.node); |
653 | m2info->fbcon_registered = 1; | 660 | m2info->fbcon_registered = 1; |
654 | return 0; | 661 | return 0; |
655 | #undef minfo | 662 | #undef minfo |
@@ -661,11 +668,11 @@ static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) { | |||
661 | int id; | 668 | int id; |
662 | struct matroxfb_dh_fb_info* crtc2; | 669 | struct matroxfb_dh_fb_info* crtc2; |
663 | 670 | ||
664 | down_write(&ACCESS_FBINFO(crtc2.lock)); | 671 | down_write(&minfo->crtc2.lock); |
665 | crtc2 = ACCESS_FBINFO(crtc2.info); | 672 | crtc2 = minfo->crtc2.info; |
666 | if (crtc2 == m2info) | 673 | if (crtc2 == m2info) |
667 | ACCESS_FBINFO(crtc2.info) = NULL; | 674 | minfo->crtc2.info = NULL; |
668 | up_write(&ACCESS_FBINFO(crtc2.lock)); | 675 | up_write(&minfo->crtc2.lock); |
669 | if (crtc2 != m2info) { | 676 | if (crtc2 != m2info) { |
670 | printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n", | 677 | printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n", |
671 | crtc2, m2info); | 678 | crtc2, m2info); |
@@ -675,7 +682,7 @@ static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) { | |||
675 | id = m2info->fbcon.node; | 682 | id = m2info->fbcon.node; |
676 | unregister_framebuffer(&m2info->fbcon); | 683 | unregister_framebuffer(&m2info->fbcon); |
677 | /* return memory back to primary head */ | 684 | /* return memory back to primary head */ |
678 | ACCESS_FBINFO(video.len_usable) += m2info->video.borrowed; | 685 | minfo->video.len_usable += m2info->video.borrowed; |
679 | printk(KERN_INFO "matroxfb_crtc2: fb%u unregistered\n", id); | 686 | printk(KERN_INFO "matroxfb_crtc2: fb%u unregistered\n", id); |
680 | m2info->fbcon_registered = 0; | 687 | m2info->fbcon_registered = 0; |
681 | } | 688 | } |
@@ -686,14 +693,14 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) { | |||
686 | struct matroxfb_dh_fb_info* m2info; | 693 | struct matroxfb_dh_fb_info* m2info; |
687 | 694 | ||
688 | /* hardware is CRTC2 incapable... */ | 695 | /* hardware is CRTC2 incapable... */ |
689 | if (!ACCESS_FBINFO(devflags.crtc2)) | 696 | if (!minfo->devflags.crtc2) |
690 | return NULL; | 697 | return NULL; |
691 | m2info = kzalloc(sizeof(*m2info), GFP_KERNEL); | 698 | m2info = kzalloc(sizeof(*m2info), GFP_KERNEL); |
692 | if (!m2info) { | 699 | if (!m2info) { |
693 | printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n"); | 700 | printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n"); |
694 | return NULL; | 701 | return NULL; |
695 | } | 702 | } |
696 | m2info->primary_dev = MINFO; | 703 | m2info->primary_dev = minfo; |
697 | if (matroxfb_dh_registerfb(m2info)) { | 704 | if (matroxfb_dh_registerfb(m2info)) { |
698 | kfree(m2info); | 705 | kfree(m2info); |
699 | printk(KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n"); | 706 | printk(KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n"); |
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c index 6209a761f674..cff0546ea6fd 100644 --- a/drivers/video/matrox/matroxfb_g450.c +++ b/drivers/video/matrox/matroxfb_g450.c | |||
@@ -80,52 +80,59 @@ static int get_ctrl_id(__u32 v4l2_id) { | |||
80 | return -EINVAL; | 80 | return -EINVAL; |
81 | } | 81 | } |
82 | 82 | ||
83 | static inline int* get_ctrl_ptr(WPMINFO unsigned int idx) { | 83 | static inline int *get_ctrl_ptr(struct matrox_fb_info *minfo, unsigned int idx) |
84 | return (int*)((char*)MINFO + g450_controls[idx].control); | 84 | { |
85 | return (int*)((char*)minfo + g450_controls[idx].control); | ||
85 | } | 86 | } |
86 | 87 | ||
87 | static void tvo_fill_defaults(WPMINFO2) { | 88 | static void tvo_fill_defaults(struct matrox_fb_info *minfo) |
89 | { | ||
88 | unsigned int i; | 90 | unsigned int i; |
89 | 91 | ||
90 | for (i = 0; i < G450CTRLS; i++) { | 92 | for (i = 0; i < G450CTRLS; i++) { |
91 | *get_ctrl_ptr(PMINFO i) = g450_controls[i].desc.default_value; | 93 | *get_ctrl_ptr(minfo, i) = g450_controls[i].desc.default_value; |
92 | } | 94 | } |
93 | } | 95 | } |
94 | 96 | ||
95 | static int cve2_get_reg(WPMINFO int reg) { | 97 | static int cve2_get_reg(struct matrox_fb_info *minfo, int reg) |
98 | { | ||
96 | unsigned long flags; | 99 | unsigned long flags; |
97 | int val; | 100 | int val; |
98 | 101 | ||
99 | matroxfb_DAC_lock_irqsave(flags); | 102 | matroxfb_DAC_lock_irqsave(flags); |
100 | matroxfb_DAC_out(PMINFO 0x87, reg); | 103 | matroxfb_DAC_out(minfo, 0x87, reg); |
101 | val = matroxfb_DAC_in(PMINFO 0x88); | 104 | val = matroxfb_DAC_in(minfo, 0x88); |
102 | matroxfb_DAC_unlock_irqrestore(flags); | 105 | matroxfb_DAC_unlock_irqrestore(flags); |
103 | return val; | 106 | return val; |
104 | } | 107 | } |
105 | 108 | ||
106 | static void cve2_set_reg(WPMINFO int reg, int val) { | 109 | static void cve2_set_reg(struct matrox_fb_info *minfo, int reg, int val) |
110 | { | ||
107 | unsigned long flags; | 111 | unsigned long flags; |
108 | 112 | ||
109 | matroxfb_DAC_lock_irqsave(flags); | 113 | matroxfb_DAC_lock_irqsave(flags); |
110 | matroxfb_DAC_out(PMINFO 0x87, reg); | 114 | matroxfb_DAC_out(minfo, 0x87, reg); |
111 | matroxfb_DAC_out(PMINFO 0x88, val); | 115 | matroxfb_DAC_out(minfo, 0x88, val); |
112 | matroxfb_DAC_unlock_irqrestore(flags); | 116 | matroxfb_DAC_unlock_irqrestore(flags); |
113 | } | 117 | } |
114 | 118 | ||
115 | static void cve2_set_reg10(WPMINFO int reg, int val) { | 119 | static void cve2_set_reg10(struct matrox_fb_info *minfo, int reg, int val) |
120 | { | ||
116 | unsigned long flags; | 121 | unsigned long flags; |
117 | 122 | ||
118 | matroxfb_DAC_lock_irqsave(flags); | 123 | matroxfb_DAC_lock_irqsave(flags); |
119 | matroxfb_DAC_out(PMINFO 0x87, reg); | 124 | matroxfb_DAC_out(minfo, 0x87, reg); |
120 | matroxfb_DAC_out(PMINFO 0x88, val >> 2); | 125 | matroxfb_DAC_out(minfo, 0x88, val >> 2); |
121 | matroxfb_DAC_out(PMINFO 0x87, reg + 1); | 126 | matroxfb_DAC_out(minfo, 0x87, reg + 1); |
122 | matroxfb_DAC_out(PMINFO 0x88, val & 3); | 127 | matroxfb_DAC_out(minfo, 0x88, val & 3); |
123 | matroxfb_DAC_unlock_irqrestore(flags); | 128 | matroxfb_DAC_unlock_irqrestore(flags); |
124 | } | 129 | } |
125 | 130 | ||
126 | static void g450_compute_bwlevel(CPMINFO int *bl, int *wl) { | 131 | static void g450_compute_bwlevel(const struct matrox_fb_info *minfo, int *bl, |
127 | const int b = ACCESS_FBINFO(altout.tvo_params.brightness) + BLMIN; | 132 | int *wl) |
128 | const int c = ACCESS_FBINFO(altout.tvo_params.contrast); | 133 | { |
134 | const int b = minfo->altout.tvo_params.brightness + BLMIN; | ||
135 | const int c = minfo->altout.tvo_params.contrast; | ||
129 | 136 | ||
130 | *bl = max(b - c, BLMIN); | 137 | *bl = max(b - c, BLMIN); |
131 | *wl = min(b + c, WLMAX); | 138 | *wl = min(b + c, WLMAX); |
@@ -154,7 +161,7 @@ static int g450_query_ctrl(void* md, struct v4l2_queryctrl *p) { | |||
154 | 161 | ||
155 | static int g450_set_ctrl(void* md, struct v4l2_control *p) { | 162 | static int g450_set_ctrl(void* md, struct v4l2_control *p) { |
156 | int i; | 163 | int i; |
157 | MINFO_FROM(md); | 164 | struct matrox_fb_info *minfo = md; |
158 | 165 | ||
159 | i = get_ctrl_id(p->id); | 166 | i = get_ctrl_id(p->id); |
160 | if (i < 0) return -EINVAL; | 167 | if (i < 0) return -EINVAL; |
@@ -162,7 +169,7 @@ static int g450_set_ctrl(void* md, struct v4l2_control *p) { | |||
162 | /* | 169 | /* |
163 | * Check if changed. | 170 | * Check if changed. |
164 | */ | 171 | */ |
165 | if (p->value == *get_ctrl_ptr(PMINFO i)) return 0; | 172 | if (p->value == *get_ctrl_ptr(minfo, i)) return 0; |
166 | 173 | ||
167 | /* | 174 | /* |
168 | * Check limits. | 175 | * Check limits. |
@@ -173,31 +180,31 @@ static int g450_set_ctrl(void* md, struct v4l2_control *p) { | |||
173 | /* | 180 | /* |
174 | * Store new value. | 181 | * Store new value. |
175 | */ | 182 | */ |
176 | *get_ctrl_ptr(PMINFO i) = p->value; | 183 | *get_ctrl_ptr(minfo, i) = p->value; |
177 | 184 | ||
178 | switch (p->id) { | 185 | switch (p->id) { |
179 | case V4L2_CID_BRIGHTNESS: | 186 | case V4L2_CID_BRIGHTNESS: |
180 | case V4L2_CID_CONTRAST: | 187 | case V4L2_CID_CONTRAST: |
181 | { | 188 | { |
182 | int blacklevel, whitelevel; | 189 | int blacklevel, whitelevel; |
183 | g450_compute_bwlevel(PMINFO &blacklevel, &whitelevel); | 190 | g450_compute_bwlevel(minfo, &blacklevel, &whitelevel); |
184 | cve2_set_reg10(PMINFO 0x0e, blacklevel); | 191 | cve2_set_reg10(minfo, 0x0e, blacklevel); |
185 | cve2_set_reg10(PMINFO 0x1e, whitelevel); | 192 | cve2_set_reg10(minfo, 0x1e, whitelevel); |
186 | } | 193 | } |
187 | break; | 194 | break; |
188 | case V4L2_CID_SATURATION: | 195 | case V4L2_CID_SATURATION: |
189 | cve2_set_reg(PMINFO 0x20, p->value); | 196 | cve2_set_reg(minfo, 0x20, p->value); |
190 | cve2_set_reg(PMINFO 0x22, p->value); | 197 | cve2_set_reg(minfo, 0x22, p->value); |
191 | break; | 198 | break; |
192 | case V4L2_CID_HUE: | 199 | case V4L2_CID_HUE: |
193 | cve2_set_reg(PMINFO 0x25, p->value); | 200 | cve2_set_reg(minfo, 0x25, p->value); |
194 | break; | 201 | break; |
195 | case MATROXFB_CID_TESTOUT: | 202 | case MATROXFB_CID_TESTOUT: |
196 | { | 203 | { |
197 | unsigned char val = cve2_get_reg (PMINFO 0x05); | 204 | unsigned char val = cve2_get_reg(minfo, 0x05); |
198 | if (p->value) val |= 0x02; | 205 | if (p->value) val |= 0x02; |
199 | else val &= ~0x02; | 206 | else val &= ~0x02; |
200 | cve2_set_reg(PMINFO 0x05, val); | 207 | cve2_set_reg(minfo, 0x05, val); |
201 | } | 208 | } |
202 | break; | 209 | break; |
203 | } | 210 | } |
@@ -208,11 +215,11 @@ static int g450_set_ctrl(void* md, struct v4l2_control *p) { | |||
208 | 215 | ||
209 | static int g450_get_ctrl(void* md, struct v4l2_control *p) { | 216 | static int g450_get_ctrl(void* md, struct v4l2_control *p) { |
210 | int i; | 217 | int i; |
211 | MINFO_FROM(md); | 218 | struct matrox_fb_info *minfo = md; |
212 | 219 | ||
213 | i = get_ctrl_id(p->id); | 220 | i = get_ctrl_id(p->id); |
214 | if (i < 0) return -EINVAL; | 221 | if (i < 0) return -EINVAL; |
215 | p->value = *get_ctrl_ptr(PMINFO i); | 222 | p->value = *get_ctrl_ptr(minfo, i); |
216 | return 0; | 223 | return 0; |
217 | } | 224 | } |
218 | 225 | ||
@@ -226,7 +233,9 @@ struct output_desc { | |||
226 | unsigned int v_total; | 233 | unsigned int v_total; |
227 | }; | 234 | }; |
228 | 235 | ||
229 | static void computeRegs(WPMINFO struct mavenregs* r, struct my_timming* mt, const struct output_desc* outd) { | 236 | static void computeRegs(struct matrox_fb_info *minfo, struct mavenregs *r, |
237 | struct my_timming *mt, const struct output_desc *outd) | ||
238 | { | ||
230 | u_int32_t chromasc; | 239 | u_int32_t chromasc; |
231 | u_int32_t hlen; | 240 | u_int32_t hlen; |
232 | u_int32_t hsl; | 241 | u_int32_t hsl; |
@@ -251,10 +260,10 @@ static void computeRegs(WPMINFO struct mavenregs* r, struct my_timming* mt, cons | |||
251 | 260 | ||
252 | dprintk(KERN_DEBUG "Want %u kHz pixclock\n", (unsigned int)piic); | 261 | dprintk(KERN_DEBUG "Want %u kHz pixclock\n", (unsigned int)piic); |
253 | 262 | ||
254 | mnp = matroxfb_g450_setclk(PMINFO piic, M_VIDEO_PLL); | 263 | mnp = matroxfb_g450_setclk(minfo, piic, M_VIDEO_PLL); |
255 | 264 | ||
256 | mt->mnp = mnp; | 265 | mt->mnp = mnp; |
257 | mt->pixclock = g450_mnp2f(PMINFO mnp); | 266 | mt->pixclock = g450_mnp2f(minfo, mnp); |
258 | 267 | ||
259 | dprintk(KERN_DEBUG "MNP=%08X\n", mnp); | 268 | dprintk(KERN_DEBUG "MNP=%08X\n", mnp); |
260 | 269 | ||
@@ -490,65 +499,67 @@ static void cve2_init_TVdata(int norm, struct mavenregs* data, const struct outp | |||
490 | return; | 499 | return; |
491 | } | 500 | } |
492 | 501 | ||
493 | #define LR(x) cve2_set_reg(PMINFO (x), m->regs[(x)]) | 502 | #define LR(x) cve2_set_reg(minfo, (x), m->regs[(x)]) |
494 | static void cve2_init_TV(WPMINFO const struct mavenregs* m) { | 503 | static void cve2_init_TV(struct matrox_fb_info *minfo, |
504 | const struct mavenregs *m) | ||
505 | { | ||
495 | int i; | 506 | int i; |
496 | 507 | ||
497 | LR(0x80); | 508 | LR(0x80); |
498 | LR(0x82); LR(0x83); | 509 | LR(0x82); LR(0x83); |
499 | LR(0x84); LR(0x85); | 510 | LR(0x84); LR(0x85); |
500 | 511 | ||
501 | cve2_set_reg(PMINFO 0x3E, 0x01); | 512 | cve2_set_reg(minfo, 0x3E, 0x01); |
502 | 513 | ||
503 | for (i = 0; i < 0x3E; i++) { | 514 | for (i = 0; i < 0x3E; i++) { |
504 | LR(i); | 515 | LR(i); |
505 | } | 516 | } |
506 | cve2_set_reg(PMINFO 0x3E, 0x00); | 517 | cve2_set_reg(minfo, 0x3E, 0x00); |
507 | } | 518 | } |
508 | 519 | ||
509 | static int matroxfb_g450_compute(void* md, struct my_timming* mt) { | 520 | static int matroxfb_g450_compute(void* md, struct my_timming* mt) { |
510 | MINFO_FROM(md); | 521 | struct matrox_fb_info *minfo = md; |
511 | 522 | ||
512 | dprintk(KERN_DEBUG "Computing, mode=%u\n", ACCESS_FBINFO(outputs[1]).mode); | 523 | dprintk(KERN_DEBUG "Computing, mode=%u\n", minfo->outputs[1].mode); |
513 | 524 | ||
514 | if (mt->crtc == MATROXFB_SRC_CRTC2 && | 525 | if (mt->crtc == MATROXFB_SRC_CRTC2 && |
515 | ACCESS_FBINFO(outputs[1]).mode != MATROXFB_OUTPUT_MODE_MONITOR) { | 526 | minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) { |
516 | const struct output_desc* outd; | 527 | const struct output_desc* outd; |
517 | 528 | ||
518 | cve2_init_TVdata(ACCESS_FBINFO(outputs[1]).mode, &ACCESS_FBINFO(hw).maven, &outd); | 529 | cve2_init_TVdata(minfo->outputs[1].mode, &minfo->hw.maven, &outd); |
519 | { | 530 | { |
520 | int blacklevel, whitelevel; | 531 | int blacklevel, whitelevel; |
521 | g450_compute_bwlevel(PMINFO &blacklevel, &whitelevel); | 532 | g450_compute_bwlevel(minfo, &blacklevel, &whitelevel); |
522 | ACCESS_FBINFO(hw).maven.regs[0x0E] = blacklevel >> 2; | 533 | minfo->hw.maven.regs[0x0E] = blacklevel >> 2; |
523 | ACCESS_FBINFO(hw).maven.regs[0x0F] = blacklevel & 3; | 534 | minfo->hw.maven.regs[0x0F] = blacklevel & 3; |
524 | ACCESS_FBINFO(hw).maven.regs[0x1E] = whitelevel >> 2; | 535 | minfo->hw.maven.regs[0x1E] = whitelevel >> 2; |
525 | ACCESS_FBINFO(hw).maven.regs[0x1F] = whitelevel & 3; | 536 | minfo->hw.maven.regs[0x1F] = whitelevel & 3; |
526 | 537 | ||
527 | ACCESS_FBINFO(hw).maven.regs[0x20] = | 538 | minfo->hw.maven.regs[0x20] = |
528 | ACCESS_FBINFO(hw).maven.regs[0x22] = ACCESS_FBINFO(altout.tvo_params.saturation); | 539 | minfo->hw.maven.regs[0x22] = minfo->altout.tvo_params.saturation; |
529 | 540 | ||
530 | ACCESS_FBINFO(hw).maven.regs[0x25] = ACCESS_FBINFO(altout.tvo_params.hue); | 541 | minfo->hw.maven.regs[0x25] = minfo->altout.tvo_params.hue; |
531 | 542 | ||
532 | if (ACCESS_FBINFO(altout.tvo_params.testout)) { | 543 | if (minfo->altout.tvo_params.testout) { |
533 | ACCESS_FBINFO(hw).maven.regs[0x05] |= 0x02; | 544 | minfo->hw.maven.regs[0x05] |= 0x02; |
534 | } | 545 | } |
535 | } | 546 | } |
536 | computeRegs(PMINFO &ACCESS_FBINFO(hw).maven, mt, outd); | 547 | computeRegs(minfo, &minfo->hw.maven, mt, outd); |
537 | } else if (mt->mnp < 0) { | 548 | } else if (mt->mnp < 0) { |
538 | /* We must program clocks before CRTC2, otherwise interlaced mode | 549 | /* We must program clocks before CRTC2, otherwise interlaced mode |
539 | startup may fail */ | 550 | startup may fail */ |
540 | mt->mnp = matroxfb_g450_setclk(PMINFO mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); | 551 | mt->mnp = matroxfb_g450_setclk(minfo, mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); |
541 | mt->pixclock = g450_mnp2f(PMINFO mt->mnp); | 552 | mt->pixclock = g450_mnp2f(minfo, mt->mnp); |
542 | } | 553 | } |
543 | dprintk(KERN_DEBUG "Pixclock = %u\n", mt->pixclock); | 554 | dprintk(KERN_DEBUG "Pixclock = %u\n", mt->pixclock); |
544 | return 0; | 555 | return 0; |
545 | } | 556 | } |
546 | 557 | ||
547 | static int matroxfb_g450_program(void* md) { | 558 | static int matroxfb_g450_program(void* md) { |
548 | MINFO_FROM(md); | 559 | struct matrox_fb_info *minfo = md; |
549 | 560 | ||
550 | if (ACCESS_FBINFO(outputs[1]).mode != MATROXFB_OUTPUT_MODE_MONITOR) { | 561 | if (minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) { |
551 | cve2_init_TV(PMINFO &ACCESS_FBINFO(hw).maven); | 562 | cve2_init_TV(minfo, &minfo->hw.maven); |
552 | } | 563 | } |
553 | return 0; | 564 | return 0; |
554 | } | 565 | } |
@@ -564,11 +575,11 @@ static int matroxfb_g450_verify_mode(void* md, u_int32_t arg) { | |||
564 | } | 575 | } |
565 | 576 | ||
566 | static int g450_dvi_compute(void* md, struct my_timming* mt) { | 577 | static int g450_dvi_compute(void* md, struct my_timming* mt) { |
567 | MINFO_FROM(md); | 578 | struct matrox_fb_info *minfo = md; |
568 | 579 | ||
569 | if (mt->mnp < 0) { | 580 | if (mt->mnp < 0) { |
570 | mt->mnp = matroxfb_g450_setclk(PMINFO mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); | 581 | mt->mnp = matroxfb_g450_setclk(minfo, mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); |
571 | mt->pixclock = g450_mnp2f(PMINFO mt->mnp); | 582 | mt->pixclock = g450_mnp2f(minfo, mt->mnp); |
572 | } | 583 | } |
573 | return 0; | 584 | return 0; |
574 | } | 585 | } |
@@ -588,34 +599,36 @@ static struct matrox_altout matroxfb_g450_dvi = { | |||
588 | .compute = g450_dvi_compute, | 599 | .compute = g450_dvi_compute, |
589 | }; | 600 | }; |
590 | 601 | ||
591 | void matroxfb_g450_connect(WPMINFO2) { | 602 | void matroxfb_g450_connect(struct matrox_fb_info *minfo) |
592 | if (ACCESS_FBINFO(devflags.g450dac)) { | 603 | { |
593 | down_write(&ACCESS_FBINFO(altout.lock)); | 604 | if (minfo->devflags.g450dac) { |
594 | tvo_fill_defaults(PMINFO2); | 605 | down_write(&minfo->altout.lock); |
595 | ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; | 606 | tvo_fill_defaults(minfo); |
596 | ACCESS_FBINFO(outputs[1]).data = MINFO; | 607 | minfo->outputs[1].src = minfo->outputs[1].default_src; |
597 | ACCESS_FBINFO(outputs[1]).output = &matroxfb_g450_altout; | 608 | minfo->outputs[1].data = minfo; |
598 | ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 609 | minfo->outputs[1].output = &matroxfb_g450_altout; |
599 | ACCESS_FBINFO(outputs[2]).src = ACCESS_FBINFO(outputs[2]).default_src; | 610 | minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
600 | ACCESS_FBINFO(outputs[2]).data = MINFO; | 611 | minfo->outputs[2].src = minfo->outputs[2].default_src; |
601 | ACCESS_FBINFO(outputs[2]).output = &matroxfb_g450_dvi; | 612 | minfo->outputs[2].data = minfo; |
602 | ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 613 | minfo->outputs[2].output = &matroxfb_g450_dvi; |
603 | up_write(&ACCESS_FBINFO(altout.lock)); | 614 | minfo->outputs[2].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
615 | up_write(&minfo->altout.lock); | ||
604 | } | 616 | } |
605 | } | 617 | } |
606 | 618 | ||
607 | void matroxfb_g450_shutdown(WPMINFO2) { | 619 | void matroxfb_g450_shutdown(struct matrox_fb_info *minfo) |
608 | if (ACCESS_FBINFO(devflags.g450dac)) { | 620 | { |
609 | down_write(&ACCESS_FBINFO(altout.lock)); | 621 | if (minfo->devflags.g450dac) { |
610 | ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE; | 622 | down_write(&minfo->altout.lock); |
611 | ACCESS_FBINFO(outputs[1]).output = NULL; | 623 | minfo->outputs[1].src = MATROXFB_SRC_NONE; |
612 | ACCESS_FBINFO(outputs[1]).data = NULL; | 624 | minfo->outputs[1].output = NULL; |
613 | ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 625 | minfo->outputs[1].data = NULL; |
614 | ACCESS_FBINFO(outputs[2]).src = MATROXFB_SRC_NONE; | 626 | minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
615 | ACCESS_FBINFO(outputs[2]).output = NULL; | 627 | minfo->outputs[2].src = MATROXFB_SRC_NONE; |
616 | ACCESS_FBINFO(outputs[2]).data = NULL; | 628 | minfo->outputs[2].output = NULL; |
617 | ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 629 | minfo->outputs[2].data = NULL; |
618 | up_write(&ACCESS_FBINFO(altout.lock)); | 630 | minfo->outputs[2].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
631 | up_write(&minfo->altout.lock); | ||
619 | } | 632 | } |
620 | } | 633 | } |
621 | 634 | ||
diff --git a/drivers/video/matrox/matroxfb_g450.h b/drivers/video/matrox/matroxfb_g450.h index a0822a6033e5..3a3e654444b8 100644 --- a/drivers/video/matrox/matroxfb_g450.h +++ b/drivers/video/matrox/matroxfb_g450.h | |||
@@ -4,11 +4,11 @@ | |||
4 | #include "matroxfb_base.h" | 4 | #include "matroxfb_base.h" |
5 | 5 | ||
6 | #ifdef CONFIG_FB_MATROX_G | 6 | #ifdef CONFIG_FB_MATROX_G |
7 | void matroxfb_g450_connect(WPMINFO2); | 7 | void matroxfb_g450_connect(struct matrox_fb_info *minfo); |
8 | void matroxfb_g450_shutdown(WPMINFO2); | 8 | void matroxfb_g450_shutdown(struct matrox_fb_info *minfo); |
9 | #else | 9 | #else |
10 | static inline void matroxfb_g450_connect(WPMINFO2) { }; | 10 | static inline void matroxfb_g450_connect(struct matrox_fb_info *minfo) { }; |
11 | static inline void matroxfb_g450_shutdown(WPMINFO2) { }; | 11 | static inline void matroxfb_g450_shutdown(struct matrox_fb_info *minfo) { }; |
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | #endif /* __MATROXFB_G450_H__ */ | 14 | #endif /* __MATROXFB_G450_H__ */ |
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index 042408a8c631..91af9159111f 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c | |||
@@ -458,9 +458,9 @@ static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* dat | |||
458 | 0x00, /* 3E written multiple times */ | 458 | 0x00, /* 3E written multiple times */ |
459 | 0x00, /* never written */ | 459 | 0x00, /* never written */ |
460 | }, MATROXFB_OUTPUT_MODE_NTSC, 525, 60 }; | 460 | }, MATROXFB_OUTPUT_MODE_NTSC, 525, 60 }; |
461 | MINFO_FROM(md->primary_head); | 461 | struct matrox_fb_info *minfo = md->primary_head; |
462 | 462 | ||
463 | if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_PAL) | 463 | if (minfo->outputs[1].mode == MATROXFB_OUTPUT_MODE_PAL) |
464 | *data = palregs; | 464 | *data = palregs; |
465 | else | 465 | else |
466 | *data = ntscregs; | 466 | *data = ntscregs; |
@@ -496,11 +496,11 @@ static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* dat | |||
496 | /* Set saturation */ | 496 | /* Set saturation */ |
497 | { | 497 | { |
498 | data->regs[0x20] = | 498 | data->regs[0x20] = |
499 | data->regs[0x22] = ACCESS_FBINFO(altout.tvo_params.saturation); | 499 | data->regs[0x22] = minfo->altout.tvo_params.saturation; |
500 | } | 500 | } |
501 | 501 | ||
502 | /* Set HUE */ | 502 | /* Set HUE */ |
503 | data->regs[0x25] = ACCESS_FBINFO(altout.tvo_params.hue); | 503 | data->regs[0x25] = minfo->altout.tvo_params.hue; |
504 | return; | 504 | return; |
505 | } | 505 | } |
506 | 506 | ||
@@ -741,9 +741,9 @@ static inline int maven_compute_timming(struct maven_data* md, | |||
741 | struct mavenregs* m) { | 741 | struct mavenregs* m) { |
742 | unsigned int tmpi; | 742 | unsigned int tmpi; |
743 | unsigned int a, bv, c; | 743 | unsigned int a, bv, c; |
744 | MINFO_FROM(md->primary_head); | 744 | struct matrox_fb_info *minfo = md->primary_head; |
745 | 745 | ||
746 | m->mode = ACCESS_FBINFO(outputs[1]).mode; | 746 | m->mode = minfo->outputs[1].mode; |
747 | if (m->mode != MATROXFB_OUTPUT_MODE_MONITOR) { | 747 | if (m->mode != MATROXFB_OUTPUT_MODE_MONITOR) { |
748 | unsigned int lmargin; | 748 | unsigned int lmargin; |
749 | unsigned int umargin; | 749 | unsigned int umargin; |
@@ -1132,7 +1132,7 @@ static int maven_get_control (struct maven_data* md, | |||
1132 | static int maven_out_compute(void* md, struct my_timming* mt) { | 1132 | static int maven_out_compute(void* md, struct my_timming* mt) { |
1133 | #define mdinfo ((struct maven_data*)md) | 1133 | #define mdinfo ((struct maven_data*)md) |
1134 | #define minfo (mdinfo->primary_head) | 1134 | #define minfo (mdinfo->primary_head) |
1135 | return maven_compute_timming(md, mt, &ACCESS_FBINFO(hw).maven); | 1135 | return maven_compute_timming(md, mt, &minfo->hw.maven); |
1136 | #undef minfo | 1136 | #undef minfo |
1137 | #undef mdinfo | 1137 | #undef mdinfo |
1138 | } | 1138 | } |
@@ -1140,7 +1140,7 @@ static int maven_out_compute(void* md, struct my_timming* mt) { | |||
1140 | static int maven_out_program(void* md) { | 1140 | static int maven_out_program(void* md) { |
1141 | #define mdinfo ((struct maven_data*)md) | 1141 | #define mdinfo ((struct maven_data*)md) |
1142 | #define minfo (mdinfo->primary_head) | 1142 | #define minfo (mdinfo->primary_head) |
1143 | return maven_program_timming(md, &ACCESS_FBINFO(hw).maven); | 1143 | return maven_program_timming(md, &minfo->hw.maven); |
1144 | #undef minfo | 1144 | #undef minfo |
1145 | #undef mdinfo | 1145 | #undef mdinfo |
1146 | } | 1146 | } |
@@ -1184,16 +1184,18 @@ static struct matrox_altout maven_altout = { | |||
1184 | 1184 | ||
1185 | static int maven_init_client(struct i2c_client* clnt) { | 1185 | static int maven_init_client(struct i2c_client* clnt) { |
1186 | struct maven_data* md = i2c_get_clientdata(clnt); | 1186 | struct maven_data* md = i2c_get_clientdata(clnt); |
1187 | MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo); | 1187 | struct matrox_fb_info *minfo = container_of(clnt->adapter, |
1188 | struct i2c_bit_adapter, | ||
1189 | adapter)->minfo; | ||
1188 | 1190 | ||
1189 | md->primary_head = MINFO; | 1191 | md->primary_head = minfo; |
1190 | md->client = clnt; | 1192 | md->client = clnt; |
1191 | down_write(&ACCESS_FBINFO(altout.lock)); | 1193 | down_write(&minfo->altout.lock); |
1192 | ACCESS_FBINFO(outputs[1]).output = &maven_altout; | 1194 | minfo->outputs[1].output = &maven_altout; |
1193 | ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; | 1195 | minfo->outputs[1].src = minfo->outputs[1].default_src; |
1194 | ACCESS_FBINFO(outputs[1]).data = md; | 1196 | minfo->outputs[1].data = md; |
1195 | ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 1197 | minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
1196 | up_write(&ACCESS_FBINFO(altout.lock)); | 1198 | up_write(&minfo->altout.lock); |
1197 | if (maven_get_reg(clnt, 0xB2) < 0x14) { | 1199 | if (maven_get_reg(clnt, 0xB2) < 0x14) { |
1198 | md->version = MGATVO_B; | 1200 | md->version = MGATVO_B; |
1199 | /* Tweak some things for this old chip */ | 1201 | /* Tweak some things for this old chip */ |
@@ -1218,14 +1220,14 @@ static int maven_shutdown_client(struct i2c_client* clnt) { | |||
1218 | struct maven_data* md = i2c_get_clientdata(clnt); | 1220 | struct maven_data* md = i2c_get_clientdata(clnt); |
1219 | 1221 | ||
1220 | if (md->primary_head) { | 1222 | if (md->primary_head) { |
1221 | MINFO_FROM(md->primary_head); | 1223 | struct matrox_fb_info *minfo = md->primary_head; |
1222 | 1224 | ||
1223 | down_write(&ACCESS_FBINFO(altout.lock)); | 1225 | down_write(&minfo->altout.lock); |
1224 | ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE; | 1226 | minfo->outputs[1].src = MATROXFB_SRC_NONE; |
1225 | ACCESS_FBINFO(outputs[1]).output = NULL; | 1227 | minfo->outputs[1].output = NULL; |
1226 | ACCESS_FBINFO(outputs[1]).data = NULL; | 1228 | minfo->outputs[1].data = NULL; |
1227 | ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; | 1229 | minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR; |
1228 | up_write(&ACCESS_FBINFO(altout.lock)); | 1230 | up_write(&minfo->altout.lock); |
1229 | md->primary_head = NULL; | 1231 | md->primary_head = NULL; |
1230 | } | 1232 | } |
1231 | return 0; | 1233 | return 0; |
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index 5b5f072fc1a8..9948ca2a3046 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c | |||
@@ -89,13 +89,15 @@ | |||
89 | #include <linux/interrupt.h> | 89 | #include <linux/interrupt.h> |
90 | #include <linux/matroxfb.h> | 90 | #include <linux/matroxfb.h> |
91 | 91 | ||
92 | void matroxfb_DAC_out(CPMINFO int reg, int val) { | 92 | void matroxfb_DAC_out(const struct matrox_fb_info *minfo, int reg, int val) |
93 | { | ||
93 | DBG_REG(__func__) | 94 | DBG_REG(__func__) |
94 | mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg); | 95 | mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg); |
95 | mga_outb(M_RAMDAC_BASE+M_X_DATAREG, val); | 96 | mga_outb(M_RAMDAC_BASE+M_X_DATAREG, val); |
96 | } | 97 | } |
97 | 98 | ||
98 | int matroxfb_DAC_in(CPMINFO int reg) { | 99 | int matroxfb_DAC_in(const struct matrox_fb_info *minfo, int reg) |
100 | { | ||
99 | DBG_REG(__func__) | 101 | DBG_REG(__func__) |
100 | mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg); | 102 | mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg); |
101 | return mga_inb(M_RAMDAC_BASE+M_X_DATAREG); | 103 | return mga_inb(M_RAMDAC_BASE+M_X_DATAREG); |
@@ -184,13 +186,14 @@ int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int f | |||
184 | return bestvco; | 186 | return bestvco; |
185 | } | 187 | } |
186 | 188 | ||
187 | int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | 189 | int matroxfb_vgaHWinit(struct matrox_fb_info *minfo, struct my_timming *m) |
190 | { | ||
188 | unsigned int hd, hs, he, hbe, ht; | 191 | unsigned int hd, hs, he, hbe, ht; |
189 | unsigned int vd, vs, ve, vt, lc; | 192 | unsigned int vd, vs, ve, vt, lc; |
190 | unsigned int wd; | 193 | unsigned int wd; |
191 | unsigned int divider; | 194 | unsigned int divider; |
192 | int i; | 195 | int i; |
193 | struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw); | 196 | struct matrox_hw_state * const hw = &minfo->hw; |
194 | 197 | ||
195 | DBG(__func__) | 198 | DBG(__func__) |
196 | 199 | ||
@@ -240,7 +243,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | |||
240 | /* standard timmings are in 8pixels, but for interleaved we cannot */ | 243 | /* standard timmings are in 8pixels, but for interleaved we cannot */ |
241 | /* do it for 4bpp (because of (4bpp >> 1(interleaved))/4 == 0) */ | 244 | /* do it for 4bpp (because of (4bpp >> 1(interleaved))/4 == 0) */ |
242 | /* using 16 or more pixels per unit can save us */ | 245 | /* using 16 or more pixels per unit can save us */ |
243 | divider = ACCESS_FBINFO(curr.final_bppShift); | 246 | divider = minfo->curr.final_bppShift; |
244 | while (divider & 3) { | 247 | while (divider & 3) { |
245 | hd >>= 1; | 248 | hd >>= 1; |
246 | hs >>= 1; | 249 | hs >>= 1; |
@@ -270,7 +273,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | |||
270 | if (((ht & 0x07) == 0x06) || ((ht & 0x0F) == 0x04)) | 273 | if (((ht & 0x07) == 0x06) || ((ht & 0x0F) == 0x04)) |
271 | ht++; | 274 | ht++; |
272 | hbe = ht; | 275 | hbe = ht; |
273 | wd = ACCESS_FBINFO(fbcon).var.xres_virtual * ACCESS_FBINFO(curr.final_bppShift) / 64; | 276 | wd = minfo->fbcon.var.xres_virtual * minfo->curr.final_bppShift / 64; |
274 | 277 | ||
275 | hw->CRTCEXT[0] = 0; | 278 | hw->CRTCEXT[0] = 0; |
276 | hw->CRTCEXT[5] = 0; | 279 | hw->CRTCEXT[5] = 0; |
@@ -287,7 +290,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | |||
287 | ((hs & 0x100) >> 6) | /* sync start */ | 290 | ((hs & 0x100) >> 6) | /* sync start */ |
288 | (hbe & 0x040); /* end hor. blanking */ | 291 | (hbe & 0x040); /* end hor. blanking */ |
289 | /* FIXME: Enable vidrst only on G400, and only if TV-out is used */ | 292 | /* FIXME: Enable vidrst only on G400, and only if TV-out is used */ |
290 | if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) | 293 | if (minfo->outputs[1].src == MATROXFB_SRC_CRTC1) |
291 | hw->CRTCEXT[1] |= 0x88; /* enable horizontal and vertical vidrst */ | 294 | hw->CRTCEXT[1] |= 0x88; /* enable horizontal and vertical vidrst */ |
292 | hw->CRTCEXT[2] = ((vt & 0xC00) >> 10) | | 295 | hw->CRTCEXT[2] = ((vt & 0xC00) >> 10) | |
293 | ((vd & 0x400) >> 8) | /* disp end */ | 296 | ((vd & 0x400) >> 8) | /* disp end */ |
@@ -331,9 +334,10 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | |||
331 | return 0; | 334 | return 0; |
332 | }; | 335 | }; |
333 | 336 | ||
334 | void matroxfb_vgaHWrestore(WPMINFO2) { | 337 | void matroxfb_vgaHWrestore(struct matrox_fb_info *minfo) |
338 | { | ||
335 | int i; | 339 | int i; |
336 | struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw); | 340 | struct matrox_hw_state * const hw = &minfo->hw; |
337 | CRITFLAGS | 341 | CRITFLAGS |
338 | 342 | ||
339 | DBG(__func__) | 343 | DBG(__func__) |
@@ -522,7 +526,9 @@ static void parse_bios(unsigned char __iomem* vbios, struct matrox_bios* bd) { | |||
522 | #endif | 526 | #endif |
523 | } | 527 | } |
524 | 528 | ||
525 | static int parse_pins1(WPMINFO const struct matrox_bios* bd) { | 529 | static int parse_pins1(struct matrox_fb_info *minfo, |
530 | const struct matrox_bios *bd) | ||
531 | { | ||
526 | unsigned int maxdac; | 532 | unsigned int maxdac; |
527 | 533 | ||
528 | switch (bd->pins[22]) { | 534 | switch (bd->pins[22]) { |
@@ -533,173 +539,188 @@ static int parse_pins1(WPMINFO const struct matrox_bios* bd) { | |||
533 | if (get_unaligned_le16(bd->pins + 24)) { | 539 | if (get_unaligned_le16(bd->pins + 24)) { |
534 | maxdac = get_unaligned_le16(bd->pins + 24) * 10; | 540 | maxdac = get_unaligned_le16(bd->pins + 24) * 10; |
535 | } | 541 | } |
536 | MINFO->limits.pixel.vcomax = maxdac; | 542 | minfo->limits.pixel.vcomax = maxdac; |
537 | MINFO->values.pll.system = get_unaligned_le16(bd->pins + 28) ? | 543 | minfo->values.pll.system = get_unaligned_le16(bd->pins + 28) ? |
538 | get_unaligned_le16(bd->pins + 28) * 10 : 50000; | 544 | get_unaligned_le16(bd->pins + 28) * 10 : 50000; |
539 | /* ignore 4MB, 8MB, module clocks */ | 545 | /* ignore 4MB, 8MB, module clocks */ |
540 | MINFO->features.pll.ref_freq = 14318; | 546 | minfo->features.pll.ref_freq = 14318; |
541 | MINFO->values.reg.mctlwtst = 0x00030101; | 547 | minfo->values.reg.mctlwtst = 0x00030101; |
542 | return 0; | 548 | return 0; |
543 | } | 549 | } |
544 | 550 | ||
545 | static void default_pins1(WPMINFO2) { | 551 | static void default_pins1(struct matrox_fb_info *minfo) |
552 | { | ||
546 | /* Millennium */ | 553 | /* Millennium */ |
547 | MINFO->limits.pixel.vcomax = 220000; | 554 | minfo->limits.pixel.vcomax = 220000; |
548 | MINFO->values.pll.system = 50000; | 555 | minfo->values.pll.system = 50000; |
549 | MINFO->features.pll.ref_freq = 14318; | 556 | minfo->features.pll.ref_freq = 14318; |
550 | MINFO->values.reg.mctlwtst = 0x00030101; | 557 | minfo->values.reg.mctlwtst = 0x00030101; |
551 | } | 558 | } |
552 | 559 | ||
553 | static int parse_pins2(WPMINFO const struct matrox_bios* bd) { | 560 | static int parse_pins2(struct matrox_fb_info *minfo, |
554 | MINFO->limits.pixel.vcomax = | 561 | const struct matrox_bios *bd) |
555 | MINFO->limits.system.vcomax = (bd->pins[41] == 0xFF) ? 230000 : ((bd->pins[41] + 100) * 1000); | 562 | { |
556 | MINFO->values.reg.mctlwtst = ((bd->pins[51] & 0x01) ? 0x00000001 : 0) | | 563 | minfo->limits.pixel.vcomax = |
564 | minfo->limits.system.vcomax = (bd->pins[41] == 0xFF) ? 230000 : ((bd->pins[41] + 100) * 1000); | ||
565 | minfo->values.reg.mctlwtst = ((bd->pins[51] & 0x01) ? 0x00000001 : 0) | | ||
557 | ((bd->pins[51] & 0x02) ? 0x00000100 : 0) | | 566 | ((bd->pins[51] & 0x02) ? 0x00000100 : 0) | |
558 | ((bd->pins[51] & 0x04) ? 0x00010000 : 0) | | 567 | ((bd->pins[51] & 0x04) ? 0x00010000 : 0) | |
559 | ((bd->pins[51] & 0x08) ? 0x00020000 : 0); | 568 | ((bd->pins[51] & 0x08) ? 0x00020000 : 0); |
560 | MINFO->values.pll.system = (bd->pins[43] == 0xFF) ? 50000 : ((bd->pins[43] + 100) * 1000); | 569 | minfo->values.pll.system = (bd->pins[43] == 0xFF) ? 50000 : ((bd->pins[43] + 100) * 1000); |
561 | MINFO->features.pll.ref_freq = 14318; | 570 | minfo->features.pll.ref_freq = 14318; |
562 | return 0; | 571 | return 0; |
563 | } | 572 | } |
564 | 573 | ||
565 | static void default_pins2(WPMINFO2) { | 574 | static void default_pins2(struct matrox_fb_info *minfo) |
575 | { | ||
566 | /* Millennium II, Mystique */ | 576 | /* Millennium II, Mystique */ |
567 | MINFO->limits.pixel.vcomax = | 577 | minfo->limits.pixel.vcomax = |
568 | MINFO->limits.system.vcomax = 230000; | 578 | minfo->limits.system.vcomax = 230000; |
569 | MINFO->values.reg.mctlwtst = 0x00030101; | 579 | minfo->values.reg.mctlwtst = 0x00030101; |
570 | MINFO->values.pll.system = 50000; | 580 | minfo->values.pll.system = 50000; |
571 | MINFO->features.pll.ref_freq = 14318; | 581 | minfo->features.pll.ref_freq = 14318; |
572 | } | 582 | } |
573 | 583 | ||
574 | static int parse_pins3(WPMINFO const struct matrox_bios* bd) { | 584 | static int parse_pins3(struct matrox_fb_info *minfo, |
575 | MINFO->limits.pixel.vcomax = | 585 | const struct matrox_bios *bd) |
576 | MINFO->limits.system.vcomax = (bd->pins[36] == 0xFF) ? 230000 : ((bd->pins[36] + 100) * 1000); | 586 | { |
577 | MINFO->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 48) == 0xFFFFFFFF ? | 587 | minfo->limits.pixel.vcomax = |
588 | minfo->limits.system.vcomax = (bd->pins[36] == 0xFF) ? 230000 : ((bd->pins[36] + 100) * 1000); | ||
589 | minfo->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 48) == 0xFFFFFFFF ? | ||
578 | 0x01250A21 : get_unaligned_le32(bd->pins + 48); | 590 | 0x01250A21 : get_unaligned_le32(bd->pins + 48); |
579 | /* memory config */ | 591 | /* memory config */ |
580 | MINFO->values.reg.memrdbk = ((bd->pins[57] << 21) & 0x1E000000) | | 592 | minfo->values.reg.memrdbk = ((bd->pins[57] << 21) & 0x1E000000) | |
581 | ((bd->pins[57] << 22) & 0x00C00000) | | 593 | ((bd->pins[57] << 22) & 0x00C00000) | |
582 | ((bd->pins[56] << 1) & 0x000001E0) | | 594 | ((bd->pins[56] << 1) & 0x000001E0) | |
583 | ( bd->pins[56] & 0x0000000F); | 595 | ( bd->pins[56] & 0x0000000F); |
584 | MINFO->values.reg.opt = (bd->pins[54] & 7) << 10; | 596 | minfo->values.reg.opt = (bd->pins[54] & 7) << 10; |
585 | MINFO->values.reg.opt2 = bd->pins[58] << 12; | 597 | minfo->values.reg.opt2 = bd->pins[58] << 12; |
586 | MINFO->features.pll.ref_freq = (bd->pins[52] & 0x20) ? 14318 : 27000; | 598 | minfo->features.pll.ref_freq = (bd->pins[52] & 0x20) ? 14318 : 27000; |
587 | return 0; | 599 | return 0; |
588 | } | 600 | } |
589 | 601 | ||
590 | static void default_pins3(WPMINFO2) { | 602 | static void default_pins3(struct matrox_fb_info *minfo) |
603 | { | ||
591 | /* G100, G200 */ | 604 | /* G100, G200 */ |
592 | MINFO->limits.pixel.vcomax = | 605 | minfo->limits.pixel.vcomax = |
593 | MINFO->limits.system.vcomax = 230000; | 606 | minfo->limits.system.vcomax = 230000; |
594 | MINFO->values.reg.mctlwtst = 0x01250A21; | 607 | minfo->values.reg.mctlwtst = 0x01250A21; |
595 | MINFO->values.reg.memrdbk = 0x00000000; | 608 | minfo->values.reg.memrdbk = 0x00000000; |
596 | MINFO->values.reg.opt = 0x00000C00; | 609 | minfo->values.reg.opt = 0x00000C00; |
597 | MINFO->values.reg.opt2 = 0x00000000; | 610 | minfo->values.reg.opt2 = 0x00000000; |
598 | MINFO->features.pll.ref_freq = 27000; | 611 | minfo->features.pll.ref_freq = 27000; |
599 | } | 612 | } |
600 | 613 | ||
601 | static int parse_pins4(WPMINFO const struct matrox_bios* bd) { | 614 | static int parse_pins4(struct matrox_fb_info *minfo, |
602 | MINFO->limits.pixel.vcomax = (bd->pins[ 39] == 0xFF) ? 230000 : bd->pins[ 39] * 4000; | 615 | const struct matrox_bios *bd) |
603 | MINFO->limits.system.vcomax = (bd->pins[ 38] == 0xFF) ? MINFO->limits.pixel.vcomax : bd->pins[ 38] * 4000; | 616 | { |
604 | MINFO->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 71); | 617 | minfo->limits.pixel.vcomax = (bd->pins[ 39] == 0xFF) ? 230000 : bd->pins[ 39] * 4000; |
605 | MINFO->values.reg.memrdbk = ((bd->pins[87] << 21) & 0x1E000000) | | 618 | minfo->limits.system.vcomax = (bd->pins[ 38] == 0xFF) ? minfo->limits.pixel.vcomax : bd->pins[ 38] * 4000; |
619 | minfo->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 71); | ||
620 | minfo->values.reg.memrdbk = ((bd->pins[87] << 21) & 0x1E000000) | | ||
606 | ((bd->pins[87] << 22) & 0x00C00000) | | 621 | ((bd->pins[87] << 22) & 0x00C00000) | |
607 | ((bd->pins[86] << 1) & 0x000001E0) | | 622 | ((bd->pins[86] << 1) & 0x000001E0) | |
608 | ( bd->pins[86] & 0x0000000F); | 623 | ( bd->pins[86] & 0x0000000F); |
609 | MINFO->values.reg.opt = ((bd->pins[53] << 15) & 0x00400000) | | 624 | minfo->values.reg.opt = ((bd->pins[53] << 15) & 0x00400000) | |
610 | ((bd->pins[53] << 22) & 0x10000000) | | 625 | ((bd->pins[53] << 22) & 0x10000000) | |
611 | ((bd->pins[53] << 7) & 0x00001C00); | 626 | ((bd->pins[53] << 7) & 0x00001C00); |
612 | MINFO->values.reg.opt3 = get_unaligned_le32(bd->pins + 67); | 627 | minfo->values.reg.opt3 = get_unaligned_le32(bd->pins + 67); |
613 | MINFO->values.pll.system = (bd->pins[ 65] == 0xFF) ? 200000 : bd->pins[ 65] * 4000; | 628 | minfo->values.pll.system = (bd->pins[ 65] == 0xFF) ? 200000 : bd->pins[ 65] * 4000; |
614 | MINFO->features.pll.ref_freq = (bd->pins[ 92] & 0x01) ? 14318 : 27000; | 629 | minfo->features.pll.ref_freq = (bd->pins[ 92] & 0x01) ? 14318 : 27000; |
615 | return 0; | 630 | return 0; |
616 | } | 631 | } |
617 | 632 | ||
618 | static void default_pins4(WPMINFO2) { | 633 | static void default_pins4(struct matrox_fb_info *minfo) |
634 | { | ||
619 | /* G400 */ | 635 | /* G400 */ |
620 | MINFO->limits.pixel.vcomax = | 636 | minfo->limits.pixel.vcomax = |
621 | MINFO->limits.system.vcomax = 252000; | 637 | minfo->limits.system.vcomax = 252000; |
622 | MINFO->values.reg.mctlwtst = 0x04A450A1; | 638 | minfo->values.reg.mctlwtst = 0x04A450A1; |
623 | MINFO->values.reg.memrdbk = 0x000000E7; | 639 | minfo->values.reg.memrdbk = 0x000000E7; |
624 | MINFO->values.reg.opt = 0x10000400; | 640 | minfo->values.reg.opt = 0x10000400; |
625 | MINFO->values.reg.opt3 = 0x0190A419; | 641 | minfo->values.reg.opt3 = 0x0190A419; |
626 | MINFO->values.pll.system = 200000; | 642 | minfo->values.pll.system = 200000; |
627 | MINFO->features.pll.ref_freq = 27000; | 643 | minfo->features.pll.ref_freq = 27000; |
628 | } | 644 | } |
629 | 645 | ||
630 | static int parse_pins5(WPMINFO const struct matrox_bios* bd) { | 646 | static int parse_pins5(struct matrox_fb_info *minfo, |
647 | const struct matrox_bios *bd) | ||
648 | { | ||
631 | unsigned int mult; | 649 | unsigned int mult; |
632 | 650 | ||
633 | mult = bd->pins[4]?8000:6000; | 651 | mult = bd->pins[4]?8000:6000; |
634 | 652 | ||
635 | MINFO->limits.pixel.vcomax = (bd->pins[ 38] == 0xFF) ? 600000 : bd->pins[ 38] * mult; | 653 | minfo->limits.pixel.vcomax = (bd->pins[ 38] == 0xFF) ? 600000 : bd->pins[ 38] * mult; |
636 | MINFO->limits.system.vcomax = (bd->pins[ 36] == 0xFF) ? MINFO->limits.pixel.vcomax : bd->pins[ 36] * mult; | 654 | minfo->limits.system.vcomax = (bd->pins[ 36] == 0xFF) ? minfo->limits.pixel.vcomax : bd->pins[ 36] * mult; |
637 | MINFO->limits.video.vcomax = (bd->pins[ 37] == 0xFF) ? MINFO->limits.system.vcomax : bd->pins[ 37] * mult; | 655 | minfo->limits.video.vcomax = (bd->pins[ 37] == 0xFF) ? minfo->limits.system.vcomax : bd->pins[ 37] * mult; |
638 | MINFO->limits.pixel.vcomin = (bd->pins[123] == 0xFF) ? 256000 : bd->pins[123] * mult; | 656 | minfo->limits.pixel.vcomin = (bd->pins[123] == 0xFF) ? 256000 : bd->pins[123] * mult; |
639 | MINFO->limits.system.vcomin = (bd->pins[121] == 0xFF) ? MINFO->limits.pixel.vcomin : bd->pins[121] * mult; | 657 | minfo->limits.system.vcomin = (bd->pins[121] == 0xFF) ? minfo->limits.pixel.vcomin : bd->pins[121] * mult; |
640 | MINFO->limits.video.vcomin = (bd->pins[122] == 0xFF) ? MINFO->limits.system.vcomin : bd->pins[122] * mult; | 658 | minfo->limits.video.vcomin = (bd->pins[122] == 0xFF) ? minfo->limits.system.vcomin : bd->pins[122] * mult; |
641 | MINFO->values.pll.system = | 659 | minfo->values.pll.system = |
642 | MINFO->values.pll.video = (bd->pins[ 92] == 0xFF) ? 284000 : bd->pins[ 92] * 4000; | 660 | minfo->values.pll.video = (bd->pins[ 92] == 0xFF) ? 284000 : bd->pins[ 92] * 4000; |
643 | MINFO->values.reg.opt = get_unaligned_le32(bd->pins + 48); | 661 | minfo->values.reg.opt = get_unaligned_le32(bd->pins + 48); |
644 | MINFO->values.reg.opt2 = get_unaligned_le32(bd->pins + 52); | 662 | minfo->values.reg.opt2 = get_unaligned_le32(bd->pins + 52); |
645 | MINFO->values.reg.opt3 = get_unaligned_le32(bd->pins + 94); | 663 | minfo->values.reg.opt3 = get_unaligned_le32(bd->pins + 94); |
646 | MINFO->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 98); | 664 | minfo->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 98); |
647 | MINFO->values.reg.memmisc = get_unaligned_le32(bd->pins + 102); | 665 | minfo->values.reg.memmisc = get_unaligned_le32(bd->pins + 102); |
648 | MINFO->values.reg.memrdbk = get_unaligned_le32(bd->pins + 106); | 666 | minfo->values.reg.memrdbk = get_unaligned_le32(bd->pins + 106); |
649 | MINFO->features.pll.ref_freq = (bd->pins[110] & 0x01) ? 14318 : 27000; | 667 | minfo->features.pll.ref_freq = (bd->pins[110] & 0x01) ? 14318 : 27000; |
650 | MINFO->values.memory.ddr = (bd->pins[114] & 0x60) == 0x20; | 668 | minfo->values.memory.ddr = (bd->pins[114] & 0x60) == 0x20; |
651 | MINFO->values.memory.dll = (bd->pins[115] & 0x02) != 0; | 669 | minfo->values.memory.dll = (bd->pins[115] & 0x02) != 0; |
652 | MINFO->values.memory.emrswen = (bd->pins[115] & 0x01) != 0; | 670 | minfo->values.memory.emrswen = (bd->pins[115] & 0x01) != 0; |
653 | MINFO->values.reg.maccess = MINFO->values.memory.emrswen ? 0x00004000 : 0x00000000; | 671 | minfo->values.reg.maccess = minfo->values.memory.emrswen ? 0x00004000 : 0x00000000; |
654 | if (bd->pins[115] & 4) { | 672 | if (bd->pins[115] & 4) { |
655 | MINFO->values.reg.mctlwtst_core = MINFO->values.reg.mctlwtst; | 673 | minfo->values.reg.mctlwtst_core = minfo->values.reg.mctlwtst; |
656 | } else { | 674 | } else { |
657 | u_int32_t wtst_xlat[] = { 0, 1, 5, 6, 7, 5, 2, 3 }; | 675 | u_int32_t wtst_xlat[] = { 0, 1, 5, 6, 7, 5, 2, 3 }; |
658 | MINFO->values.reg.mctlwtst_core = (MINFO->values.reg.mctlwtst & ~7) | | 676 | minfo->values.reg.mctlwtst_core = (minfo->values.reg.mctlwtst & ~7) | |
659 | wtst_xlat[MINFO->values.reg.mctlwtst & 7]; | 677 | wtst_xlat[minfo->values.reg.mctlwtst & 7]; |
660 | } | 678 | } |
661 | MINFO->max_pixel_clock_panellink = bd->pins[47] * 4000; | 679 | minfo->max_pixel_clock_panellink = bd->pins[47] * 4000; |
662 | return 0; | 680 | return 0; |
663 | } | 681 | } |
664 | 682 | ||
665 | static void default_pins5(WPMINFO2) { | 683 | static void default_pins5(struct matrox_fb_info *minfo) |
684 | { | ||
666 | /* Mine 16MB G450 with SDRAM DDR */ | 685 | /* Mine 16MB G450 with SDRAM DDR */ |
667 | MINFO->limits.pixel.vcomax = | 686 | minfo->limits.pixel.vcomax = |
668 | MINFO->limits.system.vcomax = | 687 | minfo->limits.system.vcomax = |
669 | MINFO->limits.video.vcomax = 600000; | 688 | minfo->limits.video.vcomax = 600000; |
670 | MINFO->limits.pixel.vcomin = | 689 | minfo->limits.pixel.vcomin = |
671 | MINFO->limits.system.vcomin = | 690 | minfo->limits.system.vcomin = |
672 | MINFO->limits.video.vcomin = 256000; | 691 | minfo->limits.video.vcomin = 256000; |
673 | MINFO->values.pll.system = | 692 | minfo->values.pll.system = |
674 | MINFO->values.pll.video = 284000; | 693 | minfo->values.pll.video = 284000; |
675 | MINFO->values.reg.opt = 0x404A1160; | 694 | minfo->values.reg.opt = 0x404A1160; |
676 | MINFO->values.reg.opt2 = 0x0000AC00; | 695 | minfo->values.reg.opt2 = 0x0000AC00; |
677 | MINFO->values.reg.opt3 = 0x0090A409; | 696 | minfo->values.reg.opt3 = 0x0090A409; |
678 | MINFO->values.reg.mctlwtst_core = | 697 | minfo->values.reg.mctlwtst_core = |
679 | MINFO->values.reg.mctlwtst = 0x0C81462B; | 698 | minfo->values.reg.mctlwtst = 0x0C81462B; |
680 | MINFO->values.reg.memmisc = 0x80000004; | 699 | minfo->values.reg.memmisc = 0x80000004; |
681 | MINFO->values.reg.memrdbk = 0x01001103; | 700 | minfo->values.reg.memrdbk = 0x01001103; |
682 | MINFO->features.pll.ref_freq = 27000; | 701 | minfo->features.pll.ref_freq = 27000; |
683 | MINFO->values.memory.ddr = 1; | 702 | minfo->values.memory.ddr = 1; |
684 | MINFO->values.memory.dll = 1; | 703 | minfo->values.memory.dll = 1; |
685 | MINFO->values.memory.emrswen = 1; | 704 | minfo->values.memory.emrswen = 1; |
686 | MINFO->values.reg.maccess = 0x00004000; | 705 | minfo->values.reg.maccess = 0x00004000; |
687 | } | 706 | } |
688 | 707 | ||
689 | static int matroxfb_set_limits(WPMINFO const struct matrox_bios* bd) { | 708 | static int matroxfb_set_limits(struct matrox_fb_info *minfo, |
709 | const struct matrox_bios *bd) | ||
710 | { | ||
690 | unsigned int pins_version; | 711 | unsigned int pins_version; |
691 | static const unsigned int pinslen[] = { 64, 64, 64, 128, 128 }; | 712 | static const unsigned int pinslen[] = { 64, 64, 64, 128, 128 }; |
692 | 713 | ||
693 | switch (ACCESS_FBINFO(chip)) { | 714 | switch (minfo->chip) { |
694 | case MGA_2064: default_pins1(PMINFO2); break; | 715 | case MGA_2064: default_pins1(minfo); break; |
695 | case MGA_2164: | 716 | case MGA_2164: |
696 | case MGA_1064: | 717 | case MGA_1064: |
697 | case MGA_1164: default_pins2(PMINFO2); break; | 718 | case MGA_1164: default_pins2(minfo); break; |
698 | case MGA_G100: | 719 | case MGA_G100: |
699 | case MGA_G200: default_pins3(PMINFO2); break; | 720 | case MGA_G200: default_pins3(minfo); break; |
700 | case MGA_G400: default_pins4(PMINFO2); break; | 721 | case MGA_G400: default_pins4(minfo); break; |
701 | case MGA_G450: | 722 | case MGA_G450: |
702 | case MGA_G550: default_pins5(PMINFO2); break; | 723 | case MGA_G550: default_pins5(minfo); break; |
703 | } | 724 | } |
704 | if (!bd->bios_valid) { | 725 | if (!bd->bios_valid) { |
705 | printk(KERN_INFO "matroxfb: Your Matrox device does not have BIOS\n"); | 726 | printk(KERN_INFO "matroxfb: Your Matrox device does not have BIOS\n"); |
@@ -724,38 +745,39 @@ static int matroxfb_set_limits(WPMINFO const struct matrox_bios* bd) { | |||
724 | } | 745 | } |
725 | switch (pins_version) { | 746 | switch (pins_version) { |
726 | case 1: | 747 | case 1: |
727 | return parse_pins1(PMINFO bd); | 748 | return parse_pins1(minfo, bd); |
728 | case 2: | 749 | case 2: |
729 | return parse_pins2(PMINFO bd); | 750 | return parse_pins2(minfo, bd); |
730 | case 3: | 751 | case 3: |
731 | return parse_pins3(PMINFO bd); | 752 | return parse_pins3(minfo, bd); |
732 | case 4: | 753 | case 4: |
733 | return parse_pins4(PMINFO bd); | 754 | return parse_pins4(minfo, bd); |
734 | case 5: | 755 | case 5: |
735 | return parse_pins5(PMINFO bd); | 756 | return parse_pins5(minfo, bd); |
736 | default: | 757 | default: |
737 | printk(KERN_DEBUG "matroxfb: Powerup info version %u is not yet supported\n", pins_version); | 758 | printk(KERN_DEBUG "matroxfb: Powerup info version %u is not yet supported\n", pins_version); |
738 | return -1; | 759 | return -1; |
739 | } | 760 | } |
740 | } | 761 | } |
741 | 762 | ||
742 | void matroxfb_read_pins(WPMINFO2) { | 763 | void matroxfb_read_pins(struct matrox_fb_info *minfo) |
764 | { | ||
743 | u32 opt; | 765 | u32 opt; |
744 | u32 biosbase; | 766 | u32 biosbase; |
745 | u32 fbbase; | 767 | u32 fbbase; |
746 | struct pci_dev* pdev = ACCESS_FBINFO(pcidev); | 768 | struct pci_dev *pdev = minfo->pcidev; |
747 | 769 | ||
748 | memset(&ACCESS_FBINFO(bios), 0, sizeof(ACCESS_FBINFO(bios))); | 770 | memset(&minfo->bios, 0, sizeof(minfo->bios)); |
749 | pci_read_config_dword(pdev, PCI_OPTION_REG, &opt); | 771 | pci_read_config_dword(pdev, PCI_OPTION_REG, &opt); |
750 | pci_write_config_dword(pdev, PCI_OPTION_REG, opt | PCI_OPTION_ENABLE_ROM); | 772 | pci_write_config_dword(pdev, PCI_OPTION_REG, opt | PCI_OPTION_ENABLE_ROM); |
751 | pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &biosbase); | 773 | pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &biosbase); |
752 | pci_read_config_dword(pdev, ACCESS_FBINFO(devflags.fbResource), &fbbase); | 774 | pci_read_config_dword(pdev, minfo->devflags.fbResource, &fbbase); |
753 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, (fbbase & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE); | 775 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, (fbbase & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE); |
754 | parse_bios(vaddr_va(ACCESS_FBINFO(video).vbase), &ACCESS_FBINFO(bios)); | 776 | parse_bios(vaddr_va(minfo->video.vbase), &minfo->bios); |
755 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, biosbase); | 777 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, biosbase); |
756 | pci_write_config_dword(pdev, PCI_OPTION_REG, opt); | 778 | pci_write_config_dword(pdev, PCI_OPTION_REG, opt); |
757 | #ifdef CONFIG_X86 | 779 | #ifdef CONFIG_X86 |
758 | if (!ACCESS_FBINFO(bios).bios_valid) { | 780 | if (!minfo->bios.bios_valid) { |
759 | unsigned char __iomem* b; | 781 | unsigned char __iomem* b; |
760 | 782 | ||
761 | b = ioremap(0x000C0000, 65536); | 783 | b = ioremap(0x000C0000, 65536); |
@@ -769,25 +791,21 @@ void matroxfb_read_pins(WPMINFO2) { | |||
769 | printk(KERN_INFO "matroxfb: Legacy BIOS is for %04X:%04X, while this device is %04X:%04X\n", | 791 | printk(KERN_INFO "matroxfb: Legacy BIOS is for %04X:%04X, while this device is %04X:%04X\n", |
770 | ven, dev, pdev->vendor, pdev->device); | 792 | ven, dev, pdev->vendor, pdev->device); |
771 | } else { | 793 | } else { |
772 | parse_bios(b, &ACCESS_FBINFO(bios)); | 794 | parse_bios(b, &minfo->bios); |
773 | } | 795 | } |
774 | iounmap(b); | 796 | iounmap(b); |
775 | } | 797 | } |
776 | } | 798 | } |
777 | #endif | 799 | #endif |
778 | matroxfb_set_limits(PMINFO &ACCESS_FBINFO(bios)); | 800 | matroxfb_set_limits(minfo, &minfo->bios); |
779 | printk(KERN_INFO "PInS memtype = %u\n", | 801 | printk(KERN_INFO "PInS memtype = %u\n", |
780 | (ACCESS_FBINFO(values).reg.opt & 0x1C00) >> 10); | 802 | (minfo->values.reg.opt & 0x1C00) >> 10); |
781 | } | 803 | } |
782 | 804 | ||
783 | EXPORT_SYMBOL(matroxfb_DAC_in); | 805 | EXPORT_SYMBOL(matroxfb_DAC_in); |
784 | EXPORT_SYMBOL(matroxfb_DAC_out); | 806 | EXPORT_SYMBOL(matroxfb_DAC_out); |
785 | EXPORT_SYMBOL(matroxfb_var2my); | 807 | EXPORT_SYMBOL(matroxfb_var2my); |
786 | EXPORT_SYMBOL(matroxfb_PLL_calcclock); | 808 | EXPORT_SYMBOL(matroxfb_PLL_calcclock); |
787 | #ifndef CONFIG_FB_MATROX_MULTIHEAD | ||
788 | struct matrox_fb_info matroxfb_global_mxinfo; | ||
789 | EXPORT_SYMBOL(matroxfb_global_mxinfo); | ||
790 | #endif | ||
791 | EXPORT_SYMBOL(matroxfb_vgaHWinit); /* DAC1064, Ti3026 */ | 809 | EXPORT_SYMBOL(matroxfb_vgaHWinit); /* DAC1064, Ti3026 */ |
792 | EXPORT_SYMBOL(matroxfb_vgaHWrestore); /* DAC1064, Ti3026 */ | 810 | EXPORT_SYMBOL(matroxfb_vgaHWrestore); /* DAC1064, Ti3026 */ |
793 | EXPORT_SYMBOL(matroxfb_read_pins); | 811 | EXPORT_SYMBOL(matroxfb_read_pins); |
diff --git a/drivers/video/matrox/matroxfb_misc.h b/drivers/video/matrox/matroxfb_misc.h index cb62cc0ead96..351c823f1f74 100644 --- a/drivers/video/matrox/matroxfb_misc.h +++ b/drivers/video/matrox/matroxfb_misc.h | |||
@@ -6,13 +6,16 @@ | |||
6 | /* also for modules */ | 6 | /* also for modules */ |
7 | int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int freq, unsigned int fmax, | 7 | int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int freq, unsigned int fmax, |
8 | unsigned int* in, unsigned int* feed, unsigned int* post); | 8 | unsigned int* in, unsigned int* feed, unsigned int* post); |
9 | static inline int PLL_calcclock(CPMINFO unsigned int freq, unsigned int fmax, | 9 | static inline int PLL_calcclock(const struct matrox_fb_info *minfo, |
10 | unsigned int* in, unsigned int* feed, unsigned int* post) { | 10 | unsigned int freq, unsigned int fmax, |
11 | return matroxfb_PLL_calcclock(&ACCESS_FBINFO(features.pll), freq, fmax, in, feed, post); | 11 | unsigned int *in, unsigned int *feed, |
12 | unsigned int *post) | ||
13 | { | ||
14 | return matroxfb_PLL_calcclock(&minfo->features.pll, freq, fmax, in, feed, post); | ||
12 | } | 15 | } |
13 | 16 | ||
14 | int matroxfb_vgaHWinit(WPMINFO struct my_timming* m); | 17 | int matroxfb_vgaHWinit(struct matrox_fb_info *minfo, struct my_timming* m); |
15 | void matroxfb_vgaHWrestore(WPMINFO2); | 18 | void matroxfb_vgaHWrestore(struct matrox_fb_info *minfo); |
16 | void matroxfb_read_pins(WPMINFO2); | 19 | void matroxfb_read_pins(struct matrox_fb_info *minfo); |
17 | 20 | ||
18 | #endif /* __MATROXFB_MISC_H__ */ | 21 | #endif /* __MATROXFB_MISC_H__ */ |
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile new file mode 100644 index 000000000000..802d6ae523fb --- /dev/null +++ b/drivers/video/msm/Makefile | |||
@@ -0,0 +1,19 @@ | |||
1 | |||
2 | # core framebuffer | ||
3 | # | ||
4 | obj-y := msm_fb.o | ||
5 | |||
6 | # MDP DMA/PPP engine | ||
7 | # | ||
8 | obj-y += mdp.o mdp_scale_tables.o mdp_ppp.o | ||
9 | |||
10 | # MDDI interface | ||
11 | # | ||
12 | obj-y += mddi.o | ||
13 | |||
14 | # MDDI client/panel drivers | ||
15 | # | ||
16 | obj-y += mddi_client_dummy.o | ||
17 | obj-y += mddi_client_toshiba.o | ||
18 | obj-y += mddi_client_nt35399.o | ||
19 | |||
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c new file mode 100644 index 000000000000..474421fe79a6 --- /dev/null +++ b/drivers/video/msm/mddi.c | |||
@@ -0,0 +1,827 @@ | |||
1 | /* | ||
2 | * MSM MDDI Transport | ||
3 | * | ||
4 | * Copyright (C) 2007 Google Incorporated | ||
5 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/dma-mapping.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/sched.h> | ||
28 | #include <mach/msm_iomap.h> | ||
29 | #include <mach/irqs.h> | ||
30 | #include <mach/board.h> | ||
31 | #include <mach/msm_fb.h> | ||
32 | #include "mddi_hw.h" | ||
33 | |||
34 | #define FLAG_DISABLE_HIBERNATION 0x0001 | ||
35 | #define FLAG_HAVE_CAPS 0x0002 | ||
36 | #define FLAG_HAS_VSYNC_IRQ 0x0004 | ||
37 | #define FLAG_HAVE_STATUS 0x0008 | ||
38 | |||
39 | #define CMD_GET_CLIENT_CAP 0x0601 | ||
40 | #define CMD_GET_CLIENT_STATUS 0x0602 | ||
41 | |||
42 | union mddi_rev { | ||
43 | unsigned char raw[MDDI_REV_BUFFER_SIZE]; | ||
44 | struct mddi_rev_packet hdr; | ||
45 | struct mddi_client_status status; | ||
46 | struct mddi_client_caps caps; | ||
47 | struct mddi_register_access reg; | ||
48 | }; | ||
49 | |||
50 | struct reg_read_info { | ||
51 | struct completion done; | ||
52 | uint32_t reg; | ||
53 | uint32_t status; | ||
54 | uint32_t result; | ||
55 | }; | ||
56 | |||
57 | struct mddi_info { | ||
58 | uint16_t flags; | ||
59 | uint16_t version; | ||
60 | char __iomem *base; | ||
61 | int irq; | ||
62 | struct clk *clk; | ||
63 | struct msm_mddi_client_data client_data; | ||
64 | |||
65 | /* buffer for rev encap packets */ | ||
66 | void *rev_data; | ||
67 | dma_addr_t rev_addr; | ||
68 | struct mddi_llentry *reg_write_data; | ||
69 | dma_addr_t reg_write_addr; | ||
70 | struct mddi_llentry *reg_read_data; | ||
71 | dma_addr_t reg_read_addr; | ||
72 | size_t rev_data_curr; | ||
73 | |||
74 | spinlock_t int_lock; | ||
75 | uint32_t int_enable; | ||
76 | uint32_t got_int; | ||
77 | wait_queue_head_t int_wait; | ||
78 | |||
79 | struct mutex reg_write_lock; | ||
80 | struct mutex reg_read_lock; | ||
81 | struct reg_read_info *reg_read; | ||
82 | |||
83 | struct mddi_client_caps caps; | ||
84 | struct mddi_client_status status; | ||
85 | |||
86 | void (*power_client)(struct msm_mddi_client_data *, int); | ||
87 | |||
88 | /* client device published to bind us to the | ||
89 | * appropriate mddi_client driver | ||
90 | */ | ||
91 | char client_name[20]; | ||
92 | |||
93 | struct platform_device client_pdev; | ||
94 | }; | ||
95 | |||
96 | static void mddi_init_rev_encap(struct mddi_info *mddi); | ||
97 | |||
98 | #define mddi_readl(r) readl(mddi->base + (MDDI_##r)) | ||
99 | #define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r)) | ||
100 | |||
101 | void mddi_activate_link(struct msm_mddi_client_data *cdata) | ||
102 | { | ||
103 | struct mddi_info *mddi = container_of(cdata, struct mddi_info, | ||
104 | client_data); | ||
105 | |||
106 | mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); | ||
107 | } | ||
108 | |||
109 | static void mddi_handle_link_list_done(struct mddi_info *mddi) | ||
110 | { | ||
111 | } | ||
112 | |||
113 | static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi) | ||
114 | { | ||
115 | printk(KERN_INFO "mddi: resetting rev ptr\n"); | ||
116 | mddi->rev_data_curr = 0; | ||
117 | mddi_writel(mddi->rev_addr, REV_PTR); | ||
118 | mddi_writel(mddi->rev_addr, REV_PTR); | ||
119 | mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD); | ||
120 | } | ||
121 | |||
122 | static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev) | ||
123 | { | ||
124 | int i; | ||
125 | struct reg_read_info *ri; | ||
126 | |||
127 | if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) && | ||
128 | (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) { | ||
129 | |||
130 | switch (rev->hdr.type) { | ||
131 | case TYPE_CLIENT_CAPS: | ||
132 | memcpy(&mddi->caps, &rev->caps, | ||
133 | sizeof(struct mddi_client_caps)); | ||
134 | mddi->flags |= FLAG_HAVE_CAPS; | ||
135 | wake_up(&mddi->int_wait); | ||
136 | break; | ||
137 | case TYPE_CLIENT_STATUS: | ||
138 | memcpy(&mddi->status, &rev->status, | ||
139 | sizeof(struct mddi_client_status)); | ||
140 | mddi->flags |= FLAG_HAVE_STATUS; | ||
141 | wake_up(&mddi->int_wait); | ||
142 | break; | ||
143 | case TYPE_REGISTER_ACCESS: | ||
144 | ri = mddi->reg_read; | ||
145 | if (ri == 0) { | ||
146 | printk(KERN_INFO "rev: got reg %x = %x without " | ||
147 | " pending read\n", | ||
148 | rev->reg.register_address, | ||
149 | rev->reg.register_data_list); | ||
150 | break; | ||
151 | } | ||
152 | if (ri->reg != rev->reg.register_address) { | ||
153 | printk(KERN_INFO "rev: got reg %x = %x for " | ||
154 | "wrong register, expected " | ||
155 | "%x\n", | ||
156 | rev->reg.register_address, | ||
157 | rev->reg.register_data_list, ri->reg); | ||
158 | break; | ||
159 | } | ||
160 | mddi->reg_read = NULL; | ||
161 | ri->status = 0; | ||
162 | ri->result = rev->reg.register_data_list; | ||
163 | complete(&ri->done); | ||
164 | break; | ||
165 | default: | ||
166 | printk(KERN_INFO "rev: unknown reverse packet: " | ||
167 | "len=%04x type=%04x CURR_REV_PTR=%x\n", | ||
168 | rev->hdr.length, rev->hdr.type, | ||
169 | mddi_readl(CURR_REV_PTR)); | ||
170 | for (i = 0; i < rev->hdr.length + 2; i++) { | ||
171 | if ((i % 16) == 0) | ||
172 | printk(KERN_INFO "\n"); | ||
173 | printk(KERN_INFO " %02x", rev->raw[i]); | ||
174 | } | ||
175 | printk(KERN_INFO "\n"); | ||
176 | mddi_reset_rev_encap_ptr(mddi); | ||
177 | } | ||
178 | } else { | ||
179 | printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n", | ||
180 | rev->hdr.length, mddi_readl(CURR_REV_PTR)); | ||
181 | mddi_reset_rev_encap_ptr(mddi); | ||
182 | } | ||
183 | } | ||
184 | |||
185 | static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask); | ||
186 | |||
187 | static void mddi_handle_rev_data_avail(struct mddi_info *mddi) | ||
188 | { | ||
189 | union mddi_rev *rev = mddi->rev_data; | ||
190 | uint32_t rev_data_count; | ||
191 | uint32_t rev_crc_err_count; | ||
192 | int i; | ||
193 | struct reg_read_info *ri; | ||
194 | size_t prev_offset; | ||
195 | uint16_t length; | ||
196 | |||
197 | union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr; | ||
198 | |||
199 | /* clear the interrupt */ | ||
200 | mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT); | ||
201 | rev_data_count = mddi_readl(REV_PKT_CNT); | ||
202 | rev_crc_err_count = mddi_readl(REV_CRC_ERR); | ||
203 | if (rev_data_count > 1) | ||
204 | printk(KERN_INFO "rev_data_count %d\n", rev_data_count); | ||
205 | |||
206 | if (rev_crc_err_count) { | ||
207 | printk(KERN_INFO "rev_crc_err_count %d, INT %x\n", | ||
208 | rev_crc_err_count, mddi_readl(INT)); | ||
209 | ri = mddi->reg_read; | ||
210 | if (ri == 0) { | ||
211 | printk(KERN_INFO "rev: got crc error without pending " | ||
212 | "read\n"); | ||
213 | } else { | ||
214 | mddi->reg_read = NULL; | ||
215 | ri->status = -EIO; | ||
216 | ri->result = -1; | ||
217 | complete(&ri->done); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | if (rev_data_count == 0) | ||
222 | return; | ||
223 | |||
224 | prev_offset = mddi->rev_data_curr; | ||
225 | |||
226 | length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr); | ||
227 | mddi->rev_data_curr++; | ||
228 | if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE) | ||
229 | mddi->rev_data_curr = 0; | ||
230 | length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8; | ||
231 | mddi->rev_data_curr += 1 + length; | ||
232 | if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE) | ||
233 | mddi->rev_data_curr = | ||
234 | mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE; | ||
235 | |||
236 | if (length > MDDI_REV_BUFFER_SIZE - 2) { | ||
237 | printk(KERN_INFO "mddi: rev data length greater than buffer" | ||
238 | "size\n"); | ||
239 | mddi_reset_rev_encap_ptr(mddi); | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) { | ||
244 | union mddi_rev tmprev; | ||
245 | size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset; | ||
246 | memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem); | ||
247 | memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem); | ||
248 | mddi_handle_rev_data(mddi, &tmprev); | ||
249 | } else { | ||
250 | mddi_handle_rev_data(mddi, crev); | ||
251 | } | ||
252 | |||
253 | if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 && | ||
254 | mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) { | ||
255 | mddi_writel(mddi->rev_addr, REV_PTR); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | static irqreturn_t mddi_isr(int irq, void *data) | ||
260 | { | ||
261 | struct msm_mddi_client_data *cdata = data; | ||
262 | struct mddi_info *mddi = container_of(cdata, struct mddi_info, | ||
263 | client_data); | ||
264 | uint32_t active, status; | ||
265 | |||
266 | spin_lock(&mddi->int_lock); | ||
267 | |||
268 | active = mddi_readl(INT); | ||
269 | status = mddi_readl(STAT); | ||
270 | |||
271 | mddi_writel(active, INT); | ||
272 | |||
273 | /* ignore any interrupts we have disabled */ | ||
274 | active &= mddi->int_enable; | ||
275 | |||
276 | mddi->got_int |= active; | ||
277 | wake_up(&mddi->int_wait); | ||
278 | |||
279 | if (active & MDDI_INT_PRI_LINK_LIST_DONE) { | ||
280 | mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE); | ||
281 | mddi_handle_link_list_done(mddi); | ||
282 | } | ||
283 | if (active & MDDI_INT_REV_DATA_AVAIL) | ||
284 | mddi_handle_rev_data_avail(mddi); | ||
285 | |||
286 | if (active & ~MDDI_INT_NEED_CLEAR) | ||
287 | mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR); | ||
288 | |||
289 | if (active & MDDI_INT_LINK_ACTIVE) { | ||
290 | mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE); | ||
291 | mddi->int_enable |= MDDI_INT_IN_HIBERNATION; | ||
292 | } | ||
293 | |||
294 | if (active & MDDI_INT_IN_HIBERNATION) { | ||
295 | mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION); | ||
296 | mddi->int_enable |= MDDI_INT_LINK_ACTIVE; | ||
297 | } | ||
298 | |||
299 | mddi_writel(mddi->int_enable, INTEN); | ||
300 | spin_unlock(&mddi->int_lock); | ||
301 | |||
302 | return IRQ_HANDLED; | ||
303 | } | ||
304 | |||
305 | static long mddi_wait_interrupt_timeout(struct mddi_info *mddi, | ||
306 | uint32_t intmask, int timeout) | ||
307 | { | ||
308 | unsigned long irq_flags; | ||
309 | |||
310 | spin_lock_irqsave(&mddi->int_lock, irq_flags); | ||
311 | mddi->got_int &= ~intmask; | ||
312 | mddi->int_enable |= intmask; | ||
313 | mddi_writel(mddi->int_enable, INTEN); | ||
314 | spin_unlock_irqrestore(&mddi->int_lock, irq_flags); | ||
315 | return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask, | ||
316 | timeout); | ||
317 | } | ||
318 | |||
319 | static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask) | ||
320 | { | ||
321 | if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0) | ||
322 | printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout " | ||
323 | "waiting for %x, INT = %x, STAT = %x gotint = %x\n", | ||
324 | current->pid, intmask, mddi_readl(INT), mddi_readl(STAT), | ||
325 | mddi->got_int); | ||
326 | } | ||
327 | |||
328 | static void mddi_init_rev_encap(struct mddi_info *mddi) | ||
329 | { | ||
330 | memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE); | ||
331 | mddi_writel(mddi->rev_addr, REV_PTR); | ||
332 | mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD); | ||
333 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
334 | } | ||
335 | |||
336 | void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on) | ||
337 | { | ||
338 | struct mddi_info *mddi = container_of(cdata, struct mddi_info, | ||
339 | client_data); | ||
340 | mddi_writel(MDDI_CMD_POWERDOWN, CMD); | ||
341 | mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION); | ||
342 | mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD); | ||
343 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
344 | } | ||
345 | |||
346 | |||
347 | static uint16_t mddi_init_registers(struct mddi_info *mddi) | ||
348 | { | ||
349 | mddi_writel(0x0001, VERSION); | ||
350 | mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS); | ||
351 | mddi_writel(0x0003, SPM); /* subframes per media */ | ||
352 | mddi_writel(0x0005, TA1_LEN); | ||
353 | mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN); | ||
354 | mddi_writel(0x0096, DRIVE_HI); | ||
355 | /* 0x32 normal, 0x50 for Toshiba display */ | ||
356 | mddi_writel(0x0050, DRIVE_LO); | ||
357 | mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */ | ||
358 | mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV); | ||
359 | |||
360 | mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE); | ||
361 | mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ); | ||
362 | |||
363 | /* disable periodic rev encap */ | ||
364 | mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD); | ||
365 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
366 | |||
367 | if (mddi_readl(PAD_CTL) == 0) { | ||
368 | /* If we are turning on band gap, need to wait 5us before | ||
369 | * turning on the rest of the PAD */ | ||
370 | mddi_writel(0x08000, PAD_CTL); | ||
371 | udelay(5); | ||
372 | } | ||
373 | |||
374 | /* Recommendation from PAD hw team */ | ||
375 | mddi_writel(0xa850f, PAD_CTL); | ||
376 | |||
377 | |||
378 | /* Need an even number for counts */ | ||
379 | mddi_writel(0x60006, DRIVER_START_CNT); | ||
380 | |||
381 | mddi_set_auto_hibernate(&mddi->client_data, 0); | ||
382 | |||
383 | mddi_writel(MDDI_CMD_DISP_IGNORE, CMD); | ||
384 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
385 | |||
386 | mddi_init_rev_encap(mddi); | ||
387 | return mddi_readl(CORE_VER) & 0xffff; | ||
388 | } | ||
389 | |||
390 | static void mddi_suspend(struct msm_mddi_client_data *cdata) | ||
391 | { | ||
392 | struct mddi_info *mddi = container_of(cdata, struct mddi_info, | ||
393 | client_data); | ||
394 | /* turn off the client */ | ||
395 | if (mddi->power_client) | ||
396 | mddi->power_client(&mddi->client_data, 0); | ||
397 | /* turn off the link */ | ||
398 | mddi_writel(MDDI_CMD_RESET, CMD); | ||
399 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
400 | /* turn off the clock */ | ||
401 | clk_disable(mddi->clk); | ||
402 | } | ||
403 | |||
404 | static void mddi_resume(struct msm_mddi_client_data *cdata) | ||
405 | { | ||
406 | struct mddi_info *mddi = container_of(cdata, struct mddi_info, | ||
407 | client_data); | ||
408 | mddi_set_auto_hibernate(&mddi->client_data, 0); | ||
409 | /* turn on the client */ | ||
410 | if (mddi->power_client) | ||
411 | mddi->power_client(&mddi->client_data, 1); | ||
412 | /* turn on the clock */ | ||
413 | clk_enable(mddi->clk); | ||
414 | /* set up the local registers */ | ||
415 | mddi->rev_data_curr = 0; | ||
416 | mddi_init_registers(mddi); | ||
417 | mddi_writel(mddi->int_enable, INTEN); | ||
418 | mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); | ||
419 | mddi_writel(MDDI_CMD_SEND_RTD, CMD); | ||
420 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
421 | mddi_set_auto_hibernate(&mddi->client_data, 1); | ||
422 | } | ||
423 | |||
424 | static int __init mddi_get_client_caps(struct mddi_info *mddi) | ||
425 | { | ||
426 | int i, j; | ||
427 | |||
428 | /* clear any stale interrupts */ | ||
429 | mddi_writel(0xffffffff, INT); | ||
430 | |||
431 | mddi->int_enable = MDDI_INT_LINK_ACTIVE | | ||
432 | MDDI_INT_IN_HIBERNATION | | ||
433 | MDDI_INT_PRI_LINK_LIST_DONE | | ||
434 | MDDI_INT_REV_DATA_AVAIL | | ||
435 | MDDI_INT_REV_OVERFLOW | | ||
436 | MDDI_INT_REV_OVERWRITE | | ||
437 | MDDI_INT_RTD_FAILURE; | ||
438 | mddi_writel(mddi->int_enable, INTEN); | ||
439 | |||
440 | mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); | ||
441 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
442 | |||
443 | for (j = 0; j < 3; j++) { | ||
444 | /* the toshiba vga panel does not respond to get | ||
445 | * caps unless you SEND_RTD, but the first SEND_RTD | ||
446 | * will fail... | ||
447 | */ | ||
448 | for (i = 0; i < 4; i++) { | ||
449 | uint32_t stat; | ||
450 | |||
451 | mddi_writel(MDDI_CMD_SEND_RTD, CMD); | ||
452 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
453 | stat = mddi_readl(STAT); | ||
454 | printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, " | ||
455 | "rtd val %x\n", mddi_readl(INT), stat, | ||
456 | mddi_readl(RTD_VAL)); | ||
457 | if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0) | ||
458 | break; | ||
459 | msleep(1); | ||
460 | } | ||
461 | |||
462 | mddi_writel(CMD_GET_CLIENT_CAP, CMD); | ||
463 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
464 | wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS, | ||
465 | HZ / 100); | ||
466 | |||
467 | if (mddi->flags & FLAG_HAVE_CAPS) | ||
468 | break; | ||
469 | printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for " | ||
470 | "caps\n"); | ||
471 | } | ||
472 | return mddi->flags & FLAG_HAVE_CAPS; | ||
473 | } | ||
474 | |||
475 | /* link must be active when this is called */ | ||
476 | int mddi_check_status(struct mddi_info *mddi) | ||
477 | { | ||
478 | int ret = -1, retry = 3; | ||
479 | mutex_lock(&mddi->reg_read_lock); | ||
480 | mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD); | ||
481 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
482 | |||
483 | do { | ||
484 | mddi->flags &= ~FLAG_HAVE_STATUS; | ||
485 | mddi_writel(CMD_GET_CLIENT_STATUS, CMD); | ||
486 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
487 | wait_event_timeout(mddi->int_wait, | ||
488 | mddi->flags & FLAG_HAVE_STATUS, | ||
489 | HZ / 100); | ||
490 | |||
491 | if (mddi->flags & FLAG_HAVE_STATUS) { | ||
492 | if (mddi->status.crc_error_count) | ||
493 | printk(KERN_INFO "mddi status: crc_error " | ||
494 | "count: %d\n", | ||
495 | mddi->status.crc_error_count); | ||
496 | else | ||
497 | ret = 0; | ||
498 | break; | ||
499 | } else | ||
500 | printk(KERN_INFO "mddi status: failed to get client " | ||
501 | "status\n"); | ||
502 | mddi_writel(MDDI_CMD_SEND_RTD, CMD); | ||
503 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
504 | } while (--retry); | ||
505 | |||
506 | mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD); | ||
507 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
508 | mutex_unlock(&mddi->reg_read_lock); | ||
509 | return ret; | ||
510 | } | ||
511 | |||
512 | |||
513 | void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val, | ||
514 | uint32_t reg) | ||
515 | { | ||
516 | struct mddi_info *mddi = container_of(cdata, struct mddi_info, | ||
517 | client_data); | ||
518 | struct mddi_llentry *ll; | ||
519 | struct mddi_register_access *ra; | ||
520 | |||
521 | mutex_lock(&mddi->reg_write_lock); | ||
522 | |||
523 | ll = mddi->reg_write_data; | ||
524 | |||
525 | ra = &(ll->u.r); | ||
526 | ra->length = 14 + 4; | ||
527 | ra->type = TYPE_REGISTER_ACCESS; | ||
528 | ra->client_id = 0; | ||
529 | ra->read_write_info = MDDI_WRITE | 1; | ||
530 | ra->crc16 = 0; | ||
531 | |||
532 | ra->register_address = reg; | ||
533 | ra->register_data_list = val; | ||
534 | |||
535 | ll->flags = 1; | ||
536 | ll->header_count = 14; | ||
537 | ll->data_count = 4; | ||
538 | ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry, | ||
539 | u.r.register_data_list); | ||
540 | ll->next = 0; | ||
541 | ll->reserved = 0; | ||
542 | |||
543 | mddi_writel(mddi->reg_write_addr, PRI_PTR); | ||
544 | |||
545 | mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE); | ||
546 | mutex_unlock(&mddi->reg_write_lock); | ||
547 | } | ||
548 | |||
549 | uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) | ||
550 | { | ||
551 | struct mddi_info *mddi = container_of(cdata, struct mddi_info, | ||
552 | client_data); | ||
553 | struct mddi_llentry *ll; | ||
554 | struct mddi_register_access *ra; | ||
555 | struct reg_read_info ri; | ||
556 | unsigned s; | ||
557 | int retry_count = 2; | ||
558 | unsigned long irq_flags; | ||
559 | |||
560 | mutex_lock(&mddi->reg_read_lock); | ||
561 | |||
562 | ll = mddi->reg_read_data; | ||
563 | |||
564 | ra = &(ll->u.r); | ||
565 | ra->length = 14; | ||
566 | ra->type = TYPE_REGISTER_ACCESS; | ||
567 | ra->client_id = 0; | ||
568 | ra->read_write_info = MDDI_READ | 1; | ||
569 | ra->crc16 = 0; | ||
570 | |||
571 | ra->register_address = reg; | ||
572 | |||
573 | ll->flags = 0x11; | ||
574 | ll->header_count = 14; | ||
575 | ll->data_count = 0; | ||
576 | ll->data = 0; | ||
577 | ll->next = 0; | ||
578 | ll->reserved = 0; | ||
579 | |||
580 | s = mddi_readl(STAT); | ||
581 | |||
582 | ri.reg = reg; | ||
583 | ri.status = -1; | ||
584 | |||
585 | do { | ||
586 | init_completion(&ri.done); | ||
587 | mddi->reg_read = &ri; | ||
588 | mddi_writel(mddi->reg_read_addr, PRI_PTR); | ||
589 | |||
590 | mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE); | ||
591 | |||
592 | /* Enable Periodic Reverse Encapsulation. */ | ||
593 | mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD); | ||
594 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
595 | if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 && | ||
596 | !ri.done.done) { | ||
597 | printk(KERN_INFO "mddi_remote_read(%x) timeout " | ||
598 | "(%d %d %d)\n", | ||
599 | reg, ri.status, ri.result, ri.done.done); | ||
600 | spin_lock_irqsave(&mddi->int_lock, irq_flags); | ||
601 | mddi->reg_read = NULL; | ||
602 | spin_unlock_irqrestore(&mddi->int_lock, irq_flags); | ||
603 | ri.status = -1; | ||
604 | ri.result = -1; | ||
605 | } | ||
606 | if (ri.status == 0) | ||
607 | break; | ||
608 | |||
609 | mddi_writel(MDDI_CMD_SEND_RTD, CMD); | ||
610 | mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); | ||
611 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
612 | printk(KERN_INFO "mddi_remote_read: failed, sent " | ||
613 | "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x " | ||
614 | "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT), | ||
615 | mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR)); | ||
616 | } while (retry_count-- > 0); | ||
617 | /* Disable Periodic Reverse Encapsulation. */ | ||
618 | mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD); | ||
619 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
620 | mddi->reg_read = NULL; | ||
621 | mutex_unlock(&mddi->reg_read_lock); | ||
622 | return ri.result; | ||
623 | } | ||
624 | |||
625 | static struct mddi_info mddi_info[2]; | ||
626 | |||
627 | static int __init mddi_clk_setup(struct platform_device *pdev, | ||
628 | struct mddi_info *mddi, | ||
629 | unsigned long clk_rate) | ||
630 | { | ||
631 | int ret; | ||
632 | |||
633 | /* set up the clocks */ | ||
634 | mddi->clk = clk_get(&pdev->dev, "mddi_clk"); | ||
635 | if (IS_ERR(mddi->clk)) { | ||
636 | printk(KERN_INFO "mddi: failed to get clock\n"); | ||
637 | return PTR_ERR(mddi->clk); | ||
638 | } | ||
639 | ret = clk_enable(mddi->clk); | ||
640 | if (ret) | ||
641 | goto fail; | ||
642 | ret = clk_set_rate(mddi->clk, clk_rate); | ||
643 | if (ret) | ||
644 | goto fail; | ||
645 | return 0; | ||
646 | |||
647 | fail: | ||
648 | clk_put(mddi->clk); | ||
649 | return ret; | ||
650 | } | ||
651 | |||
652 | static int __init mddi_rev_data_setup(struct mddi_info *mddi) | ||
653 | { | ||
654 | void *dma; | ||
655 | dma_addr_t dma_addr; | ||
656 | |||
657 | /* set up dma buffer */ | ||
658 | dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL); | ||
659 | if (dma == 0) | ||
660 | return -ENOMEM; | ||
661 | mddi->rev_data = dma; | ||
662 | mddi->rev_data_curr = 0; | ||
663 | mddi->rev_addr = dma_addr; | ||
664 | mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE; | ||
665 | mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE; | ||
666 | mddi->reg_read_data = mddi->reg_write_data + 1; | ||
667 | mddi->reg_read_addr = mddi->reg_write_addr + | ||
668 | sizeof(*mddi->reg_write_data); | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static int __init mddi_probe(struct platform_device *pdev) | ||
673 | { | ||
674 | struct msm_mddi_platform_data *pdata = pdev->dev.platform_data; | ||
675 | struct mddi_info *mddi = &mddi_info[pdev->id]; | ||
676 | struct resource *resource; | ||
677 | int ret, i; | ||
678 | |||
679 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
680 | if (!resource) { | ||
681 | printk(KERN_ERR "mddi: no associated mem resource!\n"); | ||
682 | return -ENOMEM; | ||
683 | } | ||
684 | mddi->base = ioremap(resource->start, resource->end - resource->start); | ||
685 | if (!mddi->base) { | ||
686 | printk(KERN_ERR "mddi: failed to remap base!\n"); | ||
687 | ret = -EINVAL; | ||
688 | goto error_ioremap; | ||
689 | } | ||
690 | resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
691 | if (!resource) { | ||
692 | printk(KERN_ERR "mddi: no associated irq resource!\n"); | ||
693 | ret = -EINVAL; | ||
694 | goto error_get_irq_resource; | ||
695 | } | ||
696 | mddi->irq = resource->start; | ||
697 | printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base, | ||
698 | mddi->irq); | ||
699 | mddi->power_client = pdata->power_client; | ||
700 | |||
701 | mutex_init(&mddi->reg_write_lock); | ||
702 | mutex_init(&mddi->reg_read_lock); | ||
703 | spin_lock_init(&mddi->int_lock); | ||
704 | init_waitqueue_head(&mddi->int_wait); | ||
705 | |||
706 | ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate); | ||
707 | if (ret) { | ||
708 | printk(KERN_ERR "mddi: failed to setup clock!\n"); | ||
709 | goto error_clk_setup; | ||
710 | } | ||
711 | |||
712 | ret = mddi_rev_data_setup(mddi); | ||
713 | if (ret) { | ||
714 | printk(KERN_ERR "mddi: failed to setup rev data!\n"); | ||
715 | goto error_rev_data; | ||
716 | } | ||
717 | |||
718 | mddi->int_enable = 0; | ||
719 | mddi_writel(mddi->int_enable, INTEN); | ||
720 | ret = request_irq(mddi->irq, mddi_isr, IRQF_DISABLED, "mddi", | ||
721 | &mddi->client_data); | ||
722 | if (ret) { | ||
723 | printk(KERN_ERR "mddi: failed to request enable irq!\n"); | ||
724 | goto error_request_irq; | ||
725 | } | ||
726 | |||
727 | /* turn on the mddi client bridge chip */ | ||
728 | if (mddi->power_client) | ||
729 | mddi->power_client(&mddi->client_data, 1); | ||
730 | |||
731 | /* initialize the mddi registers */ | ||
732 | mddi_set_auto_hibernate(&mddi->client_data, 0); | ||
733 | mddi_writel(MDDI_CMD_RESET, CMD); | ||
734 | mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); | ||
735 | mddi->version = mddi_init_registers(mddi); | ||
736 | if (mddi->version < 0x20) { | ||
737 | printk(KERN_ERR "mddi: unsupported version 0x%x\n", | ||
738 | mddi->version); | ||
739 | ret = -ENODEV; | ||
740 | goto error_mddi_version; | ||
741 | } | ||
742 | |||
743 | /* read the capabilities off the client */ | ||
744 | if (!mddi_get_client_caps(mddi)) { | ||
745 | printk(KERN_INFO "mddi: no client found\n"); | ||
746 | /* power down the panel */ | ||
747 | mddi_writel(MDDI_CMD_POWERDOWN, CMD); | ||
748 | printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT)); | ||
749 | msleep(100); | ||
750 | printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT)); | ||
751 | return 0; | ||
752 | } | ||
753 | mddi_set_auto_hibernate(&mddi->client_data, 1); | ||
754 | |||
755 | if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0) | ||
756 | pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code); | ||
757 | |||
758 | mddi->client_pdev.id = 0; | ||
759 | for (i = 0; i < pdata->num_clients; i++) { | ||
760 | if (pdata->client_platform_data[i].product_id == | ||
761 | (mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) { | ||
762 | mddi->client_data.private_client_data = | ||
763 | pdata->client_platform_data[i].client_data; | ||
764 | mddi->client_pdev.name = | ||
765 | pdata->client_platform_data[i].name; | ||
766 | mddi->client_pdev.id = | ||
767 | pdata->client_platform_data[i].id; | ||
768 | /* XXX: possibly set clock */ | ||
769 | break; | ||
770 | } | ||
771 | } | ||
772 | |||
773 | if (i >= pdata->num_clients) | ||
774 | mddi->client_pdev.name = "mddi_c_dummy"; | ||
775 | printk(KERN_INFO "mddi: registering panel %s\n", | ||
776 | mddi->client_pdev.name); | ||
777 | |||
778 | mddi->client_data.suspend = mddi_suspend; | ||
779 | mddi->client_data.resume = mddi_resume; | ||
780 | mddi->client_data.activate_link = mddi_activate_link; | ||
781 | mddi->client_data.remote_write = mddi_remote_write; | ||
782 | mddi->client_data.remote_read = mddi_remote_read; | ||
783 | mddi->client_data.auto_hibernate = mddi_set_auto_hibernate; | ||
784 | mddi->client_data.fb_resource = pdata->fb_resource; | ||
785 | if (pdev->id == 0) | ||
786 | mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE; | ||
787 | else if (pdev->id == 1) | ||
788 | mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE; | ||
789 | else { | ||
790 | printk(KERN_ERR "mddi: can not determine interface %d!\n", | ||
791 | pdev->id); | ||
792 | ret = -EINVAL; | ||
793 | goto error_mddi_interface; | ||
794 | } | ||
795 | |||
796 | mddi->client_pdev.dev.platform_data = &mddi->client_data; | ||
797 | printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name); | ||
798 | platform_device_register(&mddi->client_pdev); | ||
799 | return 0; | ||
800 | |||
801 | error_mddi_interface: | ||
802 | error_mddi_version: | ||
803 | free_irq(mddi->irq, 0); | ||
804 | error_request_irq: | ||
805 | dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr); | ||
806 | error_rev_data: | ||
807 | error_clk_setup: | ||
808 | error_get_irq_resource: | ||
809 | iounmap(mddi->base); | ||
810 | error_ioremap: | ||
811 | |||
812 | printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret); | ||
813 | return ret; | ||
814 | } | ||
815 | |||
816 | |||
817 | static struct platform_driver mddi_driver = { | ||
818 | .probe = mddi_probe, | ||
819 | .driver = { .name = "msm_mddi" }, | ||
820 | }; | ||
821 | |||
822 | static int __init _mddi_init(void) | ||
823 | { | ||
824 | return platform_driver_register(&mddi_driver); | ||
825 | } | ||
826 | |||
827 | module_init(_mddi_init); | ||
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/msm/mddi_client_dummy.c new file mode 100644 index 000000000000..ebbae87885b6 --- /dev/null +++ b/drivers/video/msm/mddi_client_dummy.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* drivers/video/msm_fb/mddi_client_dummy.c | ||
2 | * | ||
3 | * Support for "dummy" mddi client devices which require no | ||
4 | * special initialization code. | ||
5 | * | ||
6 | * Copyright (C) 2007 Google Incorporated | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | #include <mach/msm_fb.h> | ||
23 | |||
24 | struct panel_info { | ||
25 | struct platform_device pdev; | ||
26 | struct msm_panel_data panel_data; | ||
27 | }; | ||
28 | |||
29 | static int mddi_dummy_suspend(struct msm_panel_data *panel_data) | ||
30 | { | ||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static int mddi_dummy_resume(struct msm_panel_data *panel_data) | ||
35 | { | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int mddi_dummy_blank(struct msm_panel_data *panel_data) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int mddi_dummy_unblank(struct msm_panel_data *panel_data) | ||
45 | { | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int mddi_dummy_probe(struct platform_device *pdev) | ||
50 | { | ||
51 | struct msm_mddi_client_data *client_data = pdev->dev.platform_data; | ||
52 | struct panel_info *panel = | ||
53 | kzalloc(sizeof(struct panel_info), GFP_KERNEL); | ||
54 | int ret; | ||
55 | if (!panel) | ||
56 | return -ENOMEM; | ||
57 | platform_set_drvdata(pdev, panel); | ||
58 | panel->panel_data.suspend = mddi_dummy_suspend; | ||
59 | panel->panel_data.resume = mddi_dummy_resume; | ||
60 | panel->panel_data.blank = mddi_dummy_blank; | ||
61 | panel->panel_data.unblank = mddi_dummy_unblank; | ||
62 | panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES; | ||
63 | panel->pdev.name = "msm_panel"; | ||
64 | panel->pdev.id = pdev->id; | ||
65 | platform_device_add_resources(&panel->pdev, | ||
66 | client_data->fb_resource, 1); | ||
67 | panel->panel_data.fb_data = client_data->private_client_data; | ||
68 | panel->pdev.dev.platform_data = &panel->panel_data; | ||
69 | ret = platform_device_register(&panel->pdev); | ||
70 | if (ret) { | ||
71 | kfree(panel); | ||
72 | return ret; | ||
73 | } | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int mddi_dummy_remove(struct platform_device *pdev) | ||
78 | { | ||
79 | struct panel_info *panel = platform_get_drvdata(pdev); | ||
80 | kfree(panel); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static struct platform_driver mddi_client_dummy = { | ||
85 | .probe = mddi_dummy_probe, | ||
86 | .remove = mddi_dummy_remove, | ||
87 | .driver = { .name = "mddi_c_dummy" }, | ||
88 | }; | ||
89 | |||
90 | static int __init mddi_client_dummy_init(void) | ||
91 | { | ||
92 | platform_driver_register(&mddi_client_dummy); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | module_init(mddi_client_dummy_init); | ||
97 | |||
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c new file mode 100644 index 000000000000..c9e9349451cb --- /dev/null +++ b/drivers/video/msm/mddi_client_nt35399.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* drivers/video/msm_fb/mddi_client_nt35399.c | ||
2 | * | ||
3 | * Support for Novatek NT35399 MDDI client of Sapphire | ||
4 | * | ||
5 | * Copyright (C) 2008 HTC Incorporated | ||
6 | * Author: Solomon Chiu (solomon_chiu@htc.com) | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <mach/msm_fb.h> | ||
25 | |||
26 | static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait); | ||
27 | |||
28 | struct panel_info { | ||
29 | struct msm_mddi_client_data *client_data; | ||
30 | struct platform_device pdev; | ||
31 | struct msm_panel_data panel_data; | ||
32 | struct msmfb_callback *fb_callback; | ||
33 | struct work_struct panel_work; | ||
34 | struct workqueue_struct *fb_wq; | ||
35 | int nt35399_got_int; | ||
36 | }; | ||
37 | |||
38 | static void | ||
39 | nt35399_request_vsync(struct msm_panel_data *panel_data, | ||
40 | struct msmfb_callback *callback) | ||
41 | { | ||
42 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
43 | panel_data); | ||
44 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
45 | |||
46 | panel->fb_callback = callback; | ||
47 | if (panel->nt35399_got_int) { | ||
48 | panel->nt35399_got_int = 0; | ||
49 | client_data->activate_link(client_data); /* clears interrupt */ | ||
50 | } | ||
51 | } | ||
52 | |||
53 | static void nt35399_wait_vsync(struct msm_panel_data *panel_data) | ||
54 | { | ||
55 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
56 | panel_data); | ||
57 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
58 | |||
59 | if (panel->nt35399_got_int) { | ||
60 | panel->nt35399_got_int = 0; | ||
61 | client_data->activate_link(client_data); /* clears interrupt */ | ||
62 | } | ||
63 | |||
64 | if (wait_event_timeout(nt35399_vsync_wait, panel->nt35399_got_int, | ||
65 | HZ/2) == 0) | ||
66 | printk(KERN_ERR "timeout waiting for VSYNC\n"); | ||
67 | |||
68 | panel->nt35399_got_int = 0; | ||
69 | /* interrupt clears when screen dma starts */ | ||
70 | } | ||
71 | |||
72 | static int nt35399_suspend(struct msm_panel_data *panel_data) | ||
73 | { | ||
74 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
75 | panel_data); | ||
76 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
77 | |||
78 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
79 | client_data->private_client_data; | ||
80 | int ret; | ||
81 | |||
82 | ret = bridge_data->uninit(bridge_data, client_data); | ||
83 | if (ret) { | ||
84 | printk(KERN_INFO "mddi nt35399 client: non zero return from " | ||
85 | "uninit\n"); | ||
86 | return ret; | ||
87 | } | ||
88 | client_data->suspend(client_data); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int nt35399_resume(struct msm_panel_data *panel_data) | ||
93 | { | ||
94 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
95 | panel_data); | ||
96 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
97 | |||
98 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
99 | client_data->private_client_data; | ||
100 | int ret; | ||
101 | |||
102 | client_data->resume(client_data); | ||
103 | ret = bridge_data->init(bridge_data, client_data); | ||
104 | if (ret) | ||
105 | return ret; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int nt35399_blank(struct msm_panel_data *panel_data) | ||
110 | { | ||
111 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
112 | panel_data); | ||
113 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
114 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
115 | client_data->private_client_data; | ||
116 | |||
117 | return bridge_data->blank(bridge_data, client_data); | ||
118 | } | ||
119 | |||
120 | static int nt35399_unblank(struct msm_panel_data *panel_data) | ||
121 | { | ||
122 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
123 | panel_data); | ||
124 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
125 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
126 | client_data->private_client_data; | ||
127 | |||
128 | return bridge_data->unblank(bridge_data, client_data); | ||
129 | } | ||
130 | |||
131 | irqreturn_t nt35399_vsync_interrupt(int irq, void *data) | ||
132 | { | ||
133 | struct panel_info *panel = data; | ||
134 | |||
135 | panel->nt35399_got_int = 1; | ||
136 | |||
137 | if (panel->fb_callback) { | ||
138 | panel->fb_callback->func(panel->fb_callback); | ||
139 | panel->fb_callback = NULL; | ||
140 | } | ||
141 | |||
142 | wake_up(&nt35399_vsync_wait); | ||
143 | |||
144 | return IRQ_HANDLED; | ||
145 | } | ||
146 | |||
147 | static int setup_vsync(struct panel_info *panel, int init) | ||
148 | { | ||
149 | int ret; | ||
150 | int gpio = 97; | ||
151 | unsigned int irq; | ||
152 | |||
153 | if (!init) { | ||
154 | ret = 0; | ||
155 | goto uninit; | ||
156 | } | ||
157 | ret = gpio_request(gpio, "vsync"); | ||
158 | if (ret) | ||
159 | goto err_request_gpio_failed; | ||
160 | |||
161 | ret = gpio_direction_input(gpio); | ||
162 | if (ret) | ||
163 | goto err_gpio_direction_input_failed; | ||
164 | |||
165 | ret = irq = gpio_to_irq(gpio); | ||
166 | if (ret < 0) | ||
167 | goto err_get_irq_num_failed; | ||
168 | |||
169 | ret = request_irq(irq, nt35399_vsync_interrupt, IRQF_TRIGGER_RISING, | ||
170 | "vsync", panel); | ||
171 | if (ret) | ||
172 | goto err_request_irq_failed; | ||
173 | |||
174 | printk(KERN_INFO "vsync on gpio %d now %d\n", | ||
175 | gpio, gpio_get_value(gpio)); | ||
176 | return 0; | ||
177 | |||
178 | uninit: | ||
179 | free_irq(gpio_to_irq(gpio), panel->client_data); | ||
180 | err_request_irq_failed: | ||
181 | err_get_irq_num_failed: | ||
182 | err_gpio_direction_input_failed: | ||
183 | gpio_free(gpio); | ||
184 | err_request_gpio_failed: | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static int mddi_nt35399_probe(struct platform_device *pdev) | ||
189 | { | ||
190 | struct msm_mddi_client_data *client_data = pdev->dev.platform_data; | ||
191 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
192 | client_data->private_client_data; | ||
193 | |||
194 | int ret; | ||
195 | |||
196 | struct panel_info *panel = kzalloc(sizeof(struct panel_info), | ||
197 | GFP_KERNEL); | ||
198 | |||
199 | printk(KERN_DEBUG "%s: enter.\n", __func__); | ||
200 | |||
201 | if (!panel) | ||
202 | return -ENOMEM; | ||
203 | platform_set_drvdata(pdev, panel); | ||
204 | |||
205 | ret = setup_vsync(panel, 1); | ||
206 | if (ret) { | ||
207 | dev_err(&pdev->dev, "mddi_nt35399_setup_vsync failed\n"); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | panel->client_data = client_data; | ||
212 | panel->panel_data.suspend = nt35399_suspend; | ||
213 | panel->panel_data.resume = nt35399_resume; | ||
214 | panel->panel_data.wait_vsync = nt35399_wait_vsync; | ||
215 | panel->panel_data.request_vsync = nt35399_request_vsync; | ||
216 | panel->panel_data.blank = nt35399_blank; | ||
217 | panel->panel_data.unblank = nt35399_unblank; | ||
218 | panel->panel_data.fb_data = &bridge_data->fb_data; | ||
219 | panel->panel_data.caps = 0; | ||
220 | |||
221 | panel->pdev.name = "msm_panel"; | ||
222 | panel->pdev.id = pdev->id; | ||
223 | panel->pdev.resource = client_data->fb_resource; | ||
224 | panel->pdev.num_resources = 1; | ||
225 | panel->pdev.dev.platform_data = &panel->panel_data; | ||
226 | |||
227 | if (bridge_data->init) | ||
228 | bridge_data->init(bridge_data, client_data); | ||
229 | |||
230 | platform_device_register(&panel->pdev); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int mddi_nt35399_remove(struct platform_device *pdev) | ||
236 | { | ||
237 | struct panel_info *panel = platform_get_drvdata(pdev); | ||
238 | |||
239 | setup_vsync(panel, 0); | ||
240 | kfree(panel); | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static struct platform_driver mddi_client_0bda_8a47 = { | ||
245 | .probe = mddi_nt35399_probe, | ||
246 | .remove = mddi_nt35399_remove, | ||
247 | .driver = { .name = "mddi_c_0bda_8a47" }, | ||
248 | }; | ||
249 | |||
250 | static int __init mddi_client_nt35399_init(void) | ||
251 | { | ||
252 | return platform_driver_register(&mddi_client_0bda_8a47); | ||
253 | } | ||
254 | |||
255 | module_init(mddi_client_nt35399_init); | ||
256 | |||
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c new file mode 100644 index 000000000000..71048e78f7f0 --- /dev/null +++ b/drivers/video/msm/mddi_client_toshiba.c | |||
@@ -0,0 +1,284 @@ | |||
1 | /* drivers/video/msm_fb/mddi_client_toshiba.c | ||
2 | * | ||
3 | * Support for Toshiba TC358720XBG mddi client devices which require no | ||
4 | * special initialization code. | ||
5 | * | ||
6 | * Copyright (C) 2007 Google Incorporated | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <mach/msm_fb.h> | ||
25 | |||
26 | |||
27 | #define LCD_CONTROL_BLOCK_BASE 0x110000 | ||
28 | #define CMN (LCD_CONTROL_BLOCK_BASE|0x10) | ||
29 | #define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) | ||
30 | #define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) | ||
31 | #define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) | ||
32 | #define VPOS (LCD_CONTROL_BLOCK_BASE|0xC0) | ||
33 | #define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) | ||
34 | #define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) | ||
35 | #define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58) | ||
36 | #define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) | ||
37 | |||
38 | #define BASE5 0x150000 | ||
39 | #define BASE6 0x160000 | ||
40 | #define BASE7 0x170000 | ||
41 | |||
42 | #define GPIOIEV (BASE5 + 0x10) | ||
43 | #define GPIOIE (BASE5 + 0x14) | ||
44 | #define GPIORIS (BASE5 + 0x18) | ||
45 | #define GPIOMIS (BASE5 + 0x1C) | ||
46 | #define GPIOIC (BASE5 + 0x20) | ||
47 | |||
48 | #define INTMASK (BASE6 + 0x0C) | ||
49 | #define INTMASK_VWAKEOUT (1U << 0) | ||
50 | #define INTMASK_VWAKEOUT_ACTIVE_LOW (1U << 8) | ||
51 | #define GPIOSEL (BASE7 + 0x00) | ||
52 | #define GPIOSEL_VWAKEINT (1U << 0) | ||
53 | |||
54 | static DECLARE_WAIT_QUEUE_HEAD(toshiba_vsync_wait); | ||
55 | |||
56 | struct panel_info { | ||
57 | struct msm_mddi_client_data *client_data; | ||
58 | struct platform_device pdev; | ||
59 | struct msm_panel_data panel_data; | ||
60 | struct msmfb_callback *toshiba_callback; | ||
61 | int toshiba_got_int; | ||
62 | }; | ||
63 | |||
64 | |||
65 | static void toshiba_request_vsync(struct msm_panel_data *panel_data, | ||
66 | struct msmfb_callback *callback) | ||
67 | { | ||
68 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
69 | panel_data); | ||
70 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
71 | |||
72 | panel->toshiba_callback = callback; | ||
73 | if (panel->toshiba_got_int) { | ||
74 | panel->toshiba_got_int = 0; | ||
75 | client_data->activate_link(client_data); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | static void toshiba_clear_vsync(struct msm_panel_data *panel_data) | ||
80 | { | ||
81 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
82 | panel_data); | ||
83 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
84 | |||
85 | client_data->activate_link(client_data); | ||
86 | } | ||
87 | |||
88 | static void toshiba_wait_vsync(struct msm_panel_data *panel_data) | ||
89 | { | ||
90 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
91 | panel_data); | ||
92 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
93 | |||
94 | if (panel->toshiba_got_int) { | ||
95 | panel->toshiba_got_int = 0; | ||
96 | client_data->activate_link(client_data); /* clears interrupt */ | ||
97 | } | ||
98 | if (wait_event_timeout(toshiba_vsync_wait, panel->toshiba_got_int, | ||
99 | HZ/2) == 0) | ||
100 | printk(KERN_ERR "timeout waiting for VSYNC\n"); | ||
101 | panel->toshiba_got_int = 0; | ||
102 | /* interrupt clears when screen dma starts */ | ||
103 | } | ||
104 | |||
105 | static int toshiba_suspend(struct msm_panel_data *panel_data) | ||
106 | { | ||
107 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
108 | panel_data); | ||
109 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
110 | |||
111 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
112 | client_data->private_client_data; | ||
113 | int ret; | ||
114 | |||
115 | ret = bridge_data->uninit(bridge_data, client_data); | ||
116 | if (ret) { | ||
117 | printk(KERN_INFO "mddi toshiba client: non zero return from " | ||
118 | "uninit\n"); | ||
119 | return ret; | ||
120 | } | ||
121 | client_data->suspend(client_data); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int toshiba_resume(struct msm_panel_data *panel_data) | ||
126 | { | ||
127 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
128 | panel_data); | ||
129 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
130 | |||
131 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
132 | client_data->private_client_data; | ||
133 | int ret; | ||
134 | |||
135 | client_data->resume(client_data); | ||
136 | ret = bridge_data->init(bridge_data, client_data); | ||
137 | if (ret) | ||
138 | return ret; | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int toshiba_blank(struct msm_panel_data *panel_data) | ||
143 | { | ||
144 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
145 | panel_data); | ||
146 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
147 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
148 | client_data->private_client_data; | ||
149 | |||
150 | return bridge_data->blank(bridge_data, client_data); | ||
151 | } | ||
152 | |||
153 | static int toshiba_unblank(struct msm_panel_data *panel_data) | ||
154 | { | ||
155 | struct panel_info *panel = container_of(panel_data, struct panel_info, | ||
156 | panel_data); | ||
157 | struct msm_mddi_client_data *client_data = panel->client_data; | ||
158 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
159 | client_data->private_client_data; | ||
160 | |||
161 | return bridge_data->unblank(bridge_data, client_data); | ||
162 | } | ||
163 | |||
164 | irqreturn_t toshiba_vsync_interrupt(int irq, void *data) | ||
165 | { | ||
166 | struct panel_info *panel = data; | ||
167 | |||
168 | panel->toshiba_got_int = 1; | ||
169 | if (panel->toshiba_callback) { | ||
170 | panel->toshiba_callback->func(panel->toshiba_callback); | ||
171 | panel->toshiba_callback = 0; | ||
172 | } | ||
173 | wake_up(&toshiba_vsync_wait); | ||
174 | return IRQ_HANDLED; | ||
175 | } | ||
176 | |||
177 | static int setup_vsync(struct panel_info *panel, | ||
178 | int init) | ||
179 | { | ||
180 | int ret; | ||
181 | int gpio = 97; | ||
182 | unsigned int irq; | ||
183 | |||
184 | if (!init) { | ||
185 | ret = 0; | ||
186 | goto uninit; | ||
187 | } | ||
188 | ret = gpio_request(gpio, "vsync"); | ||
189 | if (ret) | ||
190 | goto err_request_gpio_failed; | ||
191 | |||
192 | ret = gpio_direction_input(gpio); | ||
193 | if (ret) | ||
194 | goto err_gpio_direction_input_failed; | ||
195 | |||
196 | ret = irq = gpio_to_irq(gpio); | ||
197 | if (ret < 0) | ||
198 | goto err_get_irq_num_failed; | ||
199 | |||
200 | ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING, | ||
201 | "vsync", panel); | ||
202 | if (ret) | ||
203 | goto err_request_irq_failed; | ||
204 | printk(KERN_INFO "vsync on gpio %d now %d\n", | ||
205 | gpio, gpio_get_value(gpio)); | ||
206 | return 0; | ||
207 | |||
208 | uninit: | ||
209 | free_irq(gpio_to_irq(gpio), panel); | ||
210 | err_request_irq_failed: | ||
211 | err_get_irq_num_failed: | ||
212 | err_gpio_direction_input_failed: | ||
213 | gpio_free(gpio); | ||
214 | err_request_gpio_failed: | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | static int mddi_toshiba_probe(struct platform_device *pdev) | ||
219 | { | ||
220 | int ret; | ||
221 | struct msm_mddi_client_data *client_data = pdev->dev.platform_data; | ||
222 | struct msm_mddi_bridge_platform_data *bridge_data = | ||
223 | client_data->private_client_data; | ||
224 | struct panel_info *panel = | ||
225 | kzalloc(sizeof(struct panel_info), GFP_KERNEL); | ||
226 | if (!panel) | ||
227 | return -ENOMEM; | ||
228 | platform_set_drvdata(pdev, panel); | ||
229 | |||
230 | /* mddi_remote_write(mddi, 0, WAKEUP); */ | ||
231 | client_data->remote_write(client_data, GPIOSEL_VWAKEINT, GPIOSEL); | ||
232 | client_data->remote_write(client_data, INTMASK_VWAKEOUT, INTMASK); | ||
233 | |||
234 | ret = setup_vsync(panel, 1); | ||
235 | if (ret) { | ||
236 | dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n"); | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | panel->client_data = client_data; | ||
241 | panel->panel_data.suspend = toshiba_suspend; | ||
242 | panel->panel_data.resume = toshiba_resume; | ||
243 | panel->panel_data.wait_vsync = toshiba_wait_vsync; | ||
244 | panel->panel_data.request_vsync = toshiba_request_vsync; | ||
245 | panel->panel_data.clear_vsync = toshiba_clear_vsync; | ||
246 | panel->panel_data.blank = toshiba_blank; | ||
247 | panel->panel_data.unblank = toshiba_unblank; | ||
248 | panel->panel_data.fb_data = &bridge_data->fb_data; | ||
249 | panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES; | ||
250 | |||
251 | panel->pdev.name = "msm_panel"; | ||
252 | panel->pdev.id = pdev->id; | ||
253 | panel->pdev.resource = client_data->fb_resource; | ||
254 | panel->pdev.num_resources = 1; | ||
255 | panel->pdev.dev.platform_data = &panel->panel_data; | ||
256 | bridge_data->init(bridge_data, client_data); | ||
257 | platform_device_register(&panel->pdev); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static int mddi_toshiba_remove(struct platform_device *pdev) | ||
263 | { | ||
264 | struct panel_info *panel = platform_get_drvdata(pdev); | ||
265 | |||
266 | setup_vsync(panel, 0); | ||
267 | kfree(panel); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static struct platform_driver mddi_client_d263_0000 = { | ||
272 | .probe = mddi_toshiba_probe, | ||
273 | .remove = mddi_toshiba_remove, | ||
274 | .driver = { .name = "mddi_c_d263_0000" }, | ||
275 | }; | ||
276 | |||
277 | static int __init mddi_client_toshiba_init(void) | ||
278 | { | ||
279 | platform_driver_register(&mddi_client_d263_0000); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | module_init(mddi_client_toshiba_init); | ||
284 | |||
diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/msm/mddi_hw.h new file mode 100644 index 000000000000..45cc01fc1e7f --- /dev/null +++ b/drivers/video/msm/mddi_hw.h | |||
@@ -0,0 +1,305 @@ | |||
1 | /* drivers/video/msm_fb/mddi_hw.h | ||
2 | * | ||
3 | * MSM MDDI Hardware Registers and Structures | ||
4 | * | ||
5 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
6 | * Copyright (C) 2007 Google Incorporated | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #ifndef _MDDI_HW_H_ | ||
19 | #define _MDDI_HW_H_ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | |||
23 | #define MDDI_CMD 0x0000 | ||
24 | #define MDDI_VERSION 0x0004 | ||
25 | #define MDDI_PRI_PTR 0x0008 | ||
26 | #define MDDI_SEC_PTR 0x000c | ||
27 | #define MDDI_BPS 0x0010 | ||
28 | #define MDDI_SPM 0x0014 | ||
29 | #define MDDI_INT 0x0018 | ||
30 | #define MDDI_INTEN 0x001c | ||
31 | #define MDDI_REV_PTR 0x0020 | ||
32 | #define MDDI_REV_SIZE 0x0024 | ||
33 | #define MDDI_STAT 0x0028 | ||
34 | #define MDDI_REV_RATE_DIV 0x002c | ||
35 | #define MDDI_REV_CRC_ERR 0x0030 | ||
36 | #define MDDI_TA1_LEN 0x0034 | ||
37 | #define MDDI_TA2_LEN 0x0038 | ||
38 | #define MDDI_TEST_BUS 0x003c | ||
39 | #define MDDI_TEST 0x0040 | ||
40 | #define MDDI_REV_PKT_CNT 0x0044 | ||
41 | #define MDDI_DRIVE_HI 0x0048 | ||
42 | #define MDDI_DRIVE_LO 0x004c | ||
43 | #define MDDI_DISP_WAKE 0x0050 | ||
44 | #define MDDI_REV_ENCAP_SZ 0x0054 | ||
45 | #define MDDI_RTD_VAL 0x0058 | ||
46 | #define MDDI_PAD_CTL 0x0068 | ||
47 | #define MDDI_DRIVER_START_CNT 0x006c | ||
48 | #define MDDI_NEXT_PRI_PTR 0x0070 | ||
49 | #define MDDI_NEXT_SEC_PTR 0x0074 | ||
50 | #define MDDI_MISR_CTL 0x0078 | ||
51 | #define MDDI_MISR_DATA 0x007c | ||
52 | #define MDDI_SF_CNT 0x0080 | ||
53 | #define MDDI_MF_CNT 0x0084 | ||
54 | #define MDDI_CURR_REV_PTR 0x0088 | ||
55 | #define MDDI_CORE_VER 0x008c | ||
56 | |||
57 | #define MDDI_INT_PRI_PTR_READ 0x0001 | ||
58 | #define MDDI_INT_SEC_PTR_READ 0x0002 | ||
59 | #define MDDI_INT_REV_DATA_AVAIL 0x0004 | ||
60 | #define MDDI_INT_DISP_REQ 0x0008 | ||
61 | #define MDDI_INT_PRI_UNDERFLOW 0x0010 | ||
62 | #define MDDI_INT_SEC_UNDERFLOW 0x0020 | ||
63 | #define MDDI_INT_REV_OVERFLOW 0x0040 | ||
64 | #define MDDI_INT_CRC_ERROR 0x0080 | ||
65 | #define MDDI_INT_MDDI_IN 0x0100 | ||
66 | #define MDDI_INT_PRI_OVERWRITE 0x0200 | ||
67 | #define MDDI_INT_SEC_OVERWRITE 0x0400 | ||
68 | #define MDDI_INT_REV_OVERWRITE 0x0800 | ||
69 | #define MDDI_INT_DMA_FAILURE 0x1000 | ||
70 | #define MDDI_INT_LINK_ACTIVE 0x2000 | ||
71 | #define MDDI_INT_IN_HIBERNATION 0x4000 | ||
72 | #define MDDI_INT_PRI_LINK_LIST_DONE 0x8000 | ||
73 | #define MDDI_INT_SEC_LINK_LIST_DONE 0x10000 | ||
74 | #define MDDI_INT_NO_CMD_PKTS_PEND 0x20000 | ||
75 | #define MDDI_INT_RTD_FAILURE 0x40000 | ||
76 | #define MDDI_INT_REV_PKT_RECEIVED 0x80000 | ||
77 | #define MDDI_INT_REV_PKTS_AVAIL 0x100000 | ||
78 | |||
79 | #define MDDI_INT_NEED_CLEAR ( \ | ||
80 | MDDI_INT_REV_DATA_AVAIL | \ | ||
81 | MDDI_INT_PRI_UNDERFLOW | \ | ||
82 | MDDI_INT_SEC_UNDERFLOW | \ | ||
83 | MDDI_INT_REV_OVERFLOW | \ | ||
84 | MDDI_INT_CRC_ERROR | \ | ||
85 | MDDI_INT_REV_PKT_RECEIVED) | ||
86 | |||
87 | |||
88 | #define MDDI_STAT_LINK_ACTIVE 0x0001 | ||
89 | #define MDDI_STAT_NEW_REV_PTR 0x0002 | ||
90 | #define MDDI_STAT_NEW_PRI_PTR 0x0004 | ||
91 | #define MDDI_STAT_NEW_SEC_PTR 0x0008 | ||
92 | #define MDDI_STAT_IN_HIBERNATION 0x0010 | ||
93 | #define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020 | ||
94 | #define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040 | ||
95 | #define MDDI_STAT_PENDING_TIMING_PKT 0x0080 | ||
96 | #define MDDI_STAT_PENDING_REV_ENCAP 0x0100 | ||
97 | #define MDDI_STAT_PENDING_POWERDOWN 0x0200 | ||
98 | #define MDDI_STAT_RTD_MEAS_FAIL 0x0800 | ||
99 | #define MDDI_STAT_CLIENT_WAKEUP_REQ 0x1000 | ||
100 | |||
101 | |||
102 | #define MDDI_CMD_POWERDOWN 0x0100 | ||
103 | #define MDDI_CMD_POWERUP 0x0200 | ||
104 | #define MDDI_CMD_HIBERNATE 0x0300 | ||
105 | #define MDDI_CMD_RESET 0x0400 | ||
106 | #define MDDI_CMD_DISP_IGNORE 0x0501 | ||
107 | #define MDDI_CMD_DISP_LISTEN 0x0500 | ||
108 | #define MDDI_CMD_SEND_REV_ENCAP 0x0600 | ||
109 | #define MDDI_CMD_GET_CLIENT_CAP 0x0601 | ||
110 | #define MDDI_CMD_GET_CLIENT_STATUS 0x0602 | ||
111 | #define MDDI_CMD_SEND_RTD 0x0700 | ||
112 | #define MDDI_CMD_LINK_ACTIVE 0x0900 | ||
113 | #define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00 | ||
114 | #define MDDI_CMD_FORCE_NEW_REV_PTR 0x0C00 | ||
115 | |||
116 | |||
117 | |||
118 | #define MDDI_VIDEO_REV_PKT_SIZE 0x40 | ||
119 | #define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60 | ||
120 | #define MDDI_MAX_REV_PKT_SIZE 0x60 | ||
121 | |||
122 | /* #define MDDI_REV_BUFFER_SIZE 128 */ | ||
123 | #define MDDI_REV_BUFFER_SIZE (MDDI_MAX_REV_PKT_SIZE * 4) | ||
124 | |||
125 | /* MDP sends 256 pixel packets, so lower value hibernates more without | ||
126 | * significantly increasing latency of waiting for next subframe */ | ||
127 | #define MDDI_HOST_BYTES_PER_SUBFRAME 0x3C00 | ||
128 | #define MDDI_HOST_TA2_LEN 0x000c | ||
129 | #define MDDI_HOST_REV_RATE_DIV 0x0002 | ||
130 | |||
131 | |||
132 | struct __attribute__((packed)) mddi_rev_packet { | ||
133 | uint16_t length; | ||
134 | uint16_t type; | ||
135 | uint16_t client_id; | ||
136 | }; | ||
137 | |||
138 | struct __attribute__((packed)) mddi_client_status { | ||
139 | uint16_t length; | ||
140 | uint16_t type; | ||
141 | uint16_t client_id; | ||
142 | uint16_t reverse_link_request; /* bytes needed in rev encap message */ | ||
143 | uint8_t crc_error_count; | ||
144 | uint8_t capability_change; | ||
145 | uint16_t graphics_busy_flags; | ||
146 | uint16_t crc16; | ||
147 | }; | ||
148 | |||
149 | struct __attribute__((packed)) mddi_client_caps { | ||
150 | uint16_t length; /* length, exclusive of this field */ | ||
151 | uint16_t type; /* 66 */ | ||
152 | uint16_t client_id; | ||
153 | |||
154 | uint16_t Protocol_Version; | ||
155 | uint16_t Minimum_Protocol_Version; | ||
156 | uint16_t Data_Rate_Capability; | ||
157 | uint8_t Interface_Type_Capability; | ||
158 | uint8_t Number_of_Alt_Displays; | ||
159 | uint16_t PostCal_Data_Rate; | ||
160 | uint16_t Bitmap_Width; | ||
161 | uint16_t Bitmap_Height; | ||
162 | uint16_t Display_Window_Width; | ||
163 | uint16_t Display_Window_Height; | ||
164 | uint32_t Color_Map_Size; | ||
165 | uint16_t Color_Map_RGB_Width; | ||
166 | uint16_t RGB_Capability; | ||
167 | uint8_t Monochrome_Capability; | ||
168 | uint8_t Reserved_1; | ||
169 | uint16_t Y_Cb_Cr_Capability; | ||
170 | uint16_t Bayer_Capability; | ||
171 | uint16_t Alpha_Cursor_Image_Planes; | ||
172 | uint32_t Client_Feature_Capability_Indicators; | ||
173 | uint8_t Maximum_Video_Frame_Rate_Capability; | ||
174 | uint8_t Minimum_Video_Frame_Rate_Capability; | ||
175 | uint16_t Minimum_Sub_frame_Rate; | ||
176 | uint16_t Audio_Buffer_Depth; | ||
177 | uint16_t Audio_Channel_Capability; | ||
178 | uint16_t Audio_Sample_Rate_Capability; | ||
179 | uint8_t Audio_Sample_Resolution; | ||
180 | uint8_t Mic_Audio_Sample_Resolution; | ||
181 | uint16_t Mic_Sample_Rate_Capability; | ||
182 | uint8_t Keyboard_Data_Format; | ||
183 | uint8_t pointing_device_data_format; | ||
184 | uint16_t content_protection_type; | ||
185 | uint16_t Mfr_Name; | ||
186 | uint16_t Product_Code; | ||
187 | uint16_t Reserved_3; | ||
188 | uint32_t Serial_Number; | ||
189 | uint8_t Week_of_Manufacture; | ||
190 | uint8_t Year_of_Manufacture; | ||
191 | |||
192 | uint16_t crc16; | ||
193 | } mddi_client_capability_type; | ||
194 | |||
195 | |||
196 | struct __attribute__((packed)) mddi_video_stream { | ||
197 | uint16_t length; | ||
198 | uint16_t type; /* 16 */ | ||
199 | uint16_t client_id; /* 0 */ | ||
200 | |||
201 | uint16_t video_data_format_descriptor; | ||
202 | /* format of each pixel in the Pixel Data in the present stream in the | ||
203 | * present packet. | ||
204 | * If bits [15:13] = 000 monochrome | ||
205 | * If bits [15:13] = 001 color pixels (palette). | ||
206 | * If bits [15:13] = 010 color pixels in raw RGB | ||
207 | * If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format | ||
208 | * If bits [15:13] = 100 Bayer pixels | ||
209 | */ | ||
210 | |||
211 | uint16_t pixel_data_attributes; | ||
212 | /* interpreted as follows: | ||
213 | * Bits [1:0] = 11 pixel data is displayed to both eyes | ||
214 | * Bits [1:0] = 10 pixel data is routed to the left eye only. | ||
215 | * Bits [1:0] = 01 pixel data is routed to the right eye only. | ||
216 | * Bits [1:0] = 00 pixel data is routed to the alternate display. | ||
217 | * Bit 2 is 0 Pixel Data is in the standard progressive format. | ||
218 | * Bit 2 is 1 Pixel Data is in interlace format. | ||
219 | * Bit 3 is 0 Pixel Data is in the standard progressive format. | ||
220 | * Bit 3 is 1 Pixel Data is in alternate pixel format. | ||
221 | * Bit 4 is 0 Pixel Data is to or from the display frame buffer. | ||
222 | * Bit 4 is 1 Pixel Data is to or from the camera. | ||
223 | * Bit 5 is 0 pixel data contains the next consecutive row of pixels. | ||
224 | * Bit 5 is 1 X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge, | ||
225 | * X Start, and Y Start parameters are not defined and | ||
226 | * shall be ignored by the client. | ||
227 | * Bits [7:6] = 01 Pixel data is written to the offline image buffer. | ||
228 | * Bits [7:6] = 00 Pixel data is written to the buffer to refresh display. | ||
229 | * Bits [7:6] = 11 Pixel data is written to all image buffers. | ||
230 | * Bits [7:6] = 10 Invalid. Reserved for future use. | ||
231 | * Bits 8 through 11 alternate display number. | ||
232 | * Bits 12 through 14 are reserved for future use and shall be set to zero. | ||
233 | * Bit 15 is 1 the row of pixels is the last row of pixels in a frame. | ||
234 | */ | ||
235 | |||
236 | uint16_t x_left_edge; | ||
237 | uint16_t y_top_edge; | ||
238 | /* X,Y coordinate of the top left edge of the screen window */ | ||
239 | |||
240 | uint16_t x_right_edge; | ||
241 | uint16_t y_bottom_edge; | ||
242 | /* X,Y coordinate of the bottom right edge of the window being | ||
243 | * updated. */ | ||
244 | |||
245 | uint16_t x_start; | ||
246 | uint16_t y_start; | ||
247 | /* (X Start, Y Start) is the first pixel in the Pixel Data field | ||
248 | * below. */ | ||
249 | |||
250 | uint16_t pixel_count; | ||
251 | /* number of pixels in the Pixel Data field below. */ | ||
252 | |||
253 | uint16_t parameter_CRC; | ||
254 | /* 16-bit CRC of all bytes from the Packet Length to the Pixel Count. */ | ||
255 | |||
256 | uint16_t reserved; | ||
257 | /* 16-bit variable to make structure align on 4 byte boundary */ | ||
258 | }; | ||
259 | |||
260 | #define TYPE_VIDEO_STREAM 16 | ||
261 | #define TYPE_CLIENT_CAPS 66 | ||
262 | #define TYPE_REGISTER_ACCESS 146 | ||
263 | #define TYPE_CLIENT_STATUS 70 | ||
264 | |||
265 | struct __attribute__((packed)) mddi_register_access { | ||
266 | uint16_t length; | ||
267 | uint16_t type; /* 146 */ | ||
268 | uint16_t client_id; | ||
269 | |||
270 | uint16_t read_write_info; | ||
271 | /* Bits 13:0 a 14-bit unsigned integer that specifies the number of | ||
272 | * 32-bit Register Data List items to be transferred in the | ||
273 | * Register Data List field. | ||
274 | * Bits[15:14] = 00 Write to register(s); | ||
275 | * Bits[15:14] = 10 Read from register(s); | ||
276 | * Bits[15:14] = 11 Response to a Read. | ||
277 | * Bits[15:14] = 01 this value is reserved for future use. */ | ||
278 | #define MDDI_WRITE (0 << 14) | ||
279 | #define MDDI_READ (2 << 14) | ||
280 | #define MDDI_READ_RESP (3 << 14) | ||
281 | |||
282 | uint32_t register_address; | ||
283 | /* the register address that is to be written to or read from. */ | ||
284 | |||
285 | uint16_t crc16; | ||
286 | |||
287 | uint32_t register_data_list; | ||
288 | /* list of 4-byte register data values for/from client registers */ | ||
289 | }; | ||
290 | |||
291 | struct __attribute__((packed)) mddi_llentry { | ||
292 | uint16_t flags; | ||
293 | uint16_t header_count; | ||
294 | uint16_t data_count; | ||
295 | dma_addr_t data; /* 32 bit */ | ||
296 | struct mddi_llentry *next; | ||
297 | uint16_t reserved; | ||
298 | union { | ||
299 | struct mddi_video_stream v; | ||
300 | struct mddi_register_access r; | ||
301 | uint32_t _[12]; | ||
302 | } u; | ||
303 | }; | ||
304 | |||
305 | #endif | ||
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c new file mode 100644 index 000000000000..6c519e2fa2b7 --- /dev/null +++ b/drivers/video/msm/mdp.c | |||
@@ -0,0 +1,520 @@ | |||
1 | /* drivers/video/msm_fb/mdp.c | ||
2 | * | ||
3 | * MSM MDP Interface (used by framebuffer core) | ||
4 | * | ||
5 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
6 | * Copyright (C) 2007 Google Incorporated | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/fb.h> | ||
20 | #include <linux/msm_mdp.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/wait.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/file.h> | ||
25 | #include <linux/major.h> | ||
26 | |||
27 | #include <mach/msm_iomap.h> | ||
28 | #include <mach/msm_fb.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | |||
31 | #include "mdp_hw.h" | ||
32 | |||
33 | struct class *mdp_class; | ||
34 | |||
35 | #define MDP_CMD_DEBUG_ACCESS_BASE (0x10000) | ||
36 | |||
37 | static uint16_t mdp_default_ccs[] = { | ||
38 | 0x254, 0x000, 0x331, 0x254, 0xF38, 0xE61, 0x254, 0x409, 0x000, | ||
39 | 0x010, 0x080, 0x080 | ||
40 | }; | ||
41 | |||
42 | static DECLARE_WAIT_QUEUE_HEAD(mdp_dma2_waitqueue); | ||
43 | static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue); | ||
44 | static struct msmfb_callback *dma_callback; | ||
45 | static struct clk *clk; | ||
46 | static unsigned int mdp_irq_mask; | ||
47 | static DEFINE_SPINLOCK(mdp_lock); | ||
48 | DEFINE_MUTEX(mdp_mutex); | ||
49 | |||
50 | static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) | ||
51 | { | ||
52 | unsigned long irq_flags; | ||
53 | int ret = 0; | ||
54 | |||
55 | BUG_ON(!mask); | ||
56 | |||
57 | spin_lock_irqsave(&mdp_lock, irq_flags); | ||
58 | /* if the mask bits are already set return an error, this interrupt | ||
59 | * is already enabled */ | ||
60 | if (mdp_irq_mask & mask) { | ||
61 | printk(KERN_ERR "mdp irq already on already on %x %x\n", | ||
62 | mdp_irq_mask, mask); | ||
63 | ret = -1; | ||
64 | } | ||
65 | /* if the mdp irq is not already enabled enable it */ | ||
66 | if (!mdp_irq_mask) { | ||
67 | if (clk) | ||
68 | clk_enable(clk); | ||
69 | enable_irq(mdp->irq); | ||
70 | } | ||
71 | |||
72 | /* update the irq mask to reflect the fact that the interrupt is | ||
73 | * enabled */ | ||
74 | mdp_irq_mask |= mask; | ||
75 | spin_unlock_irqrestore(&mdp_lock, irq_flags); | ||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask) | ||
80 | { | ||
81 | /* this interrupt is already disabled! */ | ||
82 | if (!(mdp_irq_mask & mask)) { | ||
83 | printk(KERN_ERR "mdp irq already off %x %x\n", | ||
84 | mdp_irq_mask, mask); | ||
85 | return -1; | ||
86 | } | ||
87 | /* update the irq mask to reflect the fact that the interrupt is | ||
88 | * disabled */ | ||
89 | mdp_irq_mask &= ~(mask); | ||
90 | /* if no one is waiting on the interrupt, disable it */ | ||
91 | if (!mdp_irq_mask) { | ||
92 | disable_irq(mdp->irq); | ||
93 | if (clk) | ||
94 | clk_disable(clk); | ||
95 | } | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask) | ||
100 | { | ||
101 | unsigned long irq_flags; | ||
102 | int ret; | ||
103 | |||
104 | spin_lock_irqsave(&mdp_lock, irq_flags); | ||
105 | ret = locked_disable_mdp_irq(mdp, mask); | ||
106 | spin_unlock_irqrestore(&mdp_lock, irq_flags); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | static irqreturn_t mdp_isr(int irq, void *data) | ||
111 | { | ||
112 | uint32_t status; | ||
113 | unsigned long irq_flags; | ||
114 | struct mdp_info *mdp = data; | ||
115 | |||
116 | spin_lock_irqsave(&mdp_lock, irq_flags); | ||
117 | |||
118 | status = mdp_readl(mdp, MDP_INTR_STATUS); | ||
119 | mdp_writel(mdp, status, MDP_INTR_CLEAR); | ||
120 | |||
121 | status &= mdp_irq_mask; | ||
122 | if (status & DL0_DMA2_TERM_DONE) { | ||
123 | if (dma_callback) { | ||
124 | dma_callback->func(dma_callback); | ||
125 | dma_callback = NULL; | ||
126 | } | ||
127 | wake_up(&mdp_dma2_waitqueue); | ||
128 | } | ||
129 | |||
130 | if (status & DL0_ROI_DONE) | ||
131 | wake_up(&mdp_ppp_waitqueue); | ||
132 | |||
133 | if (status) | ||
134 | locked_disable_mdp_irq(mdp, status); | ||
135 | |||
136 | spin_unlock_irqrestore(&mdp_lock, irq_flags); | ||
137 | return IRQ_HANDLED; | ||
138 | } | ||
139 | |||
140 | static uint32_t mdp_check_mask(uint32_t mask) | ||
141 | { | ||
142 | uint32_t ret; | ||
143 | unsigned long irq_flags; | ||
144 | |||
145 | spin_lock_irqsave(&mdp_lock, irq_flags); | ||
146 | ret = mdp_irq_mask & mask; | ||
147 | spin_unlock_irqrestore(&mdp_lock, irq_flags); | ||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq) | ||
152 | { | ||
153 | int ret = 0; | ||
154 | unsigned long irq_flags; | ||
155 | |||
156 | wait_event_timeout(*wq, !mdp_check_mask(mask), HZ); | ||
157 | |||
158 | spin_lock_irqsave(&mdp_lock, irq_flags); | ||
159 | if (mdp_irq_mask & mask) { | ||
160 | locked_disable_mdp_irq(mdp, mask); | ||
161 | printk(KERN_WARNING "timeout waiting for mdp to complete %x\n", | ||
162 | mask); | ||
163 | ret = -ETIMEDOUT; | ||
164 | } | ||
165 | spin_unlock_irqrestore(&mdp_lock, irq_flags); | ||
166 | |||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | void mdp_dma_wait(struct mdp_device *mdp_dev) | ||
171 | { | ||
172 | #define MDP_MAX_TIMEOUTS 20 | ||
173 | static int timeout_count; | ||
174 | struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); | ||
175 | |||
176 | if (mdp_wait(mdp, DL0_DMA2_TERM_DONE, &mdp_dma2_waitqueue) == -ETIMEDOUT) | ||
177 | timeout_count++; | ||
178 | else | ||
179 | timeout_count = 0; | ||
180 | |||
181 | if (timeout_count > MDP_MAX_TIMEOUTS) { | ||
182 | printk(KERN_ERR "mdp: dma failed %d times, somethings wrong!\n", | ||
183 | MDP_MAX_TIMEOUTS); | ||
184 | BUG(); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | static int mdp_ppp_wait(struct mdp_info *mdp) | ||
189 | { | ||
190 | return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue); | ||
191 | } | ||
192 | |||
193 | void mdp_dma_to_mddi(struct mdp_info *mdp, uint32_t addr, uint32_t stride, | ||
194 | uint32_t width, uint32_t height, uint32_t x, uint32_t y, | ||
195 | struct msmfb_callback *callback) | ||
196 | { | ||
197 | uint32_t dma2_cfg; | ||
198 | uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */ | ||
199 | |||
200 | if (enable_mdp_irq(mdp, DL0_DMA2_TERM_DONE)) { | ||
201 | printk(KERN_ERR "mdp_dma_to_mddi: busy\n"); | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | dma_callback = callback; | ||
206 | |||
207 | dma2_cfg = DMA_PACK_TIGHT | | ||
208 | DMA_PACK_ALIGN_LSB | | ||
209 | DMA_PACK_PATTERN_RGB | | ||
210 | DMA_OUT_SEL_AHB | | ||
211 | DMA_IBUF_NONCONTIGUOUS; | ||
212 | |||
213 | dma2_cfg |= DMA_IBUF_FORMAT_RGB565; | ||
214 | |||
215 | dma2_cfg |= DMA_OUT_SEL_MDDI; | ||
216 | |||
217 | dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; | ||
218 | |||
219 | dma2_cfg |= DMA_DITHER_EN; | ||
220 | |||
221 | /* setup size, address, and stride */ | ||
222 | mdp_writel(mdp, (height << 16) | (width), | ||
223 | MDP_CMD_DEBUG_ACCESS_BASE + 0x0184); | ||
224 | mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188); | ||
225 | mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C); | ||
226 | |||
227 | /* 666 18BPP */ | ||
228 | dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; | ||
229 | |||
230 | /* set y & x offset and MDDI transaction parameters */ | ||
231 | mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194); | ||
232 | mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0); | ||
233 | mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM, | ||
234 | MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4); | ||
235 | |||
236 | mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180); | ||
237 | |||
238 | /* start DMA2 */ | ||
239 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044); | ||
240 | } | ||
241 | |||
242 | void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride, | ||
243 | uint32_t width, uint32_t height, uint32_t x, uint32_t y, | ||
244 | struct msmfb_callback *callback, int interface) | ||
245 | { | ||
246 | struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); | ||
247 | |||
248 | if (interface == MSM_MDDI_PMDH_INTERFACE) { | ||
249 | mdp_dma_to_mddi(mdp, addr, stride, width, height, x, y, | ||
250 | callback); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | int get_img(struct mdp_img *img, struct fb_info *info, | ||
255 | unsigned long *start, unsigned long *len, | ||
256 | struct file **filep) | ||
257 | { | ||
258 | int put_needed, ret = 0; | ||
259 | struct file *file; | ||
260 | unsigned long vstart; | ||
261 | |||
262 | file = fget_light(img->memory_id, &put_needed); | ||
263 | if (file == NULL) | ||
264 | return -1; | ||
265 | |||
266 | if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { | ||
267 | *start = info->fix.smem_start; | ||
268 | *len = info->fix.smem_len; | ||
269 | } else | ||
270 | ret = -1; | ||
271 | fput_light(file, put_needed); | ||
272 | |||
273 | return ret; | ||
274 | } | ||
275 | |||
276 | void put_img(struct file *src_file, struct file *dst_file) | ||
277 | { | ||
278 | } | ||
279 | |||
280 | int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb, | ||
281 | struct mdp_blit_req *req) | ||
282 | { | ||
283 | int ret; | ||
284 | unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0; | ||
285 | struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); | ||
286 | struct file *src_file = 0, *dst_file = 0; | ||
287 | |||
288 | /* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */ | ||
289 | if (unlikely(req->src_rect.h == 0 || | ||
290 | req->src_rect.w == 0)) { | ||
291 | printk(KERN_ERR "mpd_ppp: src img of zero size!\n"); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | if (unlikely(req->dst_rect.h == 0 || | ||
295 | req->dst_rect.w == 0)) | ||
296 | return -EINVAL; | ||
297 | |||
298 | /* do this first so that if this fails, the caller can always | ||
299 | * safely call put_img */ | ||
300 | if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) { | ||
301 | printk(KERN_ERR "mpd_ppp: could not retrieve src image from " | ||
302 | "memory\n"); | ||
303 | return -EINVAL; | ||
304 | } | ||
305 | |||
306 | if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) { | ||
307 | printk(KERN_ERR "mpd_ppp: could not retrieve dst image from " | ||
308 | "memory\n"); | ||
309 | return -EINVAL; | ||
310 | } | ||
311 | mutex_lock(&mdp_mutex); | ||
312 | |||
313 | /* transp_masking unimplemented */ | ||
314 | req->transp_mask = MDP_TRANSP_NOP; | ||
315 | if (unlikely((req->transp_mask != MDP_TRANSP_NOP || | ||
316 | req->alpha != MDP_ALPHA_NOP || | ||
317 | HAS_ALPHA(req->src.format)) && | ||
318 | (req->flags & MDP_ROT_90 && | ||
319 | req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) { | ||
320 | int i; | ||
321 | unsigned int tiles = req->dst_rect.h / 16; | ||
322 | unsigned int remainder = req->dst_rect.h % 16; | ||
323 | req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h; | ||
324 | req->dst_rect.h = 16; | ||
325 | for (i = 0; i < tiles; i++) { | ||
326 | enable_mdp_irq(mdp, DL0_ROI_DONE); | ||
327 | ret = mdp_ppp_blit(mdp, req, src_file, src_start, | ||
328 | src_len, dst_file, dst_start, | ||
329 | dst_len); | ||
330 | if (ret) | ||
331 | goto err_bad_blit; | ||
332 | ret = mdp_ppp_wait(mdp); | ||
333 | if (ret) | ||
334 | goto err_wait_failed; | ||
335 | req->dst_rect.y += 16; | ||
336 | req->src_rect.x += req->src_rect.w; | ||
337 | } | ||
338 | if (!remainder) | ||
339 | goto end; | ||
340 | req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h; | ||
341 | req->dst_rect.h = remainder; | ||
342 | } | ||
343 | enable_mdp_irq(mdp, DL0_ROI_DONE); | ||
344 | ret = mdp_ppp_blit(mdp, req, src_file, src_start, src_len, dst_file, | ||
345 | dst_start, | ||
346 | dst_len); | ||
347 | if (ret) | ||
348 | goto err_bad_blit; | ||
349 | ret = mdp_ppp_wait(mdp); | ||
350 | if (ret) | ||
351 | goto err_wait_failed; | ||
352 | end: | ||
353 | put_img(src_file, dst_file); | ||
354 | mutex_unlock(&mdp_mutex); | ||
355 | return 0; | ||
356 | err_bad_blit: | ||
357 | disable_mdp_irq(mdp, DL0_ROI_DONE); | ||
358 | err_wait_failed: | ||
359 | put_img(src_file, dst_file); | ||
360 | mutex_unlock(&mdp_mutex); | ||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id) | ||
365 | { | ||
366 | struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); | ||
367 | |||
368 | disp_id &= 0xf; | ||
369 | mdp_writel(mdp, disp_id, MDP_FULL_BYPASS_WORD43); | ||
370 | } | ||
371 | |||
372 | int register_mdp_client(struct class_interface *cint) | ||
373 | { | ||
374 | if (!mdp_class) { | ||
375 | pr_err("mdp: no mdp_class when registering mdp client\n"); | ||
376 | return -ENODEV; | ||
377 | } | ||
378 | cint->class = mdp_class; | ||
379 | return class_interface_register(cint); | ||
380 | } | ||
381 | |||
382 | #include "mdp_csc_table.h" | ||
383 | #include "mdp_scale_tables.h" | ||
384 | |||
385 | int mdp_probe(struct platform_device *pdev) | ||
386 | { | ||
387 | struct resource *resource; | ||
388 | int ret; | ||
389 | int n; | ||
390 | struct mdp_info *mdp; | ||
391 | |||
392 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
393 | if (!resource) { | ||
394 | pr_err("mdp: can not get mdp mem resource!\n"); | ||
395 | return -ENOMEM; | ||
396 | } | ||
397 | |||
398 | mdp = kzalloc(sizeof(struct mdp_info), GFP_KERNEL); | ||
399 | if (!mdp) | ||
400 | return -ENOMEM; | ||
401 | |||
402 | mdp->irq = platform_get_irq(pdev, 0); | ||
403 | if (mdp->irq < 0) { | ||
404 | pr_err("mdp: can not get mdp irq\n"); | ||
405 | ret = mdp->irq; | ||
406 | goto error_get_irq; | ||
407 | } | ||
408 | |||
409 | mdp->base = ioremap(resource->start, | ||
410 | resource->end - resource->start); | ||
411 | if (mdp->base == 0) { | ||
412 | printk(KERN_ERR "msmfb: cannot allocate mdp regs!\n"); | ||
413 | ret = -ENOMEM; | ||
414 | goto error_ioremap; | ||
415 | } | ||
416 | |||
417 | mdp->mdp_dev.dma = mdp_dma; | ||
418 | mdp->mdp_dev.dma_wait = mdp_dma_wait; | ||
419 | mdp->mdp_dev.blit = mdp_blit; | ||
420 | mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp; | ||
421 | |||
422 | clk = clk_get(&pdev->dev, "mdp_clk"); | ||
423 | if (IS_ERR(clk)) { | ||
424 | printk(KERN_INFO "mdp: failed to get mdp clk"); | ||
425 | return PTR_ERR(clk); | ||
426 | } | ||
427 | |||
428 | ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp); | ||
429 | if (ret) | ||
430 | goto error_request_irq; | ||
431 | disable_irq(mdp->irq); | ||
432 | mdp_irq_mask = 0; | ||
433 | |||
434 | /* debug interface write access */ | ||
435 | mdp_writel(mdp, 1, 0x60); | ||
436 | |||
437 | mdp_writel(mdp, MDP_ANY_INTR_MASK, MDP_INTR_ENABLE); | ||
438 | mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE); | ||
439 | |||
440 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8); | ||
441 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc); | ||
442 | |||
443 | for (n = 0; n < ARRAY_SIZE(csc_table); n++) | ||
444 | mdp_writel(mdp, csc_table[n].val, csc_table[n].reg); | ||
445 | |||
446 | /* clear up unused fg/main registers */ | ||
447 | /* comp.plane 2&3 ystride */ | ||
448 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120); | ||
449 | |||
450 | /* unpacked pattern */ | ||
451 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c); | ||
452 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130); | ||
453 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134); | ||
454 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158); | ||
455 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c); | ||
456 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160); | ||
457 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170); | ||
458 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174); | ||
459 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c); | ||
460 | |||
461 | /* comp.plane 2 & 3 */ | ||
462 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114); | ||
463 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118); | ||
464 | |||
465 | /* clear unused bg registers */ | ||
466 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8); | ||
467 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0); | ||
468 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc); | ||
469 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0); | ||
470 | mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4); | ||
471 | |||
472 | for (n = 0; n < ARRAY_SIZE(mdp_upscale_table); n++) | ||
473 | mdp_writel(mdp, mdp_upscale_table[n].val, | ||
474 | mdp_upscale_table[n].reg); | ||
475 | |||
476 | for (n = 0; n < 9; n++) | ||
477 | mdp_writel(mdp, mdp_default_ccs[n], 0x40440 + 4 * n); | ||
478 | mdp_writel(mdp, mdp_default_ccs[9], 0x40500 + 4 * 0); | ||
479 | mdp_writel(mdp, mdp_default_ccs[10], 0x40500 + 4 * 0); | ||
480 | mdp_writel(mdp, mdp_default_ccs[11], 0x40500 + 4 * 0); | ||
481 | |||
482 | /* register mdp device */ | ||
483 | mdp->mdp_dev.dev.parent = &pdev->dev; | ||
484 | mdp->mdp_dev.dev.class = mdp_class; | ||
485 | |||
486 | /* if you can remove the platform device you'd have to implement | ||
487 | * this: | ||
488 | mdp_dev.release = mdp_class; */ | ||
489 | |||
490 | ret = device_register(&mdp->mdp_dev.dev); | ||
491 | if (ret) | ||
492 | goto error_device_register; | ||
493 | return 0; | ||
494 | |||
495 | error_device_register: | ||
496 | free_irq(mdp->irq, mdp); | ||
497 | error_request_irq: | ||
498 | iounmap(mdp->base); | ||
499 | error_get_irq: | ||
500 | error_ioremap: | ||
501 | kfree(mdp); | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | static struct platform_driver msm_mdp_driver = { | ||
506 | .probe = mdp_probe, | ||
507 | .driver = {.name = "msm_mdp"}, | ||
508 | }; | ||
509 | |||
510 | static int __init mdp_init(void) | ||
511 | { | ||
512 | mdp_class = class_create(THIS_MODULE, "msm_mdp"); | ||
513 | if (IS_ERR(mdp_class)) { | ||
514 | printk(KERN_ERR "Error creating mdp class\n"); | ||
515 | return PTR_ERR(mdp_class); | ||
516 | } | ||
517 | return platform_driver_register(&msm_mdp_driver); | ||
518 | } | ||
519 | |||
520 | subsys_initcall(mdp_init); | ||
diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/msm/mdp_csc_table.h new file mode 100644 index 000000000000..d1cde30ead52 --- /dev/null +++ b/drivers/video/msm/mdp_csc_table.h | |||
@@ -0,0 +1,582 @@ | |||
1 | /* drivers/video/msm_fb/mdp_csc_table.h | ||
2 | * | ||
3 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
4 | * Copyright (C) 2007 Google Incorporated | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | static struct { | ||
17 | uint32_t reg; | ||
18 | uint32_t val; | ||
19 | } csc_table[] = { | ||
20 | { 0x40400, 0x83 }, | ||
21 | { 0x40404, 0x102 }, | ||
22 | { 0x40408, 0x32 }, | ||
23 | { 0x4040c, 0xffffffb5 }, | ||
24 | { 0x40410, 0xffffff6c }, | ||
25 | { 0x40414, 0xe1 }, | ||
26 | { 0x40418, 0xe1 }, | ||
27 | { 0x4041c, 0xffffff45 }, | ||
28 | { 0x40420, 0xffffffdc }, | ||
29 | { 0x40440, 0x254 }, | ||
30 | { 0x40444, 0x0 }, | ||
31 | { 0x40448, 0x331 }, | ||
32 | { 0x4044c, 0x254 }, | ||
33 | { 0x40450, 0xffffff38 }, | ||
34 | { 0x40454, 0xfffffe61 }, | ||
35 | { 0x40458, 0x254 }, | ||
36 | { 0x4045c, 0x409 }, | ||
37 | { 0x40460, 0x0 }, | ||
38 | { 0x40480, 0x5d }, | ||
39 | { 0x40484, 0x13a }, | ||
40 | { 0x40488, 0x20 }, | ||
41 | { 0x4048c, 0xffffffcd }, | ||
42 | { 0x40490, 0xffffff54 }, | ||
43 | { 0x40494, 0xe1 }, | ||
44 | { 0x40498, 0xe1 }, | ||
45 | { 0x4049c, 0xffffff35 }, | ||
46 | { 0x404a0, 0xffffffec }, | ||
47 | { 0x404c0, 0x254 }, | ||
48 | { 0x404c4, 0x0 }, | ||
49 | { 0x404c8, 0x396 }, | ||
50 | { 0x404cc, 0x254 }, | ||
51 | { 0x404d0, 0xffffff94 }, | ||
52 | { 0x404d4, 0xfffffef0 }, | ||
53 | { 0x404d8, 0x254 }, | ||
54 | { 0x404dc, 0x43a }, | ||
55 | { 0x404e0, 0x0 }, | ||
56 | { 0x40500, 0x10 }, | ||
57 | { 0x40504, 0x80 }, | ||
58 | { 0x40508, 0x80 }, | ||
59 | { 0x40540, 0x10 }, | ||
60 | { 0x40544, 0x80 }, | ||
61 | { 0x40548, 0x80 }, | ||
62 | { 0x40580, 0x10 }, | ||
63 | { 0x40584, 0xeb }, | ||
64 | { 0x40588, 0x10 }, | ||
65 | { 0x4058c, 0xf0 }, | ||
66 | { 0x405c0, 0x10 }, | ||
67 | { 0x405c4, 0xeb }, | ||
68 | { 0x405c8, 0x10 }, | ||
69 | { 0x405cc, 0xf0 }, | ||
70 | { 0x40800, 0x0 }, | ||
71 | { 0x40804, 0x151515 }, | ||
72 | { 0x40808, 0x1d1d1d }, | ||
73 | { 0x4080c, 0x232323 }, | ||
74 | { 0x40810, 0x272727 }, | ||
75 | { 0x40814, 0x2b2b2b }, | ||
76 | { 0x40818, 0x2f2f2f }, | ||
77 | { 0x4081c, 0x333333 }, | ||
78 | { 0x40820, 0x363636 }, | ||
79 | { 0x40824, 0x393939 }, | ||
80 | { 0x40828, 0x3b3b3b }, | ||
81 | { 0x4082c, 0x3e3e3e }, | ||
82 | { 0x40830, 0x404040 }, | ||
83 | { 0x40834, 0x434343 }, | ||
84 | { 0x40838, 0x454545 }, | ||
85 | { 0x4083c, 0x474747 }, | ||
86 | { 0x40840, 0x494949 }, | ||
87 | { 0x40844, 0x4b4b4b }, | ||
88 | { 0x40848, 0x4d4d4d }, | ||
89 | { 0x4084c, 0x4f4f4f }, | ||
90 | { 0x40850, 0x515151 }, | ||
91 | { 0x40854, 0x535353 }, | ||
92 | { 0x40858, 0x555555 }, | ||
93 | { 0x4085c, 0x565656 }, | ||
94 | { 0x40860, 0x585858 }, | ||
95 | { 0x40864, 0x5a5a5a }, | ||
96 | { 0x40868, 0x5b5b5b }, | ||
97 | { 0x4086c, 0x5d5d5d }, | ||
98 | { 0x40870, 0x5e5e5e }, | ||
99 | { 0x40874, 0x606060 }, | ||
100 | { 0x40878, 0x616161 }, | ||
101 | { 0x4087c, 0x636363 }, | ||
102 | { 0x40880, 0x646464 }, | ||
103 | { 0x40884, 0x666666 }, | ||
104 | { 0x40888, 0x676767 }, | ||
105 | { 0x4088c, 0x686868 }, | ||
106 | { 0x40890, 0x6a6a6a }, | ||
107 | { 0x40894, 0x6b6b6b }, | ||
108 | { 0x40898, 0x6c6c6c }, | ||
109 | { 0x4089c, 0x6e6e6e }, | ||
110 | { 0x408a0, 0x6f6f6f }, | ||
111 | { 0x408a4, 0x707070 }, | ||
112 | { 0x408a8, 0x717171 }, | ||
113 | { 0x408ac, 0x727272 }, | ||
114 | { 0x408b0, 0x747474 }, | ||
115 | { 0x408b4, 0x757575 }, | ||
116 | { 0x408b8, 0x767676 }, | ||
117 | { 0x408bc, 0x777777 }, | ||
118 | { 0x408c0, 0x787878 }, | ||
119 | { 0x408c4, 0x797979 }, | ||
120 | { 0x408c8, 0x7a7a7a }, | ||
121 | { 0x408cc, 0x7c7c7c }, | ||
122 | { 0x408d0, 0x7d7d7d }, | ||
123 | { 0x408d4, 0x7e7e7e }, | ||
124 | { 0x408d8, 0x7f7f7f }, | ||
125 | { 0x408dc, 0x808080 }, | ||
126 | { 0x408e0, 0x818181 }, | ||
127 | { 0x408e4, 0x828282 }, | ||
128 | { 0x408e8, 0x838383 }, | ||
129 | { 0x408ec, 0x848484 }, | ||
130 | { 0x408f0, 0x858585 }, | ||
131 | { 0x408f4, 0x868686 }, | ||
132 | { 0x408f8, 0x878787 }, | ||
133 | { 0x408fc, 0x888888 }, | ||
134 | { 0x40900, 0x898989 }, | ||
135 | { 0x40904, 0x8a8a8a }, | ||
136 | { 0x40908, 0x8b8b8b }, | ||
137 | { 0x4090c, 0x8c8c8c }, | ||
138 | { 0x40910, 0x8d8d8d }, | ||
139 | { 0x40914, 0x8e8e8e }, | ||
140 | { 0x40918, 0x8f8f8f }, | ||
141 | { 0x4091c, 0x8f8f8f }, | ||
142 | { 0x40920, 0x909090 }, | ||
143 | { 0x40924, 0x919191 }, | ||
144 | { 0x40928, 0x929292 }, | ||
145 | { 0x4092c, 0x939393 }, | ||
146 | { 0x40930, 0x949494 }, | ||
147 | { 0x40934, 0x959595 }, | ||
148 | { 0x40938, 0x969696 }, | ||
149 | { 0x4093c, 0x969696 }, | ||
150 | { 0x40940, 0x979797 }, | ||
151 | { 0x40944, 0x989898 }, | ||
152 | { 0x40948, 0x999999 }, | ||
153 | { 0x4094c, 0x9a9a9a }, | ||
154 | { 0x40950, 0x9b9b9b }, | ||
155 | { 0x40954, 0x9c9c9c }, | ||
156 | { 0x40958, 0x9c9c9c }, | ||
157 | { 0x4095c, 0x9d9d9d }, | ||
158 | { 0x40960, 0x9e9e9e }, | ||
159 | { 0x40964, 0x9f9f9f }, | ||
160 | { 0x40968, 0xa0a0a0 }, | ||
161 | { 0x4096c, 0xa0a0a0 }, | ||
162 | { 0x40970, 0xa1a1a1 }, | ||
163 | { 0x40974, 0xa2a2a2 }, | ||
164 | { 0x40978, 0xa3a3a3 }, | ||
165 | { 0x4097c, 0xa4a4a4 }, | ||
166 | { 0x40980, 0xa4a4a4 }, | ||
167 | { 0x40984, 0xa5a5a5 }, | ||
168 | { 0x40988, 0xa6a6a6 }, | ||
169 | { 0x4098c, 0xa7a7a7 }, | ||
170 | { 0x40990, 0xa7a7a7 }, | ||
171 | { 0x40994, 0xa8a8a8 }, | ||
172 | { 0x40998, 0xa9a9a9 }, | ||
173 | { 0x4099c, 0xaaaaaa }, | ||
174 | { 0x409a0, 0xaaaaaa }, | ||
175 | { 0x409a4, 0xababab }, | ||
176 | { 0x409a8, 0xacacac }, | ||
177 | { 0x409ac, 0xadadad }, | ||
178 | { 0x409b0, 0xadadad }, | ||
179 | { 0x409b4, 0xaeaeae }, | ||
180 | { 0x409b8, 0xafafaf }, | ||
181 | { 0x409bc, 0xafafaf }, | ||
182 | { 0x409c0, 0xb0b0b0 }, | ||
183 | { 0x409c4, 0xb1b1b1 }, | ||
184 | { 0x409c8, 0xb2b2b2 }, | ||
185 | { 0x409cc, 0xb2b2b2 }, | ||
186 | { 0x409d0, 0xb3b3b3 }, | ||
187 | { 0x409d4, 0xb4b4b4 }, | ||
188 | { 0x409d8, 0xb4b4b4 }, | ||
189 | { 0x409dc, 0xb5b5b5 }, | ||
190 | { 0x409e0, 0xb6b6b6 }, | ||
191 | { 0x409e4, 0xb6b6b6 }, | ||
192 | { 0x409e8, 0xb7b7b7 }, | ||
193 | { 0x409ec, 0xb8b8b8 }, | ||
194 | { 0x409f0, 0xb8b8b8 }, | ||
195 | { 0x409f4, 0xb9b9b9 }, | ||
196 | { 0x409f8, 0xbababa }, | ||
197 | { 0x409fc, 0xbababa }, | ||
198 | { 0x40a00, 0xbbbbbb }, | ||
199 | { 0x40a04, 0xbcbcbc }, | ||
200 | { 0x40a08, 0xbcbcbc }, | ||
201 | { 0x40a0c, 0xbdbdbd }, | ||
202 | { 0x40a10, 0xbebebe }, | ||
203 | { 0x40a14, 0xbebebe }, | ||
204 | { 0x40a18, 0xbfbfbf }, | ||
205 | { 0x40a1c, 0xc0c0c0 }, | ||
206 | { 0x40a20, 0xc0c0c0 }, | ||
207 | { 0x40a24, 0xc1c1c1 }, | ||
208 | { 0x40a28, 0xc1c1c1 }, | ||
209 | { 0x40a2c, 0xc2c2c2 }, | ||
210 | { 0x40a30, 0xc3c3c3 }, | ||
211 | { 0x40a34, 0xc3c3c3 }, | ||
212 | { 0x40a38, 0xc4c4c4 }, | ||
213 | { 0x40a3c, 0xc5c5c5 }, | ||
214 | { 0x40a40, 0xc5c5c5 }, | ||
215 | { 0x40a44, 0xc6c6c6 }, | ||
216 | { 0x40a48, 0xc6c6c6 }, | ||
217 | { 0x40a4c, 0xc7c7c7 }, | ||
218 | { 0x40a50, 0xc8c8c8 }, | ||
219 | { 0x40a54, 0xc8c8c8 }, | ||
220 | { 0x40a58, 0xc9c9c9 }, | ||
221 | { 0x40a5c, 0xc9c9c9 }, | ||
222 | { 0x40a60, 0xcacaca }, | ||
223 | { 0x40a64, 0xcbcbcb }, | ||
224 | { 0x40a68, 0xcbcbcb }, | ||
225 | { 0x40a6c, 0xcccccc }, | ||
226 | { 0x40a70, 0xcccccc }, | ||
227 | { 0x40a74, 0xcdcdcd }, | ||
228 | { 0x40a78, 0xcecece }, | ||
229 | { 0x40a7c, 0xcecece }, | ||
230 | { 0x40a80, 0xcfcfcf }, | ||
231 | { 0x40a84, 0xcfcfcf }, | ||
232 | { 0x40a88, 0xd0d0d0 }, | ||
233 | { 0x40a8c, 0xd0d0d0 }, | ||
234 | { 0x40a90, 0xd1d1d1 }, | ||
235 | { 0x40a94, 0xd2d2d2 }, | ||
236 | { 0x40a98, 0xd2d2d2 }, | ||
237 | { 0x40a9c, 0xd3d3d3 }, | ||
238 | { 0x40aa0, 0xd3d3d3 }, | ||
239 | { 0x40aa4, 0xd4d4d4 }, | ||
240 | { 0x40aa8, 0xd4d4d4 }, | ||
241 | { 0x40aac, 0xd5d5d5 }, | ||
242 | { 0x40ab0, 0xd6d6d6 }, | ||
243 | { 0x40ab4, 0xd6d6d6 }, | ||
244 | { 0x40ab8, 0xd7d7d7 }, | ||
245 | { 0x40abc, 0xd7d7d7 }, | ||
246 | { 0x40ac0, 0xd8d8d8 }, | ||
247 | { 0x40ac4, 0xd8d8d8 }, | ||
248 | { 0x40ac8, 0xd9d9d9 }, | ||
249 | { 0x40acc, 0xd9d9d9 }, | ||
250 | { 0x40ad0, 0xdadada }, | ||
251 | { 0x40ad4, 0xdbdbdb }, | ||
252 | { 0x40ad8, 0xdbdbdb }, | ||
253 | { 0x40adc, 0xdcdcdc }, | ||
254 | { 0x40ae0, 0xdcdcdc }, | ||
255 | { 0x40ae4, 0xdddddd }, | ||
256 | { 0x40ae8, 0xdddddd }, | ||
257 | { 0x40aec, 0xdedede }, | ||
258 | { 0x40af0, 0xdedede }, | ||
259 | { 0x40af4, 0xdfdfdf }, | ||
260 | { 0x40af8, 0xdfdfdf }, | ||
261 | { 0x40afc, 0xe0e0e0 }, | ||
262 | { 0x40b00, 0xe0e0e0 }, | ||
263 | { 0x40b04, 0xe1e1e1 }, | ||
264 | { 0x40b08, 0xe1e1e1 }, | ||
265 | { 0x40b0c, 0xe2e2e2 }, | ||
266 | { 0x40b10, 0xe3e3e3 }, | ||
267 | { 0x40b14, 0xe3e3e3 }, | ||
268 | { 0x40b18, 0xe4e4e4 }, | ||
269 | { 0x40b1c, 0xe4e4e4 }, | ||
270 | { 0x40b20, 0xe5e5e5 }, | ||
271 | { 0x40b24, 0xe5e5e5 }, | ||
272 | { 0x40b28, 0xe6e6e6 }, | ||
273 | { 0x40b2c, 0xe6e6e6 }, | ||
274 | { 0x40b30, 0xe7e7e7 }, | ||
275 | { 0x40b34, 0xe7e7e7 }, | ||
276 | { 0x40b38, 0xe8e8e8 }, | ||
277 | { 0x40b3c, 0xe8e8e8 }, | ||
278 | { 0x40b40, 0xe9e9e9 }, | ||
279 | { 0x40b44, 0xe9e9e9 }, | ||
280 | { 0x40b48, 0xeaeaea }, | ||
281 | { 0x40b4c, 0xeaeaea }, | ||
282 | { 0x40b50, 0xebebeb }, | ||
283 | { 0x40b54, 0xebebeb }, | ||
284 | { 0x40b58, 0xececec }, | ||
285 | { 0x40b5c, 0xececec }, | ||
286 | { 0x40b60, 0xededed }, | ||
287 | { 0x40b64, 0xededed }, | ||
288 | { 0x40b68, 0xeeeeee }, | ||
289 | { 0x40b6c, 0xeeeeee }, | ||
290 | { 0x40b70, 0xefefef }, | ||
291 | { 0x40b74, 0xefefef }, | ||
292 | { 0x40b78, 0xf0f0f0 }, | ||
293 | { 0x40b7c, 0xf0f0f0 }, | ||
294 | { 0x40b80, 0xf1f1f1 }, | ||
295 | { 0x40b84, 0xf1f1f1 }, | ||
296 | { 0x40b88, 0xf2f2f2 }, | ||
297 | { 0x40b8c, 0xf2f2f2 }, | ||
298 | { 0x40b90, 0xf2f2f2 }, | ||
299 | { 0x40b94, 0xf3f3f3 }, | ||
300 | { 0x40b98, 0xf3f3f3 }, | ||
301 | { 0x40b9c, 0xf4f4f4 }, | ||
302 | { 0x40ba0, 0xf4f4f4 }, | ||
303 | { 0x40ba4, 0xf5f5f5 }, | ||
304 | { 0x40ba8, 0xf5f5f5 }, | ||
305 | { 0x40bac, 0xf6f6f6 }, | ||
306 | { 0x40bb0, 0xf6f6f6 }, | ||
307 | { 0x40bb4, 0xf7f7f7 }, | ||
308 | { 0x40bb8, 0xf7f7f7 }, | ||
309 | { 0x40bbc, 0xf8f8f8 }, | ||
310 | { 0x40bc0, 0xf8f8f8 }, | ||
311 | { 0x40bc4, 0xf9f9f9 }, | ||
312 | { 0x40bc8, 0xf9f9f9 }, | ||
313 | { 0x40bcc, 0xfafafa }, | ||
314 | { 0x40bd0, 0xfafafa }, | ||
315 | { 0x40bd4, 0xfafafa }, | ||
316 | { 0x40bd8, 0xfbfbfb }, | ||
317 | { 0x40bdc, 0xfbfbfb }, | ||
318 | { 0x40be0, 0xfcfcfc }, | ||
319 | { 0x40be4, 0xfcfcfc }, | ||
320 | { 0x40be8, 0xfdfdfd }, | ||
321 | { 0x40bec, 0xfdfdfd }, | ||
322 | { 0x40bf0, 0xfefefe }, | ||
323 | { 0x40bf4, 0xfefefe }, | ||
324 | { 0x40bf8, 0xffffff }, | ||
325 | { 0x40bfc, 0xffffff }, | ||
326 | { 0x40c00, 0x0 }, | ||
327 | { 0x40c04, 0x0 }, | ||
328 | { 0x40c08, 0x0 }, | ||
329 | { 0x40c0c, 0x0 }, | ||
330 | { 0x40c10, 0x0 }, | ||
331 | { 0x40c14, 0x0 }, | ||
332 | { 0x40c18, 0x0 }, | ||
333 | { 0x40c1c, 0x0 }, | ||
334 | { 0x40c20, 0x0 }, | ||
335 | { 0x40c24, 0x0 }, | ||
336 | { 0x40c28, 0x0 }, | ||
337 | { 0x40c2c, 0x0 }, | ||
338 | { 0x40c30, 0x0 }, | ||
339 | { 0x40c34, 0x0 }, | ||
340 | { 0x40c38, 0x0 }, | ||
341 | { 0x40c3c, 0x0 }, | ||
342 | { 0x40c40, 0x10101 }, | ||
343 | { 0x40c44, 0x10101 }, | ||
344 | { 0x40c48, 0x10101 }, | ||
345 | { 0x40c4c, 0x10101 }, | ||
346 | { 0x40c50, 0x10101 }, | ||
347 | { 0x40c54, 0x10101 }, | ||
348 | { 0x40c58, 0x10101 }, | ||
349 | { 0x40c5c, 0x10101 }, | ||
350 | { 0x40c60, 0x10101 }, | ||
351 | { 0x40c64, 0x10101 }, | ||
352 | { 0x40c68, 0x20202 }, | ||
353 | { 0x40c6c, 0x20202 }, | ||
354 | { 0x40c70, 0x20202 }, | ||
355 | { 0x40c74, 0x20202 }, | ||
356 | { 0x40c78, 0x20202 }, | ||
357 | { 0x40c7c, 0x20202 }, | ||
358 | { 0x40c80, 0x30303 }, | ||
359 | { 0x40c84, 0x30303 }, | ||
360 | { 0x40c88, 0x30303 }, | ||
361 | { 0x40c8c, 0x30303 }, | ||
362 | { 0x40c90, 0x30303 }, | ||
363 | { 0x40c94, 0x40404 }, | ||
364 | { 0x40c98, 0x40404 }, | ||
365 | { 0x40c9c, 0x40404 }, | ||
366 | { 0x40ca0, 0x40404 }, | ||
367 | { 0x40ca4, 0x40404 }, | ||
368 | { 0x40ca8, 0x50505 }, | ||
369 | { 0x40cac, 0x50505 }, | ||
370 | { 0x40cb0, 0x50505 }, | ||
371 | { 0x40cb4, 0x50505 }, | ||
372 | { 0x40cb8, 0x60606 }, | ||
373 | { 0x40cbc, 0x60606 }, | ||
374 | { 0x40cc0, 0x60606 }, | ||
375 | { 0x40cc4, 0x70707 }, | ||
376 | { 0x40cc8, 0x70707 }, | ||
377 | { 0x40ccc, 0x70707 }, | ||
378 | { 0x40cd0, 0x70707 }, | ||
379 | { 0x40cd4, 0x80808 }, | ||
380 | { 0x40cd8, 0x80808 }, | ||
381 | { 0x40cdc, 0x80808 }, | ||
382 | { 0x40ce0, 0x90909 }, | ||
383 | { 0x40ce4, 0x90909 }, | ||
384 | { 0x40ce8, 0xa0a0a }, | ||
385 | { 0x40cec, 0xa0a0a }, | ||
386 | { 0x40cf0, 0xa0a0a }, | ||
387 | { 0x40cf4, 0xb0b0b }, | ||
388 | { 0x40cf8, 0xb0b0b }, | ||
389 | { 0x40cfc, 0xb0b0b }, | ||
390 | { 0x40d00, 0xc0c0c }, | ||
391 | { 0x40d04, 0xc0c0c }, | ||
392 | { 0x40d08, 0xd0d0d }, | ||
393 | { 0x40d0c, 0xd0d0d }, | ||
394 | { 0x40d10, 0xe0e0e }, | ||
395 | { 0x40d14, 0xe0e0e }, | ||
396 | { 0x40d18, 0xe0e0e }, | ||
397 | { 0x40d1c, 0xf0f0f }, | ||
398 | { 0x40d20, 0xf0f0f }, | ||
399 | { 0x40d24, 0x101010 }, | ||
400 | { 0x40d28, 0x101010 }, | ||
401 | { 0x40d2c, 0x111111 }, | ||
402 | { 0x40d30, 0x111111 }, | ||
403 | { 0x40d34, 0x121212 }, | ||
404 | { 0x40d38, 0x121212 }, | ||
405 | { 0x40d3c, 0x131313 }, | ||
406 | { 0x40d40, 0x131313 }, | ||
407 | { 0x40d44, 0x141414 }, | ||
408 | { 0x40d48, 0x151515 }, | ||
409 | { 0x40d4c, 0x151515 }, | ||
410 | { 0x40d50, 0x161616 }, | ||
411 | { 0x40d54, 0x161616 }, | ||
412 | { 0x40d58, 0x171717 }, | ||
413 | { 0x40d5c, 0x171717 }, | ||
414 | { 0x40d60, 0x181818 }, | ||
415 | { 0x40d64, 0x191919 }, | ||
416 | { 0x40d68, 0x191919 }, | ||
417 | { 0x40d6c, 0x1a1a1a }, | ||
418 | { 0x40d70, 0x1b1b1b }, | ||
419 | { 0x40d74, 0x1b1b1b }, | ||
420 | { 0x40d78, 0x1c1c1c }, | ||
421 | { 0x40d7c, 0x1c1c1c }, | ||
422 | { 0x40d80, 0x1d1d1d }, | ||
423 | { 0x40d84, 0x1e1e1e }, | ||
424 | { 0x40d88, 0x1f1f1f }, | ||
425 | { 0x40d8c, 0x1f1f1f }, | ||
426 | { 0x40d90, 0x202020 }, | ||
427 | { 0x40d94, 0x212121 }, | ||
428 | { 0x40d98, 0x212121 }, | ||
429 | { 0x40d9c, 0x222222 }, | ||
430 | { 0x40da0, 0x232323 }, | ||
431 | { 0x40da4, 0x242424 }, | ||
432 | { 0x40da8, 0x242424 }, | ||
433 | { 0x40dac, 0x252525 }, | ||
434 | { 0x40db0, 0x262626 }, | ||
435 | { 0x40db4, 0x272727 }, | ||
436 | { 0x40db8, 0x272727 }, | ||
437 | { 0x40dbc, 0x282828 }, | ||
438 | { 0x40dc0, 0x292929 }, | ||
439 | { 0x40dc4, 0x2a2a2a }, | ||
440 | { 0x40dc8, 0x2b2b2b }, | ||
441 | { 0x40dcc, 0x2c2c2c }, | ||
442 | { 0x40dd0, 0x2c2c2c }, | ||
443 | { 0x40dd4, 0x2d2d2d }, | ||
444 | { 0x40dd8, 0x2e2e2e }, | ||
445 | { 0x40ddc, 0x2f2f2f }, | ||
446 | { 0x40de0, 0x303030 }, | ||
447 | { 0x40de4, 0x313131 }, | ||
448 | { 0x40de8, 0x323232 }, | ||
449 | { 0x40dec, 0x333333 }, | ||
450 | { 0x40df0, 0x333333 }, | ||
451 | { 0x40df4, 0x343434 }, | ||
452 | { 0x40df8, 0x353535 }, | ||
453 | { 0x40dfc, 0x363636 }, | ||
454 | { 0x40e00, 0x373737 }, | ||
455 | { 0x40e04, 0x383838 }, | ||
456 | { 0x40e08, 0x393939 }, | ||
457 | { 0x40e0c, 0x3a3a3a }, | ||
458 | { 0x40e10, 0x3b3b3b }, | ||
459 | { 0x40e14, 0x3c3c3c }, | ||
460 | { 0x40e18, 0x3d3d3d }, | ||
461 | { 0x40e1c, 0x3e3e3e }, | ||
462 | { 0x40e20, 0x3f3f3f }, | ||
463 | { 0x40e24, 0x404040 }, | ||
464 | { 0x40e28, 0x414141 }, | ||
465 | { 0x40e2c, 0x424242 }, | ||
466 | { 0x40e30, 0x434343 }, | ||
467 | { 0x40e34, 0x444444 }, | ||
468 | { 0x40e38, 0x464646 }, | ||
469 | { 0x40e3c, 0x474747 }, | ||
470 | { 0x40e40, 0x484848 }, | ||
471 | { 0x40e44, 0x494949 }, | ||
472 | { 0x40e48, 0x4a4a4a }, | ||
473 | { 0x40e4c, 0x4b4b4b }, | ||
474 | { 0x40e50, 0x4c4c4c }, | ||
475 | { 0x40e54, 0x4d4d4d }, | ||
476 | { 0x40e58, 0x4f4f4f }, | ||
477 | { 0x40e5c, 0x505050 }, | ||
478 | { 0x40e60, 0x515151 }, | ||
479 | { 0x40e64, 0x525252 }, | ||
480 | { 0x40e68, 0x535353 }, | ||
481 | { 0x40e6c, 0x545454 }, | ||
482 | { 0x40e70, 0x565656 }, | ||
483 | { 0x40e74, 0x575757 }, | ||
484 | { 0x40e78, 0x585858 }, | ||
485 | { 0x40e7c, 0x595959 }, | ||
486 | { 0x40e80, 0x5b5b5b }, | ||
487 | { 0x40e84, 0x5c5c5c }, | ||
488 | { 0x40e88, 0x5d5d5d }, | ||
489 | { 0x40e8c, 0x5e5e5e }, | ||
490 | { 0x40e90, 0x606060 }, | ||
491 | { 0x40e94, 0x616161 }, | ||
492 | { 0x40e98, 0x626262 }, | ||
493 | { 0x40e9c, 0x646464 }, | ||
494 | { 0x40ea0, 0x656565 }, | ||
495 | { 0x40ea4, 0x666666 }, | ||
496 | { 0x40ea8, 0x686868 }, | ||
497 | { 0x40eac, 0x696969 }, | ||
498 | { 0x40eb0, 0x6a6a6a }, | ||
499 | { 0x40eb4, 0x6c6c6c }, | ||
500 | { 0x40eb8, 0x6d6d6d }, | ||
501 | { 0x40ebc, 0x6f6f6f }, | ||
502 | { 0x40ec0, 0x707070 }, | ||
503 | { 0x40ec4, 0x717171 }, | ||
504 | { 0x40ec8, 0x737373 }, | ||
505 | { 0x40ecc, 0x747474 }, | ||
506 | { 0x40ed0, 0x767676 }, | ||
507 | { 0x40ed4, 0x777777 }, | ||
508 | { 0x40ed8, 0x797979 }, | ||
509 | { 0x40edc, 0x7a7a7a }, | ||
510 | { 0x40ee0, 0x7c7c7c }, | ||
511 | { 0x40ee4, 0x7d7d7d }, | ||
512 | { 0x40ee8, 0x7f7f7f }, | ||
513 | { 0x40eec, 0x808080 }, | ||
514 | { 0x40ef0, 0x828282 }, | ||
515 | { 0x40ef4, 0x838383 }, | ||
516 | { 0x40ef8, 0x858585 }, | ||
517 | { 0x40efc, 0x868686 }, | ||
518 | { 0x40f00, 0x888888 }, | ||
519 | { 0x40f04, 0x898989 }, | ||
520 | { 0x40f08, 0x8b8b8b }, | ||
521 | { 0x40f0c, 0x8d8d8d }, | ||
522 | { 0x40f10, 0x8e8e8e }, | ||
523 | { 0x40f14, 0x909090 }, | ||
524 | { 0x40f18, 0x919191 }, | ||
525 | { 0x40f1c, 0x939393 }, | ||
526 | { 0x40f20, 0x959595 }, | ||
527 | { 0x40f24, 0x969696 }, | ||
528 | { 0x40f28, 0x989898 }, | ||
529 | { 0x40f2c, 0x9a9a9a }, | ||
530 | { 0x40f30, 0x9b9b9b }, | ||
531 | { 0x40f34, 0x9d9d9d }, | ||
532 | { 0x40f38, 0x9f9f9f }, | ||
533 | { 0x40f3c, 0xa1a1a1 }, | ||
534 | { 0x40f40, 0xa2a2a2 }, | ||
535 | { 0x40f44, 0xa4a4a4 }, | ||
536 | { 0x40f48, 0xa6a6a6 }, | ||
537 | { 0x40f4c, 0xa7a7a7 }, | ||
538 | { 0x40f50, 0xa9a9a9 }, | ||
539 | { 0x40f54, 0xababab }, | ||
540 | { 0x40f58, 0xadadad }, | ||
541 | { 0x40f5c, 0xafafaf }, | ||
542 | { 0x40f60, 0xb0b0b0 }, | ||
543 | { 0x40f64, 0xb2b2b2 }, | ||
544 | { 0x40f68, 0xb4b4b4 }, | ||
545 | { 0x40f6c, 0xb6b6b6 }, | ||
546 | { 0x40f70, 0xb8b8b8 }, | ||
547 | { 0x40f74, 0xbababa }, | ||
548 | { 0x40f78, 0xbbbbbb }, | ||
549 | { 0x40f7c, 0xbdbdbd }, | ||
550 | { 0x40f80, 0xbfbfbf }, | ||
551 | { 0x40f84, 0xc1c1c1 }, | ||
552 | { 0x40f88, 0xc3c3c3 }, | ||
553 | { 0x40f8c, 0xc5c5c5 }, | ||
554 | { 0x40f90, 0xc7c7c7 }, | ||
555 | { 0x40f94, 0xc9c9c9 }, | ||
556 | { 0x40f98, 0xcbcbcb }, | ||
557 | { 0x40f9c, 0xcdcdcd }, | ||
558 | { 0x40fa0, 0xcfcfcf }, | ||
559 | { 0x40fa4, 0xd1d1d1 }, | ||
560 | { 0x40fa8, 0xd3d3d3 }, | ||
561 | { 0x40fac, 0xd5d5d5 }, | ||
562 | { 0x40fb0, 0xd7d7d7 }, | ||
563 | { 0x40fb4, 0xd9d9d9 }, | ||
564 | { 0x40fb8, 0xdbdbdb }, | ||
565 | { 0x40fbc, 0xdddddd }, | ||
566 | { 0x40fc0, 0xdfdfdf }, | ||
567 | { 0x40fc4, 0xe1e1e1 }, | ||
568 | { 0x40fc8, 0xe3e3e3 }, | ||
569 | { 0x40fcc, 0xe5e5e5 }, | ||
570 | { 0x40fd0, 0xe7e7e7 }, | ||
571 | { 0x40fd4, 0xe9e9e9 }, | ||
572 | { 0x40fd8, 0xebebeb }, | ||
573 | { 0x40fdc, 0xeeeeee }, | ||
574 | { 0x40fe0, 0xf0f0f0 }, | ||
575 | { 0x40fe4, 0xf2f2f2 }, | ||
576 | { 0x40fe8, 0xf4f4f4 }, | ||
577 | { 0x40fec, 0xf6f6f6 }, | ||
578 | { 0x40ff0, 0xf8f8f8 }, | ||
579 | { 0x40ff4, 0xfbfbfb }, | ||
580 | { 0x40ff8, 0xfdfdfd }, | ||
581 | { 0x40ffc, 0xffffff }, | ||
582 | }; | ||
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h new file mode 100644 index 000000000000..4e3deb4e592b --- /dev/null +++ b/drivers/video/msm/mdp_hw.h | |||
@@ -0,0 +1,621 @@ | |||
1 | /* drivers/video/msm_fb/mdp_hw.h | ||
2 | * | ||
3 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
4 | * Copyright (C) 2007 Google Incorporated | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | #ifndef _MDP_HW_H_ | ||
16 | #define _MDP_HW_H_ | ||
17 | |||
18 | #include <mach/msm_iomap.h> | ||
19 | #include <mach/msm_fb.h> | ||
20 | |||
21 | struct mdp_info { | ||
22 | struct mdp_device mdp_dev; | ||
23 | char * __iomem base; | ||
24 | int irq; | ||
25 | }; | ||
26 | struct mdp_blit_req; | ||
27 | struct mdp_device; | ||
28 | int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | ||
29 | struct file *src_file, unsigned long src_start, | ||
30 | unsigned long src_len, struct file *dst_file, | ||
31 | unsigned long dst_start, unsigned long dst_len); | ||
32 | #define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset) | ||
33 | #define mdp_readl(mdp, offset) readl(mdp->base + offset) | ||
34 | |||
35 | #define MDP_SYNC_CONFIG_0 (0x00000) | ||
36 | #define MDP_SYNC_CONFIG_1 (0x00004) | ||
37 | #define MDP_SYNC_CONFIG_2 (0x00008) | ||
38 | #define MDP_SYNC_STATUS_0 (0x0000c) | ||
39 | #define MDP_SYNC_STATUS_1 (0x00010) | ||
40 | #define MDP_SYNC_STATUS_2 (0x00014) | ||
41 | #define MDP_SYNC_THRESH_0 (0x00018) | ||
42 | #define MDP_SYNC_THRESH_1 (0x0001c) | ||
43 | #define MDP_INTR_ENABLE (0x00020) | ||
44 | #define MDP_INTR_STATUS (0x00024) | ||
45 | #define MDP_INTR_CLEAR (0x00028) | ||
46 | #define MDP_DISPLAY0_START (0x00030) | ||
47 | #define MDP_DISPLAY1_START (0x00034) | ||
48 | #define MDP_DISPLAY_STATUS (0x00038) | ||
49 | #define MDP_EBI2_LCD0 (0x0003c) | ||
50 | #define MDP_EBI2_LCD1 (0x00040) | ||
51 | #define MDP_DISPLAY0_ADDR (0x00054) | ||
52 | #define MDP_DISPLAY1_ADDR (0x00058) | ||
53 | #define MDP_EBI2_PORTMAP_MODE (0x0005c) | ||
54 | #define MDP_MODE (0x00060) | ||
55 | #define MDP_TV_OUT_STATUS (0x00064) | ||
56 | #define MDP_HW_VERSION (0x00070) | ||
57 | #define MDP_SW_RESET (0x00074) | ||
58 | #define MDP_AXI_ERROR_MASTER_STOP (0x00078) | ||
59 | #define MDP_SEL_CLK_OR_HCLK_TEST_BUS (0x0007c) | ||
60 | #define MDP_PRIMARY_VSYNC_OUT_CTRL (0x00080) | ||
61 | #define MDP_SECONDARY_VSYNC_OUT_CTRL (0x00084) | ||
62 | #define MDP_EXTERNAL_VSYNC_OUT_CTRL (0x00088) | ||
63 | #define MDP_VSYNC_CTRL (0x0008c) | ||
64 | #define MDP_CGC_EN (0x00100) | ||
65 | #define MDP_CMD_STATUS (0x10008) | ||
66 | #define MDP_PROFILE_EN (0x10010) | ||
67 | #define MDP_PROFILE_COUNT (0x10014) | ||
68 | #define MDP_DMA_START (0x10044) | ||
69 | #define MDP_FULL_BYPASS_WORD0 (0x10100) | ||
70 | #define MDP_FULL_BYPASS_WORD1 (0x10104) | ||
71 | #define MDP_COMMAND_CONFIG (0x10104) | ||
72 | #define MDP_FULL_BYPASS_WORD2 (0x10108) | ||
73 | #define MDP_FULL_BYPASS_WORD3 (0x1010c) | ||
74 | #define MDP_FULL_BYPASS_WORD4 (0x10110) | ||
75 | #define MDP_FULL_BYPASS_WORD6 (0x10118) | ||
76 | #define MDP_FULL_BYPASS_WORD7 (0x1011c) | ||
77 | #define MDP_FULL_BYPASS_WORD8 (0x10120) | ||
78 | #define MDP_FULL_BYPASS_WORD9 (0x10124) | ||
79 | #define MDP_PPP_SOURCE_CONFIG (0x10124) | ||
80 | #define MDP_FULL_BYPASS_WORD10 (0x10128) | ||
81 | #define MDP_FULL_BYPASS_WORD11 (0x1012c) | ||
82 | #define MDP_FULL_BYPASS_WORD12 (0x10130) | ||
83 | #define MDP_FULL_BYPASS_WORD13 (0x10134) | ||
84 | #define MDP_FULL_BYPASS_WORD14 (0x10138) | ||
85 | #define MDP_PPP_OPERATION_CONFIG (0x10138) | ||
86 | #define MDP_FULL_BYPASS_WORD15 (0x1013c) | ||
87 | #define MDP_FULL_BYPASS_WORD16 (0x10140) | ||
88 | #define MDP_FULL_BYPASS_WORD17 (0x10144) | ||
89 | #define MDP_FULL_BYPASS_WORD18 (0x10148) | ||
90 | #define MDP_FULL_BYPASS_WORD19 (0x1014c) | ||
91 | #define MDP_FULL_BYPASS_WORD20 (0x10150) | ||
92 | #define MDP_PPP_DESTINATION_CONFIG (0x10150) | ||
93 | #define MDP_FULL_BYPASS_WORD21 (0x10154) | ||
94 | #define MDP_FULL_BYPASS_WORD22 (0x10158) | ||
95 | #define MDP_FULL_BYPASS_WORD23 (0x1015c) | ||
96 | #define MDP_FULL_BYPASS_WORD24 (0x10160) | ||
97 | #define MDP_FULL_BYPASS_WORD25 (0x10164) | ||
98 | #define MDP_FULL_BYPASS_WORD26 (0x10168) | ||
99 | #define MDP_FULL_BYPASS_WORD27 (0x1016c) | ||
100 | #define MDP_FULL_BYPASS_WORD29 (0x10174) | ||
101 | #define MDP_FULL_BYPASS_WORD30 (0x10178) | ||
102 | #define MDP_FULL_BYPASS_WORD31 (0x1017c) | ||
103 | #define MDP_FULL_BYPASS_WORD32 (0x10180) | ||
104 | #define MDP_DMA_CONFIG (0x10180) | ||
105 | #define MDP_FULL_BYPASS_WORD33 (0x10184) | ||
106 | #define MDP_FULL_BYPASS_WORD34 (0x10188) | ||
107 | #define MDP_FULL_BYPASS_WORD35 (0x1018c) | ||
108 | #define MDP_FULL_BYPASS_WORD37 (0x10194) | ||
109 | #define MDP_FULL_BYPASS_WORD39 (0x1019c) | ||
110 | #define MDP_FULL_BYPASS_WORD40 (0x101a0) | ||
111 | #define MDP_FULL_BYPASS_WORD41 (0x101a4) | ||
112 | #define MDP_FULL_BYPASS_WORD43 (0x101ac) | ||
113 | #define MDP_FULL_BYPASS_WORD46 (0x101b8) | ||
114 | #define MDP_FULL_BYPASS_WORD47 (0x101bc) | ||
115 | #define MDP_FULL_BYPASS_WORD48 (0x101c0) | ||
116 | #define MDP_FULL_BYPASS_WORD49 (0x101c4) | ||
117 | #define MDP_FULL_BYPASS_WORD50 (0x101c8) | ||
118 | #define MDP_FULL_BYPASS_WORD51 (0x101cc) | ||
119 | #define MDP_FULL_BYPASS_WORD52 (0x101d0) | ||
120 | #define MDP_FULL_BYPASS_WORD53 (0x101d4) | ||
121 | #define MDP_FULL_BYPASS_WORD54 (0x101d8) | ||
122 | #define MDP_FULL_BYPASS_WORD55 (0x101dc) | ||
123 | #define MDP_FULL_BYPASS_WORD56 (0x101e0) | ||
124 | #define MDP_FULL_BYPASS_WORD57 (0x101e4) | ||
125 | #define MDP_FULL_BYPASS_WORD58 (0x101e8) | ||
126 | #define MDP_FULL_BYPASS_WORD59 (0x101ec) | ||
127 | #define MDP_FULL_BYPASS_WORD60 (0x101f0) | ||
128 | #define MDP_VSYNC_THRESHOLD (0x101f0) | ||
129 | #define MDP_FULL_BYPASS_WORD61 (0x101f4) | ||
130 | #define MDP_FULL_BYPASS_WORD62 (0x101f8) | ||
131 | #define MDP_FULL_BYPASS_WORD63 (0x101fc) | ||
132 | #define MDP_TFETCH_TEST_MODE (0x20004) | ||
133 | #define MDP_TFETCH_STATUS (0x20008) | ||
134 | #define MDP_TFETCH_TILE_COUNT (0x20010) | ||
135 | #define MDP_TFETCH_FETCH_COUNT (0x20014) | ||
136 | #define MDP_TFETCH_CONSTANT_COLOR (0x20040) | ||
137 | #define MDP_CSC_BYPASS (0x40004) | ||
138 | #define MDP_SCALE_COEFF_LSB (0x5fffc) | ||
139 | #define MDP_TV_OUT_CTL (0xc0000) | ||
140 | #define MDP_TV_OUT_FIR_COEFF (0xc0004) | ||
141 | #define MDP_TV_OUT_BUF_ADDR (0xc0008) | ||
142 | #define MDP_TV_OUT_CC_DATA (0xc000c) | ||
143 | #define MDP_TV_OUT_SOBEL (0xc0010) | ||
144 | #define MDP_TV_OUT_Y_CLAMP (0xc0018) | ||
145 | #define MDP_TV_OUT_CB_CLAMP (0xc001c) | ||
146 | #define MDP_TV_OUT_CR_CLAMP (0xc0020) | ||
147 | #define MDP_TEST_MODE_CLK (0xd0000) | ||
148 | #define MDP_TEST_MISR_RESET_CLK (0xd0004) | ||
149 | #define MDP_TEST_EXPORT_MISR_CLK (0xd0008) | ||
150 | #define MDP_TEST_MISR_CURR_VAL_CLK (0xd000c) | ||
151 | #define MDP_TEST_MODE_HCLK (0xd0100) | ||
152 | #define MDP_TEST_MISR_RESET_HCLK (0xd0104) | ||
153 | #define MDP_TEST_EXPORT_MISR_HCLK (0xd0108) | ||
154 | #define MDP_TEST_MISR_CURR_VAL_HCLK (0xd010c) | ||
155 | #define MDP_TEST_MODE_DCLK (0xd0200) | ||
156 | #define MDP_TEST_MISR_RESET_DCLK (0xd0204) | ||
157 | #define MDP_TEST_EXPORT_MISR_DCLK (0xd0208) | ||
158 | #define MDP_TEST_MISR_CURR_VAL_DCLK (0xd020c) | ||
159 | #define MDP_TEST_CAPTURED_DCLK (0xd0210) | ||
160 | #define MDP_TEST_MISR_CAPT_VAL_DCLK (0xd0214) | ||
161 | #define MDP_LCDC_CTL (0xe0000) | ||
162 | #define MDP_LCDC_HSYNC_CTL (0xe0004) | ||
163 | #define MDP_LCDC_VSYNC_CTL (0xe0008) | ||
164 | #define MDP_LCDC_ACTIVE_HCTL (0xe000c) | ||
165 | #define MDP_LCDC_ACTIVE_VCTL (0xe0010) | ||
166 | #define MDP_LCDC_BORDER_CLR (0xe0014) | ||
167 | #define MDP_LCDC_H_BLANK (0xe0018) | ||
168 | #define MDP_LCDC_V_BLANK (0xe001c) | ||
169 | #define MDP_LCDC_UNDERFLOW_CLR (0xe0020) | ||
170 | #define MDP_LCDC_HSYNC_SKEW (0xe0024) | ||
171 | #define MDP_LCDC_TEST_CTL (0xe0028) | ||
172 | #define MDP_LCDC_LINE_IRQ (0xe002c) | ||
173 | #define MDP_LCDC_CTL_POLARITY (0xe0030) | ||
174 | #define MDP_LCDC_DMA_CONFIG (0xe1000) | ||
175 | #define MDP_LCDC_DMA_SIZE (0xe1004) | ||
176 | #define MDP_LCDC_DMA_IBUF_ADDR (0xe1008) | ||
177 | #define MDP_LCDC_DMA_IBUF_Y_STRIDE (0xe100c) | ||
178 | |||
179 | |||
180 | #define MDP_DMA2_TERM 0x1 | ||
181 | #define MDP_DMA3_TERM 0x2 | ||
182 | #define MDP_PPP_TERM 0x3 | ||
183 | |||
184 | /* MDP_INTR_ENABLE */ | ||
185 | #define DL0_ROI_DONE (1<<0) | ||
186 | #define DL1_ROI_DONE (1<<1) | ||
187 | #define DL0_DMA2_TERM_DONE (1<<2) | ||
188 | #define DL1_DMA2_TERM_DONE (1<<3) | ||
189 | #define DL0_PPP_TERM_DONE (1<<4) | ||
190 | #define DL1_PPP_TERM_DONE (1<<5) | ||
191 | #define TV_OUT_DMA3_DONE (1<<6) | ||
192 | #define TV_ENC_UNDERRUN (1<<7) | ||
193 | #define DL0_FETCH_DONE (1<<11) | ||
194 | #define DL1_FETCH_DONE (1<<12) | ||
195 | |||
196 | #define MDP_PPP_BUSY_STATUS (DL0_ROI_DONE| \ | ||
197 | DL1_ROI_DONE| \ | ||
198 | DL0_PPP_TERM_DONE| \ | ||
199 | DL1_PPP_TERM_DONE) | ||
200 | |||
201 | #define MDP_ANY_INTR_MASK (DL0_ROI_DONE| \ | ||
202 | DL1_ROI_DONE| \ | ||
203 | DL0_DMA2_TERM_DONE| \ | ||
204 | DL1_DMA2_TERM_DONE| \ | ||
205 | DL0_PPP_TERM_DONE| \ | ||
206 | DL1_PPP_TERM_DONE| \ | ||
207 | DL0_FETCH_DONE| \ | ||
208 | DL1_FETCH_DONE| \ | ||
209 | TV_ENC_UNDERRUN) | ||
210 | |||
211 | #define MDP_TOP_LUMA 16 | ||
212 | #define MDP_TOP_CHROMA 0 | ||
213 | #define MDP_BOTTOM_LUMA 19 | ||
214 | #define MDP_BOTTOM_CHROMA 3 | ||
215 | #define MDP_LEFT_LUMA 22 | ||
216 | #define MDP_LEFT_CHROMA 6 | ||
217 | #define MDP_RIGHT_LUMA 25 | ||
218 | #define MDP_RIGHT_CHROMA 9 | ||
219 | |||
220 | #define CLR_G 0x0 | ||
221 | #define CLR_B 0x1 | ||
222 | #define CLR_R 0x2 | ||
223 | #define CLR_ALPHA 0x3 | ||
224 | |||
225 | #define CLR_Y CLR_G | ||
226 | #define CLR_CB CLR_B | ||
227 | #define CLR_CR CLR_R | ||
228 | |||
229 | /* from lsb to msb */ | ||
230 | #define MDP_GET_PACK_PATTERN(a, x, y, z, bit) \ | ||
231 | (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z)) | ||
232 | |||
233 | /* MDP_SYNC_CONFIG_0/1/2 */ | ||
234 | #define MDP_SYNCFG_HGT_LOC 22 | ||
235 | #define MDP_SYNCFG_VSYNC_EXT_EN (1<<21) | ||
236 | #define MDP_SYNCFG_VSYNC_INT_EN (1<<20) | ||
237 | |||
238 | /* MDP_SYNC_THRESH_0 */ | ||
239 | #define MDP_PRIM_BELOW_LOC 0 | ||
240 | #define MDP_PRIM_ABOVE_LOC 8 | ||
241 | |||
242 | /* MDP_{PRIMARY,SECONDARY,EXTERNAL}_VSYNC_OUT_CRL */ | ||
243 | #define VSYNC_PULSE_EN (1<<31) | ||
244 | #define VSYNC_PULSE_INV (1<<30) | ||
245 | |||
246 | /* MDP_VSYNC_CTRL */ | ||
247 | #define DISP0_VSYNC_MAP_VSYNC0 0 | ||
248 | #define DISP0_VSYNC_MAP_VSYNC1 (1<<0) | ||
249 | #define DISP0_VSYNC_MAP_VSYNC2 ((1<<0)|(1<<1)) | ||
250 | |||
251 | #define DISP1_VSYNC_MAP_VSYNC0 0 | ||
252 | #define DISP1_VSYNC_MAP_VSYNC1 (1<<2) | ||
253 | #define DISP1_VSYNC_MAP_VSYNC2 ((1<<2)|(1<<3)) | ||
254 | |||
255 | #define PRIMARY_LCD_SYNC_EN (1<<4) | ||
256 | #define PRIMARY_LCD_SYNC_DISABLE 0 | ||
257 | |||
258 | #define SECONDARY_LCD_SYNC_EN (1<<5) | ||
259 | #define SECONDARY_LCD_SYNC_DISABLE 0 | ||
260 | |||
261 | #define EXTERNAL_LCD_SYNC_EN (1<<6) | ||
262 | #define EXTERNAL_LCD_SYNC_DISABLE 0 | ||
263 | |||
264 | /* MDP_VSYNC_THRESHOLD / MDP_FULL_BYPASS_WORD60 */ | ||
265 | #define VSYNC_THRESHOLD_ABOVE_LOC 0 | ||
266 | #define VSYNC_THRESHOLD_BELOW_LOC 16 | ||
267 | #define VSYNC_ANTI_TEAR_EN (1<<31) | ||
268 | |||
269 | /* MDP_COMMAND_CONFIG / MDP_FULL_BYPASS_WORD1 */ | ||
270 | #define MDP_CMD_DBGBUS_EN (1<<0) | ||
271 | |||
272 | /* MDP_PPP_SOURCE_CONFIG / MDP_FULL_BYPASS_WORD9&53 */ | ||
273 | #define PPP_SRC_C0G_8BIT ((1<<1)|(1<<0)) | ||
274 | #define PPP_SRC_C1B_8BIT ((1<<3)|(1<<2)) | ||
275 | #define PPP_SRC_C2R_8BIT ((1<<5)|(1<<4)) | ||
276 | #define PPP_SRC_C3A_8BIT ((1<<7)|(1<<6)) | ||
277 | |||
278 | #define PPP_SRC_C0G_6BIT (1<<1) | ||
279 | #define PPP_SRC_C1B_6BIT (1<<3) | ||
280 | #define PPP_SRC_C2R_6BIT (1<<5) | ||
281 | |||
282 | #define PPP_SRC_C0G_5BIT (1<<0) | ||
283 | #define PPP_SRC_C1B_5BIT (1<<2) | ||
284 | #define PPP_SRC_C2R_5BIT (1<<4) | ||
285 | |||
286 | #define PPP_SRC_C3ALPHA_EN (1<<8) | ||
287 | |||
288 | #define PPP_SRC_BPP_1BYTES 0 | ||
289 | #define PPP_SRC_BPP_2BYTES (1<<9) | ||
290 | #define PPP_SRC_BPP_3BYTES (1<<10) | ||
291 | #define PPP_SRC_BPP_4BYTES ((1<<10)|(1<<9)) | ||
292 | |||
293 | #define PPP_SRC_BPP_ROI_ODD_X (1<<11) | ||
294 | #define PPP_SRC_BPP_ROI_ODD_Y (1<<12) | ||
295 | #define PPP_SRC_INTERLVD_2COMPONENTS (1<<13) | ||
296 | #define PPP_SRC_INTERLVD_3COMPONENTS (1<<14) | ||
297 | #define PPP_SRC_INTERLVD_4COMPONENTS ((1<<14)|(1<<13)) | ||
298 | |||
299 | |||
300 | /* RGB666 unpack format | ||
301 | ** TIGHT means R6+G6+B6 together | ||
302 | ** LOOSE means R6+2 +G6+2+ B6+2 (with MSB) | ||
303 | ** or 2+R6 +2+G6 +2+B6 (with LSB) | ||
304 | */ | ||
305 | #define PPP_SRC_PACK_TIGHT (1<<17) | ||
306 | #define PPP_SRC_PACK_LOOSE 0 | ||
307 | #define PPP_SRC_PACK_ALIGN_LSB 0 | ||
308 | #define PPP_SRC_PACK_ALIGN_MSB (1<<18) | ||
309 | |||
310 | #define PPP_SRC_PLANE_INTERLVD 0 | ||
311 | #define PPP_SRC_PLANE_PSEUDOPLNR (1<<20) | ||
312 | |||
313 | #define PPP_SRC_WMV9_MODE (1<<21) | ||
314 | |||
315 | /* MDP_PPP_OPERATION_CONFIG / MDP_FULL_BYPASS_WORD14 */ | ||
316 | #define PPP_OP_SCALE_X_ON (1<<0) | ||
317 | #define PPP_OP_SCALE_Y_ON (1<<1) | ||
318 | |||
319 | #define PPP_OP_CONVERT_RGB2YCBCR 0 | ||
320 | #define PPP_OP_CONVERT_YCBCR2RGB (1<<2) | ||
321 | #define PPP_OP_CONVERT_ON (1<<3) | ||
322 | |||
323 | #define PPP_OP_CONVERT_MATRIX_PRIMARY 0 | ||
324 | #define PPP_OP_CONVERT_MATRIX_SECONDARY (1<<4) | ||
325 | |||
326 | #define PPP_OP_LUT_C0_ON (1<<5) | ||
327 | #define PPP_OP_LUT_C1_ON (1<<6) | ||
328 | #define PPP_OP_LUT_C2_ON (1<<7) | ||
329 | |||
330 | /* rotate or blend enable */ | ||
331 | #define PPP_OP_ROT_ON (1<<8) | ||
332 | |||
333 | #define PPP_OP_ROT_90 (1<<9) | ||
334 | #define PPP_OP_FLIP_LR (1<<10) | ||
335 | #define PPP_OP_FLIP_UD (1<<11) | ||
336 | |||
337 | #define PPP_OP_BLEND_ON (1<<12) | ||
338 | |||
339 | #define PPP_OP_BLEND_SRCPIXEL_ALPHA 0 | ||
340 | #define PPP_OP_BLEND_DSTPIXEL_ALPHA (1<<13) | ||
341 | #define PPP_OP_BLEND_CONSTANT_ALPHA (1<<14) | ||
342 | #define PPP_OP_BLEND_SRCPIXEL_TRANSP ((1<<13)|(1<<14)) | ||
343 | |||
344 | #define PPP_OP_BLEND_ALPHA_BLEND_NORMAL 0 | ||
345 | #define PPP_OP_BLEND_ALPHA_BLEND_REVERSE (1<<15) | ||
346 | |||
347 | #define PPP_OP_DITHER_EN (1<<16) | ||
348 | |||
349 | #define PPP_OP_COLOR_SPACE_RGB 0 | ||
350 | #define PPP_OP_COLOR_SPACE_YCBCR (1<<17) | ||
351 | |||
352 | #define PPP_OP_SRC_CHROMA_RGB 0 | ||
353 | #define PPP_OP_SRC_CHROMA_H2V1 (1<<18) | ||
354 | #define PPP_OP_SRC_CHROMA_H1V2 (1<<19) | ||
355 | #define PPP_OP_SRC_CHROMA_420 ((1<<18)|(1<<19)) | ||
356 | #define PPP_OP_SRC_CHROMA_COSITE 0 | ||
357 | #define PPP_OP_SRC_CHROMA_OFFSITE (1<<20) | ||
358 | |||
359 | #define PPP_OP_DST_CHROMA_RGB 0 | ||
360 | #define PPP_OP_DST_CHROMA_H2V1 (1<<21) | ||
361 | #define PPP_OP_DST_CHROMA_H1V2 (1<<22) | ||
362 | #define PPP_OP_DST_CHROMA_420 ((1<<21)|(1<<22)) | ||
363 | #define PPP_OP_DST_CHROMA_COSITE 0 | ||
364 | #define PPP_OP_DST_CHROMA_OFFSITE (1<<23) | ||
365 | |||
366 | #define PPP_BLEND_ALPHA_TRANSP (1<<24) | ||
367 | |||
368 | #define PPP_OP_BG_CHROMA_RGB 0 | ||
369 | #define PPP_OP_BG_CHROMA_H2V1 (1<<25) | ||
370 | #define PPP_OP_BG_CHROMA_H1V2 (1<<26) | ||
371 | #define PPP_OP_BG_CHROMA_420 ((1<<25)|(1<<26)) | ||
372 | #define PPP_OP_BG_CHROMA_SITE_COSITE 0 | ||
373 | #define PPP_OP_BG_CHROMA_SITE_OFFSITE (1<<27) | ||
374 | |||
375 | /* MDP_PPP_DESTINATION_CONFIG / MDP_FULL_BYPASS_WORD20 */ | ||
376 | #define PPP_DST_C0G_8BIT ((1<<0)|(1<<1)) | ||
377 | #define PPP_DST_C1B_8BIT ((1<<3)|(1<<2)) | ||
378 | #define PPP_DST_C2R_8BIT ((1<<5)|(1<<4)) | ||
379 | #define PPP_DST_C3A_8BIT ((1<<7)|(1<<6)) | ||
380 | |||
381 | #define PPP_DST_C0G_6BIT (1<<1) | ||
382 | #define PPP_DST_C1B_6BIT (1<<3) | ||
383 | #define PPP_DST_C2R_6BIT (1<<5) | ||
384 | |||
385 | #define PPP_DST_C0G_5BIT (1<<0) | ||
386 | #define PPP_DST_C1B_5BIT (1<<2) | ||
387 | #define PPP_DST_C2R_5BIT (1<<4) | ||
388 | |||
389 | #define PPP_DST_C3A_8BIT ((1<<7)|(1<<6)) | ||
390 | #define PPP_DST_C3ALPHA_EN (1<<8) | ||
391 | |||
392 | #define PPP_DST_INTERLVD_2COMPONENTS (1<<9) | ||
393 | #define PPP_DST_INTERLVD_3COMPONENTS (1<<10) | ||
394 | #define PPP_DST_INTERLVD_4COMPONENTS ((1<<10)|(1<<9)) | ||
395 | #define PPP_DST_INTERLVD_6COMPONENTS ((1<<11)|(1<<9)) | ||
396 | |||
397 | #define PPP_DST_PACK_LOOSE 0 | ||
398 | #define PPP_DST_PACK_TIGHT (1<<13) | ||
399 | #define PPP_DST_PACK_ALIGN_LSB 0 | ||
400 | #define PPP_DST_PACK_ALIGN_MSB (1<<14) | ||
401 | |||
402 | #define PPP_DST_OUT_SEL_AXI 0 | ||
403 | #define PPP_DST_OUT_SEL_MDDI (1<<15) | ||
404 | |||
405 | #define PPP_DST_BPP_2BYTES (1<<16) | ||
406 | #define PPP_DST_BPP_3BYTES (1<<17) | ||
407 | #define PPP_DST_BPP_4BYTES ((1<<17)|(1<<16)) | ||
408 | |||
409 | #define PPP_DST_PLANE_INTERLVD 0 | ||
410 | #define PPP_DST_PLANE_PLANAR (1<<18) | ||
411 | #define PPP_DST_PLANE_PSEUDOPLNR (1<<19) | ||
412 | |||
413 | #define PPP_DST_TO_TV (1<<20) | ||
414 | |||
415 | #define PPP_DST_MDDI_PRIMARY 0 | ||
416 | #define PPP_DST_MDDI_SECONDARY (1<<21) | ||
417 | #define PPP_DST_MDDI_EXTERNAL (1<<22) | ||
418 | |||
419 | /* image configurations by image type */ | ||
420 | #define PPP_CFG_MDP_RGB_565(dir) (PPP_##dir##_C2R_5BIT | \ | ||
421 | PPP_##dir##_C0G_6BIT | \ | ||
422 | PPP_##dir##_C1B_5BIT | \ | ||
423 | PPP_##dir##_BPP_2BYTES | \ | ||
424 | PPP_##dir##_INTERLVD_3COMPONENTS | \ | ||
425 | PPP_##dir##_PACK_TIGHT | \ | ||
426 | PPP_##dir##_PACK_ALIGN_LSB | \ | ||
427 | PPP_##dir##_PLANE_INTERLVD) | ||
428 | |||
429 | #define PPP_CFG_MDP_RGB_888(dir) (PPP_##dir##_C2R_8BIT | \ | ||
430 | PPP_##dir##_C0G_8BIT | \ | ||
431 | PPP_##dir##_C1B_8BIT | \ | ||
432 | PPP_##dir##_BPP_3BYTES | \ | ||
433 | PPP_##dir##_INTERLVD_3COMPONENTS | \ | ||
434 | PPP_##dir##_PACK_TIGHT | \ | ||
435 | PPP_##dir##_PACK_ALIGN_LSB | \ | ||
436 | PPP_##dir##_PLANE_INTERLVD) | ||
437 | |||
438 | #define PPP_CFG_MDP_ARGB_8888(dir) (PPP_##dir##_C2R_8BIT | \ | ||
439 | PPP_##dir##_C0G_8BIT | \ | ||
440 | PPP_##dir##_C1B_8BIT | \ | ||
441 | PPP_##dir##_C3A_8BIT | \ | ||
442 | PPP_##dir##_C3ALPHA_EN | \ | ||
443 | PPP_##dir##_BPP_4BYTES | \ | ||
444 | PPP_##dir##_INTERLVD_4COMPONENTS | \ | ||
445 | PPP_##dir##_PACK_TIGHT | \ | ||
446 | PPP_##dir##_PACK_ALIGN_LSB | \ | ||
447 | PPP_##dir##_PLANE_INTERLVD) | ||
448 | |||
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) | ||
451 | #define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) | ||
452 | |||
453 | #define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \ | ||
454 | PPP_##dir##_C0G_8BIT | \ | ||
455 | PPP_##dir##_C1B_8BIT | \ | ||
456 | PPP_##dir##_C3A_8BIT | \ | ||
457 | PPP_##dir##_BPP_2BYTES | \ | ||
458 | PPP_##dir##_INTERLVD_2COMPONENTS | \ | ||
459 | PPP_##dir##_PACK_TIGHT | \ | ||
460 | PPP_##dir##_PACK_ALIGN_LSB | \ | ||
461 | PPP_##dir##_PLANE_PSEUDOPLNR) | ||
462 | |||
463 | #define PPP_CFG_MDP_Y_CRCB_H2V2(dir) PPP_CFG_MDP_Y_CBCR_H2V2(dir) | ||
464 | |||
465 | #define PPP_CFG_MDP_YCRYCB_H2V1(dir) (PPP_##dir##_C2R_8BIT | \ | ||
466 | PPP_##dir##_C0G_8BIT | \ | ||
467 | PPP_##dir##_C1B_8BIT | \ | ||
468 | PPP_##dir##_C3A_8BIT | \ | ||
469 | PPP_##dir##_BPP_2BYTES | \ | ||
470 | PPP_##dir##_INTERLVD_4COMPONENTS | \ | ||
471 | PPP_##dir##_PACK_TIGHT | \ | ||
472 | PPP_##dir##_PACK_ALIGN_LSB |\ | ||
473 | PPP_##dir##_PLANE_INTERLVD) | ||
474 | |||
475 | #define PPP_CFG_MDP_Y_CBCR_H2V1(dir) (PPP_##dir##_C2R_8BIT | \ | ||
476 | PPP_##dir##_C0G_8BIT | \ | ||
477 | PPP_##dir##_C1B_8BIT | \ | ||
478 | PPP_##dir##_C3A_8BIT | \ | ||
479 | PPP_##dir##_BPP_2BYTES | \ | ||
480 | PPP_##dir##_INTERLVD_2COMPONENTS | \ | ||
481 | PPP_##dir##_PACK_TIGHT | \ | ||
482 | PPP_##dir##_PACK_ALIGN_LSB | \ | ||
483 | PPP_##dir##_PLANE_PSEUDOPLNR) | ||
484 | |||
485 | #define PPP_CFG_MDP_Y_CRCB_H2V1(dir) PPP_CFG_MDP_Y_CBCR_H2V1(dir) | ||
486 | |||
487 | #define PPP_PACK_PATTERN_MDP_RGB_565 \ | ||
488 | 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_XRGB_8888 \ | ||
491 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8) | ||
492 | #define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888 | ||
493 | #define PPP_PACK_PATTERN_MDP_RGBA_8888 \ | ||
494 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8) | ||
495 | #define PPP_PACK_PATTERN_MDP_BGRA_8888 \ | ||
496 | MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8) | ||
497 | #define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \ | ||
498 | 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 | ||
500 | #define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1 \ | ||
501 | MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8) | ||
502 | #define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V2 PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1 | ||
503 | #define PPP_PACK_PATTERN_MDP_YCRYCB_H2V1 \ | ||
504 | MDP_GET_PACK_PATTERN(CLR_Y, CLR_R, CLR_Y, CLR_B, 8) | ||
505 | |||
506 | #define PPP_CHROMA_SAMP_MDP_RGB_565(dir) PPP_OP_##dir##_CHROMA_RGB | ||
507 | #define PPP_CHROMA_SAMP_MDP_RGB_888(dir) PPP_OP_##dir##_CHROMA_RGB | ||
508 | #define PPP_CHROMA_SAMP_MDP_XRGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB | ||
509 | #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 | ||
511 | #define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB | ||
512 | #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 | ||
514 | #define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 | ||
515 | #define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V2(dir) PPP_OP_##dir##_CHROMA_420 | ||
516 | #define PPP_CHROMA_SAMP_MDP_YCRYCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 | ||
517 | |||
518 | /* Helpful array generation macros */ | ||
519 | #define PPP_ARRAY0(name) \ | ||
520 | [MDP_RGB_565] = PPP_##name##_MDP_RGB_565,\ | ||
521 | [MDP_RGB_888] = PPP_##name##_MDP_RGB_888,\ | ||
522 | [MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888,\ | ||
523 | [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\ | ||
524 | [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\ | ||
525 | [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\ | ||
526 | [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\ | ||
527 | [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\ | ||
528 | [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\ | ||
529 | [MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2,\ | ||
530 | [MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1 | ||
531 | |||
532 | #define PPP_ARRAY1(name, dir) \ | ||
533 | [MDP_RGB_565] = PPP_##name##_MDP_RGB_565(dir),\ | ||
534 | [MDP_RGB_888] = PPP_##name##_MDP_RGB_888(dir),\ | ||
535 | [MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888(dir),\ | ||
536 | [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\ | ||
537 | [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\ | ||
538 | [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\ | ||
539 | [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\ | ||
540 | [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\ | ||
541 | [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\ | ||
542 | [MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2(dir),\ | ||
543 | [MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1(dir) | ||
544 | |||
545 | #define IS_YCRCB(img) ((img == MDP_Y_CRCB_H2V2) | (img == MDP_Y_CBCR_H2V2) | \ | ||
546 | (img == MDP_Y_CRCB_H2V1) | (img == MDP_Y_CBCR_H2V1) | \ | ||
547 | (img == MDP_YCRYCB_H2V1)) | ||
548 | #define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \ | ||
549 | (img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ | ||
550 | (img == MDP_XRGB_8888) | (img == MDP_BGRA_8888)) | ||
551 | #define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ | ||
552 | (img == MDP_BGRA_8888)) | ||
553 | |||
554 | #define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \ | ||
555 | (img == MDP_Y_CBCR_H2V2) | \ | ||
556 | (img == MDP_Y_CRCB_H2V1) | \ | ||
557 | (img == MDP_Y_CBCR_H2V1)) | ||
558 | |||
559 | /* Mappings from addr to purpose */ | ||
560 | #define PPP_ADDR_SRC_ROI MDP_FULL_BYPASS_WORD2 | ||
561 | #define PPP_ADDR_SRC0 MDP_FULL_BYPASS_WORD3 | ||
562 | #define PPP_ADDR_SRC1 MDP_FULL_BYPASS_WORD4 | ||
563 | #define PPP_ADDR_SRC_YSTRIDE MDP_FULL_BYPASS_WORD7 | ||
564 | #define PPP_ADDR_SRC_CFG MDP_FULL_BYPASS_WORD9 | ||
565 | #define PPP_ADDR_SRC_PACK_PATTERN MDP_FULL_BYPASS_WORD10 | ||
566 | #define PPP_ADDR_OPERATION MDP_FULL_BYPASS_WORD14 | ||
567 | #define PPP_ADDR_PHASEX_INIT MDP_FULL_BYPASS_WORD15 | ||
568 | #define PPP_ADDR_PHASEY_INIT MDP_FULL_BYPASS_WORD16 | ||
569 | #define PPP_ADDR_PHASEX_STEP MDP_FULL_BYPASS_WORD17 | ||
570 | #define PPP_ADDR_PHASEY_STEP MDP_FULL_BYPASS_WORD18 | ||
571 | #define PPP_ADDR_ALPHA_TRANSP MDP_FULL_BYPASS_WORD19 | ||
572 | #define PPP_ADDR_DST_CFG MDP_FULL_BYPASS_WORD20 | ||
573 | #define PPP_ADDR_DST_PACK_PATTERN MDP_FULL_BYPASS_WORD21 | ||
574 | #define PPP_ADDR_DST_ROI MDP_FULL_BYPASS_WORD25 | ||
575 | #define PPP_ADDR_DST0 MDP_FULL_BYPASS_WORD26 | ||
576 | #define PPP_ADDR_DST1 MDP_FULL_BYPASS_WORD27 | ||
577 | #define PPP_ADDR_DST_YSTRIDE MDP_FULL_BYPASS_WORD30 | ||
578 | #define PPP_ADDR_EDGE MDP_FULL_BYPASS_WORD46 | ||
579 | #define PPP_ADDR_BG0 MDP_FULL_BYPASS_WORD48 | ||
580 | #define PPP_ADDR_BG1 MDP_FULL_BYPASS_WORD49 | ||
581 | #define PPP_ADDR_BG_YSTRIDE MDP_FULL_BYPASS_WORD51 | ||
582 | #define PPP_ADDR_BG_CFG MDP_FULL_BYPASS_WORD53 | ||
583 | #define PPP_ADDR_BG_PACK_PATTERN MDP_FULL_BYPASS_WORD54 | ||
584 | |||
585 | /* MDP_DMA_CONFIG / MDP_FULL_BYPASS_WORD32 */ | ||
586 | #define DMA_DSTC0G_6BITS (1<<1) | ||
587 | #define DMA_DSTC1B_6BITS (1<<3) | ||
588 | #define DMA_DSTC2R_6BITS (1<<5) | ||
589 | #define DMA_DSTC0G_5BITS (1<<0) | ||
590 | #define DMA_DSTC1B_5BITS (1<<2) | ||
591 | #define DMA_DSTC2R_5BITS (1<<4) | ||
592 | |||
593 | #define DMA_PACK_TIGHT (1<<6) | ||
594 | #define DMA_PACK_LOOSE 0 | ||
595 | #define DMA_PACK_ALIGN_LSB 0 | ||
596 | #define DMA_PACK_ALIGN_MSB (1<<7) | ||
597 | #define DMA_PACK_PATTERN_RGB \ | ||
598 | (MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8) | ||
599 | |||
600 | #define DMA_OUT_SEL_AHB 0 | ||
601 | #define DMA_OUT_SEL_MDDI (1<<14) | ||
602 | #define DMA_AHBM_LCD_SEL_PRIMARY 0 | ||
603 | #define DMA_AHBM_LCD_SEL_SECONDARY (1<<15) | ||
604 | #define DMA_IBUF_C3ALPHA_EN (1<<16) | ||
605 | #define DMA_DITHER_EN (1<<17) | ||
606 | |||
607 | #define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0 | ||
608 | #define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (1<<18) | ||
609 | #define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (1<<19) | ||
610 | |||
611 | #define DMA_IBUF_FORMAT_RGB565 (1<<20) | ||
612 | #define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0 | ||
613 | |||
614 | #define DMA_IBUF_NONCONTIGUOUS (1<<21) | ||
615 | |||
616 | /* MDDI REGISTER ? */ | ||
617 | #define MDDI_VDO_PACKET_DESC 0x5666 | ||
618 | #define MDDI_VDO_PACKET_PRIM 0xC3 | ||
619 | #define MDDI_VDO_PACKET_SECD 0xC0 | ||
620 | |||
621 | #endif | ||
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c new file mode 100644 index 000000000000..4ff001f4cbbd --- /dev/null +++ b/drivers/video/msm/mdp_ppp.c | |||
@@ -0,0 +1,730 @@ | |||
1 | /* drivers/video/msm/mdp_ppp.c | ||
2 | * | ||
3 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
4 | * Copyright (C) 2007 Google Incorporated | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | #include <linux/fb.h> | ||
16 | #include <linux/file.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/msm_mdp.h> | ||
19 | #include <mach/msm_fb.h> | ||
20 | |||
21 | #include "mdp_hw.h" | ||
22 | #include "mdp_scale_tables.h" | ||
23 | |||
24 | #define DLOG(x...) do {} while (0) | ||
25 | |||
26 | #define MDP_DOWNSCALE_BLUR (MDP_DOWNSCALE_MAX + 1) | ||
27 | static int downscale_y_table = MDP_DOWNSCALE_MAX; | ||
28 | static int downscale_x_table = MDP_DOWNSCALE_MAX; | ||
29 | |||
30 | struct mdp_regs { | ||
31 | uint32_t src0; | ||
32 | uint32_t src1; | ||
33 | uint32_t dst0; | ||
34 | uint32_t dst1; | ||
35 | uint32_t src_cfg; | ||
36 | uint32_t dst_cfg; | ||
37 | uint32_t src_pack; | ||
38 | uint32_t dst_pack; | ||
39 | uint32_t src_rect; | ||
40 | uint32_t dst_rect; | ||
41 | uint32_t src_ystride; | ||
42 | uint32_t dst_ystride; | ||
43 | uint32_t op; | ||
44 | uint32_t src_bpp; | ||
45 | uint32_t dst_bpp; | ||
46 | uint32_t edge; | ||
47 | uint32_t phasex_init; | ||
48 | uint32_t phasey_init; | ||
49 | uint32_t phasex_step; | ||
50 | uint32_t phasey_step; | ||
51 | }; | ||
52 | |||
53 | static uint32_t pack_pattern[] = { | ||
54 | PPP_ARRAY0(PACK_PATTERN) | ||
55 | }; | ||
56 | |||
57 | static uint32_t src_img_cfg[] = { | ||
58 | PPP_ARRAY1(CFG, SRC) | ||
59 | }; | ||
60 | |||
61 | static uint32_t dst_img_cfg[] = { | ||
62 | PPP_ARRAY1(CFG, DST) | ||
63 | }; | ||
64 | |||
65 | static uint32_t bytes_per_pixel[] = { | ||
66 | [MDP_RGB_565] = 2, | ||
67 | [MDP_RGB_888] = 3, | ||
68 | [MDP_XRGB_8888] = 4, | ||
69 | [MDP_ARGB_8888] = 4, | ||
70 | [MDP_RGBA_8888] = 4, | ||
71 | [MDP_BGRA_8888] = 4, | ||
72 | [MDP_Y_CBCR_H2V1] = 1, | ||
73 | [MDP_Y_CBCR_H2V2] = 1, | ||
74 | [MDP_Y_CRCB_H2V1] = 1, | ||
75 | [MDP_Y_CRCB_H2V2] = 1, | ||
76 | [MDP_YCRYCB_H2V1] = 2 | ||
77 | }; | ||
78 | |||
79 | static uint32_t dst_op_chroma[] = { | ||
80 | PPP_ARRAY1(CHROMA_SAMP, DST) | ||
81 | }; | ||
82 | |||
83 | static uint32_t src_op_chroma[] = { | ||
84 | PPP_ARRAY1(CHROMA_SAMP, SRC) | ||
85 | }; | ||
86 | |||
87 | static uint32_t bg_op_chroma[] = { | ||
88 | PPP_ARRAY1(CHROMA_SAMP, BG) | ||
89 | }; | ||
90 | |||
91 | static void rotate_dst_addr_x(struct mdp_blit_req *req, struct mdp_regs *regs) | ||
92 | { | ||
93 | regs->dst0 += (req->dst_rect.w - | ||
94 | min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp; | ||
95 | regs->dst1 += (req->dst_rect.w - | ||
96 | min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp; | ||
97 | } | ||
98 | |||
99 | static void rotate_dst_addr_y(struct mdp_blit_req *req, struct mdp_regs *regs) | ||
100 | { | ||
101 | regs->dst0 += (req->dst_rect.h - | ||
102 | min((uint32_t)16, req->dst_rect.h)) * | ||
103 | regs->dst_ystride; | ||
104 | regs->dst1 += (req->dst_rect.h - | ||
105 | min((uint32_t)16, req->dst_rect.h)) * | ||
106 | regs->dst_ystride; | ||
107 | } | ||
108 | |||
109 | static void blit_rotate(struct mdp_blit_req *req, | ||
110 | struct mdp_regs *regs) | ||
111 | { | ||
112 | if (req->flags == MDP_ROT_NOP) | ||
113 | return; | ||
114 | |||
115 | regs->op |= PPP_OP_ROT_ON; | ||
116 | if ((req->flags & MDP_ROT_90 || req->flags & MDP_FLIP_LR) && | ||
117 | !(req->flags & MDP_ROT_90 && req->flags & MDP_FLIP_LR)) | ||
118 | rotate_dst_addr_x(req, regs); | ||
119 | if (req->flags & MDP_ROT_90) | ||
120 | regs->op |= PPP_OP_ROT_90; | ||
121 | if (req->flags & MDP_FLIP_UD) { | ||
122 | regs->op |= PPP_OP_FLIP_UD; | ||
123 | rotate_dst_addr_y(req, regs); | ||
124 | } | ||
125 | if (req->flags & MDP_FLIP_LR) | ||
126 | regs->op |= PPP_OP_FLIP_LR; | ||
127 | } | ||
128 | |||
129 | static void blit_convert(struct mdp_blit_req *req, struct mdp_regs *regs) | ||
130 | { | ||
131 | if (req->src.format == req->dst.format) | ||
132 | return; | ||
133 | if (IS_RGB(req->src.format) && IS_YCRCB(req->dst.format)) { | ||
134 | regs->op |= PPP_OP_CONVERT_RGB2YCBCR | PPP_OP_CONVERT_ON; | ||
135 | } else if (IS_YCRCB(req->src.format) && IS_RGB(req->dst.format)) { | ||
136 | regs->op |= PPP_OP_CONVERT_YCBCR2RGB | PPP_OP_CONVERT_ON; | ||
137 | if (req->dst.format == MDP_RGB_565) | ||
138 | regs->op |= PPP_OP_CONVERT_MATRIX_SECONDARY; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | #define GET_BIT_RANGE(value, high, low) \ | ||
143 | (((1 << (high - low + 1)) - 1) & (value >> low)) | ||
144 | static uint32_t transp_convert(struct mdp_blit_req *req) | ||
145 | { | ||
146 | uint32_t transp = 0; | ||
147 | if (req->src.format == MDP_RGB_565) { | ||
148 | /* pad each value to 8 bits by copying the high bits into the | ||
149 | * low end, convert RGB to RBG by switching low 2 components */ | ||
150 | transp |= ((GET_BIT_RANGE(req->transp_mask, 15, 11) << 3) | | ||
151 | (GET_BIT_RANGE(req->transp_mask, 15, 13))) << 16; | ||
152 | |||
153 | transp |= ((GET_BIT_RANGE(req->transp_mask, 4, 0) << 3) | | ||
154 | (GET_BIT_RANGE(req->transp_mask, 4, 2))) << 8; | ||
155 | |||
156 | transp |= (GET_BIT_RANGE(req->transp_mask, 10, 5) << 2) | | ||
157 | (GET_BIT_RANGE(req->transp_mask, 10, 9)); | ||
158 | } else { | ||
159 | /* convert RGB to RBG */ | ||
160 | transp |= (GET_BIT_RANGE(req->transp_mask, 15, 8)) | | ||
161 | (GET_BIT_RANGE(req->transp_mask, 23, 16) << 16) | | ||
162 | (GET_BIT_RANGE(req->transp_mask, 7, 0) << 8); | ||
163 | } | ||
164 | return transp; | ||
165 | } | ||
166 | #undef GET_BIT_RANGE | ||
167 | |||
168 | static void blit_blend(struct mdp_blit_req *req, struct mdp_regs *regs) | ||
169 | { | ||
170 | /* TRANSP BLEND */ | ||
171 | if (req->transp_mask != MDP_TRANSP_NOP) { | ||
172 | req->transp_mask = transp_convert(req); | ||
173 | if (req->alpha != MDP_ALPHA_NOP) { | ||
174 | /* use blended transparancy mode | ||
175 | * pixel = (src == transp) ? dst : blend | ||
176 | * blend is combo of blend_eq_sel and | ||
177 | * blend_alpha_sel */ | ||
178 | regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON | | ||
179 | PPP_OP_BLEND_ALPHA_BLEND_NORMAL | | ||
180 | PPP_OP_BLEND_CONSTANT_ALPHA | | ||
181 | PPP_BLEND_ALPHA_TRANSP; | ||
182 | } else { | ||
183 | /* simple transparancy mode | ||
184 | * pixel = (src == transp) ? dst : src */ | ||
185 | regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON | | ||
186 | PPP_OP_BLEND_SRCPIXEL_TRANSP; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | req->alpha &= 0xff; | ||
191 | /* ALPHA BLEND */ | ||
192 | if (HAS_ALPHA(req->src.format)) { | ||
193 | regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON | | ||
194 | PPP_OP_BLEND_SRCPIXEL_ALPHA; | ||
195 | } else if (req->alpha < MDP_ALPHA_NOP) { | ||
196 | /* just blend by alpha */ | ||
197 | regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON | | ||
198 | PPP_OP_BLEND_ALPHA_BLEND_NORMAL | | ||
199 | PPP_OP_BLEND_CONSTANT_ALPHA; | ||
200 | } | ||
201 | |||
202 | regs->op |= bg_op_chroma[req->dst.format]; | ||
203 | } | ||
204 | |||
205 | #define ONE_HALF (1LL << 32) | ||
206 | #define ONE (1LL << 33) | ||
207 | #define TWO (2LL << 33) | ||
208 | #define THREE (3LL << 33) | ||
209 | #define FRAC_MASK (ONE - 1) | ||
210 | #define INT_MASK (~FRAC_MASK) | ||
211 | |||
212 | static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t origin, | ||
213 | uint32_t *phase_init, uint32_t *phase_step) | ||
214 | { | ||
215 | /* to improve precicsion calculations are done in U31.33 and converted | ||
216 | * to U3.29 at the end */ | ||
217 | int64_t k1, k2, k3, k4, tmp; | ||
218 | uint64_t n, d, os, os_p, od, od_p, oreq; | ||
219 | unsigned rpa = 0; | ||
220 | int64_t ip64, delta; | ||
221 | |||
222 | if (dim_out % 3 == 0) | ||
223 | rpa = !(dim_in % (dim_out / 3)); | ||
224 | |||
225 | n = ((uint64_t)dim_out) << 34; | ||
226 | d = dim_in; | ||
227 | if (!d) | ||
228 | return -1; | ||
229 | do_div(n, d); | ||
230 | k3 = (n + 1) >> 1; | ||
231 | if ((k3 >> 4) < (1LL << 27) || (k3 >> 4) > (1LL << 31)) { | ||
232 | DLOG("crap bad scale\n"); | ||
233 | return -1; | ||
234 | } | ||
235 | n = ((uint64_t)dim_in) << 34; | ||
236 | d = (uint64_t)dim_out; | ||
237 | if (!d) | ||
238 | return -1; | ||
239 | do_div(n, d); | ||
240 | k1 = (n + 1) >> 1; | ||
241 | k2 = (k1 - ONE) >> 1; | ||
242 | |||
243 | *phase_init = (int)(k2 >> 4); | ||
244 | k4 = (k3 - ONE) >> 1; | ||
245 | |||
246 | if (rpa) { | ||
247 | os = ((uint64_t)origin << 33) - ONE_HALF; | ||
248 | tmp = (dim_out * os) + ONE_HALF; | ||
249 | if (!dim_in) | ||
250 | return -1; | ||
251 | do_div(tmp, dim_in); | ||
252 | od = tmp - ONE_HALF; | ||
253 | } else { | ||
254 | os = ((uint64_t)origin << 1) - 1; | ||
255 | od = (((k3 * os) >> 1) + k4); | ||
256 | } | ||
257 | |||
258 | od_p = od & INT_MASK; | ||
259 | if (od_p != od) | ||
260 | od_p += ONE; | ||
261 | |||
262 | if (rpa) { | ||
263 | tmp = (dim_in * od_p) + ONE_HALF; | ||
264 | if (!dim_in) | ||
265 | return -1; | ||
266 | do_div(tmp, dim_in); | ||
267 | os_p = tmp - ONE_HALF; | ||
268 | } else { | ||
269 | os_p = ((k1 * (od_p >> 33)) + k2); | ||
270 | } | ||
271 | |||
272 | oreq = (os_p & INT_MASK) - ONE; | ||
273 | |||
274 | ip64 = os_p - oreq; | ||
275 | delta = ((int64_t)(origin) << 33) - oreq; | ||
276 | ip64 -= delta; | ||
277 | /* limit to valid range before the left shift */ | ||
278 | delta = (ip64 & (1LL << 63)) ? 4 : -4; | ||
279 | delta <<= 33; | ||
280 | while (abs((int)(ip64 >> 33)) > 4) | ||
281 | ip64 += delta; | ||
282 | *phase_init = (int)(ip64 >> 4); | ||
283 | *phase_step = (uint32_t)(k1 >> 4); | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static void load_scale_table(const struct mdp_info *mdp, | ||
288 | struct mdp_table_entry *table, int len) | ||
289 | { | ||
290 | int i; | ||
291 | for (i = 0; i < len; i++) | ||
292 | mdp_writel(mdp, table[i].val, table[i].reg); | ||
293 | } | ||
294 | |||
295 | enum { | ||
296 | IMG_LEFT, | ||
297 | IMG_RIGHT, | ||
298 | IMG_TOP, | ||
299 | IMG_BOTTOM, | ||
300 | }; | ||
301 | |||
302 | static void get_edge_info(uint32_t src, uint32_t src_coord, uint32_t dst, | ||
303 | uint32_t *interp1, uint32_t *interp2, | ||
304 | uint32_t *repeat1, uint32_t *repeat2) { | ||
305 | if (src > 3 * dst) { | ||
306 | *interp1 = 0; | ||
307 | *interp2 = src - 1; | ||
308 | *repeat1 = 0; | ||
309 | *repeat2 = 0; | ||
310 | } else if (src == 3 * dst) { | ||
311 | *interp1 = 0; | ||
312 | *interp2 = src; | ||
313 | *repeat1 = 0; | ||
314 | *repeat2 = 1; | ||
315 | } else if (src > dst && src < 3 * dst) { | ||
316 | *interp1 = -1; | ||
317 | *interp2 = src; | ||
318 | *repeat1 = 1; | ||
319 | *repeat2 = 1; | ||
320 | } else if (src == dst) { | ||
321 | *interp1 = -1; | ||
322 | *interp2 = src + 1; | ||
323 | *repeat1 = 1; | ||
324 | *repeat2 = 2; | ||
325 | } else { | ||
326 | *interp1 = -2; | ||
327 | *interp2 = src + 1; | ||
328 | *repeat1 = 2; | ||
329 | *repeat2 = 2; | ||
330 | } | ||
331 | *interp1 += src_coord; | ||
332 | *interp2 += src_coord; | ||
333 | } | ||
334 | |||
335 | static int get_edge_cond(struct mdp_blit_req *req, struct mdp_regs *regs) | ||
336 | { | ||
337 | int32_t luma_interp[4]; | ||
338 | int32_t luma_repeat[4]; | ||
339 | int32_t chroma_interp[4]; | ||
340 | int32_t chroma_bound[4]; | ||
341 | int32_t chroma_repeat[4]; | ||
342 | uint32_t dst_w, dst_h; | ||
343 | |||
344 | memset(&luma_interp, 0, sizeof(int32_t) * 4); | ||
345 | memset(&luma_repeat, 0, sizeof(int32_t) * 4); | ||
346 | memset(&chroma_interp, 0, sizeof(int32_t) * 4); | ||
347 | memset(&chroma_bound, 0, sizeof(int32_t) * 4); | ||
348 | memset(&chroma_repeat, 0, sizeof(int32_t) * 4); | ||
349 | regs->edge = 0; | ||
350 | |||
351 | if (req->flags & MDP_ROT_90) { | ||
352 | dst_w = req->dst_rect.h; | ||
353 | dst_h = req->dst_rect.w; | ||
354 | } else { | ||
355 | dst_w = req->dst_rect.w; | ||
356 | dst_h = req->dst_rect.h; | ||
357 | } | ||
358 | |||
359 | if (regs->op & (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON)) { | ||
360 | get_edge_info(req->src_rect.h, req->src_rect.y, dst_h, | ||
361 | &luma_interp[IMG_TOP], &luma_interp[IMG_BOTTOM], | ||
362 | &luma_repeat[IMG_TOP], &luma_repeat[IMG_BOTTOM]); | ||
363 | get_edge_info(req->src_rect.w, req->src_rect.x, dst_w, | ||
364 | &luma_interp[IMG_LEFT], &luma_interp[IMG_RIGHT], | ||
365 | &luma_repeat[IMG_LEFT], &luma_repeat[IMG_RIGHT]); | ||
366 | } else { | ||
367 | luma_interp[IMG_LEFT] = req->src_rect.x; | ||
368 | luma_interp[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1; | ||
369 | luma_interp[IMG_TOP] = req->src_rect.y; | ||
370 | luma_interp[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1; | ||
371 | luma_repeat[IMG_LEFT] = 0; | ||
372 | luma_repeat[IMG_TOP] = 0; | ||
373 | luma_repeat[IMG_RIGHT] = 0; | ||
374 | luma_repeat[IMG_BOTTOM] = 0; | ||
375 | } | ||
376 | |||
377 | chroma_interp[IMG_LEFT] = luma_interp[IMG_LEFT]; | ||
378 | chroma_interp[IMG_RIGHT] = luma_interp[IMG_RIGHT]; | ||
379 | chroma_interp[IMG_TOP] = luma_interp[IMG_TOP]; | ||
380 | chroma_interp[IMG_BOTTOM] = luma_interp[IMG_BOTTOM]; | ||
381 | |||
382 | chroma_bound[IMG_LEFT] = req->src_rect.x; | ||
383 | chroma_bound[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1; | ||
384 | chroma_bound[IMG_TOP] = req->src_rect.y; | ||
385 | chroma_bound[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1; | ||
386 | |||
387 | if (IS_YCRCB(req->src.format)) { | ||
388 | chroma_interp[IMG_LEFT] = chroma_interp[IMG_LEFT] >> 1; | ||
389 | chroma_interp[IMG_RIGHT] = (chroma_interp[IMG_RIGHT] + 1) >> 1; | ||
390 | |||
391 | chroma_bound[IMG_LEFT] = chroma_bound[IMG_LEFT] >> 1; | ||
392 | chroma_bound[IMG_RIGHT] = chroma_bound[IMG_RIGHT] >> 1; | ||
393 | } | ||
394 | |||
395 | if (req->src.format == MDP_Y_CBCR_H2V2 || | ||
396 | req->src.format == MDP_Y_CRCB_H2V2) { | ||
397 | chroma_interp[IMG_TOP] = (chroma_interp[IMG_TOP] - 1) >> 1; | ||
398 | chroma_interp[IMG_BOTTOM] = (chroma_interp[IMG_BOTTOM] + 1) | ||
399 | >> 1; | ||
400 | chroma_bound[IMG_TOP] = (chroma_bound[IMG_TOP] + 1) >> 1; | ||
401 | chroma_bound[IMG_BOTTOM] = chroma_bound[IMG_BOTTOM] >> 1; | ||
402 | } | ||
403 | |||
404 | chroma_repeat[IMG_LEFT] = chroma_bound[IMG_LEFT] - | ||
405 | chroma_interp[IMG_LEFT]; | ||
406 | chroma_repeat[IMG_RIGHT] = chroma_interp[IMG_RIGHT] - | ||
407 | chroma_bound[IMG_RIGHT]; | ||
408 | chroma_repeat[IMG_TOP] = chroma_bound[IMG_TOP] - | ||
409 | chroma_interp[IMG_TOP]; | ||
410 | chroma_repeat[IMG_BOTTOM] = chroma_interp[IMG_BOTTOM] - | ||
411 | chroma_bound[IMG_BOTTOM]; | ||
412 | |||
413 | if (chroma_repeat[IMG_LEFT] < 0 || chroma_repeat[IMG_LEFT] > 3 || | ||
414 | chroma_repeat[IMG_RIGHT] < 0 || chroma_repeat[IMG_RIGHT] > 3 || | ||
415 | chroma_repeat[IMG_TOP] < 0 || chroma_repeat[IMG_TOP] > 3 || | ||
416 | chroma_repeat[IMG_BOTTOM] < 0 || chroma_repeat[IMG_BOTTOM] > 3 || | ||
417 | luma_repeat[IMG_LEFT] < 0 || luma_repeat[IMG_LEFT] > 3 || | ||
418 | luma_repeat[IMG_RIGHT] < 0 || luma_repeat[IMG_RIGHT] > 3 || | ||
419 | luma_repeat[IMG_TOP] < 0 || luma_repeat[IMG_TOP] > 3 || | ||
420 | luma_repeat[IMG_BOTTOM] < 0 || luma_repeat[IMG_BOTTOM] > 3) | ||
421 | return -1; | ||
422 | |||
423 | regs->edge |= (chroma_repeat[IMG_LEFT] & 3) << MDP_LEFT_CHROMA; | ||
424 | regs->edge |= (chroma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_CHROMA; | ||
425 | regs->edge |= (chroma_repeat[IMG_TOP] & 3) << MDP_TOP_CHROMA; | ||
426 | regs->edge |= (chroma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_CHROMA; | ||
427 | regs->edge |= (luma_repeat[IMG_LEFT] & 3) << MDP_LEFT_LUMA; | ||
428 | regs->edge |= (luma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_LUMA; | ||
429 | regs->edge |= (luma_repeat[IMG_TOP] & 3) << MDP_TOP_LUMA; | ||
430 | regs->edge |= (luma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_LUMA; | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req, | ||
435 | struct mdp_regs *regs) | ||
436 | { | ||
437 | uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y; | ||
438 | uint32_t scale_factor_x, scale_factor_y; | ||
439 | uint32_t downscale; | ||
440 | uint32_t dst_w, dst_h; | ||
441 | |||
442 | if (req->flags & MDP_ROT_90) { | ||
443 | dst_w = req->dst_rect.h; | ||
444 | dst_h = req->dst_rect.w; | ||
445 | } else { | ||
446 | dst_w = req->dst_rect.w; | ||
447 | dst_h = req->dst_rect.h; | ||
448 | } | ||
449 | if ((req->src_rect.w == dst_w) && (req->src_rect.h == dst_h) && | ||
450 | !(req->flags & MDP_BLUR)) { | ||
451 | regs->phasex_init = 0; | ||
452 | regs->phasey_init = 0; | ||
453 | regs->phasex_step = 0; | ||
454 | regs->phasey_step = 0; | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | if (scale_params(req->src_rect.w, dst_w, 1, &phase_init_x, | ||
459 | &phase_step_x) || | ||
460 | scale_params(req->src_rect.h, dst_h, 1, &phase_init_y, | ||
461 | &phase_step_y)) | ||
462 | return -1; | ||
463 | |||
464 | scale_factor_x = (dst_w * 10) / req->src_rect.w; | ||
465 | scale_factor_y = (dst_h * 10) / req->src_rect.h; | ||
466 | |||
467 | if (scale_factor_x > 8) | ||
468 | downscale = MDP_DOWNSCALE_PT8TO1; | ||
469 | else if (scale_factor_x > 6) | ||
470 | downscale = MDP_DOWNSCALE_PT6TOPT8; | ||
471 | else if (scale_factor_x > 4) | ||
472 | downscale = MDP_DOWNSCALE_PT4TOPT6; | ||
473 | else | ||
474 | downscale = MDP_DOWNSCALE_PT2TOPT4; | ||
475 | if (downscale != downscale_x_table) { | ||
476 | load_scale_table(mdp, mdp_downscale_x_table[downscale], 64); | ||
477 | downscale_x_table = downscale; | ||
478 | } | ||
479 | |||
480 | if (scale_factor_y > 8) | ||
481 | downscale = MDP_DOWNSCALE_PT8TO1; | ||
482 | else if (scale_factor_y > 6) | ||
483 | downscale = MDP_DOWNSCALE_PT6TOPT8; | ||
484 | else if (scale_factor_y > 4) | ||
485 | downscale = MDP_DOWNSCALE_PT4TOPT6; | ||
486 | else | ||
487 | downscale = MDP_DOWNSCALE_PT2TOPT4; | ||
488 | if (downscale != downscale_y_table) { | ||
489 | load_scale_table(mdp, mdp_downscale_y_table[downscale], 64); | ||
490 | downscale_y_table = downscale; | ||
491 | } | ||
492 | |||
493 | regs->phasex_init = phase_init_x; | ||
494 | regs->phasey_init = phase_init_y; | ||
495 | regs->phasex_step = phase_step_x; | ||
496 | regs->phasey_step = phase_step_y; | ||
497 | regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON); | ||
498 | return 0; | ||
499 | |||
500 | } | ||
501 | |||
502 | static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req *req, | ||
503 | struct mdp_regs *regs) | ||
504 | { | ||
505 | if (!(req->flags & MDP_BLUR)) | ||
506 | return; | ||
507 | |||
508 | if (!(downscale_x_table == MDP_DOWNSCALE_BLUR && | ||
509 | downscale_y_table == MDP_DOWNSCALE_BLUR)) { | ||
510 | load_scale_table(mdp, mdp_gaussian_blur_table, 128); | ||
511 | downscale_x_table = MDP_DOWNSCALE_BLUR; | ||
512 | downscale_y_table = MDP_DOWNSCALE_BLUR; | ||
513 | } | ||
514 | |||
515 | regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON); | ||
516 | } | ||
517 | |||
518 | |||
519 | #define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp) | ||
520 | |||
521 | #define Y_TO_CRCB_RATIO(format) \ | ||
522 | ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\ | ||
523 | (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1) | ||
524 | |||
525 | static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp, | ||
526 | uint32_t *len0, uint32_t *len1) | ||
527 | { | ||
528 | *len0 = IMG_LEN(rect->h, img->width, rect->w, bpp); | ||
529 | if (IS_PSEUDOPLNR(img->format)) | ||
530 | *len1 = *len0/Y_TO_CRCB_RATIO(img->format); | ||
531 | else | ||
532 | *len1 = 0; | ||
533 | } | ||
534 | |||
535 | static int valid_src_dst(unsigned long src_start, unsigned long src_len, | ||
536 | unsigned long dst_start, unsigned long dst_len, | ||
537 | struct mdp_blit_req *req, struct mdp_regs *regs) | ||
538 | { | ||
539 | unsigned long src_min_ok = src_start; | ||
540 | unsigned long src_max_ok = src_start + src_len; | ||
541 | unsigned long dst_min_ok = dst_start; | ||
542 | unsigned long dst_max_ok = dst_start + dst_len; | ||
543 | uint32_t src0_len, src1_len, dst0_len, dst1_len; | ||
544 | get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len, | ||
545 | &src1_len); | ||
546 | get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len, | ||
547 | &dst1_len); | ||
548 | |||
549 | if (regs->src0 < src_min_ok || regs->src0 > src_max_ok || | ||
550 | regs->src0 + src0_len > src_max_ok) { | ||
551 | DLOG("invalid_src %x %x %lx %lx\n", regs->src0, | ||
552 | src0_len, src_min_ok, src_max_ok); | ||
553 | return 0; | ||
554 | } | ||
555 | if (regs->src_cfg & PPP_SRC_PLANE_PSEUDOPLNR) { | ||
556 | if (regs->src1 < src_min_ok || regs->src1 > src_max_ok || | ||
557 | regs->src1 + src1_len > src_max_ok) { | ||
558 | DLOG("invalid_src1"); | ||
559 | return 0; | ||
560 | } | ||
561 | } | ||
562 | if (regs->dst0 < dst_min_ok || regs->dst0 > dst_max_ok || | ||
563 | regs->dst0 + dst0_len > dst_max_ok) { | ||
564 | DLOG("invalid_dst"); | ||
565 | return 0; | ||
566 | } | ||
567 | if (regs->dst_cfg & PPP_SRC_PLANE_PSEUDOPLNR) { | ||
568 | if (regs->dst1 < dst_min_ok || regs->dst1 > dst_max_ok || | ||
569 | regs->dst1 + dst1_len > dst_max_ok) { | ||
570 | DLOG("invalid_dst1"); | ||
571 | return 0; | ||
572 | } | ||
573 | } | ||
574 | return 1; | ||
575 | } | ||
576 | |||
577 | |||
578 | static void flush_imgs(struct mdp_blit_req *req, struct mdp_regs *regs, | ||
579 | struct file *src_file, struct file *dst_file) | ||
580 | { | ||
581 | } | ||
582 | |||
583 | static void get_chroma_addr(struct mdp_img *img, struct mdp_rect *rect, | ||
584 | uint32_t base, uint32_t bpp, uint32_t cfg, | ||
585 | uint32_t *addr, uint32_t *ystride) | ||
586 | { | ||
587 | uint32_t compress_v = Y_TO_CRCB_RATIO(img->format); | ||
588 | uint32_t compress_h = 2; | ||
589 | uint32_t offset; | ||
590 | |||
591 | if (IS_PSEUDOPLNR(img->format)) { | ||
592 | offset = (rect->x / compress_h) * compress_h; | ||
593 | offset += rect->y == 0 ? 0 : | ||
594 | ((rect->y + 1) / compress_v) * img->width; | ||
595 | *addr = base + (img->width * img->height * bpp); | ||
596 | *addr += offset * bpp; | ||
597 | *ystride |= *ystride << 16; | ||
598 | } else { | ||
599 | *addr = 0; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | ||
604 | struct mdp_regs *regs, struct file *src_file, | ||
605 | struct file *dst_file) | ||
606 | { | ||
607 | mdp_writel(mdp, 1, 0x060); | ||
608 | mdp_writel(mdp, regs->src_rect, PPP_ADDR_SRC_ROI); | ||
609 | mdp_writel(mdp, regs->src0, PPP_ADDR_SRC0); | ||
610 | mdp_writel(mdp, regs->src1, PPP_ADDR_SRC1); | ||
611 | mdp_writel(mdp, regs->src_ystride, PPP_ADDR_SRC_YSTRIDE); | ||
612 | mdp_writel(mdp, regs->src_cfg, PPP_ADDR_SRC_CFG); | ||
613 | mdp_writel(mdp, regs->src_pack, PPP_ADDR_SRC_PACK_PATTERN); | ||
614 | |||
615 | mdp_writel(mdp, regs->op, PPP_ADDR_OPERATION); | ||
616 | mdp_writel(mdp, regs->phasex_init, PPP_ADDR_PHASEX_INIT); | ||
617 | mdp_writel(mdp, regs->phasey_init, PPP_ADDR_PHASEY_INIT); | ||
618 | mdp_writel(mdp, regs->phasex_step, PPP_ADDR_PHASEX_STEP); | ||
619 | mdp_writel(mdp, regs->phasey_step, PPP_ADDR_PHASEY_STEP); | ||
620 | |||
621 | mdp_writel(mdp, (req->alpha << 24) | (req->transp_mask & 0xffffff), | ||
622 | PPP_ADDR_ALPHA_TRANSP); | ||
623 | |||
624 | mdp_writel(mdp, regs->dst_cfg, PPP_ADDR_DST_CFG); | ||
625 | mdp_writel(mdp, regs->dst_pack, PPP_ADDR_DST_PACK_PATTERN); | ||
626 | mdp_writel(mdp, regs->dst_rect, PPP_ADDR_DST_ROI); | ||
627 | mdp_writel(mdp, regs->dst0, PPP_ADDR_DST0); | ||
628 | mdp_writel(mdp, regs->dst1, PPP_ADDR_DST1); | ||
629 | mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_DST_YSTRIDE); | ||
630 | |||
631 | mdp_writel(mdp, regs->edge, PPP_ADDR_EDGE); | ||
632 | if (regs->op & PPP_OP_BLEND_ON) { | ||
633 | mdp_writel(mdp, regs->dst0, PPP_ADDR_BG0); | ||
634 | mdp_writel(mdp, regs->dst1, PPP_ADDR_BG1); | ||
635 | mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_BG_YSTRIDE); | ||
636 | mdp_writel(mdp, src_img_cfg[req->dst.format], PPP_ADDR_BG_CFG); | ||
637 | mdp_writel(mdp, pack_pattern[req->dst.format], | ||
638 | PPP_ADDR_BG_PACK_PATTERN); | ||
639 | } | ||
640 | flush_imgs(req, regs, src_file, dst_file); | ||
641 | mdp_writel(mdp, 0x1000, MDP_DISPLAY0_START); | ||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, | ||
646 | struct file *src_file, unsigned long src_start, unsigned long src_len, | ||
647 | struct file *dst_file, unsigned long dst_start, unsigned long dst_len) | ||
648 | { | ||
649 | struct mdp_regs regs = {0}; | ||
650 | |||
651 | if (unlikely(req->src.format >= MDP_IMGTYPE_LIMIT || | ||
652 | req->dst.format >= MDP_IMGTYPE_LIMIT)) { | ||
653 | printk(KERN_ERR "mpd_ppp: img is of wrong format\n"); | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | |||
657 | if (unlikely(req->src_rect.x > req->src.width || | ||
658 | req->src_rect.y > req->src.height || | ||
659 | req->dst_rect.x > req->dst.width || | ||
660 | req->dst_rect.y > req->dst.height)) { | ||
661 | printk(KERN_ERR "mpd_ppp: img rect is outside of img!\n"); | ||
662 | return -EINVAL; | ||
663 | } | ||
664 | |||
665 | /* set the src image configuration */ | ||
666 | regs.src_cfg = src_img_cfg[req->src.format]; | ||
667 | regs.src_cfg |= (req->src_rect.x & 0x1) ? PPP_SRC_BPP_ROI_ODD_X : 0; | ||
668 | regs.src_cfg |= (req->src_rect.y & 0x1) ? PPP_SRC_BPP_ROI_ODD_Y : 0; | ||
669 | regs.src_rect = (req->src_rect.h << 16) | req->src_rect.w; | ||
670 | regs.src_pack = pack_pattern[req->src.format]; | ||
671 | |||
672 | /* set the dest image configuration */ | ||
673 | regs.dst_cfg = dst_img_cfg[req->dst.format] | PPP_DST_OUT_SEL_AXI; | ||
674 | regs.dst_rect = (req->dst_rect.h << 16) | req->dst_rect.w; | ||
675 | regs.dst_pack = pack_pattern[req->dst.format]; | ||
676 | |||
677 | /* set src, bpp, start pixel and ystride */ | ||
678 | regs.src_bpp = bytes_per_pixel[req->src.format]; | ||
679 | regs.src0 = src_start + req->src.offset; | ||
680 | regs.src_ystride = req->src.width * regs.src_bpp; | ||
681 | get_chroma_addr(&req->src, &req->src_rect, regs.src0, regs.src_bpp, | ||
682 | regs.src_cfg, ®s.src1, ®s.src_ystride); | ||
683 | regs.src0 += (req->src_rect.x + (req->src_rect.y * req->src.width)) * | ||
684 | regs.src_bpp; | ||
685 | |||
686 | /* set dst, bpp, start pixel and ystride */ | ||
687 | regs.dst_bpp = bytes_per_pixel[req->dst.format]; | ||
688 | regs.dst0 = dst_start + req->dst.offset; | ||
689 | regs.dst_ystride = req->dst.width * regs.dst_bpp; | ||
690 | get_chroma_addr(&req->dst, &req->dst_rect, regs.dst0, regs.dst_bpp, | ||
691 | regs.dst_cfg, ®s.dst1, ®s.dst_ystride); | ||
692 | regs.dst0 += (req->dst_rect.x + (req->dst_rect.y * req->dst.width)) * | ||
693 | regs.dst_bpp; | ||
694 | |||
695 | if (!valid_src_dst(src_start, src_len, dst_start, dst_len, req, | ||
696 | ®s)) { | ||
697 | printk(KERN_ERR "mpd_ppp: final src or dst location is " | ||
698 | "invalid, are you trying to make an image too large " | ||
699 | "or to place it outside the screen?\n"); | ||
700 | return -EINVAL; | ||
701 | } | ||
702 | |||
703 | /* set up operation register */ | ||
704 | regs.op = 0; | ||
705 | blit_rotate(req, ®s); | ||
706 | blit_convert(req, ®s); | ||
707 | if (req->flags & MDP_DITHER) | ||
708 | regs.op |= PPP_OP_DITHER_EN; | ||
709 | blit_blend(req, ®s); | ||
710 | if (blit_scale(mdp, req, ®s)) { | ||
711 | printk(KERN_ERR "mpd_ppp: error computing scale for img.\n"); | ||
712 | return -EINVAL; | ||
713 | } | ||
714 | blit_blur(mdp, req, ®s); | ||
715 | regs.op |= dst_op_chroma[req->dst.format] | | ||
716 | src_op_chroma[req->src.format]; | ||
717 | |||
718 | /* if the image is YCRYCB, the x and w must be even */ | ||
719 | if (unlikely(req->src.format == MDP_YCRYCB_H2V1)) { | ||
720 | req->src_rect.x = req->src_rect.x & (~0x1); | ||
721 | req->src_rect.w = req->src_rect.w & (~0x1); | ||
722 | req->dst_rect.x = req->dst_rect.x & (~0x1); | ||
723 | req->dst_rect.w = req->dst_rect.w & (~0x1); | ||
724 | } | ||
725 | if (get_edge_cond(req, ®s)) | ||
726 | return -EINVAL; | ||
727 | |||
728 | send_blit(mdp, req, ®s, src_file, dst_file); | ||
729 | return 0; | ||
730 | } | ||
diff --git a/drivers/video/msm/mdp_scale_tables.c b/drivers/video/msm/mdp_scale_tables.c new file mode 100644 index 000000000000..604783b2e17c --- /dev/null +++ b/drivers/video/msm/mdp_scale_tables.c | |||
@@ -0,0 +1,766 @@ | |||
1 | /* drivers/video/msm_fb/mdp_scale_tables.c | ||
2 | * | ||
3 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
4 | * Copyright (C) 2007 Google Incorporated | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include "mdp_scale_tables.h" | ||
17 | #include "mdp_hw.h" | ||
18 | |||
19 | struct mdp_table_entry mdp_upscale_table[] = { | ||
20 | { 0x5fffc, 0x0 }, | ||
21 | { 0x50200, 0x7fc00000 }, | ||
22 | { 0x5fffc, 0xff80000d }, | ||
23 | { 0x50204, 0x7ec003f9 }, | ||
24 | { 0x5fffc, 0xfec0001c }, | ||
25 | { 0x50208, 0x7d4003f3 }, | ||
26 | { 0x5fffc, 0xfe40002b }, | ||
27 | { 0x5020c, 0x7b8003ed }, | ||
28 | { 0x5fffc, 0xfd80003c }, | ||
29 | { 0x50210, 0x794003e8 }, | ||
30 | { 0x5fffc, 0xfcc0004d }, | ||
31 | { 0x50214, 0x76c003e4 }, | ||
32 | { 0x5fffc, 0xfc40005f }, | ||
33 | { 0x50218, 0x73c003e0 }, | ||
34 | { 0x5fffc, 0xfb800071 }, | ||
35 | { 0x5021c, 0x708003de }, | ||
36 | { 0x5fffc, 0xfac00085 }, | ||
37 | { 0x50220, 0x6d0003db }, | ||
38 | { 0x5fffc, 0xfa000098 }, | ||
39 | { 0x50224, 0x698003d9 }, | ||
40 | { 0x5fffc, 0xf98000ac }, | ||
41 | { 0x50228, 0x654003d8 }, | ||
42 | { 0x5fffc, 0xf8c000c1 }, | ||
43 | { 0x5022c, 0x610003d7 }, | ||
44 | { 0x5fffc, 0xf84000d5 }, | ||
45 | { 0x50230, 0x5c8003d7 }, | ||
46 | { 0x5fffc, 0xf7c000e9 }, | ||
47 | { 0x50234, 0x580003d7 }, | ||
48 | { 0x5fffc, 0xf74000fd }, | ||
49 | { 0x50238, 0x534003d8 }, | ||
50 | { 0x5fffc, 0xf6c00112 }, | ||
51 | { 0x5023c, 0x4e8003d8 }, | ||
52 | { 0x5fffc, 0xf6800126 }, | ||
53 | { 0x50240, 0x494003da }, | ||
54 | { 0x5fffc, 0xf600013a }, | ||
55 | { 0x50244, 0x448003db }, | ||
56 | { 0x5fffc, 0xf600014d }, | ||
57 | { 0x50248, 0x3f4003dd }, | ||
58 | { 0x5fffc, 0xf5c00160 }, | ||
59 | { 0x5024c, 0x3a4003df }, | ||
60 | { 0x5fffc, 0xf5c00172 }, | ||
61 | { 0x50250, 0x354003e1 }, | ||
62 | { 0x5fffc, 0xf5c00184 }, | ||
63 | { 0x50254, 0x304003e3 }, | ||
64 | { 0x5fffc, 0xf6000195 }, | ||
65 | { 0x50258, 0x2b0003e6 }, | ||
66 | { 0x5fffc, 0xf64001a6 }, | ||
67 | { 0x5025c, 0x260003e8 }, | ||
68 | { 0x5fffc, 0xf6c001b4 }, | ||
69 | { 0x50260, 0x214003eb }, | ||
70 | { 0x5fffc, 0xf78001c2 }, | ||
71 | { 0x50264, 0x1c4003ee }, | ||
72 | { 0x5fffc, 0xf80001cf }, | ||
73 | { 0x50268, 0x17c003f1 }, | ||
74 | { 0x5fffc, 0xf90001db }, | ||
75 | { 0x5026c, 0x134003f3 }, | ||
76 | { 0x5fffc, 0xfa0001e5 }, | ||
77 | { 0x50270, 0xf0003f6 }, | ||
78 | { 0x5fffc, 0xfb4001ee }, | ||
79 | { 0x50274, 0xac003f9 }, | ||
80 | { 0x5fffc, 0xfcc001f5 }, | ||
81 | { 0x50278, 0x70003fb }, | ||
82 | { 0x5fffc, 0xfe4001fb }, | ||
83 | { 0x5027c, 0x34003fe }, | ||
84 | }; | ||
85 | |||
86 | static struct mdp_table_entry mdp_downscale_x_table_PT2TOPT4[] = { | ||
87 | { 0x5fffc, 0x740008c }, | ||
88 | { 0x50280, 0x33800088 }, | ||
89 | { 0x5fffc, 0x800008e }, | ||
90 | { 0x50284, 0x33400084 }, | ||
91 | { 0x5fffc, 0x8400092 }, | ||
92 | { 0x50288, 0x33000080 }, | ||
93 | { 0x5fffc, 0x9000094 }, | ||
94 | { 0x5028c, 0x3300007b }, | ||
95 | { 0x5fffc, 0x9c00098 }, | ||
96 | { 0x50290, 0x32400077 }, | ||
97 | { 0x5fffc, 0xa40009b }, | ||
98 | { 0x50294, 0x32000073 }, | ||
99 | { 0x5fffc, 0xb00009d }, | ||
100 | { 0x50298, 0x31c0006f }, | ||
101 | { 0x5fffc, 0xbc000a0 }, | ||
102 | { 0x5029c, 0x3140006b }, | ||
103 | { 0x5fffc, 0xc8000a2 }, | ||
104 | { 0x502a0, 0x31000067 }, | ||
105 | { 0x5fffc, 0xd8000a5 }, | ||
106 | { 0x502a4, 0x30800062 }, | ||
107 | { 0x5fffc, 0xe4000a8 }, | ||
108 | { 0x502a8, 0x2fc0005f }, | ||
109 | { 0x5fffc, 0xec000aa }, | ||
110 | { 0x502ac, 0x2fc0005b }, | ||
111 | { 0x5fffc, 0xf8000ad }, | ||
112 | { 0x502b0, 0x2f400057 }, | ||
113 | { 0x5fffc, 0x108000b0 }, | ||
114 | { 0x502b4, 0x2e400054 }, | ||
115 | { 0x5fffc, 0x114000b2 }, | ||
116 | { 0x502b8, 0x2e000050 }, | ||
117 | { 0x5fffc, 0x124000b4 }, | ||
118 | { 0x502bc, 0x2d80004c }, | ||
119 | { 0x5fffc, 0x130000b6 }, | ||
120 | { 0x502c0, 0x2d000049 }, | ||
121 | { 0x5fffc, 0x140000b8 }, | ||
122 | { 0x502c4, 0x2c800045 }, | ||
123 | { 0x5fffc, 0x150000b9 }, | ||
124 | { 0x502c8, 0x2c000042 }, | ||
125 | { 0x5fffc, 0x15c000bd }, | ||
126 | { 0x502cc, 0x2b40003e }, | ||
127 | { 0x5fffc, 0x16c000bf }, | ||
128 | { 0x502d0, 0x2a80003b }, | ||
129 | { 0x5fffc, 0x17c000bf }, | ||
130 | { 0x502d4, 0x2a000039 }, | ||
131 | { 0x5fffc, 0x188000c2 }, | ||
132 | { 0x502d8, 0x29400036 }, | ||
133 | { 0x5fffc, 0x19c000c4 }, | ||
134 | { 0x502dc, 0x28800032 }, | ||
135 | { 0x5fffc, 0x1ac000c5 }, | ||
136 | { 0x502e0, 0x2800002f }, | ||
137 | { 0x5fffc, 0x1bc000c7 }, | ||
138 | { 0x502e4, 0x2740002c }, | ||
139 | { 0x5fffc, 0x1cc000c8 }, | ||
140 | { 0x502e8, 0x26c00029 }, | ||
141 | { 0x5fffc, 0x1dc000c9 }, | ||
142 | { 0x502ec, 0x26000027 }, | ||
143 | { 0x5fffc, 0x1ec000cc }, | ||
144 | { 0x502f0, 0x25000024 }, | ||
145 | { 0x5fffc, 0x200000cc }, | ||
146 | { 0x502f4, 0x24800021 }, | ||
147 | { 0x5fffc, 0x210000cd }, | ||
148 | { 0x502f8, 0x23800020 }, | ||
149 | { 0x5fffc, 0x220000ce }, | ||
150 | { 0x502fc, 0x2300001d }, | ||
151 | }; | ||
152 | |||
153 | static struct mdp_table_entry mdp_downscale_x_table_PT4TOPT6[] = { | ||
154 | { 0x5fffc, 0x740008c }, | ||
155 | { 0x50280, 0x33800088 }, | ||
156 | { 0x5fffc, 0x800008e }, | ||
157 | { 0x50284, 0x33400084 }, | ||
158 | { 0x5fffc, 0x8400092 }, | ||
159 | { 0x50288, 0x33000080 }, | ||
160 | { 0x5fffc, 0x9000094 }, | ||
161 | { 0x5028c, 0x3300007b }, | ||
162 | { 0x5fffc, 0x9c00098 }, | ||
163 | { 0x50290, 0x32400077 }, | ||
164 | { 0x5fffc, 0xa40009b }, | ||
165 | { 0x50294, 0x32000073 }, | ||
166 | { 0x5fffc, 0xb00009d }, | ||
167 | { 0x50298, 0x31c0006f }, | ||
168 | { 0x5fffc, 0xbc000a0 }, | ||
169 | { 0x5029c, 0x3140006b }, | ||
170 | { 0x5fffc, 0xc8000a2 }, | ||
171 | { 0x502a0, 0x31000067 }, | ||
172 | { 0x5fffc, 0xd8000a5 }, | ||
173 | { 0x502a4, 0x30800062 }, | ||
174 | { 0x5fffc, 0xe4000a8 }, | ||
175 | { 0x502a8, 0x2fc0005f }, | ||
176 | { 0x5fffc, 0xec000aa }, | ||
177 | { 0x502ac, 0x2fc0005b }, | ||
178 | { 0x5fffc, 0xf8000ad }, | ||
179 | { 0x502b0, 0x2f400057 }, | ||
180 | { 0x5fffc, 0x108000b0 }, | ||
181 | { 0x502b4, 0x2e400054 }, | ||
182 | { 0x5fffc, 0x114000b2 }, | ||
183 | { 0x502b8, 0x2e000050 }, | ||
184 | { 0x5fffc, 0x124000b4 }, | ||
185 | { 0x502bc, 0x2d80004c }, | ||
186 | { 0x5fffc, 0x130000b6 }, | ||
187 | { 0x502c0, 0x2d000049 }, | ||
188 | { 0x5fffc, 0x140000b8 }, | ||
189 | { 0x502c4, 0x2c800045 }, | ||
190 | { 0x5fffc, 0x150000b9 }, | ||
191 | { 0x502c8, 0x2c000042 }, | ||
192 | { 0x5fffc, 0x15c000bd }, | ||
193 | { 0x502cc, 0x2b40003e }, | ||
194 | { 0x5fffc, 0x16c000bf }, | ||
195 | { 0x502d0, 0x2a80003b }, | ||
196 | { 0x5fffc, 0x17c000bf }, | ||
197 | { 0x502d4, 0x2a000039 }, | ||
198 | { 0x5fffc, 0x188000c2 }, | ||
199 | { 0x502d8, 0x29400036 }, | ||
200 | { 0x5fffc, 0x19c000c4 }, | ||
201 | { 0x502dc, 0x28800032 }, | ||
202 | { 0x5fffc, 0x1ac000c5 }, | ||
203 | { 0x502e0, 0x2800002f }, | ||
204 | { 0x5fffc, 0x1bc000c7 }, | ||
205 | { 0x502e4, 0x2740002c }, | ||
206 | { 0x5fffc, 0x1cc000c8 }, | ||
207 | { 0x502e8, 0x26c00029 }, | ||
208 | { 0x5fffc, 0x1dc000c9 }, | ||
209 | { 0x502ec, 0x26000027 }, | ||
210 | { 0x5fffc, 0x1ec000cc }, | ||
211 | { 0x502f0, 0x25000024 }, | ||
212 | { 0x5fffc, 0x200000cc }, | ||
213 | { 0x502f4, 0x24800021 }, | ||
214 | { 0x5fffc, 0x210000cd }, | ||
215 | { 0x502f8, 0x23800020 }, | ||
216 | { 0x5fffc, 0x220000ce }, | ||
217 | { 0x502fc, 0x2300001d }, | ||
218 | }; | ||
219 | |||
220 | static struct mdp_table_entry mdp_downscale_x_table_PT6TOPT8[] = { | ||
221 | { 0x5fffc, 0xfe000070 }, | ||
222 | { 0x50280, 0x4bc00068 }, | ||
223 | { 0x5fffc, 0xfe000078 }, | ||
224 | { 0x50284, 0x4bc00060 }, | ||
225 | { 0x5fffc, 0xfe000080 }, | ||
226 | { 0x50288, 0x4b800059 }, | ||
227 | { 0x5fffc, 0xfe000089 }, | ||
228 | { 0x5028c, 0x4b000052 }, | ||
229 | { 0x5fffc, 0xfe400091 }, | ||
230 | { 0x50290, 0x4a80004b }, | ||
231 | { 0x5fffc, 0xfe40009a }, | ||
232 | { 0x50294, 0x4a000044 }, | ||
233 | { 0x5fffc, 0xfe8000a3 }, | ||
234 | { 0x50298, 0x4940003d }, | ||
235 | { 0x5fffc, 0xfec000ac }, | ||
236 | { 0x5029c, 0x48400037 }, | ||
237 | { 0x5fffc, 0xff0000b4 }, | ||
238 | { 0x502a0, 0x47800031 }, | ||
239 | { 0x5fffc, 0xff8000bd }, | ||
240 | { 0x502a4, 0x4640002b }, | ||
241 | { 0x5fffc, 0xc5 }, | ||
242 | { 0x502a8, 0x45000026 }, | ||
243 | { 0x5fffc, 0x8000ce }, | ||
244 | { 0x502ac, 0x43800021 }, | ||
245 | { 0x5fffc, 0x10000d6 }, | ||
246 | { 0x502b0, 0x4240001c }, | ||
247 | { 0x5fffc, 0x18000df }, | ||
248 | { 0x502b4, 0x40800018 }, | ||
249 | { 0x5fffc, 0x24000e6 }, | ||
250 | { 0x502b8, 0x3f000014 }, | ||
251 | { 0x5fffc, 0x30000ee }, | ||
252 | { 0x502bc, 0x3d400010 }, | ||
253 | { 0x5fffc, 0x40000f5 }, | ||
254 | { 0x502c0, 0x3b80000c }, | ||
255 | { 0x5fffc, 0x50000fc }, | ||
256 | { 0x502c4, 0x39800009 }, | ||
257 | { 0x5fffc, 0x6000102 }, | ||
258 | { 0x502c8, 0x37c00006 }, | ||
259 | { 0x5fffc, 0x7000109 }, | ||
260 | { 0x502cc, 0x35800004 }, | ||
261 | { 0x5fffc, 0x840010e }, | ||
262 | { 0x502d0, 0x33800002 }, | ||
263 | { 0x5fffc, 0x9800114 }, | ||
264 | { 0x502d4, 0x31400000 }, | ||
265 | { 0x5fffc, 0xac00119 }, | ||
266 | { 0x502d8, 0x2f4003fe }, | ||
267 | { 0x5fffc, 0xc40011e }, | ||
268 | { 0x502dc, 0x2d0003fc }, | ||
269 | { 0x5fffc, 0xdc00121 }, | ||
270 | { 0x502e0, 0x2b0003fb }, | ||
271 | { 0x5fffc, 0xf400125 }, | ||
272 | { 0x502e4, 0x28c003fa }, | ||
273 | { 0x5fffc, 0x11000128 }, | ||
274 | { 0x502e8, 0x268003f9 }, | ||
275 | { 0x5fffc, 0x12c0012a }, | ||
276 | { 0x502ec, 0x244003f9 }, | ||
277 | { 0x5fffc, 0x1480012c }, | ||
278 | { 0x502f0, 0x224003f8 }, | ||
279 | { 0x5fffc, 0x1640012e }, | ||
280 | { 0x502f4, 0x200003f8 }, | ||
281 | { 0x5fffc, 0x1800012f }, | ||
282 | { 0x502f8, 0x1e0003f8 }, | ||
283 | { 0x5fffc, 0x1a00012f }, | ||
284 | { 0x502fc, 0x1c0003f8 }, | ||
285 | }; | ||
286 | |||
287 | static struct mdp_table_entry mdp_downscale_x_table_PT8TO1[] = { | ||
288 | { 0x5fffc, 0x0 }, | ||
289 | { 0x50280, 0x7fc00000 }, | ||
290 | { 0x5fffc, 0xff80000d }, | ||
291 | { 0x50284, 0x7ec003f9 }, | ||
292 | { 0x5fffc, 0xfec0001c }, | ||
293 | { 0x50288, 0x7d4003f3 }, | ||
294 | { 0x5fffc, 0xfe40002b }, | ||
295 | { 0x5028c, 0x7b8003ed }, | ||
296 | { 0x5fffc, 0xfd80003c }, | ||
297 | { 0x50290, 0x794003e8 }, | ||
298 | { 0x5fffc, 0xfcc0004d }, | ||
299 | { 0x50294, 0x76c003e4 }, | ||
300 | { 0x5fffc, 0xfc40005f }, | ||
301 | { 0x50298, 0x73c003e0 }, | ||
302 | { 0x5fffc, 0xfb800071 }, | ||
303 | { 0x5029c, 0x708003de }, | ||
304 | { 0x5fffc, 0xfac00085 }, | ||
305 | { 0x502a0, 0x6d0003db }, | ||
306 | { 0x5fffc, 0xfa000098 }, | ||
307 | { 0x502a4, 0x698003d9 }, | ||
308 | { 0x5fffc, 0xf98000ac }, | ||
309 | { 0x502a8, 0x654003d8 }, | ||
310 | { 0x5fffc, 0xf8c000c1 }, | ||
311 | { 0x502ac, 0x610003d7 }, | ||
312 | { 0x5fffc, 0xf84000d5 }, | ||
313 | { 0x502b0, 0x5c8003d7 }, | ||
314 | { 0x5fffc, 0xf7c000e9 }, | ||
315 | { 0x502b4, 0x580003d7 }, | ||
316 | { 0x5fffc, 0xf74000fd }, | ||
317 | { 0x502b8, 0x534003d8 }, | ||
318 | { 0x5fffc, 0xf6c00112 }, | ||
319 | { 0x502bc, 0x4e8003d8 }, | ||
320 | { 0x5fffc, 0xf6800126 }, | ||
321 | { 0x502c0, 0x494003da }, | ||
322 | { 0x5fffc, 0xf600013a }, | ||
323 | { 0x502c4, 0x448003db }, | ||
324 | { 0x5fffc, 0xf600014d }, | ||
325 | { 0x502c8, 0x3f4003dd }, | ||
326 | { 0x5fffc, 0xf5c00160 }, | ||
327 | { 0x502cc, 0x3a4003df }, | ||
328 | { 0x5fffc, 0xf5c00172 }, | ||
329 | { 0x502d0, 0x354003e1 }, | ||
330 | { 0x5fffc, 0xf5c00184 }, | ||
331 | { 0x502d4, 0x304003e3 }, | ||
332 | { 0x5fffc, 0xf6000195 }, | ||
333 | { 0x502d8, 0x2b0003e6 }, | ||
334 | { 0x5fffc, 0xf64001a6 }, | ||
335 | { 0x502dc, 0x260003e8 }, | ||
336 | { 0x5fffc, 0xf6c001b4 }, | ||
337 | { 0x502e0, 0x214003eb }, | ||
338 | { 0x5fffc, 0xf78001c2 }, | ||
339 | { 0x502e4, 0x1c4003ee }, | ||
340 | { 0x5fffc, 0xf80001cf }, | ||
341 | { 0x502e8, 0x17c003f1 }, | ||
342 | { 0x5fffc, 0xf90001db }, | ||
343 | { 0x502ec, 0x134003f3 }, | ||
344 | { 0x5fffc, 0xfa0001e5 }, | ||
345 | { 0x502f0, 0xf0003f6 }, | ||
346 | { 0x5fffc, 0xfb4001ee }, | ||
347 | { 0x502f4, 0xac003f9 }, | ||
348 | { 0x5fffc, 0xfcc001f5 }, | ||
349 | { 0x502f8, 0x70003fb }, | ||
350 | { 0x5fffc, 0xfe4001fb }, | ||
351 | { 0x502fc, 0x34003fe }, | ||
352 | }; | ||
353 | |||
354 | struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX] = { | ||
355 | [MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_x_table_PT2TOPT4, | ||
356 | [MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_x_table_PT4TOPT6, | ||
357 | [MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_x_table_PT6TOPT8, | ||
358 | [MDP_DOWNSCALE_PT8TO1] = mdp_downscale_x_table_PT8TO1, | ||
359 | }; | ||
360 | |||
361 | static struct mdp_table_entry mdp_downscale_y_table_PT2TOPT4[] = { | ||
362 | { 0x5fffc, 0x740008c }, | ||
363 | { 0x50300, 0x33800088 }, | ||
364 | { 0x5fffc, 0x800008e }, | ||
365 | { 0x50304, 0x33400084 }, | ||
366 | { 0x5fffc, 0x8400092 }, | ||
367 | { 0x50308, 0x33000080 }, | ||
368 | { 0x5fffc, 0x9000094 }, | ||
369 | { 0x5030c, 0x3300007b }, | ||
370 | { 0x5fffc, 0x9c00098 }, | ||
371 | { 0x50310, 0x32400077 }, | ||
372 | { 0x5fffc, 0xa40009b }, | ||
373 | { 0x50314, 0x32000073 }, | ||
374 | { 0x5fffc, 0xb00009d }, | ||
375 | { 0x50318, 0x31c0006f }, | ||
376 | { 0x5fffc, 0xbc000a0 }, | ||
377 | { 0x5031c, 0x3140006b }, | ||
378 | { 0x5fffc, 0xc8000a2 }, | ||
379 | { 0x50320, 0x31000067 }, | ||
380 | { 0x5fffc, 0xd8000a5 }, | ||
381 | { 0x50324, 0x30800062 }, | ||
382 | { 0x5fffc, 0xe4000a8 }, | ||
383 | { 0x50328, 0x2fc0005f }, | ||
384 | { 0x5fffc, 0xec000aa }, | ||
385 | { 0x5032c, 0x2fc0005b }, | ||
386 | { 0x5fffc, 0xf8000ad }, | ||
387 | { 0x50330, 0x2f400057 }, | ||
388 | { 0x5fffc, 0x108000b0 }, | ||
389 | { 0x50334, 0x2e400054 }, | ||
390 | { 0x5fffc, 0x114000b2 }, | ||
391 | { 0x50338, 0x2e000050 }, | ||
392 | { 0x5fffc, 0x124000b4 }, | ||
393 | { 0x5033c, 0x2d80004c }, | ||
394 | { 0x5fffc, 0x130000b6 }, | ||
395 | { 0x50340, 0x2d000049 }, | ||
396 | { 0x5fffc, 0x140000b8 }, | ||
397 | { 0x50344, 0x2c800045 }, | ||
398 | { 0x5fffc, 0x150000b9 }, | ||
399 | { 0x50348, 0x2c000042 }, | ||
400 | { 0x5fffc, 0x15c000bd }, | ||
401 | { 0x5034c, 0x2b40003e }, | ||
402 | { 0x5fffc, 0x16c000bf }, | ||
403 | { 0x50350, 0x2a80003b }, | ||
404 | { 0x5fffc, 0x17c000bf }, | ||
405 | { 0x50354, 0x2a000039 }, | ||
406 | { 0x5fffc, 0x188000c2 }, | ||
407 | { 0x50358, 0x29400036 }, | ||
408 | { 0x5fffc, 0x19c000c4 }, | ||
409 | { 0x5035c, 0x28800032 }, | ||
410 | { 0x5fffc, 0x1ac000c5 }, | ||
411 | { 0x50360, 0x2800002f }, | ||
412 | { 0x5fffc, 0x1bc000c7 }, | ||
413 | { 0x50364, 0x2740002c }, | ||
414 | { 0x5fffc, 0x1cc000c8 }, | ||
415 | { 0x50368, 0x26c00029 }, | ||
416 | { 0x5fffc, 0x1dc000c9 }, | ||
417 | { 0x5036c, 0x26000027 }, | ||
418 | { 0x5fffc, 0x1ec000cc }, | ||
419 | { 0x50370, 0x25000024 }, | ||
420 | { 0x5fffc, 0x200000cc }, | ||
421 | { 0x50374, 0x24800021 }, | ||
422 | { 0x5fffc, 0x210000cd }, | ||
423 | { 0x50378, 0x23800020 }, | ||
424 | { 0x5fffc, 0x220000ce }, | ||
425 | { 0x5037c, 0x2300001d }, | ||
426 | }; | ||
427 | |||
428 | static struct mdp_table_entry mdp_downscale_y_table_PT4TOPT6[] = { | ||
429 | { 0x5fffc, 0x740008c }, | ||
430 | { 0x50300, 0x33800088 }, | ||
431 | { 0x5fffc, 0x800008e }, | ||
432 | { 0x50304, 0x33400084 }, | ||
433 | { 0x5fffc, 0x8400092 }, | ||
434 | { 0x50308, 0x33000080 }, | ||
435 | { 0x5fffc, 0x9000094 }, | ||
436 | { 0x5030c, 0x3300007b }, | ||
437 | { 0x5fffc, 0x9c00098 }, | ||
438 | { 0x50310, 0x32400077 }, | ||
439 | { 0x5fffc, 0xa40009b }, | ||
440 | { 0x50314, 0x32000073 }, | ||
441 | { 0x5fffc, 0xb00009d }, | ||
442 | { 0x50318, 0x31c0006f }, | ||
443 | { 0x5fffc, 0xbc000a0 }, | ||
444 | { 0x5031c, 0x3140006b }, | ||
445 | { 0x5fffc, 0xc8000a2 }, | ||
446 | { 0x50320, 0x31000067 }, | ||
447 | { 0x5fffc, 0xd8000a5 }, | ||
448 | { 0x50324, 0x30800062 }, | ||
449 | { 0x5fffc, 0xe4000a8 }, | ||
450 | { 0x50328, 0x2fc0005f }, | ||
451 | { 0x5fffc, 0xec000aa }, | ||
452 | { 0x5032c, 0x2fc0005b }, | ||
453 | { 0x5fffc, 0xf8000ad }, | ||
454 | { 0x50330, 0x2f400057 }, | ||
455 | { 0x5fffc, 0x108000b0 }, | ||
456 | { 0x50334, 0x2e400054 }, | ||
457 | { 0x5fffc, 0x114000b2 }, | ||
458 | { 0x50338, 0x2e000050 }, | ||
459 | { 0x5fffc, 0x124000b4 }, | ||
460 | { 0x5033c, 0x2d80004c }, | ||
461 | { 0x5fffc, 0x130000b6 }, | ||
462 | { 0x50340, 0x2d000049 }, | ||
463 | { 0x5fffc, 0x140000b8 }, | ||
464 | { 0x50344, 0x2c800045 }, | ||
465 | { 0x5fffc, 0x150000b9 }, | ||
466 | { 0x50348, 0x2c000042 }, | ||
467 | { 0x5fffc, 0x15c000bd }, | ||
468 | { 0x5034c, 0x2b40003e }, | ||
469 | { 0x5fffc, 0x16c000bf }, | ||
470 | { 0x50350, 0x2a80003b }, | ||
471 | { 0x5fffc, 0x17c000bf }, | ||
472 | { 0x50354, 0x2a000039 }, | ||
473 | { 0x5fffc, 0x188000c2 }, | ||
474 | { 0x50358, 0x29400036 }, | ||
475 | { 0x5fffc, 0x19c000c4 }, | ||
476 | { 0x5035c, 0x28800032 }, | ||
477 | { 0x5fffc, 0x1ac000c5 }, | ||
478 | { 0x50360, 0x2800002f }, | ||
479 | { 0x5fffc, 0x1bc000c7 }, | ||
480 | { 0x50364, 0x2740002c }, | ||
481 | { 0x5fffc, 0x1cc000c8 }, | ||
482 | { 0x50368, 0x26c00029 }, | ||
483 | { 0x5fffc, 0x1dc000c9 }, | ||
484 | { 0x5036c, 0x26000027 }, | ||
485 | { 0x5fffc, 0x1ec000cc }, | ||
486 | { 0x50370, 0x25000024 }, | ||
487 | { 0x5fffc, 0x200000cc }, | ||
488 | { 0x50374, 0x24800021 }, | ||
489 | { 0x5fffc, 0x210000cd }, | ||
490 | { 0x50378, 0x23800020 }, | ||
491 | { 0x5fffc, 0x220000ce }, | ||
492 | { 0x5037c, 0x2300001d }, | ||
493 | }; | ||
494 | |||
495 | static struct mdp_table_entry mdp_downscale_y_table_PT6TOPT8[] = { | ||
496 | { 0x5fffc, 0xfe000070 }, | ||
497 | { 0x50300, 0x4bc00068 }, | ||
498 | { 0x5fffc, 0xfe000078 }, | ||
499 | { 0x50304, 0x4bc00060 }, | ||
500 | { 0x5fffc, 0xfe000080 }, | ||
501 | { 0x50308, 0x4b800059 }, | ||
502 | { 0x5fffc, 0xfe000089 }, | ||
503 | { 0x5030c, 0x4b000052 }, | ||
504 | { 0x5fffc, 0xfe400091 }, | ||
505 | { 0x50310, 0x4a80004b }, | ||
506 | { 0x5fffc, 0xfe40009a }, | ||
507 | { 0x50314, 0x4a000044 }, | ||
508 | { 0x5fffc, 0xfe8000a3 }, | ||
509 | { 0x50318, 0x4940003d }, | ||
510 | { 0x5fffc, 0xfec000ac }, | ||
511 | { 0x5031c, 0x48400037 }, | ||
512 | { 0x5fffc, 0xff0000b4 }, | ||
513 | { 0x50320, 0x47800031 }, | ||
514 | { 0x5fffc, 0xff8000bd }, | ||
515 | { 0x50324, 0x4640002b }, | ||
516 | { 0x5fffc, 0xc5 }, | ||
517 | { 0x50328, 0x45000026 }, | ||
518 | { 0x5fffc, 0x8000ce }, | ||
519 | { 0x5032c, 0x43800021 }, | ||
520 | { 0x5fffc, 0x10000d6 }, | ||
521 | { 0x50330, 0x4240001c }, | ||
522 | { 0x5fffc, 0x18000df }, | ||
523 | { 0x50334, 0x40800018 }, | ||
524 | { 0x5fffc, 0x24000e6 }, | ||
525 | { 0x50338, 0x3f000014 }, | ||
526 | { 0x5fffc, 0x30000ee }, | ||
527 | { 0x5033c, 0x3d400010 }, | ||
528 | { 0x5fffc, 0x40000f5 }, | ||
529 | { 0x50340, 0x3b80000c }, | ||
530 | { 0x5fffc, 0x50000fc }, | ||
531 | { 0x50344, 0x39800009 }, | ||
532 | { 0x5fffc, 0x6000102 }, | ||
533 | { 0x50348, 0x37c00006 }, | ||
534 | { 0x5fffc, 0x7000109 }, | ||
535 | { 0x5034c, 0x35800004 }, | ||
536 | { 0x5fffc, 0x840010e }, | ||
537 | { 0x50350, 0x33800002 }, | ||
538 | { 0x5fffc, 0x9800114 }, | ||
539 | { 0x50354, 0x31400000 }, | ||
540 | { 0x5fffc, 0xac00119 }, | ||
541 | { 0x50358, 0x2f4003fe }, | ||
542 | { 0x5fffc, 0xc40011e }, | ||
543 | { 0x5035c, 0x2d0003fc }, | ||
544 | { 0x5fffc, 0xdc00121 }, | ||
545 | { 0x50360, 0x2b0003fb }, | ||
546 | { 0x5fffc, 0xf400125 }, | ||
547 | { 0x50364, 0x28c003fa }, | ||
548 | { 0x5fffc, 0x11000128 }, | ||
549 | { 0x50368, 0x268003f9 }, | ||
550 | { 0x5fffc, 0x12c0012a }, | ||
551 | { 0x5036c, 0x244003f9 }, | ||
552 | { 0x5fffc, 0x1480012c }, | ||
553 | { 0x50370, 0x224003f8 }, | ||
554 | { 0x5fffc, 0x1640012e }, | ||
555 | { 0x50374, 0x200003f8 }, | ||
556 | { 0x5fffc, 0x1800012f }, | ||
557 | { 0x50378, 0x1e0003f8 }, | ||
558 | { 0x5fffc, 0x1a00012f }, | ||
559 | { 0x5037c, 0x1c0003f8 }, | ||
560 | }; | ||
561 | |||
562 | static struct mdp_table_entry mdp_downscale_y_table_PT8TO1[] = { | ||
563 | { 0x5fffc, 0x0 }, | ||
564 | { 0x50300, 0x7fc00000 }, | ||
565 | { 0x5fffc, 0xff80000d }, | ||
566 | { 0x50304, 0x7ec003f9 }, | ||
567 | { 0x5fffc, 0xfec0001c }, | ||
568 | { 0x50308, 0x7d4003f3 }, | ||
569 | { 0x5fffc, 0xfe40002b }, | ||
570 | { 0x5030c, 0x7b8003ed }, | ||
571 | { 0x5fffc, 0xfd80003c }, | ||
572 | { 0x50310, 0x794003e8 }, | ||
573 | { 0x5fffc, 0xfcc0004d }, | ||
574 | { 0x50314, 0x76c003e4 }, | ||
575 | { 0x5fffc, 0xfc40005f }, | ||
576 | { 0x50318, 0x73c003e0 }, | ||
577 | { 0x5fffc, 0xfb800071 }, | ||
578 | { 0x5031c, 0x708003de }, | ||
579 | { 0x5fffc, 0xfac00085 }, | ||
580 | { 0x50320, 0x6d0003db }, | ||
581 | { 0x5fffc, 0xfa000098 }, | ||
582 | { 0x50324, 0x698003d9 }, | ||
583 | { 0x5fffc, 0xf98000ac }, | ||
584 | { 0x50328, 0x654003d8 }, | ||
585 | { 0x5fffc, 0xf8c000c1 }, | ||
586 | { 0x5032c, 0x610003d7 }, | ||
587 | { 0x5fffc, 0xf84000d5 }, | ||
588 | { 0x50330, 0x5c8003d7 }, | ||
589 | { 0x5fffc, 0xf7c000e9 }, | ||
590 | { 0x50334, 0x580003d7 }, | ||
591 | { 0x5fffc, 0xf74000fd }, | ||
592 | { 0x50338, 0x534003d8 }, | ||
593 | { 0x5fffc, 0xf6c00112 }, | ||
594 | { 0x5033c, 0x4e8003d8 }, | ||
595 | { 0x5fffc, 0xf6800126 }, | ||
596 | { 0x50340, 0x494003da }, | ||
597 | { 0x5fffc, 0xf600013a }, | ||
598 | { 0x50344, 0x448003db }, | ||
599 | { 0x5fffc, 0xf600014d }, | ||
600 | { 0x50348, 0x3f4003dd }, | ||
601 | { 0x5fffc, 0xf5c00160 }, | ||
602 | { 0x5034c, 0x3a4003df }, | ||
603 | { 0x5fffc, 0xf5c00172 }, | ||
604 | { 0x50350, 0x354003e1 }, | ||
605 | { 0x5fffc, 0xf5c00184 }, | ||
606 | { 0x50354, 0x304003e3 }, | ||
607 | { 0x5fffc, 0xf6000195 }, | ||
608 | { 0x50358, 0x2b0003e6 }, | ||
609 | { 0x5fffc, 0xf64001a6 }, | ||
610 | { 0x5035c, 0x260003e8 }, | ||
611 | { 0x5fffc, 0xf6c001b4 }, | ||
612 | { 0x50360, 0x214003eb }, | ||
613 | { 0x5fffc, 0xf78001c2 }, | ||
614 | { 0x50364, 0x1c4003ee }, | ||
615 | { 0x5fffc, 0xf80001cf }, | ||
616 | { 0x50368, 0x17c003f1 }, | ||
617 | { 0x5fffc, 0xf90001db }, | ||
618 | { 0x5036c, 0x134003f3 }, | ||
619 | { 0x5fffc, 0xfa0001e5 }, | ||
620 | { 0x50370, 0xf0003f6 }, | ||
621 | { 0x5fffc, 0xfb4001ee }, | ||
622 | { 0x50374, 0xac003f9 }, | ||
623 | { 0x5fffc, 0xfcc001f5 }, | ||
624 | { 0x50378, 0x70003fb }, | ||
625 | { 0x5fffc, 0xfe4001fb }, | ||
626 | { 0x5037c, 0x34003fe }, | ||
627 | }; | ||
628 | |||
629 | struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX] = { | ||
630 | [MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_y_table_PT2TOPT4, | ||
631 | [MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_y_table_PT4TOPT6, | ||
632 | [MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_y_table_PT6TOPT8, | ||
633 | [MDP_DOWNSCALE_PT8TO1] = mdp_downscale_y_table_PT8TO1, | ||
634 | }; | ||
635 | |||
636 | struct mdp_table_entry mdp_gaussian_blur_table[] = { | ||
637 | /* max variance */ | ||
638 | { 0x5fffc, 0x20000080 }, | ||
639 | { 0x50280, 0x20000080 }, | ||
640 | { 0x5fffc, 0x20000080 }, | ||
641 | { 0x50284, 0x20000080 }, | ||
642 | { 0x5fffc, 0x20000080 }, | ||
643 | { 0x50288, 0x20000080 }, | ||
644 | { 0x5fffc, 0x20000080 }, | ||
645 | { 0x5028c, 0x20000080 }, | ||
646 | { 0x5fffc, 0x20000080 }, | ||
647 | { 0x50290, 0x20000080 }, | ||
648 | { 0x5fffc, 0x20000080 }, | ||
649 | { 0x50294, 0x20000080 }, | ||
650 | { 0x5fffc, 0x20000080 }, | ||
651 | { 0x50298, 0x20000080 }, | ||
652 | { 0x5fffc, 0x20000080 }, | ||
653 | { 0x5029c, 0x20000080 }, | ||
654 | { 0x5fffc, 0x20000080 }, | ||
655 | { 0x502a0, 0x20000080 }, | ||
656 | { 0x5fffc, 0x20000080 }, | ||
657 | { 0x502a4, 0x20000080 }, | ||
658 | { 0x5fffc, 0x20000080 }, | ||
659 | { 0x502a8, 0x20000080 }, | ||
660 | { 0x5fffc, 0x20000080 }, | ||
661 | { 0x502ac, 0x20000080 }, | ||
662 | { 0x5fffc, 0x20000080 }, | ||
663 | { 0x502b0, 0x20000080 }, | ||
664 | { 0x5fffc, 0x20000080 }, | ||
665 | { 0x502b4, 0x20000080 }, | ||
666 | { 0x5fffc, 0x20000080 }, | ||
667 | { 0x502b8, 0x20000080 }, | ||
668 | { 0x5fffc, 0x20000080 }, | ||
669 | { 0x502bc, 0x20000080 }, | ||
670 | { 0x5fffc, 0x20000080 }, | ||
671 | { 0x502c0, 0x20000080 }, | ||
672 | { 0x5fffc, 0x20000080 }, | ||
673 | { 0x502c4, 0x20000080 }, | ||
674 | { 0x5fffc, 0x20000080 }, | ||
675 | { 0x502c8, 0x20000080 }, | ||
676 | { 0x5fffc, 0x20000080 }, | ||
677 | { 0x502cc, 0x20000080 }, | ||
678 | { 0x5fffc, 0x20000080 }, | ||
679 | { 0x502d0, 0x20000080 }, | ||
680 | { 0x5fffc, 0x20000080 }, | ||
681 | { 0x502d4, 0x20000080 }, | ||
682 | { 0x5fffc, 0x20000080 }, | ||
683 | { 0x502d8, 0x20000080 }, | ||
684 | { 0x5fffc, 0x20000080 }, | ||
685 | { 0x502dc, 0x20000080 }, | ||
686 | { 0x5fffc, 0x20000080 }, | ||
687 | { 0x502e0, 0x20000080 }, | ||
688 | { 0x5fffc, 0x20000080 }, | ||
689 | { 0x502e4, 0x20000080 }, | ||
690 | { 0x5fffc, 0x20000080 }, | ||
691 | { 0x502e8, 0x20000080 }, | ||
692 | { 0x5fffc, 0x20000080 }, | ||
693 | { 0x502ec, 0x20000080 }, | ||
694 | { 0x5fffc, 0x20000080 }, | ||
695 | { 0x502f0, 0x20000080 }, | ||
696 | { 0x5fffc, 0x20000080 }, | ||
697 | { 0x502f4, 0x20000080 }, | ||
698 | { 0x5fffc, 0x20000080 }, | ||
699 | { 0x502f8, 0x20000080 }, | ||
700 | { 0x5fffc, 0x20000080 }, | ||
701 | { 0x502fc, 0x20000080 }, | ||
702 | { 0x5fffc, 0x20000080 }, | ||
703 | { 0x50300, 0x20000080 }, | ||
704 | { 0x5fffc, 0x20000080 }, | ||
705 | { 0x50304, 0x20000080 }, | ||
706 | { 0x5fffc, 0x20000080 }, | ||
707 | { 0x50308, 0x20000080 }, | ||
708 | { 0x5fffc, 0x20000080 }, | ||
709 | { 0x5030c, 0x20000080 }, | ||
710 | { 0x5fffc, 0x20000080 }, | ||
711 | { 0x50310, 0x20000080 }, | ||
712 | { 0x5fffc, 0x20000080 }, | ||
713 | { 0x50314, 0x20000080 }, | ||
714 | { 0x5fffc, 0x20000080 }, | ||
715 | { 0x50318, 0x20000080 }, | ||
716 | { 0x5fffc, 0x20000080 }, | ||
717 | { 0x5031c, 0x20000080 }, | ||
718 | { 0x5fffc, 0x20000080 }, | ||
719 | { 0x50320, 0x20000080 }, | ||
720 | { 0x5fffc, 0x20000080 }, | ||
721 | { 0x50324, 0x20000080 }, | ||
722 | { 0x5fffc, 0x20000080 }, | ||
723 | { 0x50328, 0x20000080 }, | ||
724 | { 0x5fffc, 0x20000080 }, | ||
725 | { 0x5032c, 0x20000080 }, | ||
726 | { 0x5fffc, 0x20000080 }, | ||
727 | { 0x50330, 0x20000080 }, | ||
728 | { 0x5fffc, 0x20000080 }, | ||
729 | { 0x50334, 0x20000080 }, | ||
730 | { 0x5fffc, 0x20000080 }, | ||
731 | { 0x50338, 0x20000080 }, | ||
732 | { 0x5fffc, 0x20000080 }, | ||
733 | { 0x5033c, 0x20000080 }, | ||
734 | { 0x5fffc, 0x20000080 }, | ||
735 | { 0x50340, 0x20000080 }, | ||
736 | { 0x5fffc, 0x20000080 }, | ||
737 | { 0x50344, 0x20000080 }, | ||
738 | { 0x5fffc, 0x20000080 }, | ||
739 | { 0x50348, 0x20000080 }, | ||
740 | { 0x5fffc, 0x20000080 }, | ||
741 | { 0x5034c, 0x20000080 }, | ||
742 | { 0x5fffc, 0x20000080 }, | ||
743 | { 0x50350, 0x20000080 }, | ||
744 | { 0x5fffc, 0x20000080 }, | ||
745 | { 0x50354, 0x20000080 }, | ||
746 | { 0x5fffc, 0x20000080 }, | ||
747 | { 0x50358, 0x20000080 }, | ||
748 | { 0x5fffc, 0x20000080 }, | ||
749 | { 0x5035c, 0x20000080 }, | ||
750 | { 0x5fffc, 0x20000080 }, | ||
751 | { 0x50360, 0x20000080 }, | ||
752 | { 0x5fffc, 0x20000080 }, | ||
753 | { 0x50364, 0x20000080 }, | ||
754 | { 0x5fffc, 0x20000080 }, | ||
755 | { 0x50368, 0x20000080 }, | ||
756 | { 0x5fffc, 0x20000080 }, | ||
757 | { 0x5036c, 0x20000080 }, | ||
758 | { 0x5fffc, 0x20000080 }, | ||
759 | { 0x50370, 0x20000080 }, | ||
760 | { 0x5fffc, 0x20000080 }, | ||
761 | { 0x50374, 0x20000080 }, | ||
762 | { 0x5fffc, 0x20000080 }, | ||
763 | { 0x50378, 0x20000080 }, | ||
764 | { 0x5fffc, 0x20000080 }, | ||
765 | { 0x5037c, 0x20000080 }, | ||
766 | }; | ||
diff --git a/drivers/video/msm/mdp_scale_tables.h b/drivers/video/msm/mdp_scale_tables.h new file mode 100644 index 000000000000..34077b1af603 --- /dev/null +++ b/drivers/video/msm/mdp_scale_tables.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* drivers/video/msm_fb/mdp_scale_tables.h | ||
2 | * | ||
3 | * Copyright (C) 2007 QUALCOMM Incorporated | ||
4 | * Copyright (C) 2007 Google Incorporated | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | #ifndef _MDP_SCALE_TABLES_H_ | ||
16 | #define _MDP_SCALE_TABLES_H_ | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | struct mdp_table_entry { | ||
20 | uint32_t reg; | ||
21 | uint32_t val; | ||
22 | }; | ||
23 | |||
24 | extern struct mdp_table_entry mdp_upscale_table[64]; | ||
25 | |||
26 | enum { | ||
27 | MDP_DOWNSCALE_PT2TOPT4, | ||
28 | MDP_DOWNSCALE_PT4TOPT6, | ||
29 | MDP_DOWNSCALE_PT6TOPT8, | ||
30 | MDP_DOWNSCALE_PT8TO1, | ||
31 | MDP_DOWNSCALE_MAX, | ||
32 | }; | ||
33 | |||
34 | extern struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX]; | ||
35 | extern struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX]; | ||
36 | extern struct mdp_table_entry mdp_gaussian_blur_table[]; | ||
37 | |||
38 | #endif | ||
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c new file mode 100644 index 000000000000..49101dda45ee --- /dev/null +++ b/drivers/video/msm/msm_fb.c | |||
@@ -0,0 +1,636 @@ | |||
1 | /* drivers/video/msm/msm_fb.c | ||
2 | * | ||
3 | * Core MSM framebuffer driver. | ||
4 | * | ||
5 | * Copyright (C) 2007 Google Incorporated | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/fb.h> | ||
20 | #include <linux/delay.h> | ||
21 | |||
22 | #include <linux/freezer.h> | ||
23 | #include <linux/wait.h> | ||
24 | #include <linux/msm_mdp.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/uaccess.h> | ||
27 | #include <mach/msm_fb.h> | ||
28 | #include <mach/board.h> | ||
29 | #include <linux/workqueue.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <linux/debugfs.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | |||
34 | #define PRINT_FPS 0 | ||
35 | #define PRINT_BLIT_TIME 0 | ||
36 | |||
37 | #define SLEEPING 0x4 | ||
38 | #define UPDATING 0x3 | ||
39 | #define FULL_UPDATE_DONE 0x2 | ||
40 | #define WAKING 0x1 | ||
41 | #define AWAKE 0x0 | ||
42 | |||
43 | #define NONE 0 | ||
44 | #define SUSPEND_RESUME 0x1 | ||
45 | #define FPS 0x2 | ||
46 | #define BLIT_TIME 0x4 | ||
47 | #define SHOW_UPDATES 0x8 | ||
48 | |||
49 | #define DLOG(mask, fmt, args...) \ | ||
50 | do { \ | ||
51 | if (msmfb_debug_mask & mask) \ | ||
52 | printk(KERN_INFO "msmfb: "fmt, ##args); \ | ||
53 | } while (0) | ||
54 | |||
55 | static int msmfb_debug_mask; | ||
56 | module_param_named(msmfb_debug_mask, msmfb_debug_mask, int, | ||
57 | S_IRUGO | S_IWUSR | S_IWGRP); | ||
58 | |||
59 | struct mdp_device *mdp; | ||
60 | |||
61 | struct msmfb_info { | ||
62 | struct fb_info *fb; | ||
63 | struct msm_panel_data *panel; | ||
64 | int xres; | ||
65 | int yres; | ||
66 | unsigned output_format; | ||
67 | unsigned yoffset; | ||
68 | unsigned frame_requested; | ||
69 | unsigned frame_done; | ||
70 | int sleeping; | ||
71 | unsigned update_frame; | ||
72 | struct { | ||
73 | int left; | ||
74 | int top; | ||
75 | int eright; /* exclusive */ | ||
76 | int ebottom; /* exclusive */ | ||
77 | } update_info; | ||
78 | char *black; | ||
79 | |||
80 | spinlock_t update_lock; | ||
81 | struct mutex panel_init_lock; | ||
82 | wait_queue_head_t frame_wq; | ||
83 | struct workqueue_struct *resume_workqueue; | ||
84 | struct work_struct resume_work; | ||
85 | struct msmfb_callback dma_callback; | ||
86 | struct msmfb_callback vsync_callback; | ||
87 | struct hrtimer fake_vsync; | ||
88 | ktime_t vsync_request_time; | ||
89 | }; | ||
90 | |||
91 | static int msmfb_open(struct fb_info *info, int user) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int msmfb_release(struct fb_info *info, int user) | ||
97 | { | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | /* Called from dma interrupt handler, must not sleep */ | ||
102 | static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback) | ||
103 | { | ||
104 | unsigned long irq_flags; | ||
105 | struct msmfb_info *msmfb = container_of(callback, struct msmfb_info, | ||
106 | dma_callback); | ||
107 | |||
108 | spin_lock_irqsave(&msmfb->update_lock, irq_flags); | ||
109 | msmfb->frame_done = msmfb->frame_requested; | ||
110 | if (msmfb->sleeping == UPDATING && | ||
111 | msmfb->frame_done == msmfb->update_frame) { | ||
112 | DLOG(SUSPEND_RESUME, "full update completed\n"); | ||
113 | queue_work(msmfb->resume_workqueue, &msmfb->resume_work); | ||
114 | } | ||
115 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
116 | wake_up(&msmfb->frame_wq); | ||
117 | } | ||
118 | |||
119 | static int msmfb_start_dma(struct msmfb_info *msmfb) | ||
120 | { | ||
121 | uint32_t x, y, w, h; | ||
122 | unsigned addr; | ||
123 | unsigned long irq_flags; | ||
124 | uint32_t yoffset; | ||
125 | s64 time_since_request; | ||
126 | struct msm_panel_data *panel = msmfb->panel; | ||
127 | |||
128 | spin_lock_irqsave(&msmfb->update_lock, irq_flags); | ||
129 | time_since_request = ktime_to_ns(ktime_sub(ktime_get(), | ||
130 | msmfb->vsync_request_time)); | ||
131 | if (time_since_request > 20 * NSEC_PER_MSEC) { | ||
132 | uint32_t us; | ||
133 | us = do_div(time_since_request, NSEC_PER_MSEC) / NSEC_PER_USEC; | ||
134 | printk(KERN_WARNING "msmfb_start_dma %lld.%03u ms after vsync " | ||
135 | "request\n", time_since_request, us); | ||
136 | } | ||
137 | if (msmfb->frame_done == msmfb->frame_requested) { | ||
138 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
139 | return -1; | ||
140 | } | ||
141 | if (msmfb->sleeping == SLEEPING) { | ||
142 | DLOG(SUSPEND_RESUME, "tried to start dma while asleep\n"); | ||
143 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
144 | return -1; | ||
145 | } | ||
146 | x = msmfb->update_info.left; | ||
147 | y = msmfb->update_info.top; | ||
148 | w = msmfb->update_info.eright - x; | ||
149 | h = msmfb->update_info.ebottom - y; | ||
150 | yoffset = msmfb->yoffset; | ||
151 | msmfb->update_info.left = msmfb->xres + 1; | ||
152 | msmfb->update_info.top = msmfb->yres + 1; | ||
153 | msmfb->update_info.eright = 0; | ||
154 | msmfb->update_info.ebottom = 0; | ||
155 | if (unlikely(w > msmfb->xres || h > msmfb->yres || | ||
156 | w == 0 || h == 0)) { | ||
157 | printk(KERN_INFO "invalid update: %d %d %d " | ||
158 | "%d\n", x, y, w, h); | ||
159 | msmfb->frame_done = msmfb->frame_requested; | ||
160 | goto error; | ||
161 | } | ||
162 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
163 | |||
164 | addr = ((msmfb->xres * (yoffset + y) + x) * 2); | ||
165 | mdp->dma(mdp, addr + msmfb->fb->fix.smem_start, | ||
166 | msmfb->xres * 2, w, h, x, y, &msmfb->dma_callback, | ||
167 | panel->interface_type); | ||
168 | return 0; | ||
169 | error: | ||
170 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
171 | /* some clients need to clear their vsync interrupt */ | ||
172 | if (panel->clear_vsync) | ||
173 | panel->clear_vsync(panel); | ||
174 | wake_up(&msmfb->frame_wq); | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | /* Called from esync interrupt handler, must not sleep */ | ||
179 | static void msmfb_handle_vsync_interrupt(struct msmfb_callback *callback) | ||
180 | { | ||
181 | struct msmfb_info *msmfb = container_of(callback, struct msmfb_info, | ||
182 | vsync_callback); | ||
183 | msmfb_start_dma(msmfb); | ||
184 | } | ||
185 | |||
186 | static enum hrtimer_restart msmfb_fake_vsync(struct hrtimer *timer) | ||
187 | { | ||
188 | struct msmfb_info *msmfb = container_of(timer, struct msmfb_info, | ||
189 | fake_vsync); | ||
190 | msmfb_start_dma(msmfb); | ||
191 | return HRTIMER_NORESTART; | ||
192 | } | ||
193 | |||
194 | static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, | ||
195 | uint32_t eright, uint32_t ebottom, | ||
196 | uint32_t yoffset, int pan_display) | ||
197 | { | ||
198 | struct msmfb_info *msmfb = info->par; | ||
199 | struct msm_panel_data *panel = msmfb->panel; | ||
200 | unsigned long irq_flags; | ||
201 | int sleeping; | ||
202 | int retry = 1; | ||
203 | |||
204 | DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n", | ||
205 | left, top, eright, ebottom, yoffset, pan_display); | ||
206 | restart: | ||
207 | spin_lock_irqsave(&msmfb->update_lock, irq_flags); | ||
208 | |||
209 | /* if we are sleeping, on a pan_display wait 10ms (to throttle back | ||
210 | * drawing otherwise return */ | ||
211 | if (msmfb->sleeping == SLEEPING) { | ||
212 | DLOG(SUSPEND_RESUME, "drawing while asleep\n"); | ||
213 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
214 | if (pan_display) | ||
215 | wait_event_interruptible_timeout(msmfb->frame_wq, | ||
216 | msmfb->sleeping != SLEEPING, HZ/10); | ||
217 | return; | ||
218 | } | ||
219 | |||
220 | sleeping = msmfb->sleeping; | ||
221 | /* on a full update, if the last frame has not completed, wait for it */ | ||
222 | if (pan_display && (msmfb->frame_requested != msmfb->frame_done || | ||
223 | sleeping == UPDATING)) { | ||
224 | int ret; | ||
225 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
226 | ret = wait_event_interruptible_timeout(msmfb->frame_wq, | ||
227 | msmfb->frame_done == msmfb->frame_requested && | ||
228 | msmfb->sleeping != UPDATING, 5 * HZ); | ||
229 | if (ret <= 0 && (msmfb->frame_requested != msmfb->frame_done || | ||
230 | msmfb->sleeping == UPDATING)) { | ||
231 | if (retry && panel->request_vsync && | ||
232 | (sleeping == AWAKE)) { | ||
233 | panel->request_vsync(panel, | ||
234 | &msmfb->vsync_callback); | ||
235 | retry = 0; | ||
236 | printk(KERN_WARNING "msmfb_pan_display timeout " | ||
237 | "rerequest vsync\n"); | ||
238 | } else { | ||
239 | printk(KERN_WARNING "msmfb_pan_display timeout " | ||
240 | "waiting for frame start, %d %d\n", | ||
241 | msmfb->frame_requested, | ||
242 | msmfb->frame_done); | ||
243 | return; | ||
244 | } | ||
245 | } | ||
246 | goto restart; | ||
247 | } | ||
248 | |||
249 | |||
250 | msmfb->frame_requested++; | ||
251 | /* if necessary, update the y offset, if this is the | ||
252 | * first full update on resume, set the sleeping state */ | ||
253 | if (pan_display) { | ||
254 | msmfb->yoffset = yoffset; | ||
255 | if (left == 0 && top == 0 && eright == info->var.xres && | ||
256 | ebottom == info->var.yres) { | ||
257 | if (sleeping == WAKING) { | ||
258 | msmfb->update_frame = msmfb->frame_requested; | ||
259 | DLOG(SUSPEND_RESUME, "full update starting\n"); | ||
260 | msmfb->sleeping = UPDATING; | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | |||
265 | /* set the update request */ | ||
266 | if (left < msmfb->update_info.left) | ||
267 | msmfb->update_info.left = left; | ||
268 | if (top < msmfb->update_info.top) | ||
269 | msmfb->update_info.top = top; | ||
270 | if (eright > msmfb->update_info.eright) | ||
271 | msmfb->update_info.eright = eright; | ||
272 | if (ebottom > msmfb->update_info.ebottom) | ||
273 | msmfb->update_info.ebottom = ebottom; | ||
274 | DLOG(SHOW_UPDATES, "update queued %d %d %d %d %d\n", | ||
275 | msmfb->update_info.left, msmfb->update_info.top, | ||
276 | msmfb->update_info.eright, msmfb->update_info.ebottom, | ||
277 | msmfb->yoffset); | ||
278 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
279 | |||
280 | /* if the panel is all the way on wait for vsync, otherwise sleep | ||
281 | * for 16 ms (long enough for the dma to panel) and then begin dma */ | ||
282 | msmfb->vsync_request_time = ktime_get(); | ||
283 | if (panel->request_vsync && (sleeping == AWAKE)) { | ||
284 | panel->request_vsync(panel, &msmfb->vsync_callback); | ||
285 | } else { | ||
286 | if (!hrtimer_active(&msmfb->fake_vsync)) { | ||
287 | hrtimer_start(&msmfb->fake_vsync, | ||
288 | ktime_set(0, NSEC_PER_SEC/60), | ||
289 | HRTIMER_MODE_REL); | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | |||
294 | static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top, | ||
295 | uint32_t eright, uint32_t ebottom) | ||
296 | { | ||
297 | msmfb_pan_update(info, left, top, eright, ebottom, 0, 0); | ||
298 | } | ||
299 | |||
300 | static void power_on_panel(struct work_struct *work) | ||
301 | { | ||
302 | struct msmfb_info *msmfb = | ||
303 | container_of(work, struct msmfb_info, resume_work); | ||
304 | struct msm_panel_data *panel = msmfb->panel; | ||
305 | unsigned long irq_flags; | ||
306 | |||
307 | mutex_lock(&msmfb->panel_init_lock); | ||
308 | DLOG(SUSPEND_RESUME, "turning on panel\n"); | ||
309 | if (msmfb->sleeping == UPDATING) { | ||
310 | if (panel->unblank(panel)) { | ||
311 | printk(KERN_INFO "msmfb: panel unblank failed," | ||
312 | "not starting drawing\n"); | ||
313 | goto error; | ||
314 | } | ||
315 | spin_lock_irqsave(&msmfb->update_lock, irq_flags); | ||
316 | msmfb->sleeping = AWAKE; | ||
317 | wake_up(&msmfb->frame_wq); | ||
318 | spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); | ||
319 | } | ||
320 | error: | ||
321 | mutex_unlock(&msmfb->panel_init_lock); | ||
322 | } | ||
323 | |||
324 | |||
325 | static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
326 | { | ||
327 | if ((var->xres != info->var.xres) || | ||
328 | (var->yres != info->var.yres) || | ||
329 | (var->xres_virtual != info->var.xres_virtual) || | ||
330 | (var->yres_virtual != info->var.yres_virtual) || | ||
331 | (var->xoffset != info->var.xoffset) || | ||
332 | (var->bits_per_pixel != info->var.bits_per_pixel) || | ||
333 | (var->grayscale != info->var.grayscale)) | ||
334 | return -EINVAL; | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | ||
339 | { | ||
340 | struct msmfb_info *msmfb = info->par; | ||
341 | struct msm_panel_data *panel = msmfb->panel; | ||
342 | |||
343 | /* "UPDT" */ | ||
344 | if ((panel->caps & MSMFB_CAP_PARTIAL_UPDATES) && | ||
345 | (var->reserved[0] == 0x54445055)) { | ||
346 | msmfb_pan_update(info, var->reserved[1] & 0xffff, | ||
347 | var->reserved[1] >> 16, | ||
348 | var->reserved[2] & 0xffff, | ||
349 | var->reserved[2] >> 16, var->yoffset, 1); | ||
350 | } else { | ||
351 | msmfb_pan_update(info, 0, 0, info->var.xres, info->var.yres, | ||
352 | var->yoffset, 1); | ||
353 | } | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) | ||
358 | { | ||
359 | cfb_fillrect(p, rect); | ||
360 | msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width, | ||
361 | rect->dy + rect->height); | ||
362 | } | ||
363 | |||
364 | static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) | ||
365 | { | ||
366 | cfb_copyarea(p, area); | ||
367 | msmfb_update(p, area->dx, area->dy, area->dx + area->width, | ||
368 | area->dy + area->height); | ||
369 | } | ||
370 | |||
371 | static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image) | ||
372 | { | ||
373 | cfb_imageblit(p, image); | ||
374 | msmfb_update(p, image->dx, image->dy, image->dx + image->width, | ||
375 | image->dy + image->height); | ||
376 | } | ||
377 | |||
378 | |||
379 | static int msmfb_blit(struct fb_info *info, | ||
380 | void __user *p) | ||
381 | { | ||
382 | struct mdp_blit_req req; | ||
383 | struct mdp_blit_req_list req_list; | ||
384 | int i; | ||
385 | int ret; | ||
386 | |||
387 | if (copy_from_user(&req_list, p, sizeof(req_list))) | ||
388 | return -EFAULT; | ||
389 | |||
390 | for (i = 0; i < req_list.count; i++) { | ||
391 | struct mdp_blit_req_list *list = | ||
392 | (struct mdp_blit_req_list *)p; | ||
393 | if (copy_from_user(&req, &list->req[i], sizeof(req))) | ||
394 | return -EFAULT; | ||
395 | ret = mdp->blit(mdp, info, &req); | ||
396 | if (ret) | ||
397 | return ret; | ||
398 | } | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | |||
403 | DEFINE_MUTEX(mdp_ppp_lock); | ||
404 | |||
405 | static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg) | ||
406 | { | ||
407 | void __user *argp = (void __user *)arg; | ||
408 | int ret; | ||
409 | |||
410 | switch (cmd) { | ||
411 | case MSMFB_GRP_DISP: | ||
412 | mdp->set_grp_disp(mdp, arg); | ||
413 | break; | ||
414 | case MSMFB_BLIT: | ||
415 | ret = msmfb_blit(p, argp); | ||
416 | if (ret) | ||
417 | return ret; | ||
418 | break; | ||
419 | default: | ||
420 | printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd); | ||
421 | return -EINVAL; | ||
422 | } | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static struct fb_ops msmfb_ops = { | ||
427 | .owner = THIS_MODULE, | ||
428 | .fb_open = msmfb_open, | ||
429 | .fb_release = msmfb_release, | ||
430 | .fb_check_var = msmfb_check_var, | ||
431 | .fb_pan_display = msmfb_pan_display, | ||
432 | .fb_fillrect = msmfb_fillrect, | ||
433 | .fb_copyarea = msmfb_copyarea, | ||
434 | .fb_imageblit = msmfb_imageblit, | ||
435 | .fb_ioctl = msmfb_ioctl, | ||
436 | }; | ||
437 | |||
438 | static unsigned PP[16]; | ||
439 | |||
440 | |||
441 | |||
442 | #define BITS_PER_PIXEL 16 | ||
443 | |||
444 | static void setup_fb_info(struct msmfb_info *msmfb) | ||
445 | { | ||
446 | struct fb_info *fb_info = msmfb->fb; | ||
447 | int r; | ||
448 | |||
449 | /* finish setting up the fb_info struct */ | ||
450 | strncpy(fb_info->fix.id, "msmfb", 16); | ||
451 | fb_info->fix.ypanstep = 1; | ||
452 | |||
453 | fb_info->fbops = &msmfb_ops; | ||
454 | fb_info->flags = FBINFO_DEFAULT; | ||
455 | |||
456 | fb_info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
457 | fb_info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
458 | fb_info->fix.line_length = msmfb->xres * 2; | ||
459 | |||
460 | fb_info->var.xres = msmfb->xres; | ||
461 | fb_info->var.yres = msmfb->yres; | ||
462 | fb_info->var.width = msmfb->panel->fb_data->width; | ||
463 | fb_info->var.height = msmfb->panel->fb_data->height; | ||
464 | fb_info->var.xres_virtual = msmfb->xres; | ||
465 | fb_info->var.yres_virtual = msmfb->yres * 2; | ||
466 | fb_info->var.bits_per_pixel = BITS_PER_PIXEL; | ||
467 | fb_info->var.accel_flags = 0; | ||
468 | |||
469 | fb_info->var.yoffset = 0; | ||
470 | |||
471 | if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) { | ||
472 | fb_info->var.reserved[0] = 0x54445055; | ||
473 | fb_info->var.reserved[1] = 0; | ||
474 | fb_info->var.reserved[2] = (uint16_t)msmfb->xres | | ||
475 | ((uint32_t)msmfb->yres << 16); | ||
476 | } | ||
477 | |||
478 | fb_info->var.red.offset = 11; | ||
479 | fb_info->var.red.length = 5; | ||
480 | fb_info->var.red.msb_right = 0; | ||
481 | fb_info->var.green.offset = 5; | ||
482 | fb_info->var.green.length = 6; | ||
483 | fb_info->var.green.msb_right = 0; | ||
484 | fb_info->var.blue.offset = 0; | ||
485 | fb_info->var.blue.length = 5; | ||
486 | fb_info->var.blue.msb_right = 0; | ||
487 | |||
488 | r = fb_alloc_cmap(&fb_info->cmap, 16, 0); | ||
489 | fb_info->pseudo_palette = PP; | ||
490 | |||
491 | PP[0] = 0; | ||
492 | for (r = 1; r < 16; r++) | ||
493 | PP[r] = 0xffffffff; | ||
494 | } | ||
495 | |||
496 | static int setup_fbmem(struct msmfb_info *msmfb, struct platform_device *pdev) | ||
497 | { | ||
498 | struct fb_info *fb = msmfb->fb; | ||
499 | struct resource *resource; | ||
500 | unsigned long size = msmfb->xres * msmfb->yres * | ||
501 | (BITS_PER_PIXEL >> 3) * 2; | ||
502 | unsigned char *fbram; | ||
503 | |||
504 | /* board file might have attached a resource describing an fb */ | ||
505 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
506 | if (!resource) | ||
507 | return -EINVAL; | ||
508 | |||
509 | /* check the resource is large enough to fit the fb */ | ||
510 | if (resource->end - resource->start < size) { | ||
511 | printk(KERN_ERR "allocated resource is too small for " | ||
512 | "fb\n"); | ||
513 | return -ENOMEM; | ||
514 | } | ||
515 | fb->fix.smem_start = resource->start; | ||
516 | fb->fix.smem_len = resource->end - resource->start; | ||
517 | fbram = ioremap(resource->start, | ||
518 | resource->end - resource->start); | ||
519 | if (fbram == 0) { | ||
520 | printk(KERN_ERR "msmfb: cannot allocate fbram!\n"); | ||
521 | return -ENOMEM; | ||
522 | } | ||
523 | fb->screen_base = fbram; | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int msmfb_probe(struct platform_device *pdev) | ||
528 | { | ||
529 | struct fb_info *fb; | ||
530 | struct msmfb_info *msmfb; | ||
531 | struct msm_panel_data *panel = pdev->dev.platform_data; | ||
532 | int ret; | ||
533 | |||
534 | if (!panel) { | ||
535 | pr_err("msmfb_probe: no platform data\n"); | ||
536 | return -EINVAL; | ||
537 | } | ||
538 | if (!panel->fb_data) { | ||
539 | pr_err("msmfb_probe: no fb_data\n"); | ||
540 | return -EINVAL; | ||
541 | } | ||
542 | |||
543 | fb = framebuffer_alloc(sizeof(struct msmfb_info), &pdev->dev); | ||
544 | if (!fb) | ||
545 | return -ENOMEM; | ||
546 | msmfb = fb->par; | ||
547 | msmfb->fb = fb; | ||
548 | msmfb->panel = panel; | ||
549 | msmfb->xres = panel->fb_data->xres; | ||
550 | msmfb->yres = panel->fb_data->yres; | ||
551 | |||
552 | ret = setup_fbmem(msmfb, pdev); | ||
553 | if (ret) | ||
554 | goto error_setup_fbmem; | ||
555 | |||
556 | setup_fb_info(msmfb); | ||
557 | |||
558 | spin_lock_init(&msmfb->update_lock); | ||
559 | mutex_init(&msmfb->panel_init_lock); | ||
560 | init_waitqueue_head(&msmfb->frame_wq); | ||
561 | msmfb->resume_workqueue = create_workqueue("panel_on"); | ||
562 | if (msmfb->resume_workqueue == NULL) { | ||
563 | printk(KERN_ERR "failed to create panel_on workqueue\n"); | ||
564 | ret = -ENOMEM; | ||
565 | goto error_create_workqueue; | ||
566 | } | ||
567 | INIT_WORK(&msmfb->resume_work, power_on_panel); | ||
568 | msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres, | ||
569 | GFP_KERNEL); | ||
570 | |||
571 | printk(KERN_INFO "msmfb_probe() installing %d x %d panel\n", | ||
572 | msmfb->xres, msmfb->yres); | ||
573 | |||
574 | msmfb->dma_callback.func = msmfb_handle_dma_interrupt; | ||
575 | msmfb->vsync_callback.func = msmfb_handle_vsync_interrupt; | ||
576 | hrtimer_init(&msmfb->fake_vsync, CLOCK_MONOTONIC, | ||
577 | HRTIMER_MODE_REL); | ||
578 | |||
579 | |||
580 | msmfb->fake_vsync.function = msmfb_fake_vsync; | ||
581 | |||
582 | ret = register_framebuffer(fb); | ||
583 | if (ret) | ||
584 | goto error_register_framebuffer; | ||
585 | |||
586 | msmfb->sleeping = WAKING; | ||
587 | |||
588 | return 0; | ||
589 | |||
590 | error_register_framebuffer: | ||
591 | destroy_workqueue(msmfb->resume_workqueue); | ||
592 | error_create_workqueue: | ||
593 | iounmap(fb->screen_base); | ||
594 | error_setup_fbmem: | ||
595 | framebuffer_release(msmfb->fb); | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | static struct platform_driver msm_panel_driver = { | ||
600 | /* need to write remove */ | ||
601 | .probe = msmfb_probe, | ||
602 | .driver = {.name = "msm_panel"}, | ||
603 | }; | ||
604 | |||
605 | |||
606 | static int msmfb_add_mdp_device(struct device *dev, | ||
607 | struct class_interface *class_intf) | ||
608 | { | ||
609 | /* might need locking if mulitple mdp devices */ | ||
610 | if (mdp) | ||
611 | return 0; | ||
612 | mdp = container_of(dev, struct mdp_device, dev); | ||
613 | return platform_driver_register(&msm_panel_driver); | ||
614 | } | ||
615 | |||
616 | static void msmfb_remove_mdp_device(struct device *dev, | ||
617 | struct class_interface *class_intf) | ||
618 | { | ||
619 | /* might need locking if mulitple mdp devices */ | ||
620 | if (dev != &mdp->dev) | ||
621 | return; | ||
622 | platform_driver_unregister(&msm_panel_driver); | ||
623 | mdp = NULL; | ||
624 | } | ||
625 | |||
626 | static struct class_interface msm_fb_interface = { | ||
627 | .add_dev = &msmfb_add_mdp_device, | ||
628 | .remove_dev = &msmfb_remove_mdp_device, | ||
629 | }; | ||
630 | |||
631 | static int __init msmfb_init(void) | ||
632 | { | ||
633 | return register_mdp_client(&msm_fb_interface); | ||
634 | } | ||
635 | |||
636 | module_init(msmfb_init); | ||
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index b7af5256e887..054ef29be479 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c | |||
@@ -669,7 +669,8 @@ static uint32_t bpp_to_pixfmt(int bpp) | |||
669 | } | 669 | } |
670 | 670 | ||
671 | static int mx3fb_blank(int blank, struct fb_info *fbi); | 671 | static int mx3fb_blank(int blank, struct fb_info *fbi); |
672 | static int mx3fb_map_video_memory(struct fb_info *fbi); | 672 | static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len, |
673 | bool lock); | ||
673 | static int mx3fb_unmap_video_memory(struct fb_info *fbi); | 674 | static int mx3fb_unmap_video_memory(struct fb_info *fbi); |
674 | 675 | ||
675 | /** | 676 | /** |
@@ -711,12 +712,7 @@ static void mx3fb_dma_done(void *arg) | |||
711 | complete(&mx3_fbi->flip_cmpl); | 712 | complete(&mx3_fbi->flip_cmpl); |
712 | } | 713 | } |
713 | 714 | ||
714 | /** | 715 | static int __set_par(struct fb_info *fbi, bool lock) |
715 | * mx3fb_set_par() - set framebuffer parameters and change the operating mode. | ||
716 | * @fbi: framebuffer information pointer. | ||
717 | * @return: 0 on success or negative error code on failure. | ||
718 | */ | ||
719 | static int mx3fb_set_par(struct fb_info *fbi) | ||
720 | { | 716 | { |
721 | u32 mem_len; | 717 | u32 mem_len; |
722 | struct ipu_di_signal_cfg sig_cfg; | 718 | struct ipu_di_signal_cfg sig_cfg; |
@@ -727,10 +723,6 @@ static int mx3fb_set_par(struct fb_info *fbi) | |||
727 | struct idmac_video_param *video = &ichan->params.video; | 723 | struct idmac_video_param *video = &ichan->params.video; |
728 | struct scatterlist *sg = mx3_fbi->sg; | 724 | struct scatterlist *sg = mx3_fbi->sg; |
729 | 725 | ||
730 | dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); | ||
731 | |||
732 | mutex_lock(&mx3_fbi->mutex); | ||
733 | |||
734 | /* Total cleanup */ | 726 | /* Total cleanup */ |
735 | if (mx3_fbi->txd) | 727 | if (mx3_fbi->txd) |
736 | sdc_disable_channel(mx3_fbi); | 728 | sdc_disable_channel(mx3_fbi); |
@@ -742,11 +734,8 @@ static int mx3fb_set_par(struct fb_info *fbi) | |||
742 | if (fbi->fix.smem_start) | 734 | if (fbi->fix.smem_start) |
743 | mx3fb_unmap_video_memory(fbi); | 735 | mx3fb_unmap_video_memory(fbi); |
744 | 736 | ||
745 | fbi->fix.smem_len = mem_len; | 737 | if (mx3fb_map_video_memory(fbi, mem_len, lock) < 0) |
746 | if (mx3fb_map_video_memory(fbi) < 0) { | ||
747 | mutex_unlock(&mx3_fbi->mutex); | ||
748 | return -ENOMEM; | 738 | return -ENOMEM; |
749 | } | ||
750 | } | 739 | } |
751 | 740 | ||
752 | sg_init_table(&sg[0], 1); | 741 | sg_init_table(&sg[0], 1); |
@@ -792,7 +781,6 @@ static int mx3fb_set_par(struct fb_info *fbi) | |||
792 | fbi->var.vsync_len, | 781 | fbi->var.vsync_len, |
793 | fbi->var.lower_margin + | 782 | fbi->var.lower_margin + |
794 | fbi->var.vsync_len, sig_cfg) != 0) { | 783 | fbi->var.vsync_len, sig_cfg) != 0) { |
795 | mutex_unlock(&mx3_fbi->mutex); | ||
796 | dev_err(fbi->device, | 784 | dev_err(fbi->device, |
797 | "mx3fb: Error initializing panel.\n"); | 785 | "mx3fb: Error initializing panel.\n"); |
798 | return -EINVAL; | 786 | return -EINVAL; |
@@ -811,9 +799,30 @@ static int mx3fb_set_par(struct fb_info *fbi) | |||
811 | if (mx3_fbi->blank == FB_BLANK_UNBLANK) | 799 | if (mx3_fbi->blank == FB_BLANK_UNBLANK) |
812 | sdc_enable_channel(mx3_fbi); | 800 | sdc_enable_channel(mx3_fbi); |
813 | 801 | ||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | /** | ||
806 | * mx3fb_set_par() - set framebuffer parameters and change the operating mode. | ||
807 | * @fbi: framebuffer information pointer. | ||
808 | * @return: 0 on success or negative error code on failure. | ||
809 | */ | ||
810 | static int mx3fb_set_par(struct fb_info *fbi) | ||
811 | { | ||
812 | struct mx3fb_info *mx3_fbi = fbi->par; | ||
813 | struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; | ||
814 | struct idmac_channel *ichan = mx3_fbi->idmac_channel; | ||
815 | int ret; | ||
816 | |||
817 | dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); | ||
818 | |||
819 | mutex_lock(&mx3_fbi->mutex); | ||
820 | |||
821 | ret = __set_par(fbi, true); | ||
822 | |||
814 | mutex_unlock(&mx3_fbi->mutex); | 823 | mutex_unlock(&mx3_fbi->mutex); |
815 | 824 | ||
816 | return 0; | 825 | return ret; |
817 | } | 826 | } |
818 | 827 | ||
819 | /** | 828 | /** |
@@ -967,21 +976,11 @@ static int mx3fb_setcolreg(unsigned int regno, unsigned int red, | |||
967 | return ret; | 976 | return ret; |
968 | } | 977 | } |
969 | 978 | ||
970 | /** | 979 | static void __blank(int blank, struct fb_info *fbi) |
971 | * mx3fb_blank() - blank the display. | ||
972 | */ | ||
973 | static int mx3fb_blank(int blank, struct fb_info *fbi) | ||
974 | { | 980 | { |
975 | struct mx3fb_info *mx3_fbi = fbi->par; | 981 | struct mx3fb_info *mx3_fbi = fbi->par; |
976 | struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; | 982 | struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; |
977 | 983 | ||
978 | dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__, | ||
979 | blank, fbi->screen_base, fbi->fix.smem_len); | ||
980 | |||
981 | if (mx3_fbi->blank == blank) | ||
982 | return 0; | ||
983 | |||
984 | mutex_lock(&mx3_fbi->mutex); | ||
985 | mx3_fbi->blank = blank; | 984 | mx3_fbi->blank = blank; |
986 | 985 | ||
987 | switch (blank) { | 986 | switch (blank) { |
@@ -1000,6 +999,23 @@ static int mx3fb_blank(int blank, struct fb_info *fbi) | |||
1000 | sdc_set_brightness(mx3fb, mx3fb->backlight_level); | 999 | sdc_set_brightness(mx3fb, mx3fb->backlight_level); |
1001 | break; | 1000 | break; |
1002 | } | 1001 | } |
1002 | } | ||
1003 | |||
1004 | /** | ||
1005 | * mx3fb_blank() - blank the display. | ||
1006 | */ | ||
1007 | static int mx3fb_blank(int blank, struct fb_info *fbi) | ||
1008 | { | ||
1009 | struct mx3fb_info *mx3_fbi = fbi->par; | ||
1010 | |||
1011 | dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__, | ||
1012 | blank, fbi->screen_base, fbi->fix.smem_len); | ||
1013 | |||
1014 | if (mx3_fbi->blank == blank) | ||
1015 | return 0; | ||
1016 | |||
1017 | mutex_lock(&mx3_fbi->mutex); | ||
1018 | __blank(blank, fbi); | ||
1003 | mutex_unlock(&mx3_fbi->mutex); | 1019 | mutex_unlock(&mx3_fbi->mutex); |
1004 | 1020 | ||
1005 | return 0; | 1021 | return 0; |
@@ -1198,6 +1214,8 @@ static int mx3fb_resume(struct platform_device *pdev) | |||
1198 | /** | 1214 | /** |
1199 | * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. | 1215 | * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. |
1200 | * @fbi: framebuffer information pointer | 1216 | * @fbi: framebuffer information pointer |
1217 | * @mem_len: length of mapped memory | ||
1218 | * @lock: do not lock during initialisation | ||
1201 | * @return: Error code indicating success or failure | 1219 | * @return: Error code indicating success or failure |
1202 | * | 1220 | * |
1203 | * This buffer is remapped into a non-cached, non-buffered, memory region to | 1221 | * This buffer is remapped into a non-cached, non-buffered, memory region to |
@@ -1205,23 +1223,29 @@ static int mx3fb_resume(struct platform_device *pdev) | |||
1205 | * area is remapped, all virtual memory access to the video memory should occur | 1223 | * area is remapped, all virtual memory access to the video memory should occur |
1206 | * at the new region. | 1224 | * at the new region. |
1207 | */ | 1225 | */ |
1208 | static int mx3fb_map_video_memory(struct fb_info *fbi) | 1226 | static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len, |
1227 | bool lock) | ||
1209 | { | 1228 | { |
1210 | int retval = 0; | 1229 | int retval = 0; |
1211 | dma_addr_t addr; | 1230 | dma_addr_t addr; |
1212 | 1231 | ||
1213 | fbi->screen_base = dma_alloc_writecombine(fbi->device, | 1232 | fbi->screen_base = dma_alloc_writecombine(fbi->device, |
1214 | fbi->fix.smem_len, | 1233 | mem_len, |
1215 | &addr, GFP_DMA); | 1234 | &addr, GFP_DMA); |
1216 | 1235 | ||
1217 | if (!fbi->screen_base) { | 1236 | if (!fbi->screen_base) { |
1218 | dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", | 1237 | dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", |
1219 | fbi->fix.smem_len); | 1238 | mem_len); |
1220 | retval = -EBUSY; | 1239 | retval = -EBUSY; |
1221 | goto err0; | 1240 | goto err0; |
1222 | } | 1241 | } |
1223 | 1242 | ||
1243 | if (lock) | ||
1244 | mutex_lock(&fbi->mm_lock); | ||
1224 | fbi->fix.smem_start = addr; | 1245 | fbi->fix.smem_start = addr; |
1246 | fbi->fix.smem_len = mem_len; | ||
1247 | if (lock) | ||
1248 | mutex_unlock(&fbi->mm_lock); | ||
1225 | 1249 | ||
1226 | dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", | 1250 | dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", |
1227 | (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); | 1251 | (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); |
@@ -1251,8 +1275,10 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi) | |||
1251 | fbi->screen_base, fbi->fix.smem_start); | 1275 | fbi->screen_base, fbi->fix.smem_start); |
1252 | 1276 | ||
1253 | fbi->screen_base = 0; | 1277 | fbi->screen_base = 0; |
1278 | mutex_lock(&fbi->mm_lock); | ||
1254 | fbi->fix.smem_start = 0; | 1279 | fbi->fix.smem_start = 0; |
1255 | fbi->fix.smem_len = 0; | 1280 | fbi->fix.smem_len = 0; |
1281 | mutex_unlock(&fbi->mm_lock); | ||
1256 | return 0; | 1282 | return 0; |
1257 | } | 1283 | } |
1258 | 1284 | ||
@@ -1360,11 +1386,11 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) | |||
1360 | init_completion(&mx3fbi->flip_cmpl); | 1386 | init_completion(&mx3fbi->flip_cmpl); |
1361 | disable_irq(ichan->eof_irq); | 1387 | disable_irq(ichan->eof_irq); |
1362 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); | 1388 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); |
1363 | ret = mx3fb_set_par(fbi); | 1389 | ret = __set_par(fbi, false); |
1364 | if (ret < 0) | 1390 | if (ret < 0) |
1365 | goto esetpar; | 1391 | goto esetpar; |
1366 | 1392 | ||
1367 | mx3fb_blank(FB_BLANK_UNBLANK, fbi); | 1393 | __blank(FB_BLANK_UNBLANK, fbi); |
1368 | 1394 | ||
1369 | dev_info(dev, "registered, using mode %s\n", fb_mode); | 1395 | dev_info(dev, "registered, using mode %s\n", fb_mode); |
1370 | 1396 | ||
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig index 44408850e2eb..551e3e9c4cbe 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/omap/Kconfig | |||
@@ -7,6 +7,69 @@ config FB_OMAP | |||
7 | help | 7 | help |
8 | Frame buffer driver for OMAP based boards. | 8 | Frame buffer driver for OMAP based boards. |
9 | 9 | ||
10 | config FB_OMAP_LCD_VGA | ||
11 | bool "Use LCD in VGA mode" | ||
12 | depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP | ||
13 | |||
14 | choice | ||
15 | depends on FB_OMAP && MACH_OVERO | ||
16 | prompt "Screen resolution" | ||
17 | default FB_OMAP_079M3R | ||
18 | help | ||
19 | Selected desired screen resolution | ||
20 | |||
21 | config FB_OMAP_031M3R | ||
22 | boolean "640 x 480 @ 60 Hz Reduced blanking" | ||
23 | |||
24 | config FB_OMAP_048M3R | ||
25 | boolean "800 x 600 @ 60 Hz Reduced blanking" | ||
26 | |||
27 | config FB_OMAP_079M3R | ||
28 | boolean "1024 x 768 @ 60 Hz Reduced blanking" | ||
29 | |||
30 | config FB_OMAP_092M9R | ||
31 | boolean "1280 x 720 @ 60 Hz Reduced blanking" | ||
32 | |||
33 | endchoice | ||
34 | |||
35 | config FB_OMAP_LCDC_EXTERNAL | ||
36 | bool "External LCD controller support" | ||
37 | depends on FB_OMAP | ||
38 | help | ||
39 | Say Y here, if you want to have support for boards with an | ||
40 | external LCD controller connected to the SoSSI/RFBI interface. | ||
41 | |||
42 | config FB_OMAP_LCDC_HWA742 | ||
43 | bool "Epson HWA742 LCD controller support" | ||
44 | depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL | ||
45 | help | ||
46 | Say Y here if you want to have support for the external | ||
47 | Epson HWA742 LCD controller. | ||
48 | |||
49 | config FB_OMAP_LCDC_BLIZZARD | ||
50 | bool "Epson Blizzard LCD controller support" | ||
51 | depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL | ||
52 | help | ||
53 | Say Y here if you want to have support for the external | ||
54 | Epson Blizzard LCD controller. | ||
55 | |||
56 | config FB_OMAP_MANUAL_UPDATE | ||
57 | bool "Default to manual update mode" | ||
58 | depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL | ||
59 | help | ||
60 | Say Y here, if your user-space applications are capable of | ||
61 | notifying the frame buffer driver when a change has occured in | ||
62 | the frame buffer content and thus a reload of the image data to | ||
63 | the external frame buffer is required. If unsure, say N. | ||
64 | |||
65 | config FB_OMAP_LCD_MIPID | ||
66 | bool "MIPI DBI-C/DCS compatible LCD support" | ||
67 | depends on FB_OMAP && SPI_MASTER | ||
68 | help | ||
69 | Say Y here if you want to have support for LCDs compatible with | ||
70 | the Mobile Industry Processor Interface DBI-C/DCS | ||
71 | specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3) | ||
72 | |||
10 | config FB_OMAP_BOOTLOADER_INIT | 73 | config FB_OMAP_BOOTLOADER_INIT |
11 | bool "Check bootloader initialization" | 74 | bool "Check bootloader initialization" |
12 | depends on FB_OMAP | 75 | depends on FB_OMAP |
@@ -36,23 +99,4 @@ config FB_OMAP_DMA_TUNE | |||
36 | answer yes. Answer no if you have a dedicated video | 99 | answer yes. Answer no if you have a dedicated video |
37 | memory, or don't use any of the accelerated features. | 100 | memory, or don't use any of the accelerated features. |
38 | 101 | ||
39 | config FB_OMAP_LCDC_EXTERNAL | ||
40 | bool "External LCD controller support" | ||
41 | depends on FB_OMAP | ||
42 | help | ||
43 | Say Y here, if you want to have support for boards with an | ||
44 | external LCD controller connected to the SoSSI/RFBI interface. | ||
45 | |||
46 | config FB_OMAP_LCDC_HWA742 | ||
47 | bool "Epson HWA742 LCD controller support" | ||
48 | depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL | ||
49 | help | ||
50 | Say Y here if you want to have support for the external | ||
51 | Epson HWA742 LCD controller. | ||
52 | 102 | ||
53 | config FB_OMAP_LCDC_BLIZZARD | ||
54 | bool "Epson Blizzard LCD controller support" | ||
55 | depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL | ||
56 | help | ||
57 | Say Y here if you want to have support for the external | ||
58 | Epson Blizzard LCD controller. | ||
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile index ed13889c1162..b63b198d1f03 100644 --- a/drivers/video/omap/Makefile +++ b/drivers/video/omap/Makefile | |||
@@ -8,6 +8,7 @@ objs-yy := omapfb_main.o | |||
8 | 8 | ||
9 | objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o | 9 | objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o |
10 | objs-y$(CONFIG_ARCH_OMAP2) += dispc.o | 10 | objs-y$(CONFIG_ARCH_OMAP2) += dispc.o |
11 | objs-y$(CONFIG_ARCH_OMAP3) += dispc.o | ||
11 | 12 | ||
12 | objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o | 13 | objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o |
13 | objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o | 14 | objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o |
@@ -15,6 +16,7 @@ objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o | |||
15 | objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o | 16 | objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o |
16 | objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o | 17 | objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o |
17 | 18 | ||
19 | objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o | ||
18 | objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o | 20 | objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o |
19 | objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o | 21 | objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o |
20 | objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o | 22 | objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o |
@@ -24,5 +26,15 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o | |||
24 | objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o | 26 | objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o |
25 | objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o | 27 | objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o |
26 | 28 | ||
29 | objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o | ||
30 | objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o | ||
31 | objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o | ||
32 | objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o | ||
33 | objs-y$(CONFIG_MACH_OMAP2EVM) += lcd_omap2evm.o | ||
34 | objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o | ||
35 | objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o | ||
36 | objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o | ||
37 | objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o | ||
38 | |||
27 | omapfb-objs := $(objs-yy) | 39 | omapfb-objs := $(objs-yy) |
28 | 40 | ||
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c index 9dfcf39d3367..70dadf9d2334 100644 --- a/drivers/video/omap/blizzard.c +++ b/drivers/video/omap/blizzard.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #define BLIZZARD_CLK_SRC 0x0e | 44 | #define BLIZZARD_CLK_SRC 0x0e |
45 | #define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 | 45 | #define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 |
46 | #define BLIZZARD_MEM_BANK0_STATUS 0x14 | 46 | #define BLIZZARD_MEM_BANK0_STATUS 0x14 |
47 | #define BLIZZARD_PANEL_CONFIGURATION 0x28 | ||
47 | #define BLIZZARD_HDISP 0x2a | 48 | #define BLIZZARD_HDISP 0x2a |
48 | #define BLIZZARD_HNDP 0x2c | 49 | #define BLIZZARD_HNDP 0x2c |
49 | #define BLIZZARD_VDISP0 0x2e | 50 | #define BLIZZARD_VDISP0 0x2e |
@@ -92,7 +93,7 @@ struct blizzard_reg_list { | |||
92 | }; | 93 | }; |
93 | 94 | ||
94 | /* These need to be saved / restored separately from the rest. */ | 95 | /* These need to be saved / restored separately from the rest. */ |
95 | static struct blizzard_reg_list blizzard_pll_regs[] = { | 96 | static const struct blizzard_reg_list blizzard_pll_regs[] = { |
96 | { | 97 | { |
97 | .start = 0x04, /* Don't save PLL ctrl (0x0C) */ | 98 | .start = 0x04, /* Don't save PLL ctrl (0x0C) */ |
98 | .end = 0x0a, | 99 | .end = 0x0a, |
@@ -103,7 +104,7 @@ static struct blizzard_reg_list blizzard_pll_regs[] = { | |||
103 | }, | 104 | }, |
104 | }; | 105 | }; |
105 | 106 | ||
106 | static struct blizzard_reg_list blizzard_gen_regs[] = { | 107 | static const struct blizzard_reg_list blizzard_gen_regs[] = { |
107 | { | 108 | { |
108 | .start = 0x18, /* SDRAM control */ | 109 | .start = 0x18, /* SDRAM control */ |
109 | .end = 0x20, | 110 | .end = 0x20, |
@@ -162,6 +163,10 @@ struct blizzard_struct { | |||
162 | int vid_scaled; | 163 | int vid_scaled; |
163 | int last_color_mode; | 164 | int last_color_mode; |
164 | int zoom_on; | 165 | int zoom_on; |
166 | int zoom_area_gx1; | ||
167 | int zoom_area_gx2; | ||
168 | int zoom_area_gy1; | ||
169 | int zoom_area_gy2; | ||
165 | int screen_width; | 170 | int screen_width; |
166 | int screen_height; | 171 | int screen_height; |
167 | unsigned te_connected:1; | 172 | unsigned te_connected:1; |
@@ -186,7 +191,7 @@ struct blizzard_struct { | |||
186 | 191 | ||
187 | struct omapfb_device *fbdev; | 192 | struct omapfb_device *fbdev; |
188 | struct lcd_ctrl_extif *extif; | 193 | struct lcd_ctrl_extif *extif; |
189 | struct lcd_ctrl *int_ctrl; | 194 | const struct lcd_ctrl *int_ctrl; |
190 | 195 | ||
191 | void (*power_up)(struct device *dev); | 196 | void (*power_up)(struct device *dev); |
192 | void (*power_down)(struct device *dev); | 197 | void (*power_down)(struct device *dev); |
@@ -513,6 +518,13 @@ static int do_full_screen_update(struct blizzard_request *req) | |||
513 | return REQ_PENDING; | 518 | return REQ_PENDING; |
514 | } | 519 | } |
515 | 520 | ||
521 | static int check_1d_intersect(int a1, int a2, int b1, int b2) | ||
522 | { | ||
523 | if (a2 <= b1 || b2 <= a1) | ||
524 | return 0; | ||
525 | return 1; | ||
526 | } | ||
527 | |||
516 | /* Setup all planes with an overlapping area with the update window. */ | 528 | /* Setup all planes with an overlapping area with the update window. */ |
517 | static int do_partial_update(struct blizzard_request *req, int plane, | 529 | static int do_partial_update(struct blizzard_request *req, int plane, |
518 | int x, int y, int w, int h, | 530 | int x, int y, int w, int h, |
@@ -525,6 +537,7 @@ static int do_partial_update(struct blizzard_request *req, int plane, | |||
525 | int color_mode; | 537 | int color_mode; |
526 | int flags; | 538 | int flags; |
527 | int zoom_off; | 539 | int zoom_off; |
540 | int have_zoom_for_this_update = 0; | ||
528 | 541 | ||
529 | /* Global coordinates, relative to pixel 0,0 of the LCD */ | 542 | /* Global coordinates, relative to pixel 0,0 of the LCD */ |
530 | gx1 = x + blizzard.plane[plane].pos_x; | 543 | gx1 = x + blizzard.plane[plane].pos_x; |
@@ -544,10 +557,6 @@ static int do_partial_update(struct blizzard_request *req, int plane, | |||
544 | gx2_out = gx1_out + w_out; | 557 | gx2_out = gx1_out + w_out; |
545 | gy2_out = gy1_out + h_out; | 558 | gy2_out = gy1_out + h_out; |
546 | } | 559 | } |
547 | zoom_off = blizzard.zoom_on && gx1 == 0 && gy1 == 0 && | ||
548 | w == blizzard.screen_width && h == blizzard.screen_height; | ||
549 | blizzard.zoom_on = (!zoom_off && blizzard.zoom_on) || | ||
550 | (w < w_out || h < h_out); | ||
551 | 560 | ||
552 | for (i = 0; i < OMAPFB_PLANE_NUM; i++) { | 561 | for (i = 0; i < OMAPFB_PLANE_NUM; i++) { |
553 | struct plane_info *p = &blizzard.plane[i]; | 562 | struct plane_info *p = &blizzard.plane[i]; |
@@ -653,8 +662,49 @@ static int do_partial_update(struct blizzard_request *req, int plane, | |||
653 | else | 662 | else |
654 | disable_tearsync(); | 663 | disable_tearsync(); |
655 | 664 | ||
665 | if ((gx2_out - gx1_out) != (gx2 - gx1) || | ||
666 | (gy2_out - gy1_out) != (gy2 - gy1)) | ||
667 | have_zoom_for_this_update = 1; | ||
668 | |||
669 | /* 'background' type of screen update (as opposed to 'destructive') | ||
670 | can be used to disable scaling if scaling is active */ | ||
671 | zoom_off = blizzard.zoom_on && !have_zoom_for_this_update && | ||
672 | (gx1_out == 0) && (gx2_out == blizzard.screen_width) && | ||
673 | (gy1_out == 0) && (gy2_out == blizzard.screen_height) && | ||
674 | (gx1 == 0) && (gy1 == 0); | ||
675 | |||
676 | if (blizzard.zoom_on && !have_zoom_for_this_update && !zoom_off && | ||
677 | check_1d_intersect(blizzard.zoom_area_gx1, blizzard.zoom_area_gx2, | ||
678 | gx1_out, gx2_out) && | ||
679 | check_1d_intersect(blizzard.zoom_area_gy1, blizzard.zoom_area_gy2, | ||
680 | gy1_out, gy2_out)) { | ||
681 | /* Previous screen update was using scaling, current update | ||
682 | * is not using it. Additionally, current screen update is | ||
683 | * going to overlap with the scaled area. Scaling needs to be | ||
684 | * disabled in order to avoid 'magnifying glass' effect. | ||
685 | * Dummy setup of background window can be used for this. | ||
686 | */ | ||
687 | set_window_regs(0, 0, blizzard.screen_width, | ||
688 | blizzard.screen_height, | ||
689 | 0, 0, blizzard.screen_width, | ||
690 | blizzard.screen_height, | ||
691 | BLIZZARD_COLOR_RGB565, 1, flags); | ||
692 | blizzard.zoom_on = 0; | ||
693 | } | ||
694 | |||
695 | /* remember scaling settings if we have scaled update */ | ||
696 | if (have_zoom_for_this_update) { | ||
697 | blizzard.zoom_on = 1; | ||
698 | blizzard.zoom_area_gx1 = gx1_out; | ||
699 | blizzard.zoom_area_gx2 = gx2_out; | ||
700 | blizzard.zoom_area_gy1 = gy1_out; | ||
701 | blizzard.zoom_area_gy2 = gy2_out; | ||
702 | } | ||
703 | |||
656 | set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out, | 704 | set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out, |
657 | color_mode, zoom_off, flags); | 705 | color_mode, zoom_off, flags); |
706 | if (zoom_off) | ||
707 | blizzard.zoom_on = 0; | ||
658 | 708 | ||
659 | blizzard.extif->set_bits_per_cycle(16); | 709 | blizzard.extif->set_bits_per_cycle(16); |
660 | /* set_window_regs has left the register index at the right | 710 | /* set_window_regs has left the register index at the right |
@@ -908,6 +958,35 @@ static int blizzard_set_scale(int plane, int orig_w, int orig_h, | |||
908 | return 0; | 958 | return 0; |
909 | } | 959 | } |
910 | 960 | ||
961 | static int blizzard_set_rotate(int angle) | ||
962 | { | ||
963 | u32 l; | ||
964 | |||
965 | l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION); | ||
966 | l &= ~0x03; | ||
967 | |||
968 | switch (angle) { | ||
969 | case 0: | ||
970 | l = l | 0x00; | ||
971 | break; | ||
972 | case 90: | ||
973 | l = l | 0x03; | ||
974 | break; | ||
975 | case 180: | ||
976 | l = l | 0x02; | ||
977 | break; | ||
978 | case 270: | ||
979 | l = l | 0x01; | ||
980 | break; | ||
981 | default: | ||
982 | return -EINVAL; | ||
983 | } | ||
984 | |||
985 | blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l); | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | |||
911 | static int blizzard_enable_plane(int plane, int enable) | 990 | static int blizzard_enable_plane(int plane, int enable) |
912 | { | 991 | { |
913 | if (enable) | 992 | if (enable) |
@@ -1285,14 +1364,15 @@ static void blizzard_get_caps(int plane, struct omapfb_caps *caps) | |||
1285 | caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE | | 1364 | caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE | |
1286 | OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE | | 1365 | OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE | |
1287 | OMAPFB_CAPS_WINDOW_SCALE | | 1366 | OMAPFB_CAPS_WINDOW_SCALE | |
1288 | OMAPFB_CAPS_WINDOW_OVERLAY; | 1367 | OMAPFB_CAPS_WINDOW_OVERLAY | |
1368 | OMAPFB_CAPS_WINDOW_ROTATE; | ||
1289 | if (blizzard.te_connected) | 1369 | if (blizzard.te_connected) |
1290 | caps->ctrl |= OMAPFB_CAPS_TEARSYNC; | 1370 | caps->ctrl |= OMAPFB_CAPS_TEARSYNC; |
1291 | caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) | | 1371 | caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) | |
1292 | (1 << OMAPFB_COLOR_YUV420); | 1372 | (1 << OMAPFB_COLOR_YUV420); |
1293 | } | 1373 | } |
1294 | 1374 | ||
1295 | static void _save_regs(struct blizzard_reg_list *list, int cnt) | 1375 | static void _save_regs(const struct blizzard_reg_list *list, int cnt) |
1296 | { | 1376 | { |
1297 | int i; | 1377 | int i; |
1298 | 1378 | ||
@@ -1303,7 +1383,7 @@ static void _save_regs(struct blizzard_reg_list *list, int cnt) | |||
1303 | } | 1383 | } |
1304 | } | 1384 | } |
1305 | 1385 | ||
1306 | static void _restore_regs(struct blizzard_reg_list *list, int cnt) | 1386 | static void _restore_regs(const struct blizzard_reg_list *list, int cnt) |
1307 | { | 1387 | { |
1308 | int i; | 1388 | int i; |
1309 | 1389 | ||
@@ -1560,6 +1640,7 @@ struct lcd_ctrl blizzard_ctrl = { | |||
1560 | .setup_plane = blizzard_setup_plane, | 1640 | .setup_plane = blizzard_setup_plane, |
1561 | .set_scale = blizzard_set_scale, | 1641 | .set_scale = blizzard_set_scale, |
1562 | .enable_plane = blizzard_enable_plane, | 1642 | .enable_plane = blizzard_enable_plane, |
1643 | .set_rotate = blizzard_set_rotate, | ||
1563 | .update_window = blizzard_update_window_async, | 1644 | .update_window = blizzard_update_window_async, |
1564 | .sync = blizzard_sync, | 1645 | .sync = blizzard_sync, |
1565 | .suspend = blizzard_suspend, | 1646 | .suspend = blizzard_suspend, |
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index 148cbcc39602..f16e42154229 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c | |||
@@ -155,6 +155,8 @@ struct resmap { | |||
155 | unsigned long *map; | 155 | unsigned long *map; |
156 | }; | 156 | }; |
157 | 157 | ||
158 | #define MAX_IRQ_HANDLERS 4 | ||
159 | |||
158 | static struct { | 160 | static struct { |
159 | void __iomem *base; | 161 | void __iomem *base; |
160 | 162 | ||
@@ -167,9 +169,11 @@ static struct { | |||
167 | 169 | ||
168 | int ext_mode; | 170 | int ext_mode; |
169 | 171 | ||
170 | unsigned long enabled_irqs; | 172 | struct { |
171 | void (*irq_callback)(void *); | 173 | u32 irq_mask; |
172 | void *irq_callback_data; | 174 | void (*callback)(void *); |
175 | void *data; | ||
176 | } irq_handlers[MAX_IRQ_HANDLERS]; | ||
173 | struct completion frame_done; | 177 | struct completion frame_done; |
174 | 178 | ||
175 | int fir_hinc[OMAPFB_PLANE_NUM]; | 179 | int fir_hinc[OMAPFB_PLANE_NUM]; |
@@ -212,9 +216,9 @@ static void enable_rfbi_mode(int enable) | |||
212 | dispc_write_reg(DISPC_CONTROL, l); | 216 | dispc_write_reg(DISPC_CONTROL, l); |
213 | 217 | ||
214 | /* Set bypass mode in RFBI module */ | 218 | /* Set bypass mode in RFBI module */ |
215 | l = __raw_readl(IO_ADDRESS(RFBI_CONTROL)); | 219 | l = __raw_readl(OMAP2_IO_ADDRESS(RFBI_CONTROL)); |
216 | l |= enable ? 0 : (1 << 1); | 220 | l |= enable ? 0 : (1 << 1); |
217 | __raw_writel(l, IO_ADDRESS(RFBI_CONTROL)); | 221 | __raw_writel(l, OMAP2_IO_ADDRESS(RFBI_CONTROL)); |
218 | } | 222 | } |
219 | 223 | ||
220 | static void set_lcd_data_lines(int data_lines) | 224 | static void set_lcd_data_lines(int data_lines) |
@@ -286,7 +290,7 @@ static void setup_plane_fifo(int plane, int ext_mode) | |||
286 | BUG_ON(plane > 2); | 290 | BUG_ON(plane > 2); |
287 | 291 | ||
288 | l = dispc_read_reg(fsz_reg[plane]); | 292 | l = dispc_read_reg(fsz_reg[plane]); |
289 | l &= FLD_MASK(0, 9); | 293 | l &= FLD_MASK(0, 11); |
290 | if (ext_mode) { | 294 | if (ext_mode) { |
291 | low = l * 3 / 4; | 295 | low = l * 3 / 4; |
292 | high = l; | 296 | high = l; |
@@ -294,7 +298,7 @@ static void setup_plane_fifo(int plane, int ext_mode) | |||
294 | low = l / 4; | 298 | low = l / 4; |
295 | high = l * 3 / 4; | 299 | high = l * 3 / 4; |
296 | } | 300 | } |
297 | MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 9) | FLD_MASK(0, 9), | 301 | MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 12) | FLD_MASK(0, 12), |
298 | (high << 16) | low); | 302 | (high << 16) | low); |
299 | } | 303 | } |
300 | 304 | ||
@@ -809,57 +813,74 @@ static void set_lcd_timings(void) | |||
809 | panel->pixel_clock = fck / lck_div / pck_div / 1000; | 813 | panel->pixel_clock = fck / lck_div / pck_div / 1000; |
810 | } | 814 | } |
811 | 815 | ||
812 | int omap_dispc_request_irq(void (*callback)(void *data), void *data) | 816 | static void recalc_irq_mask(void) |
813 | { | 817 | { |
814 | int r = 0; | 818 | int i; |
819 | unsigned long irq_mask = DISPC_IRQ_MASK_ERROR; | ||
815 | 820 | ||
816 | BUG_ON(callback == NULL); | 821 | for (i = 0; i < MAX_IRQ_HANDLERS; i++) { |
822 | if (!dispc.irq_handlers[i].callback) | ||
823 | continue; | ||
817 | 824 | ||
818 | if (dispc.irq_callback) | 825 | irq_mask |= dispc.irq_handlers[i].irq_mask; |
819 | r = -EBUSY; | ||
820 | else { | ||
821 | dispc.irq_callback = callback; | ||
822 | dispc.irq_callback_data = data; | ||
823 | } | 826 | } |
824 | 827 | ||
825 | return r; | ||
826 | } | ||
827 | EXPORT_SYMBOL(omap_dispc_request_irq); | ||
828 | |||
829 | void omap_dispc_enable_irqs(int irq_mask) | ||
830 | { | ||
831 | enable_lcd_clocks(1); | 828 | enable_lcd_clocks(1); |
832 | dispc.enabled_irqs = irq_mask; | ||
833 | irq_mask |= DISPC_IRQ_MASK_ERROR; | ||
834 | MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask); | 829 | MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask); |
835 | enable_lcd_clocks(0); | 830 | enable_lcd_clocks(0); |
836 | } | 831 | } |
837 | EXPORT_SYMBOL(omap_dispc_enable_irqs); | ||
838 | 832 | ||
839 | void omap_dispc_disable_irqs(int irq_mask) | 833 | int omap_dispc_request_irq(unsigned long irq_mask, void (*callback)(void *data), |
834 | void *data) | ||
840 | { | 835 | { |
841 | enable_lcd_clocks(1); | 836 | int i; |
842 | dispc.enabled_irqs &= ~irq_mask; | 837 | |
843 | irq_mask &= ~DISPC_IRQ_MASK_ERROR; | 838 | BUG_ON(callback == NULL); |
844 | MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask); | 839 | |
845 | enable_lcd_clocks(0); | 840 | for (i = 0; i < MAX_IRQ_HANDLERS; i++) { |
841 | if (dispc.irq_handlers[i].callback) | ||
842 | continue; | ||
843 | |||
844 | dispc.irq_handlers[i].irq_mask = irq_mask; | ||
845 | dispc.irq_handlers[i].callback = callback; | ||
846 | dispc.irq_handlers[i].data = data; | ||
847 | recalc_irq_mask(); | ||
848 | |||
849 | return 0; | ||
850 | } | ||
851 | |||
852 | return -EBUSY; | ||
846 | } | 853 | } |
847 | EXPORT_SYMBOL(omap_dispc_disable_irqs); | 854 | EXPORT_SYMBOL(omap_dispc_request_irq); |
848 | 855 | ||
849 | void omap_dispc_free_irq(void) | 856 | void omap_dispc_free_irq(unsigned long irq_mask, void (*callback)(void *data), |
857 | void *data) | ||
850 | { | 858 | { |
851 | enable_lcd_clocks(1); | 859 | int i; |
852 | omap_dispc_disable_irqs(DISPC_IRQ_MASK_ALL); | 860 | |
853 | dispc.irq_callback = NULL; | 861 | for (i = 0; i < MAX_IRQ_HANDLERS; i++) { |
854 | dispc.irq_callback_data = NULL; | 862 | if (dispc.irq_handlers[i].callback == callback && |
855 | enable_lcd_clocks(0); | 863 | dispc.irq_handlers[i].data == data) { |
864 | dispc.irq_handlers[i].irq_mask = 0; | ||
865 | dispc.irq_handlers[i].callback = NULL; | ||
866 | dispc.irq_handlers[i].data = NULL; | ||
867 | recalc_irq_mask(); | ||
868 | return; | ||
869 | } | ||
870 | } | ||
871 | |||
872 | BUG(); | ||
856 | } | 873 | } |
857 | EXPORT_SYMBOL(omap_dispc_free_irq); | 874 | EXPORT_SYMBOL(omap_dispc_free_irq); |
858 | 875 | ||
859 | static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) | 876 | static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) |
860 | { | 877 | { |
861 | u32 stat = dispc_read_reg(DISPC_IRQSTATUS); | 878 | u32 stat; |
879 | int i = 0; | ||
880 | |||
881 | enable_lcd_clocks(1); | ||
862 | 882 | ||
883 | stat = dispc_read_reg(DISPC_IRQSTATUS); | ||
863 | if (stat & DISPC_IRQ_FRAMEMASK) | 884 | if (stat & DISPC_IRQ_FRAMEMASK) |
864 | complete(&dispc.frame_done); | 885 | complete(&dispc.frame_done); |
865 | 886 | ||
@@ -870,11 +891,17 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) | |||
870 | } | 891 | } |
871 | } | 892 | } |
872 | 893 | ||
873 | if ((stat & dispc.enabled_irqs) && dispc.irq_callback) | 894 | for (i = 0; i < MAX_IRQ_HANDLERS; i++) { |
874 | dispc.irq_callback(dispc.irq_callback_data); | 895 | if (unlikely(dispc.irq_handlers[i].callback && |
896 | (stat & dispc.irq_handlers[i].irq_mask))) | ||
897 | dispc.irq_handlers[i].callback( | ||
898 | dispc.irq_handlers[i].data); | ||
899 | } | ||
875 | 900 | ||
876 | dispc_write_reg(DISPC_IRQSTATUS, stat); | 901 | dispc_write_reg(DISPC_IRQSTATUS, stat); |
877 | 902 | ||
903 | enable_lcd_clocks(0); | ||
904 | |||
878 | return IRQ_HANDLED; | 905 | return IRQ_HANDLED; |
879 | } | 906 | } |
880 | 907 | ||
@@ -913,18 +940,13 @@ static void put_dss_clocks(void) | |||
913 | 940 | ||
914 | static void enable_lcd_clocks(int enable) | 941 | static void enable_lcd_clocks(int enable) |
915 | { | 942 | { |
916 | if (enable) | 943 | if (enable) { |
944 | clk_enable(dispc.dss_ick); | ||
917 | clk_enable(dispc.dss1_fck); | 945 | clk_enable(dispc.dss1_fck); |
918 | else | 946 | } else { |
919 | clk_disable(dispc.dss1_fck); | 947 | clk_disable(dispc.dss1_fck); |
920 | } | ||
921 | |||
922 | static void enable_interface_clocks(int enable) | ||
923 | { | ||
924 | if (enable) | ||
925 | clk_enable(dispc.dss_ick); | ||
926 | else | ||
927 | clk_disable(dispc.dss_ick); | 948 | clk_disable(dispc.dss_ick); |
949 | } | ||
928 | } | 950 | } |
929 | 951 | ||
930 | static void enable_digit_clocks(int enable) | 952 | static void enable_digit_clocks(int enable) |
@@ -1013,7 +1035,7 @@ static void mmap_user_close(struct vm_area_struct *vma) | |||
1013 | atomic_dec(&dispc.map_count[plane]); | 1035 | atomic_dec(&dispc.map_count[plane]); |
1014 | } | 1036 | } |
1015 | 1037 | ||
1016 | static struct vm_operations_struct mmap_user_ops = { | 1038 | static const struct vm_operations_struct mmap_user_ops = { |
1017 | .open = mmap_user_open, | 1039 | .open = mmap_user_open, |
1018 | .close = mmap_user_close, | 1040 | .close = mmap_user_close, |
1019 | }; | 1041 | }; |
@@ -1365,7 +1387,6 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
1365 | if ((r = get_dss_clocks()) < 0) | 1387 | if ((r = get_dss_clocks()) < 0) |
1366 | goto fail0; | 1388 | goto fail0; |
1367 | 1389 | ||
1368 | enable_interface_clocks(1); | ||
1369 | enable_lcd_clocks(1); | 1390 | enable_lcd_clocks(1); |
1370 | 1391 | ||
1371 | #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT | 1392 | #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT |
@@ -1396,10 +1417,10 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
1396 | enable_digit_clocks(0); | 1417 | enable_digit_clocks(0); |
1397 | } | 1418 | } |
1398 | 1419 | ||
1399 | /* Enable smart idle and autoidle */ | 1420 | /* Enable smart standby/idle, autoidle and wakeup */ |
1400 | l = dispc_read_reg(DISPC_CONTROL); | 1421 | l = dispc_read_reg(DISPC_SYSCONFIG); |
1401 | l &= ~((3 << 12) | (3 << 3)); | 1422 | l &= ~((3 << 12) | (3 << 3)); |
1402 | l |= (2 << 12) | (2 << 3) | (1 << 0); | 1423 | l |= (2 << 12) | (2 << 3) | (1 << 2) | (1 << 0); |
1403 | dispc_write_reg(DISPC_SYSCONFIG, l); | 1424 | dispc_write_reg(DISPC_SYSCONFIG, l); |
1404 | omap_writel(1 << 0, DSS_BASE + DSS_SYSCONFIG); | 1425 | omap_writel(1 << 0, DSS_BASE + DSS_SYSCONFIG); |
1405 | 1426 | ||
@@ -1409,10 +1430,9 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
1409 | dispc_write_reg(DISPC_CONFIG, l); | 1430 | dispc_write_reg(DISPC_CONFIG, l); |
1410 | 1431 | ||
1411 | l = dispc_read_reg(DISPC_IRQSTATUS); | 1432 | l = dispc_read_reg(DISPC_IRQSTATUS); |
1412 | dispc_write_reg(l, DISPC_IRQSTATUS); | 1433 | dispc_write_reg(DISPC_IRQSTATUS, l); |
1413 | 1434 | ||
1414 | /* Enable those that we handle always */ | 1435 | recalc_irq_mask(); |
1415 | omap_dispc_enable_irqs(DISPC_IRQ_FRAMEMASK); | ||
1416 | 1436 | ||
1417 | if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler, | 1437 | if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler, |
1418 | 0, MODULE_NAME, fbdev)) < 0) { | 1438 | 0, MODULE_NAME, fbdev)) < 0) { |
@@ -1421,7 +1441,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
1421 | } | 1441 | } |
1422 | 1442 | ||
1423 | /* L3 firewall setting: enable access to OCM RAM */ | 1443 | /* L3 firewall setting: enable access to OCM RAM */ |
1424 | __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0)); | 1444 | __raw_writel(0x402000b0, OMAP2_IO_ADDRESS(0x680050a0)); |
1425 | 1445 | ||
1426 | if ((r = alloc_palette_ram()) < 0) | 1446 | if ((r = alloc_palette_ram()) < 0) |
1427 | goto fail2; | 1447 | goto fail2; |
@@ -1469,7 +1489,6 @@ fail2: | |||
1469 | free_irq(INT_24XX_DSS_IRQ, fbdev); | 1489 | free_irq(INT_24XX_DSS_IRQ, fbdev); |
1470 | fail1: | 1490 | fail1: |
1471 | enable_lcd_clocks(0); | 1491 | enable_lcd_clocks(0); |
1472 | enable_interface_clocks(0); | ||
1473 | put_dss_clocks(); | 1492 | put_dss_clocks(); |
1474 | fail0: | 1493 | fail0: |
1475 | iounmap(dispc.base); | 1494 | iounmap(dispc.base); |
@@ -1487,7 +1506,6 @@ static void omap_dispc_cleanup(void) | |||
1487 | cleanup_fbmem(); | 1506 | cleanup_fbmem(); |
1488 | free_palette_ram(); | 1507 | free_palette_ram(); |
1489 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); | 1508 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); |
1490 | enable_interface_clocks(0); | ||
1491 | put_dss_clocks(); | 1509 | put_dss_clocks(); |
1492 | iounmap(dispc.base); | 1510 | iounmap(dispc.base); |
1493 | } | 1511 | } |
diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h index ef720a78f6d5..c15ea77f0604 100644 --- a/drivers/video/omap/dispc.h +++ b/drivers/video/omap/dispc.h | |||
@@ -37,9 +37,10 @@ extern void omap_dispc_set_lcd_size(int width, int height); | |||
37 | extern void omap_dispc_enable_lcd_out(int enable); | 37 | extern void omap_dispc_enable_lcd_out(int enable); |
38 | extern void omap_dispc_enable_digit_out(int enable); | 38 | extern void omap_dispc_enable_digit_out(int enable); |
39 | 39 | ||
40 | extern int omap_dispc_request_irq(void (*callback)(void *data), void *data); | 40 | extern int omap_dispc_request_irq(unsigned long irq_mask, |
41 | extern void omap_dispc_free_irq(void); | 41 | void (*callback)(void *data), void *data); |
42 | extern void omap_dispc_free_irq(unsigned long irq_mask, | ||
43 | void (*callback)(void *data), void *data); | ||
42 | 44 | ||
43 | extern const struct lcd_ctrl omap2_int_ctrl; | 45 | extern const struct lcd_ctrl omap2_int_ctrl; |
44 | |||
45 | #endif | 46 | #endif |
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c index 5d4f34887a22..ca51583ec98a 100644 --- a/drivers/video/omap/hwa742.c +++ b/drivers/video/omap/hwa742.c | |||
@@ -131,7 +131,7 @@ struct { | |||
131 | 131 | ||
132 | struct omapfb_device *fbdev; | 132 | struct omapfb_device *fbdev; |
133 | struct lcd_ctrl_extif *extif; | 133 | struct lcd_ctrl_extif *extif; |
134 | struct lcd_ctrl *int_ctrl; | 134 | const struct lcd_ctrl *int_ctrl; |
135 | 135 | ||
136 | struct clk *sys_ck; | 136 | struct clk *sys_ck; |
137 | } hwa742; | 137 | } hwa742; |
diff --git a/drivers/video/omap/lcd_2430sdp.c b/drivers/video/omap/lcd_2430sdp.c new file mode 100644 index 000000000000..393712b6f369 --- /dev/null +++ b/drivers/video/omap/lcd_2430sdp.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * LCD panel support for the TI 2430SDP board | ||
3 | * | ||
4 | * Copyright (C) 2007 MontaVista | ||
5 | * Author: Hunyue Yau <hyau@mvista.com> | ||
6 | * | ||
7 | * Derived from drivers/video/omap/lcd-apollon.c | ||
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 as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/i2c/twl4030.h> | ||
29 | |||
30 | #include <mach/mux.h> | ||
31 | #include <mach/omapfb.h> | ||
32 | #include <asm/mach-types.h> | ||
33 | |||
34 | #define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91 | ||
35 | #define SDP2430_LCD_PANEL_ENABLE_GPIO 154 | ||
36 | #define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 24 | ||
37 | #define SDP3430_LCD_PANEL_ENABLE_GPIO 28 | ||
38 | |||
39 | static unsigned backlight_gpio; | ||
40 | static unsigned enable_gpio; | ||
41 | |||
42 | #define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */ | ||
43 | #define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER | ||
44 | #define ENABLE_VAUX2_DEDICATED 0x09 | ||
45 | #define ENABLE_VAUX2_DEV_GRP 0x20 | ||
46 | #define ENABLE_VAUX3_DEDICATED 0x03 | ||
47 | #define ENABLE_VAUX3_DEV_GRP 0x20 | ||
48 | |||
49 | #define ENABLE_VPLL2_DEDICATED 0x05 | ||
50 | #define ENABLE_VPLL2_DEV_GRP 0xE0 | ||
51 | #define TWL4030_VPLL2_DEV_GRP 0x33 | ||
52 | #define TWL4030_VPLL2_DEDICATED 0x36 | ||
53 | |||
54 | #define t2_out(c, r, v) twl4030_i2c_write_u8(c, r, v) | ||
55 | |||
56 | |||
57 | static int sdp2430_panel_init(struct lcd_panel *panel, | ||
58 | struct omapfb_device *fbdev) | ||
59 | { | ||
60 | if (machine_is_omap_3430sdp()) { | ||
61 | enable_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO; | ||
62 | backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO; | ||
63 | } else { | ||
64 | enable_gpio = SDP2430_LCD_PANEL_ENABLE_GPIO; | ||
65 | backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO; | ||
66 | } | ||
67 | |||
68 | gpio_request(enable_gpio, "LCD enable"); /* LCD panel */ | ||
69 | gpio_request(backlight_gpio, "LCD bl"); /* LCD backlight */ | ||
70 | gpio_direction_output(enable_gpio, 0); | ||
71 | gpio_direction_output(backlight_gpio, 0); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static void sdp2430_panel_cleanup(struct lcd_panel *panel) | ||
77 | { | ||
78 | gpio_free(backlight_gpio); | ||
79 | gpio_free(enable_gpio); | ||
80 | } | ||
81 | |||
82 | static int sdp2430_panel_enable(struct lcd_panel *panel) | ||
83 | { | ||
84 | u8 ded_val, ded_reg; | ||
85 | u8 grp_val, grp_reg; | ||
86 | |||
87 | if (machine_is_omap_3430sdp()) { | ||
88 | ded_reg = TWL4030_VAUX3_DEDICATED; | ||
89 | ded_val = ENABLE_VAUX3_DEDICATED; | ||
90 | grp_reg = TWL4030_VAUX3_DEV_GRP; | ||
91 | grp_val = ENABLE_VAUX3_DEV_GRP; | ||
92 | |||
93 | if (omap_rev() > OMAP3430_REV_ES1_0) { | ||
94 | t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED, | ||
95 | TWL4030_VPLL2_DEDICATED); | ||
96 | t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP, | ||
97 | TWL4030_VPLL2_DEV_GRP); | ||
98 | } | ||
99 | } else { | ||
100 | ded_reg = TWL4030_VAUX2_DEDICATED; | ||
101 | ded_val = ENABLE_VAUX2_DEDICATED; | ||
102 | grp_reg = TWL4030_VAUX2_DEV_GRP; | ||
103 | grp_val = ENABLE_VAUX2_DEV_GRP; | ||
104 | } | ||
105 | |||
106 | gpio_set_value(enable_gpio, 1); | ||
107 | gpio_set_value(backlight_gpio, 1); | ||
108 | |||
109 | if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg)) | ||
110 | return -EIO; | ||
111 | if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg)) | ||
112 | return -EIO; | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static void sdp2430_panel_disable(struct lcd_panel *panel) | ||
118 | { | ||
119 | gpio_set_value(enable_gpio, 0); | ||
120 | gpio_set_value(backlight_gpio, 0); | ||
121 | if (omap_rev() > OMAP3430_REV_ES1_0) { | ||
122 | t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED); | ||
123 | t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP); | ||
124 | msleep(4); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel) | ||
129 | { | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | struct lcd_panel sdp2430_panel = { | ||
134 | .name = "sdp2430", | ||
135 | .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | | ||
136 | OMAP_LCDC_INV_HSYNC, | ||
137 | |||
138 | .bpp = 16, | ||
139 | .data_lines = 16, | ||
140 | .x_res = 240, | ||
141 | .y_res = 320, | ||
142 | .hsw = 3, /* hsync_len (4) - 1 */ | ||
143 | .hfp = 3, /* right_margin (4) - 1 */ | ||
144 | .hbp = 39, /* left_margin (40) - 1 */ | ||
145 | .vsw = 1, /* vsync_len (2) - 1 */ | ||
146 | .vfp = 2, /* lower_margin */ | ||
147 | .vbp = 7, /* upper_margin (8) - 1 */ | ||
148 | |||
149 | .pixel_clock = LCD_PIXCLOCK_MAX, | ||
150 | |||
151 | .init = sdp2430_panel_init, | ||
152 | .cleanup = sdp2430_panel_cleanup, | ||
153 | .enable = sdp2430_panel_enable, | ||
154 | .disable = sdp2430_panel_disable, | ||
155 | .get_caps = sdp2430_panel_get_caps, | ||
156 | }; | ||
157 | |||
158 | static int sdp2430_panel_probe(struct platform_device *pdev) | ||
159 | { | ||
160 | omapfb_register_panel(&sdp2430_panel); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int sdp2430_panel_remove(struct platform_device *pdev) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int sdp2430_panel_suspend(struct platform_device *pdev, | ||
170 | pm_message_t mesg) | ||
171 | { | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int sdp2430_panel_resume(struct platform_device *pdev) | ||
176 | { | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | struct platform_driver sdp2430_panel_driver = { | ||
181 | .probe = sdp2430_panel_probe, | ||
182 | .remove = sdp2430_panel_remove, | ||
183 | .suspend = sdp2430_panel_suspend, | ||
184 | .resume = sdp2430_panel_resume, | ||
185 | .driver = { | ||
186 | .name = "sdp2430_lcd", | ||
187 | .owner = THIS_MODULE, | ||
188 | }, | ||
189 | }; | ||
190 | |||
191 | static int __init sdp2430_panel_drv_init(void) | ||
192 | { | ||
193 | return platform_driver_register(&sdp2430_panel_driver); | ||
194 | } | ||
195 | |||
196 | static void __exit sdp2430_panel_drv_exit(void) | ||
197 | { | ||
198 | platform_driver_unregister(&sdp2430_panel_driver); | ||
199 | } | ||
200 | |||
201 | module_init(sdp2430_panel_drv_init); | ||
202 | module_exit(sdp2430_panel_drv_exit); | ||
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c new file mode 100644 index 000000000000..1f7439955e02 --- /dev/null +++ b/drivers/video/omap/lcd_ams_delta.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | * Based on drivers/video/omap/lcd_inn1510.c | ||
3 | * | ||
4 | * LCD panel support for the Amstrad E3 (Delta) videophone. | ||
5 | * | ||
6 | * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li> | ||
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/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/delay.h> | ||
27 | |||
28 | #include <mach/board-ams-delta.h> | ||
29 | #include <mach/hardware.h> | ||
30 | #include <mach/omapfb.h> | ||
31 | |||
32 | #define AMS_DELTA_DEFAULT_CONTRAST 112 | ||
33 | |||
34 | static int ams_delta_panel_init(struct lcd_panel *panel, | ||
35 | struct omapfb_device *fbdev) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static void ams_delta_panel_cleanup(struct lcd_panel *panel) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | static int ams_delta_panel_enable(struct lcd_panel *panel) | ||
45 | { | ||
46 | ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, | ||
47 | AMS_DELTA_LATCH2_LCD_NDISP); | ||
48 | ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, | ||
49 | AMS_DELTA_LATCH2_LCD_VBLEN); | ||
50 | |||
51 | omap_writeb(1, OMAP_PWL_CLK_ENABLE); | ||
52 | omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static void ams_delta_panel_disable(struct lcd_panel *panel) | ||
58 | { | ||
59 | ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 0); | ||
60 | ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, 0); | ||
61 | } | ||
62 | |||
63 | static unsigned long ams_delta_panel_get_caps(struct lcd_panel *panel) | ||
64 | { | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static struct lcd_panel ams_delta_panel = { | ||
69 | .name = "ams-delta", | ||
70 | .config = 0, | ||
71 | |||
72 | .bpp = 12, | ||
73 | .data_lines = 16, | ||
74 | .x_res = 480, | ||
75 | .y_res = 320, | ||
76 | .pixel_clock = 4687, | ||
77 | .hsw = 3, | ||
78 | .hfp = 1, | ||
79 | .hbp = 1, | ||
80 | .vsw = 1, | ||
81 | .vfp = 0, | ||
82 | .vbp = 0, | ||
83 | .pcd = 0, | ||
84 | .acb = 37, | ||
85 | |||
86 | .init = ams_delta_panel_init, | ||
87 | .cleanup = ams_delta_panel_cleanup, | ||
88 | .enable = ams_delta_panel_enable, | ||
89 | .disable = ams_delta_panel_disable, | ||
90 | .get_caps = ams_delta_panel_get_caps, | ||
91 | }; | ||
92 | |||
93 | static int ams_delta_panel_probe(struct platform_device *pdev) | ||
94 | { | ||
95 | omapfb_register_panel(&ams_delta_panel); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static int ams_delta_panel_remove(struct platform_device *pdev) | ||
100 | { | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int ams_delta_panel_suspend(struct platform_device *pdev, | ||
105 | pm_message_t mesg) | ||
106 | { | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int ams_delta_panel_resume(struct platform_device *pdev) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | struct platform_driver ams_delta_panel_driver = { | ||
116 | .probe = ams_delta_panel_probe, | ||
117 | .remove = ams_delta_panel_remove, | ||
118 | .suspend = ams_delta_panel_suspend, | ||
119 | .resume = ams_delta_panel_resume, | ||
120 | .driver = { | ||
121 | .name = "lcd_ams_delta", | ||
122 | .owner = THIS_MODULE, | ||
123 | }, | ||
124 | }; | ||
125 | |||
126 | static int ams_delta_panel_drv_init(void) | ||
127 | { | ||
128 | return platform_driver_register(&ams_delta_panel_driver); | ||
129 | } | ||
130 | |||
131 | static void ams_delta_panel_drv_cleanup(void) | ||
132 | { | ||
133 | platform_driver_unregister(&ams_delta_panel_driver); | ||
134 | } | ||
135 | |||
136 | module_init(ams_delta_panel_drv_init); | ||
137 | module_exit(ams_delta_panel_drv_cleanup); | ||
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c new file mode 100644 index 000000000000..626ae3a532ff --- /dev/null +++ b/drivers/video/omap/lcd_apollon.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * LCD panel support for the Samsung OMAP2 Apollon board | ||
3 | * | ||
4 | * Copyright (C) 2005,2006 Samsung Electronics | ||
5 | * Author: Kyungmin Park <kyungmin.park@samsung.com> | ||
6 | * | ||
7 | * Derived from drivers/video/omap/lcd-h4.c | ||
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 as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #include <mach/gpio.h> | ||
28 | #include <mach/mux.h> | ||
29 | #include <mach/omapfb.h> | ||
30 | |||
31 | /* #define USE_35INCH_LCD 1 */ | ||
32 | |||
33 | static int apollon_panel_init(struct lcd_panel *panel, | ||
34 | struct omapfb_device *fbdev) | ||
35 | { | ||
36 | /* configure LCD PWR_EN */ | ||
37 | omap_cfg_reg(M21_242X_GPIO11); | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static void apollon_panel_cleanup(struct lcd_panel *panel) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | static int apollon_panel_enable(struct lcd_panel *panel) | ||
46 | { | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static void apollon_panel_disable(struct lcd_panel *panel) | ||
51 | { | ||
52 | } | ||
53 | |||
54 | static unsigned long apollon_panel_get_caps(struct lcd_panel *panel) | ||
55 | { | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | struct lcd_panel apollon_panel = { | ||
60 | .name = "apollon", | ||
61 | .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | | ||
62 | OMAP_LCDC_INV_HSYNC, | ||
63 | |||
64 | .bpp = 16, | ||
65 | .data_lines = 18, | ||
66 | #ifdef USE_35INCH_LCD | ||
67 | .x_res = 240, | ||
68 | .y_res = 320, | ||
69 | .hsw = 2, | ||
70 | .hfp = 3, | ||
71 | .hbp = 9, | ||
72 | .vsw = 4, | ||
73 | .vfp = 3, | ||
74 | .vbp = 5, | ||
75 | #else | ||
76 | .x_res = 480, | ||
77 | .y_res = 272, | ||
78 | .hsw = 41, | ||
79 | .hfp = 2, | ||
80 | .hbp = 2, | ||
81 | .vsw = 10, | ||
82 | .vfp = 2, | ||
83 | .vbp = 2, | ||
84 | #endif | ||
85 | .pixel_clock = 6250, | ||
86 | |||
87 | .init = apollon_panel_init, | ||
88 | .cleanup = apollon_panel_cleanup, | ||
89 | .enable = apollon_panel_enable, | ||
90 | .disable = apollon_panel_disable, | ||
91 | .get_caps = apollon_panel_get_caps, | ||
92 | }; | ||
93 | |||
94 | static int apollon_panel_probe(struct platform_device *pdev) | ||
95 | { | ||
96 | omapfb_register_panel(&apollon_panel); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int apollon_panel_remove(struct platform_device *pdev) | ||
101 | { | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int apollon_panel_suspend(struct platform_device *pdev, | ||
106 | pm_message_t mesg) | ||
107 | { | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int apollon_panel_resume(struct platform_device *pdev) | ||
112 | { | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | struct platform_driver apollon_panel_driver = { | ||
117 | .probe = apollon_panel_probe, | ||
118 | .remove = apollon_panel_remove, | ||
119 | .suspend = apollon_panel_suspend, | ||
120 | .resume = apollon_panel_resume, | ||
121 | .driver = { | ||
122 | .name = "apollon_lcd", | ||
123 | .owner = THIS_MODULE, | ||
124 | }, | ||
125 | }; | ||
126 | |||
127 | static int __init apollon_panel_drv_init(void) | ||
128 | { | ||
129 | return platform_driver_register(&apollon_panel_driver); | ||
130 | } | ||
131 | |||
132 | static void __exit apollon_panel_drv_exit(void) | ||
133 | { | ||
134 | platform_driver_unregister(&apollon_panel_driver); | ||
135 | } | ||
136 | |||
137 | module_init(apollon_panel_drv_init); | ||
138 | module_exit(apollon_panel_drv_exit); | ||
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c index 2486237ebba5..417ae5efa8bb 100644 --- a/drivers/video/omap/lcd_h3.c +++ b/drivers/video/omap/lcd_h3.c | |||
@@ -124,12 +124,12 @@ struct platform_driver h3_panel_driver = { | |||
124 | }, | 124 | }, |
125 | }; | 125 | }; |
126 | 126 | ||
127 | static int h3_panel_drv_init(void) | 127 | static int __init h3_panel_drv_init(void) |
128 | { | 128 | { |
129 | return platform_driver_register(&h3_panel_driver); | 129 | return platform_driver_register(&h3_panel_driver); |
130 | } | 130 | } |
131 | 131 | ||
132 | static void h3_panel_drv_cleanup(void) | 132 | static void __exit h3_panel_drv_cleanup(void) |
133 | { | 133 | { |
134 | platform_driver_unregister(&h3_panel_driver); | 134 | platform_driver_unregister(&h3_panel_driver); |
135 | } | 135 | } |
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c index 6ff56430341b..0c398bda7601 100644 --- a/drivers/video/omap/lcd_h4.c +++ b/drivers/video/omap/lcd_h4.c | |||
@@ -102,12 +102,12 @@ static struct platform_driver h4_panel_driver = { | |||
102 | }, | 102 | }, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static int h4_panel_drv_init(void) | 105 | static int __init h4_panel_drv_init(void) |
106 | { | 106 | { |
107 | return platform_driver_register(&h4_panel_driver); | 107 | return platform_driver_register(&h4_panel_driver); |
108 | } | 108 | } |
109 | 109 | ||
110 | static void h4_panel_drv_cleanup(void) | 110 | static void __exit h4_panel_drv_cleanup(void) |
111 | { | 111 | { |
112 | platform_driver_unregister(&h4_panel_driver); | 112 | platform_driver_unregister(&h4_panel_driver); |
113 | } | 113 | } |
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c index 6953ed4b5820..cdbd8bb607be 100644 --- a/drivers/video/omap/lcd_inn1510.c +++ b/drivers/video/omap/lcd_inn1510.c | |||
@@ -109,12 +109,12 @@ struct platform_driver innovator1510_panel_driver = { | |||
109 | }, | 109 | }, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static int innovator1510_panel_drv_init(void) | 112 | static int __init innovator1510_panel_drv_init(void) |
113 | { | 113 | { |
114 | return platform_driver_register(&innovator1510_panel_driver); | 114 | return platform_driver_register(&innovator1510_panel_driver); |
115 | } | 115 | } |
116 | 116 | ||
117 | static void innovator1510_panel_drv_cleanup(void) | 117 | static void __exit innovator1510_panel_drv_cleanup(void) |
118 | { | 118 | { |
119 | platform_driver_unregister(&innovator1510_panel_driver); | 119 | platform_driver_unregister(&innovator1510_panel_driver); |
120 | } | 120 | } |
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c index 4c4f7ee6d733..268f7f808a4e 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/omap/lcd_inn1610.c | |||
@@ -133,12 +133,12 @@ struct platform_driver innovator1610_panel_driver = { | |||
133 | }, | 133 | }, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static int innovator1610_panel_drv_init(void) | 136 | static int __init innovator1610_panel_drv_init(void) |
137 | { | 137 | { |
138 | return platform_driver_register(&innovator1610_panel_driver); | 138 | return platform_driver_register(&innovator1610_panel_driver); |
139 | } | 139 | } |
140 | 140 | ||
141 | static void innovator1610_panel_drv_cleanup(void) | 141 | static void __exit innovator1610_panel_drv_cleanup(void) |
142 | { | 142 | { |
143 | platform_driver_unregister(&innovator1610_panel_driver); | 143 | platform_driver_unregister(&innovator1610_panel_driver); |
144 | } | 144 | } |
diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c new file mode 100644 index 000000000000..dbfe8974fb94 --- /dev/null +++ b/drivers/video/omap/lcd_ldp.c | |||
@@ -0,0 +1,200 @@ | |||
1 | /* | ||
2 | * LCD panel support for the TI LDP board | ||
3 | * | ||
4 | * Copyright (C) 2007 WindRiver | ||
5 | * Author: Stanley Miao <stanley.miao@windriver.com> | ||
6 | * | ||
7 | * Derived from drivers/video/omap/lcd-2430sdp.c | ||
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 as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/i2c/twl4030.h> | ||
28 | |||
29 | #include <mach/gpio.h> | ||
30 | #include <mach/mux.h> | ||
31 | #include <mach/omapfb.h> | ||
32 | #include <asm/mach-types.h> | ||
33 | |||
34 | #define LCD_PANEL_BACKLIGHT_GPIO (15 + OMAP_MAX_GPIO_LINES) | ||
35 | #define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES) | ||
36 | |||
37 | #define LCD_PANEL_RESET_GPIO 55 | ||
38 | #define LCD_PANEL_QVGA_GPIO 56 | ||
39 | |||
40 | #ifdef CONFIG_FB_OMAP_LCD_VGA | ||
41 | #define LCD_XRES 480 | ||
42 | #define LCD_YRES 640 | ||
43 | #define LCD_PIXCLOCK_MAX 41700 | ||
44 | #else | ||
45 | #define LCD_XRES 240 | ||
46 | #define LCD_YRES 320 | ||
47 | #define LCD_PIXCLOCK_MAX 185186 | ||
48 | #endif | ||
49 | |||
50 | #define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER | ||
51 | #define ENABLE_VAUX2_DEDICATED 0x09 | ||
52 | #define ENABLE_VAUX2_DEV_GRP 0x20 | ||
53 | #define ENABLE_VAUX3_DEDICATED 0x03 | ||
54 | #define ENABLE_VAUX3_DEV_GRP 0x20 | ||
55 | |||
56 | #define ENABLE_VPLL2_DEDICATED 0x05 | ||
57 | #define ENABLE_VPLL2_DEV_GRP 0xE0 | ||
58 | #define TWL4030_VPLL2_DEV_GRP 0x33 | ||
59 | #define TWL4030_VPLL2_DEDICATED 0x36 | ||
60 | |||
61 | #define t2_out(c, r, v) twl4030_i2c_write_u8(c, r, v) | ||
62 | |||
63 | |||
64 | static int ldp_panel_init(struct lcd_panel *panel, | ||
65 | struct omapfb_device *fbdev) | ||
66 | { | ||
67 | gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset"); | ||
68 | gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga"); | ||
69 | gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel"); | ||
70 | gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight"); | ||
71 | |||
72 | gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0); | ||
73 | gpio_direction_output(LCD_PANEL_RESET_GPIO, 0); | ||
74 | gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0); | ||
75 | gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0); | ||
76 | |||
77 | #ifdef CONFIG_FB_OMAP_LCD_VGA | ||
78 | gpio_set_value(LCD_PANEL_QVGA_GPIO, 0); | ||
79 | #else | ||
80 | gpio_set_value(LCD_PANEL_QVGA_GPIO, 1); | ||
81 | #endif | ||
82 | gpio_set_value(LCD_PANEL_RESET_GPIO, 1); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static void ldp_panel_cleanup(struct lcd_panel *panel) | ||
88 | { | ||
89 | gpio_free(LCD_PANEL_BACKLIGHT_GPIO); | ||
90 | gpio_free(LCD_PANEL_ENABLE_GPIO); | ||
91 | gpio_free(LCD_PANEL_QVGA_GPIO); | ||
92 | gpio_free(LCD_PANEL_RESET_GPIO); | ||
93 | } | ||
94 | |||
95 | static int ldp_panel_enable(struct lcd_panel *panel) | ||
96 | { | ||
97 | if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED, | ||
98 | TWL4030_VPLL2_DEDICATED)) | ||
99 | return -EIO; | ||
100 | if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP, | ||
101 | TWL4030_VPLL2_DEV_GRP)) | ||
102 | return -EIO; | ||
103 | |||
104 | gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1); | ||
105 | gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1); | ||
106 | |||
107 | if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED, | ||
108 | TWL4030_VAUX3_DEDICATED)) | ||
109 | return -EIO; | ||
110 | if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP, | ||
111 | TWL4030_VAUX3_DEV_GRP)) | ||
112 | return -EIO; | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static void ldp_panel_disable(struct lcd_panel *panel) | ||
118 | { | ||
119 | gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0); | ||
120 | gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0); | ||
121 | |||
122 | t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED); | ||
123 | t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP); | ||
124 | msleep(4); | ||
125 | } | ||
126 | |||
127 | static unsigned long ldp_panel_get_caps(struct lcd_panel *panel) | ||
128 | { | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | struct lcd_panel ldp_panel = { | ||
133 | .name = "ldp", | ||
134 | .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | | ||
135 | OMAP_LCDC_INV_HSYNC, | ||
136 | |||
137 | .bpp = 16, | ||
138 | .data_lines = 18, | ||
139 | .x_res = LCD_XRES, | ||
140 | .y_res = LCD_YRES, | ||
141 | .hsw = 3, /* hsync_len (4) - 1 */ | ||
142 | .hfp = 3, /* right_margin (4) - 1 */ | ||
143 | .hbp = 39, /* left_margin (40) - 1 */ | ||
144 | .vsw = 1, /* vsync_len (2) - 1 */ | ||
145 | .vfp = 2, /* lower_margin */ | ||
146 | .vbp = 7, /* upper_margin (8) - 1 */ | ||
147 | |||
148 | .pixel_clock = LCD_PIXCLOCK_MAX, | ||
149 | |||
150 | .init = ldp_panel_init, | ||
151 | .cleanup = ldp_panel_cleanup, | ||
152 | .enable = ldp_panel_enable, | ||
153 | .disable = ldp_panel_disable, | ||
154 | .get_caps = ldp_panel_get_caps, | ||
155 | }; | ||
156 | |||
157 | static int ldp_panel_probe(struct platform_device *pdev) | ||
158 | { | ||
159 | omapfb_register_panel(&ldp_panel); | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int ldp_panel_remove(struct platform_device *pdev) | ||
164 | { | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg) | ||
169 | { | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int ldp_panel_resume(struct platform_device *pdev) | ||
174 | { | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | struct platform_driver ldp_panel_driver = { | ||
179 | .probe = ldp_panel_probe, | ||
180 | .remove = ldp_panel_remove, | ||
181 | .suspend = ldp_panel_suspend, | ||
182 | .resume = ldp_panel_resume, | ||
183 | .driver = { | ||
184 | .name = "ldp_lcd", | ||
185 | .owner = THIS_MODULE, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static int __init ldp_panel_drv_init(void) | ||
190 | { | ||
191 | return platform_driver_register(&ldp_panel_driver); | ||
192 | } | ||
193 | |||
194 | static void __exit ldp_panel_drv_exit(void) | ||
195 | { | ||
196 | platform_driver_unregister(&ldp_panel_driver); | ||
197 | } | ||
198 | |||
199 | module_init(ldp_panel_drv_init); | ||
200 | module_exit(ldp_panel_drv_exit); | ||
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c new file mode 100644 index 000000000000..918ee8934196 --- /dev/null +++ b/drivers/video/omap/lcd_mipid.c | |||
@@ -0,0 +1,625 @@ | |||
1 | /* | ||
2 | * LCD driver for MIPI DBI-C / DCS compatible LCDs | ||
3 | * | ||
4 | * Copyright (C) 2006 Nokia Corporation | ||
5 | * Author: Imre Deak <imre.deak@nokia.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/workqueue.h> | ||
24 | #include <linux/spi/spi.h> | ||
25 | |||
26 | #include <mach/omapfb.h> | ||
27 | #include <mach/lcd_mipid.h> | ||
28 | |||
29 | #define MIPID_MODULE_NAME "lcd_mipid" | ||
30 | |||
31 | #define MIPID_CMD_READ_DISP_ID 0x04 | ||
32 | #define MIPID_CMD_READ_RED 0x06 | ||
33 | #define MIPID_CMD_READ_GREEN 0x07 | ||
34 | #define MIPID_CMD_READ_BLUE 0x08 | ||
35 | #define MIPID_CMD_READ_DISP_STATUS 0x09 | ||
36 | #define MIPID_CMD_RDDSDR 0x0F | ||
37 | #define MIPID_CMD_SLEEP_IN 0x10 | ||
38 | #define MIPID_CMD_SLEEP_OUT 0x11 | ||
39 | #define MIPID_CMD_DISP_OFF 0x28 | ||
40 | #define MIPID_CMD_DISP_ON 0x29 | ||
41 | |||
42 | #define MIPID_ESD_CHECK_PERIOD msecs_to_jiffies(5000) | ||
43 | |||
44 | #define to_mipid_device(p) container_of(p, struct mipid_device, \ | ||
45 | panel) | ||
46 | struct mipid_device { | ||
47 | int enabled; | ||
48 | int revision; | ||
49 | unsigned int saved_bklight_level; | ||
50 | unsigned long hw_guard_end; /* next value of jiffies | ||
51 | when we can issue the | ||
52 | next sleep in/out command */ | ||
53 | unsigned long hw_guard_wait; /* max guard time in jiffies */ | ||
54 | |||
55 | struct omapfb_device *fbdev; | ||
56 | struct spi_device *spi; | ||
57 | struct mutex mutex; | ||
58 | struct lcd_panel panel; | ||
59 | |||
60 | struct workqueue_struct *esd_wq; | ||
61 | struct delayed_work esd_work; | ||
62 | void (*esd_check)(struct mipid_device *m); | ||
63 | }; | ||
64 | |||
65 | static void mipid_transfer(struct mipid_device *md, int cmd, const u8 *wbuf, | ||
66 | int wlen, u8 *rbuf, int rlen) | ||
67 | { | ||
68 | struct spi_message m; | ||
69 | struct spi_transfer *x, xfer[4]; | ||
70 | u16 w; | ||
71 | int r; | ||
72 | |||
73 | BUG_ON(md->spi == NULL); | ||
74 | |||
75 | spi_message_init(&m); | ||
76 | |||
77 | memset(xfer, 0, sizeof(xfer)); | ||
78 | x = &xfer[0]; | ||
79 | |||
80 | cmd &= 0xff; | ||
81 | x->tx_buf = &cmd; | ||
82 | x->bits_per_word = 9; | ||
83 | x->len = 2; | ||
84 | spi_message_add_tail(x, &m); | ||
85 | |||
86 | if (wlen) { | ||
87 | x++; | ||
88 | x->tx_buf = wbuf; | ||
89 | x->len = wlen; | ||
90 | x->bits_per_word = 9; | ||
91 | spi_message_add_tail(x, &m); | ||
92 | } | ||
93 | |||
94 | if (rlen) { | ||
95 | x++; | ||
96 | x->rx_buf = &w; | ||
97 | x->len = 1; | ||
98 | spi_message_add_tail(x, &m); | ||
99 | |||
100 | if (rlen > 1) { | ||
101 | /* Arrange for the extra clock before the first | ||
102 | * data bit. | ||
103 | */ | ||
104 | x->bits_per_word = 9; | ||
105 | x->len = 2; | ||
106 | |||
107 | x++; | ||
108 | x->rx_buf = &rbuf[1]; | ||
109 | x->len = rlen - 1; | ||
110 | spi_message_add_tail(x, &m); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | r = spi_sync(md->spi, &m); | ||
115 | if (r < 0) | ||
116 | dev_dbg(&md->spi->dev, "spi_sync %d\n", r); | ||
117 | |||
118 | if (rlen) | ||
119 | rbuf[0] = w & 0xff; | ||
120 | } | ||
121 | |||
122 | static inline void mipid_cmd(struct mipid_device *md, int cmd) | ||
123 | { | ||
124 | mipid_transfer(md, cmd, NULL, 0, NULL, 0); | ||
125 | } | ||
126 | |||
127 | static inline void mipid_write(struct mipid_device *md, | ||
128 | int reg, const u8 *buf, int len) | ||
129 | { | ||
130 | mipid_transfer(md, reg, buf, len, NULL, 0); | ||
131 | } | ||
132 | |||
133 | static inline void mipid_read(struct mipid_device *md, | ||
134 | int reg, u8 *buf, int len) | ||
135 | { | ||
136 | mipid_transfer(md, reg, NULL, 0, buf, len); | ||
137 | } | ||
138 | |||
139 | static void set_data_lines(struct mipid_device *md, int data_lines) | ||
140 | { | ||
141 | u16 par; | ||
142 | |||
143 | switch (data_lines) { | ||
144 | case 16: | ||
145 | par = 0x150; | ||
146 | break; | ||
147 | case 18: | ||
148 | par = 0x160; | ||
149 | break; | ||
150 | case 24: | ||
151 | par = 0x170; | ||
152 | break; | ||
153 | } | ||
154 | mipid_write(md, 0x3a, (u8 *)&par, 2); | ||
155 | } | ||
156 | |||
157 | static void send_init_string(struct mipid_device *md) | ||
158 | { | ||
159 | u16 initpar[] = { 0x0102, 0x0100, 0x0100 }; | ||
160 | |||
161 | mipid_write(md, 0xc2, (u8 *)initpar, sizeof(initpar)); | ||
162 | set_data_lines(md, md->panel.data_lines); | ||
163 | } | ||
164 | |||
165 | static void hw_guard_start(struct mipid_device *md, int guard_msec) | ||
166 | { | ||
167 | md->hw_guard_wait = msecs_to_jiffies(guard_msec); | ||
168 | md->hw_guard_end = jiffies + md->hw_guard_wait; | ||
169 | } | ||
170 | |||
171 | static void hw_guard_wait(struct mipid_device *md) | ||
172 | { | ||
173 | unsigned long wait = md->hw_guard_end - jiffies; | ||
174 | |||
175 | if ((long)wait > 0 && wait <= md->hw_guard_wait) { | ||
176 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
177 | schedule_timeout(wait); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | static void set_sleep_mode(struct mipid_device *md, int on) | ||
182 | { | ||
183 | int cmd, sleep_time = 50; | ||
184 | |||
185 | if (on) | ||
186 | cmd = MIPID_CMD_SLEEP_IN; | ||
187 | else | ||
188 | cmd = MIPID_CMD_SLEEP_OUT; | ||
189 | hw_guard_wait(md); | ||
190 | mipid_cmd(md, cmd); | ||
191 | hw_guard_start(md, 120); | ||
192 | /* | ||
193 | * When we enable the panel, it seems we _have_ to sleep | ||
194 | * 120 ms before sending the init string. When disabling the | ||
195 | * panel we'll sleep for the duration of 2 frames, so that the | ||
196 | * controller can still provide the PCLK,HS,VS signals. | ||
197 | */ | ||
198 | if (!on) | ||
199 | sleep_time = 120; | ||
200 | msleep(sleep_time); | ||
201 | } | ||
202 | |||
203 | static void set_display_state(struct mipid_device *md, int enabled) | ||
204 | { | ||
205 | int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; | ||
206 | |||
207 | mipid_cmd(md, cmd); | ||
208 | } | ||
209 | |||
210 | static int mipid_set_bklight_level(struct lcd_panel *panel, unsigned int level) | ||
211 | { | ||
212 | struct mipid_device *md = to_mipid_device(panel); | ||
213 | struct mipid_platform_data *pd = md->spi->dev.platform_data; | ||
214 | |||
215 | if (pd->get_bklight_max == NULL || pd->set_bklight_level == NULL) | ||
216 | return -ENODEV; | ||
217 | if (level > pd->get_bklight_max(pd)) | ||
218 | return -EINVAL; | ||
219 | if (!md->enabled) { | ||
220 | md->saved_bklight_level = level; | ||
221 | return 0; | ||
222 | } | ||
223 | pd->set_bklight_level(pd, level); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static unsigned int mipid_get_bklight_level(struct lcd_panel *panel) | ||
229 | { | ||
230 | struct mipid_device *md = to_mipid_device(panel); | ||
231 | struct mipid_platform_data *pd = md->spi->dev.platform_data; | ||
232 | |||
233 | if (pd->get_bklight_level == NULL) | ||
234 | return -ENODEV; | ||
235 | return pd->get_bklight_level(pd); | ||
236 | } | ||
237 | |||
238 | static unsigned int mipid_get_bklight_max(struct lcd_panel *panel) | ||
239 | { | ||
240 | struct mipid_device *md = to_mipid_device(panel); | ||
241 | struct mipid_platform_data *pd = md->spi->dev.platform_data; | ||
242 | |||
243 | if (pd->get_bklight_max == NULL) | ||
244 | return -ENODEV; | ||
245 | |||
246 | return pd->get_bklight_max(pd); | ||
247 | } | ||
248 | |||
249 | static unsigned long mipid_get_caps(struct lcd_panel *panel) | ||
250 | { | ||
251 | return OMAPFB_CAPS_SET_BACKLIGHT; | ||
252 | } | ||
253 | |||
254 | static u16 read_first_pixel(struct mipid_device *md) | ||
255 | { | ||
256 | u16 pixel; | ||
257 | u8 red, green, blue; | ||
258 | |||
259 | mutex_lock(&md->mutex); | ||
260 | mipid_read(md, MIPID_CMD_READ_RED, &red, 1); | ||
261 | mipid_read(md, MIPID_CMD_READ_GREEN, &green, 1); | ||
262 | mipid_read(md, MIPID_CMD_READ_BLUE, &blue, 1); | ||
263 | mutex_unlock(&md->mutex); | ||
264 | |||
265 | switch (md->panel.data_lines) { | ||
266 | case 16: | ||
267 | pixel = ((red >> 1) << 11) | (green << 5) | (blue >> 1); | ||
268 | break; | ||
269 | case 24: | ||
270 | /* 24 bit -> 16 bit */ | ||
271 | pixel = ((red >> 3) << 11) | ((green >> 2) << 5) | | ||
272 | (blue >> 3); | ||
273 | break; | ||
274 | default: | ||
275 | pixel = 0; | ||
276 | BUG(); | ||
277 | } | ||
278 | |||
279 | return pixel; | ||
280 | } | ||
281 | |||
282 | static int mipid_run_test(struct lcd_panel *panel, int test_num) | ||
283 | { | ||
284 | struct mipid_device *md = to_mipid_device(panel); | ||
285 | static const u16 test_values[4] = { | ||
286 | 0x0000, 0xffff, 0xaaaa, 0x5555, | ||
287 | }; | ||
288 | int i; | ||
289 | |||
290 | if (test_num != MIPID_TEST_RGB_LINES) | ||
291 | return MIPID_TEST_INVALID; | ||
292 | |||
293 | for (i = 0; i < ARRAY_SIZE(test_values); i++) { | ||
294 | int delay; | ||
295 | unsigned long tmo; | ||
296 | |||
297 | omapfb_write_first_pixel(md->fbdev, test_values[i]); | ||
298 | tmo = jiffies + msecs_to_jiffies(100); | ||
299 | delay = 25; | ||
300 | while (1) { | ||
301 | u16 pixel; | ||
302 | |||
303 | msleep(delay); | ||
304 | pixel = read_first_pixel(md); | ||
305 | if (pixel == test_values[i]) | ||
306 | break; | ||
307 | if (time_after(jiffies, tmo)) { | ||
308 | dev_err(&md->spi->dev, | ||
309 | "MIPI LCD RGB I/F test failed: " | ||
310 | "expecting %04x, got %04x\n", | ||
311 | test_values[i], pixel); | ||
312 | return MIPID_TEST_FAILED; | ||
313 | } | ||
314 | delay = 10; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static void ls041y3_esd_recover(struct mipid_device *md) | ||
322 | { | ||
323 | dev_err(&md->spi->dev, "performing LCD ESD recovery\n"); | ||
324 | set_sleep_mode(md, 1); | ||
325 | set_sleep_mode(md, 0); | ||
326 | } | ||
327 | |||
328 | static void ls041y3_esd_check_mode1(struct mipid_device *md) | ||
329 | { | ||
330 | u8 state1, state2; | ||
331 | |||
332 | mipid_read(md, MIPID_CMD_RDDSDR, &state1, 1); | ||
333 | set_sleep_mode(md, 0); | ||
334 | mipid_read(md, MIPID_CMD_RDDSDR, &state2, 1); | ||
335 | dev_dbg(&md->spi->dev, "ESD mode 1 state1 %02x state2 %02x\n", | ||
336 | state1, state2); | ||
337 | /* Each sleep out command will trigger a self diagnostic and flip | ||
338 | * Bit6 if the test passes. | ||
339 | */ | ||
340 | if (!((state1 ^ state2) & (1 << 6))) | ||
341 | ls041y3_esd_recover(md); | ||
342 | } | ||
343 | |||
344 | static void ls041y3_esd_check_mode2(struct mipid_device *md) | ||
345 | { | ||
346 | int i; | ||
347 | u8 rbuf[2]; | ||
348 | static const struct { | ||
349 | int cmd; | ||
350 | int wlen; | ||
351 | u16 wbuf[3]; | ||
352 | } *rd, rd_ctrl[7] = { | ||
353 | { 0xb0, 4, { 0x0101, 0x01fe, } }, | ||
354 | { 0xb1, 4, { 0x01de, 0x0121, } }, | ||
355 | { 0xc2, 4, { 0x0100, 0x0100, } }, | ||
356 | { 0xbd, 2, { 0x0100, } }, | ||
357 | { 0xc2, 4, { 0x01fc, 0x0103, } }, | ||
358 | { 0xb4, 0, }, | ||
359 | { 0x00, 0, }, | ||
360 | }; | ||
361 | |||
362 | rd = rd_ctrl; | ||
363 | for (i = 0; i < 3; i++, rd++) | ||
364 | mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen); | ||
365 | |||
366 | udelay(10); | ||
367 | mipid_read(md, rd->cmd, rbuf, 2); | ||
368 | rd++; | ||
369 | |||
370 | for (i = 0; i < 3; i++, rd++) { | ||
371 | udelay(10); | ||
372 | mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen); | ||
373 | } | ||
374 | |||
375 | dev_dbg(&md->spi->dev, "ESD mode 2 state %02x\n", rbuf[1]); | ||
376 | if (rbuf[1] == 0x00) | ||
377 | ls041y3_esd_recover(md); | ||
378 | } | ||
379 | |||
380 | static void ls041y3_esd_check(struct mipid_device *md) | ||
381 | { | ||
382 | ls041y3_esd_check_mode1(md); | ||
383 | if (md->revision >= 0x88) | ||
384 | ls041y3_esd_check_mode2(md); | ||
385 | } | ||
386 | |||
387 | static void mipid_esd_start_check(struct mipid_device *md) | ||
388 | { | ||
389 | if (md->esd_check != NULL) | ||
390 | queue_delayed_work(md->esd_wq, &md->esd_work, | ||
391 | MIPID_ESD_CHECK_PERIOD); | ||
392 | } | ||
393 | |||
394 | static void mipid_esd_stop_check(struct mipid_device *md) | ||
395 | { | ||
396 | if (md->esd_check != NULL) | ||
397 | cancel_rearming_delayed_workqueue(md->esd_wq, &md->esd_work); | ||
398 | } | ||
399 | |||
400 | static void mipid_esd_work(struct work_struct *work) | ||
401 | { | ||
402 | struct mipid_device *md = container_of(work, struct mipid_device, | ||
403 | esd_work.work); | ||
404 | |||
405 | mutex_lock(&md->mutex); | ||
406 | md->esd_check(md); | ||
407 | mutex_unlock(&md->mutex); | ||
408 | mipid_esd_start_check(md); | ||
409 | } | ||
410 | |||
411 | static int mipid_enable(struct lcd_panel *panel) | ||
412 | { | ||
413 | struct mipid_device *md = to_mipid_device(panel); | ||
414 | |||
415 | mutex_lock(&md->mutex); | ||
416 | |||
417 | if (md->enabled) { | ||
418 | mutex_unlock(&md->mutex); | ||
419 | return 0; | ||
420 | } | ||
421 | set_sleep_mode(md, 0); | ||
422 | md->enabled = 1; | ||
423 | send_init_string(md); | ||
424 | set_display_state(md, 1); | ||
425 | mipid_set_bklight_level(panel, md->saved_bklight_level); | ||
426 | mipid_esd_start_check(md); | ||
427 | |||
428 | mutex_unlock(&md->mutex); | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static void mipid_disable(struct lcd_panel *panel) | ||
433 | { | ||
434 | struct mipid_device *md = to_mipid_device(panel); | ||
435 | |||
436 | /* | ||
437 | * A final ESD work might be called before returning, | ||
438 | * so do this without holding the lock. | ||
439 | */ | ||
440 | mipid_esd_stop_check(md); | ||
441 | mutex_lock(&md->mutex); | ||
442 | |||
443 | if (!md->enabled) { | ||
444 | mutex_unlock(&md->mutex); | ||
445 | return; | ||
446 | } | ||
447 | md->saved_bklight_level = mipid_get_bklight_level(panel); | ||
448 | mipid_set_bklight_level(panel, 0); | ||
449 | set_display_state(md, 0); | ||
450 | set_sleep_mode(md, 1); | ||
451 | md->enabled = 0; | ||
452 | |||
453 | mutex_unlock(&md->mutex); | ||
454 | } | ||
455 | |||
456 | static int panel_enabled(struct mipid_device *md) | ||
457 | { | ||
458 | u32 disp_status; | ||
459 | int enabled; | ||
460 | |||
461 | mipid_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); | ||
462 | disp_status = __be32_to_cpu(disp_status); | ||
463 | enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); | ||
464 | dev_dbg(&md->spi->dev, | ||
465 | "LCD panel %senabled by bootloader (status 0x%04x)\n", | ||
466 | enabled ? "" : "not ", disp_status); | ||
467 | return enabled; | ||
468 | } | ||
469 | |||
470 | static int mipid_init(struct lcd_panel *panel, | ||
471 | struct omapfb_device *fbdev) | ||
472 | { | ||
473 | struct mipid_device *md = to_mipid_device(panel); | ||
474 | |||
475 | md->fbdev = fbdev; | ||
476 | md->esd_wq = create_singlethread_workqueue("mipid_esd"); | ||
477 | if (md->esd_wq == NULL) { | ||
478 | dev_err(&md->spi->dev, "can't create ESD workqueue\n"); | ||
479 | return -ENOMEM; | ||
480 | } | ||
481 | INIT_DELAYED_WORK(&md->esd_work, mipid_esd_work); | ||
482 | mutex_init(&md->mutex); | ||
483 | |||
484 | md->enabled = panel_enabled(md); | ||
485 | |||
486 | if (md->enabled) | ||
487 | mipid_esd_start_check(md); | ||
488 | else | ||
489 | md->saved_bklight_level = mipid_get_bklight_level(panel); | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static void mipid_cleanup(struct lcd_panel *panel) | ||
495 | { | ||
496 | struct mipid_device *md = to_mipid_device(panel); | ||
497 | |||
498 | if (md->enabled) | ||
499 | mipid_esd_stop_check(md); | ||
500 | destroy_workqueue(md->esd_wq); | ||
501 | } | ||
502 | |||
503 | static struct lcd_panel mipid_panel = { | ||
504 | .config = OMAP_LCDC_PANEL_TFT, | ||
505 | |||
506 | .bpp = 16, | ||
507 | .x_res = 800, | ||
508 | .y_res = 480, | ||
509 | .pixel_clock = 21940, | ||
510 | .hsw = 50, | ||
511 | .hfp = 20, | ||
512 | .hbp = 15, | ||
513 | .vsw = 2, | ||
514 | .vfp = 1, | ||
515 | .vbp = 3, | ||
516 | |||
517 | .init = mipid_init, | ||
518 | .cleanup = mipid_cleanup, | ||
519 | .enable = mipid_enable, | ||
520 | .disable = mipid_disable, | ||
521 | .get_caps = mipid_get_caps, | ||
522 | .set_bklight_level = mipid_set_bklight_level, | ||
523 | .get_bklight_level = mipid_get_bklight_level, | ||
524 | .get_bklight_max = mipid_get_bklight_max, | ||
525 | .run_test = mipid_run_test, | ||
526 | }; | ||
527 | |||
528 | static int mipid_detect(struct mipid_device *md) | ||
529 | { | ||
530 | struct mipid_platform_data *pdata; | ||
531 | u8 display_id[3]; | ||
532 | |||
533 | pdata = md->spi->dev.platform_data; | ||
534 | if (pdata == NULL) { | ||
535 | dev_err(&md->spi->dev, "missing platform data\n"); | ||
536 | return -ENOENT; | ||
537 | } | ||
538 | |||
539 | mipid_read(md, MIPID_CMD_READ_DISP_ID, display_id, 3); | ||
540 | dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", | ||
541 | display_id[0], display_id[1], display_id[2]); | ||
542 | |||
543 | switch (display_id[0]) { | ||
544 | case 0x45: | ||
545 | md->panel.name = "lph8923"; | ||
546 | break; | ||
547 | case 0x83: | ||
548 | md->panel.name = "ls041y3"; | ||
549 | md->esd_check = ls041y3_esd_check; | ||
550 | break; | ||
551 | default: | ||
552 | md->panel.name = "unknown"; | ||
553 | dev_err(&md->spi->dev, "invalid display ID\n"); | ||
554 | return -ENODEV; | ||
555 | } | ||
556 | |||
557 | md->revision = display_id[1]; | ||
558 | md->panel.data_lines = pdata->data_lines; | ||
559 | pr_info("omapfb: %s rev %02x LCD detected, %d data lines\n", | ||
560 | md->panel.name, md->revision, md->panel.data_lines); | ||
561 | |||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static int mipid_spi_probe(struct spi_device *spi) | ||
566 | { | ||
567 | struct mipid_device *md; | ||
568 | int r; | ||
569 | |||
570 | md = kzalloc(sizeof(*md), GFP_KERNEL); | ||
571 | if (md == NULL) { | ||
572 | dev_err(&spi->dev, "out of memory\n"); | ||
573 | return -ENOMEM; | ||
574 | } | ||
575 | |||
576 | spi->mode = SPI_MODE_0; | ||
577 | md->spi = spi; | ||
578 | dev_set_drvdata(&spi->dev, md); | ||
579 | md->panel = mipid_panel; | ||
580 | |||
581 | r = mipid_detect(md); | ||
582 | if (r < 0) | ||
583 | return r; | ||
584 | |||
585 | omapfb_register_panel(&md->panel); | ||
586 | |||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int mipid_spi_remove(struct spi_device *spi) | ||
591 | { | ||
592 | struct mipid_device *md = dev_get_drvdata(&spi->dev); | ||
593 | |||
594 | mipid_disable(&md->panel); | ||
595 | kfree(md); | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static struct spi_driver mipid_spi_driver = { | ||
601 | .driver = { | ||
602 | .name = MIPID_MODULE_NAME, | ||
603 | .bus = &spi_bus_type, | ||
604 | .owner = THIS_MODULE, | ||
605 | }, | ||
606 | .probe = mipid_spi_probe, | ||
607 | .remove = __devexit_p(mipid_spi_remove), | ||
608 | }; | ||
609 | |||
610 | static int mipid_drv_init(void) | ||
611 | { | ||
612 | spi_register_driver(&mipid_spi_driver); | ||
613 | |||
614 | return 0; | ||
615 | } | ||
616 | module_init(mipid_drv_init); | ||
617 | |||
618 | static void mipid_drv_cleanup(void) | ||
619 | { | ||
620 | spi_unregister_driver(&mipid_spi_driver); | ||
621 | } | ||
622 | module_exit(mipid_drv_cleanup); | ||
623 | |||
624 | MODULE_DESCRIPTION("MIPI display driver"); | ||
625 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap/lcd_omap2evm.c b/drivers/video/omap/lcd_omap2evm.c new file mode 100644 index 000000000000..7a2bbe2ecec3 --- /dev/null +++ b/drivers/video/omap/lcd_omap2evm.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * LCD panel support for the MISTRAL OMAP2EVM board | ||
3 | * | ||
4 | * Author: Arun C <arunedarath@mistralsolutions.com> | ||
5 | * | ||
6 | * Derived from drivers/video/omap/lcd_omap3evm.c | ||
7 | * Derived from drivers/video/omap/lcd-apollon.c | ||
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 as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/i2c/twl4030.h> | ||
28 | |||
29 | #include <mach/mux.h> | ||
30 | #include <mach/omapfb.h> | ||
31 | #include <asm/mach-types.h> | ||
32 | |||
33 | #define LCD_PANEL_ENABLE_GPIO 154 | ||
34 | #define LCD_PANEL_LR 128 | ||
35 | #define LCD_PANEL_UD 129 | ||
36 | #define LCD_PANEL_INI 152 | ||
37 | #define LCD_PANEL_QVGA 148 | ||
38 | #define LCD_PANEL_RESB 153 | ||
39 | |||
40 | #define TWL_LED_LEDEN 0x00 | ||
41 | #define TWL_PWMA_PWMAON 0x00 | ||
42 | #define TWL_PWMA_PWMAOFF 0x01 | ||
43 | |||
44 | static unsigned int bklight_level; | ||
45 | |||
46 | static int omap2evm_panel_init(struct lcd_panel *panel, | ||
47 | struct omapfb_device *fbdev) | ||
48 | { | ||
49 | gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable"); | ||
50 | gpio_request(LCD_PANEL_LR, "LCD lr"); | ||
51 | gpio_request(LCD_PANEL_UD, "LCD ud"); | ||
52 | gpio_request(LCD_PANEL_INI, "LCD ini"); | ||
53 | gpio_request(LCD_PANEL_QVGA, "LCD qvga"); | ||
54 | gpio_request(LCD_PANEL_RESB, "LCD resb"); | ||
55 | |||
56 | gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1); | ||
57 | gpio_direction_output(LCD_PANEL_RESB, 1); | ||
58 | gpio_direction_output(LCD_PANEL_INI, 1); | ||
59 | gpio_direction_output(LCD_PANEL_QVGA, 0); | ||
60 | gpio_direction_output(LCD_PANEL_LR, 1); | ||
61 | gpio_direction_output(LCD_PANEL_UD, 1); | ||
62 | |||
63 | twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN); | ||
64 | twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON); | ||
65 | twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF); | ||
66 | bklight_level = 100; | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static void omap2evm_panel_cleanup(struct lcd_panel *panel) | ||
72 | { | ||
73 | gpio_free(LCD_PANEL_RESB); | ||
74 | gpio_free(LCD_PANEL_QVGA); | ||
75 | gpio_free(LCD_PANEL_INI); | ||
76 | gpio_free(LCD_PANEL_UD); | ||
77 | gpio_free(LCD_PANEL_LR); | ||
78 | gpio_free(LCD_PANEL_ENABLE_GPIO); | ||
79 | } | ||
80 | |||
81 | static int omap2evm_panel_enable(struct lcd_panel *panel) | ||
82 | { | ||
83 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static void omap2evm_panel_disable(struct lcd_panel *panel) | ||
88 | { | ||
89 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1); | ||
90 | } | ||
91 | |||
92 | static unsigned long omap2evm_panel_get_caps(struct lcd_panel *panel) | ||
93 | { | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int omap2evm_bklight_setlevel(struct lcd_panel *panel, | ||
98 | unsigned int level) | ||
99 | { | ||
100 | u8 c; | ||
101 | if ((level >= 0) && (level <= 100)) { | ||
102 | c = (125 * (100 - level)) / 100 + 2; | ||
103 | twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF); | ||
104 | bklight_level = level; | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static unsigned int omap2evm_bklight_getlevel(struct lcd_panel *panel) | ||
110 | { | ||
111 | return bklight_level; | ||
112 | } | ||
113 | |||
114 | static unsigned int omap2evm_bklight_getmaxlevel(struct lcd_panel *panel) | ||
115 | { | ||
116 | return 100; | ||
117 | } | ||
118 | |||
119 | struct lcd_panel omap2evm_panel = { | ||
120 | .name = "omap2evm", | ||
121 | .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | | ||
122 | OMAP_LCDC_INV_HSYNC, | ||
123 | |||
124 | .bpp = 16, | ||
125 | .data_lines = 18, | ||
126 | .x_res = 480, | ||
127 | .y_res = 640, | ||
128 | .hsw = 3, | ||
129 | .hfp = 0, | ||
130 | .hbp = 28, | ||
131 | .vsw = 2, | ||
132 | .vfp = 1, | ||
133 | .vbp = 0, | ||
134 | |||
135 | .pixel_clock = 20000, | ||
136 | |||
137 | .init = omap2evm_panel_init, | ||
138 | .cleanup = omap2evm_panel_cleanup, | ||
139 | .enable = omap2evm_panel_enable, | ||
140 | .disable = omap2evm_panel_disable, | ||
141 | .get_caps = omap2evm_panel_get_caps, | ||
142 | .set_bklight_level = omap2evm_bklight_setlevel, | ||
143 | .get_bklight_level = omap2evm_bklight_getlevel, | ||
144 | .get_bklight_max = omap2evm_bklight_getmaxlevel, | ||
145 | }; | ||
146 | |||
147 | static int omap2evm_panel_probe(struct platform_device *pdev) | ||
148 | { | ||
149 | omapfb_register_panel(&omap2evm_panel); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int omap2evm_panel_remove(struct platform_device *pdev) | ||
154 | { | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int omap2evm_panel_suspend(struct platform_device *pdev, | ||
159 | pm_message_t mesg) | ||
160 | { | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int omap2evm_panel_resume(struct platform_device *pdev) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | struct platform_driver omap2evm_panel_driver = { | ||
170 | .probe = omap2evm_panel_probe, | ||
171 | .remove = omap2evm_panel_remove, | ||
172 | .suspend = omap2evm_panel_suspend, | ||
173 | .resume = omap2evm_panel_resume, | ||
174 | .driver = { | ||
175 | .name = "omap2evm_lcd", | ||
176 | .owner = THIS_MODULE, | ||
177 | }, | ||
178 | }; | ||
179 | |||
180 | static int __init omap2evm_panel_drv_init(void) | ||
181 | { | ||
182 | return platform_driver_register(&omap2evm_panel_driver); | ||
183 | } | ||
184 | |||
185 | static void __exit omap2evm_panel_drv_exit(void) | ||
186 | { | ||
187 | platform_driver_unregister(&omap2evm_panel_driver); | ||
188 | } | ||
189 | |||
190 | module_init(omap2evm_panel_drv_init); | ||
191 | module_exit(omap2evm_panel_drv_exit); | ||
diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c new file mode 100644 index 000000000000..4011910123bf --- /dev/null +++ b/drivers/video/omap/lcd_omap3beagle.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * LCD panel support for the TI OMAP3 Beagle board | ||
3 | * | ||
4 | * Author: Koen Kooi <koen@openembedded.org> | ||
5 | * | ||
6 | * Derived from drivers/video/omap/lcd-omap3evm.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/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/gpio.h> | ||
26 | #include <linux/i2c/twl4030.h> | ||
27 | |||
28 | #include <mach/mux.h> | ||
29 | #include <mach/omapfb.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | |||
32 | #define LCD_PANEL_ENABLE_GPIO 170 | ||
33 | |||
34 | static int omap3beagle_panel_init(struct lcd_panel *panel, | ||
35 | struct omapfb_device *fbdev) | ||
36 | { | ||
37 | gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable"); | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static void omap3beagle_panel_cleanup(struct lcd_panel *panel) | ||
42 | { | ||
43 | gpio_free(LCD_PANEL_ENABLE_GPIO); | ||
44 | } | ||
45 | |||
46 | static int omap3beagle_panel_enable(struct lcd_panel *panel) | ||
47 | { | ||
48 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static void omap3beagle_panel_disable(struct lcd_panel *panel) | ||
53 | { | ||
54 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0); | ||
55 | } | ||
56 | |||
57 | static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel) | ||
58 | { | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | struct lcd_panel omap3beagle_panel = { | ||
63 | .name = "omap3beagle", | ||
64 | .config = OMAP_LCDC_PANEL_TFT, | ||
65 | |||
66 | .bpp = 16, | ||
67 | .data_lines = 24, | ||
68 | .x_res = 1024, | ||
69 | .y_res = 768, | ||
70 | .hsw = 3, /* hsync_len (4) - 1 */ | ||
71 | .hfp = 3, /* right_margin (4) - 1 */ | ||
72 | .hbp = 39, /* left_margin (40) - 1 */ | ||
73 | .vsw = 1, /* vsync_len (2) - 1 */ | ||
74 | .vfp = 2, /* lower_margin */ | ||
75 | .vbp = 7, /* upper_margin (8) - 1 */ | ||
76 | |||
77 | .pixel_clock = 64000, | ||
78 | |||
79 | .init = omap3beagle_panel_init, | ||
80 | .cleanup = omap3beagle_panel_cleanup, | ||
81 | .enable = omap3beagle_panel_enable, | ||
82 | .disable = omap3beagle_panel_disable, | ||
83 | .get_caps = omap3beagle_panel_get_caps, | ||
84 | }; | ||
85 | |||
86 | static int omap3beagle_panel_probe(struct platform_device *pdev) | ||
87 | { | ||
88 | omapfb_register_panel(&omap3beagle_panel); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int omap3beagle_panel_remove(struct platform_device *pdev) | ||
93 | { | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int omap3beagle_panel_suspend(struct platform_device *pdev, | ||
98 | pm_message_t mesg) | ||
99 | { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int omap3beagle_panel_resume(struct platform_device *pdev) | ||
104 | { | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | struct platform_driver omap3beagle_panel_driver = { | ||
109 | .probe = omap3beagle_panel_probe, | ||
110 | .remove = omap3beagle_panel_remove, | ||
111 | .suspend = omap3beagle_panel_suspend, | ||
112 | .resume = omap3beagle_panel_resume, | ||
113 | .driver = { | ||
114 | .name = "omap3beagle_lcd", | ||
115 | .owner = THIS_MODULE, | ||
116 | }, | ||
117 | }; | ||
118 | |||
119 | static int __init omap3beagle_panel_drv_init(void) | ||
120 | { | ||
121 | return platform_driver_register(&omap3beagle_panel_driver); | ||
122 | } | ||
123 | |||
124 | static void __exit omap3beagle_panel_drv_exit(void) | ||
125 | { | ||
126 | platform_driver_unregister(&omap3beagle_panel_driver); | ||
127 | } | ||
128 | |||
129 | module_init(omap3beagle_panel_drv_init); | ||
130 | module_exit(omap3beagle_panel_drv_exit); | ||
diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c new file mode 100644 index 000000000000..b6a4c2c57a2f --- /dev/null +++ b/drivers/video/omap/lcd_omap3evm.c | |||
@@ -0,0 +1,192 @@ | |||
1 | /* | ||
2 | * LCD panel support for the TI OMAP3 EVM board | ||
3 | * | ||
4 | * Author: Steve Sakoman <steve@sakoman.com> | ||
5 | * | ||
6 | * Derived from drivers/video/omap/lcd-apollon.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/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/gpio.h> | ||
26 | #include <linux/i2c/twl4030.h> | ||
27 | |||
28 | #include <mach/mux.h> | ||
29 | #include <mach/omapfb.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | |||
32 | #define LCD_PANEL_ENABLE_GPIO 153 | ||
33 | #define LCD_PANEL_LR 2 | ||
34 | #define LCD_PANEL_UD 3 | ||
35 | #define LCD_PANEL_INI 152 | ||
36 | #define LCD_PANEL_QVGA 154 | ||
37 | #define LCD_PANEL_RESB 155 | ||
38 | |||
39 | #define ENABLE_VDAC_DEDICATED 0x03 | ||
40 | #define ENABLE_VDAC_DEV_GRP 0x20 | ||
41 | #define ENABLE_VPLL2_DEDICATED 0x05 | ||
42 | #define ENABLE_VPLL2_DEV_GRP 0xE0 | ||
43 | |||
44 | #define TWL_LED_LEDEN 0x00 | ||
45 | #define TWL_PWMA_PWMAON 0x00 | ||
46 | #define TWL_PWMA_PWMAOFF 0x01 | ||
47 | |||
48 | static unsigned int bklight_level; | ||
49 | |||
50 | static int omap3evm_panel_init(struct lcd_panel *panel, | ||
51 | struct omapfb_device *fbdev) | ||
52 | { | ||
53 | gpio_request(LCD_PANEL_LR, "LCD lr"); | ||
54 | gpio_request(LCD_PANEL_UD, "LCD ud"); | ||
55 | gpio_request(LCD_PANEL_INI, "LCD ini"); | ||
56 | gpio_request(LCD_PANEL_RESB, "LCD resb"); | ||
57 | gpio_request(LCD_PANEL_QVGA, "LCD qvga"); | ||
58 | |||
59 | gpio_direction_output(LCD_PANEL_RESB, 1); | ||
60 | gpio_direction_output(LCD_PANEL_INI, 1); | ||
61 | gpio_direction_output(LCD_PANEL_QVGA, 0); | ||
62 | gpio_direction_output(LCD_PANEL_LR, 1); | ||
63 | gpio_direction_output(LCD_PANEL_UD, 1); | ||
64 | |||
65 | twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN); | ||
66 | twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON); | ||
67 | twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF); | ||
68 | bklight_level = 100; | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static void omap3evm_panel_cleanup(struct lcd_panel *panel) | ||
74 | { | ||
75 | gpio_free(LCD_PANEL_QVGA); | ||
76 | gpio_free(LCD_PANEL_RESB); | ||
77 | gpio_free(LCD_PANEL_INI); | ||
78 | gpio_free(LCD_PANEL_UD); | ||
79 | gpio_free(LCD_PANEL_LR); | ||
80 | } | ||
81 | |||
82 | static int omap3evm_panel_enable(struct lcd_panel *panel) | ||
83 | { | ||
84 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static void omap3evm_panel_disable(struct lcd_panel *panel) | ||
89 | { | ||
90 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1); | ||
91 | } | ||
92 | |||
93 | static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel) | ||
94 | { | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int omap3evm_bklight_setlevel(struct lcd_panel *panel, | ||
99 | unsigned int level) | ||
100 | { | ||
101 | u8 c; | ||
102 | if ((level >= 0) && (level <= 100)) { | ||
103 | c = (125 * (100 - level)) / 100 + 2; | ||
104 | twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF); | ||
105 | bklight_level = level; | ||
106 | } | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel) | ||
111 | { | ||
112 | return bklight_level; | ||
113 | } | ||
114 | |||
115 | static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel) | ||
116 | { | ||
117 | return 100; | ||
118 | } | ||
119 | |||
120 | struct lcd_panel omap3evm_panel = { | ||
121 | .name = "omap3evm", | ||
122 | .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | | ||
123 | OMAP_LCDC_INV_HSYNC, | ||
124 | |||
125 | .bpp = 16, | ||
126 | .data_lines = 18, | ||
127 | .x_res = 480, | ||
128 | .y_res = 640, | ||
129 | .hsw = 3, /* hsync_len (4) - 1 */ | ||
130 | .hfp = 3, /* right_margin (4) - 1 */ | ||
131 | .hbp = 39, /* left_margin (40) - 1 */ | ||
132 | .vsw = 1, /* vsync_len (2) - 1 */ | ||
133 | .vfp = 2, /* lower_margin */ | ||
134 | .vbp = 7, /* upper_margin (8) - 1 */ | ||
135 | |||
136 | .pixel_clock = 26000, | ||
137 | |||
138 | .init = omap3evm_panel_init, | ||
139 | .cleanup = omap3evm_panel_cleanup, | ||
140 | .enable = omap3evm_panel_enable, | ||
141 | .disable = omap3evm_panel_disable, | ||
142 | .get_caps = omap3evm_panel_get_caps, | ||
143 | .set_bklight_level = omap3evm_bklight_setlevel, | ||
144 | .get_bklight_level = omap3evm_bklight_getlevel, | ||
145 | .get_bklight_max = omap3evm_bklight_getmaxlevel, | ||
146 | }; | ||
147 | |||
148 | static int omap3evm_panel_probe(struct platform_device *pdev) | ||
149 | { | ||
150 | omapfb_register_panel(&omap3evm_panel); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int omap3evm_panel_remove(struct platform_device *pdev) | ||
155 | { | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int omap3evm_panel_suspend(struct platform_device *pdev, | ||
160 | pm_message_t mesg) | ||
161 | { | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int omap3evm_panel_resume(struct platform_device *pdev) | ||
166 | { | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | struct platform_driver omap3evm_panel_driver = { | ||
171 | .probe = omap3evm_panel_probe, | ||
172 | .remove = omap3evm_panel_remove, | ||
173 | .suspend = omap3evm_panel_suspend, | ||
174 | .resume = omap3evm_panel_resume, | ||
175 | .driver = { | ||
176 | .name = "omap3evm_lcd", | ||
177 | .owner = THIS_MODULE, | ||
178 | }, | ||
179 | }; | ||
180 | |||
181 | static int __init omap3evm_panel_drv_init(void) | ||
182 | { | ||
183 | return platform_driver_register(&omap3evm_panel_driver); | ||
184 | } | ||
185 | |||
186 | static void __exit omap3evm_panel_drv_exit(void) | ||
187 | { | ||
188 | platform_driver_unregister(&omap3evm_panel_driver); | ||
189 | } | ||
190 | |||
191 | module_init(omap3evm_panel_drv_init); | ||
192 | module_exit(omap3evm_panel_drv_exit); | ||
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c index 379c96d36da5..b3fa88bc6269 100644 --- a/drivers/video/omap/lcd_osk.c +++ b/drivers/video/omap/lcd_osk.c | |||
@@ -127,12 +127,12 @@ struct platform_driver osk_panel_driver = { | |||
127 | }, | 127 | }, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | static int osk_panel_drv_init(void) | 130 | static int __init osk_panel_drv_init(void) |
131 | { | 131 | { |
132 | return platform_driver_register(&osk_panel_driver); | 132 | return platform_driver_register(&osk_panel_driver); |
133 | } | 133 | } |
134 | 134 | ||
135 | static void osk_panel_drv_cleanup(void) | 135 | static void __exit osk_panel_drv_cleanup(void) |
136 | { | 136 | { |
137 | platform_driver_unregister(&osk_panel_driver); | 137 | platform_driver_unregister(&osk_panel_driver); |
138 | } | 138 | } |
diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c new file mode 100644 index 000000000000..2bc5c9268e5e --- /dev/null +++ b/drivers/video/omap/lcd_overo.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * LCD panel support for the Gumstix Overo | ||
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 as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/i2c/twl4030.h> | ||
25 | |||
26 | #include <mach/gpio.h> | ||
27 | #include <mach/mux.h> | ||
28 | #include <mach/omapfb.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | |||
31 | #define LCD_ENABLE 144 | ||
32 | |||
33 | static int overo_panel_init(struct lcd_panel *panel, | ||
34 | struct omapfb_device *fbdev) | ||
35 | { | ||
36 | if ((gpio_request(LCD_ENABLE, "LCD_ENABLE") == 0) && | ||
37 | (gpio_direction_output(LCD_ENABLE, 1) == 0)) | ||
38 | gpio_export(LCD_ENABLE, 0); | ||
39 | else | ||
40 | printk(KERN_ERR "could not obtain gpio for LCD_ENABLE\n"); | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static void overo_panel_cleanup(struct lcd_panel *panel) | ||
46 | { | ||
47 | gpio_free(LCD_ENABLE); | ||
48 | } | ||
49 | |||
50 | static int overo_panel_enable(struct lcd_panel *panel) | ||
51 | { | ||
52 | gpio_set_value(LCD_ENABLE, 1); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static void overo_panel_disable(struct lcd_panel *panel) | ||
57 | { | ||
58 | gpio_set_value(LCD_ENABLE, 0); | ||
59 | } | ||
60 | |||
61 | static unsigned long overo_panel_get_caps(struct lcd_panel *panel) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | struct lcd_panel overo_panel = { | ||
67 | .name = "overo", | ||
68 | .config = OMAP_LCDC_PANEL_TFT, | ||
69 | .bpp = 16, | ||
70 | .data_lines = 24, | ||
71 | |||
72 | #if defined CONFIG_FB_OMAP_031M3R | ||
73 | |||
74 | /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ | ||
75 | .x_res = 640, | ||
76 | .y_res = 480, | ||
77 | .hfp = 48, | ||
78 | .hsw = 32, | ||
79 | .hbp = 80, | ||
80 | .vfp = 3, | ||
81 | .vsw = 4, | ||
82 | .vbp = 7, | ||
83 | .pixel_clock = 23500, | ||
84 | |||
85 | #elif defined CONFIG_FB_OMAP_048M3R | ||
86 | |||
87 | /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */ | ||
88 | .x_res = 800, | ||
89 | .y_res = 600, | ||
90 | .hfp = 48, | ||
91 | .hsw = 32, | ||
92 | .hbp = 80, | ||
93 | .vfp = 3, | ||
94 | .vsw = 4, | ||
95 | .vbp = 11, | ||
96 | .pixel_clock = 35500, | ||
97 | |||
98 | #elif defined CONFIG_FB_OMAP_079M3R | ||
99 | |||
100 | /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */ | ||
101 | .x_res = 1024, | ||
102 | .y_res = 768, | ||
103 | .hfp = 48, | ||
104 | .hsw = 32, | ||
105 | .hbp = 80, | ||
106 | .vfp = 3, | ||
107 | .vsw = 4, | ||
108 | .vbp = 15, | ||
109 | .pixel_clock = 56000, | ||
110 | |||
111 | #elif defined CONFIG_FB_OMAP_092M9R | ||
112 | |||
113 | /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */ | ||
114 | .x_res = 1280, | ||
115 | .y_res = 720, | ||
116 | .hfp = 48, | ||
117 | .hsw = 32, | ||
118 | .hbp = 80, | ||
119 | .vfp = 3, | ||
120 | .vsw = 5, | ||
121 | .vbp = 13, | ||
122 | .pixel_clock = 64000, | ||
123 | |||
124 | #else | ||
125 | |||
126 | /* use 640 x 480 if no config option */ | ||
127 | /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ | ||
128 | .x_res = 640, | ||
129 | .y_res = 480, | ||
130 | .hfp = 48, | ||
131 | .hsw = 32, | ||
132 | .hbp = 80, | ||
133 | .vfp = 3, | ||
134 | .vsw = 4, | ||
135 | .vbp = 7, | ||
136 | .pixel_clock = 23500, | ||
137 | |||
138 | #endif | ||
139 | |||
140 | .init = overo_panel_init, | ||
141 | .cleanup = overo_panel_cleanup, | ||
142 | .enable = overo_panel_enable, | ||
143 | .disable = overo_panel_disable, | ||
144 | .get_caps = overo_panel_get_caps, | ||
145 | }; | ||
146 | |||
147 | static int overo_panel_probe(struct platform_device *pdev) | ||
148 | { | ||
149 | omapfb_register_panel(&overo_panel); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int overo_panel_remove(struct platform_device *pdev) | ||
154 | { | ||
155 | /* omapfb does not have unregister_panel */ | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static struct platform_driver overo_panel_driver = { | ||
160 | .probe = overo_panel_probe, | ||
161 | .remove = overo_panel_remove, | ||
162 | .driver = { | ||
163 | .name = "overo_lcd", | ||
164 | .owner = THIS_MODULE, | ||
165 | }, | ||
166 | }; | ||
167 | |||
168 | static int __init overo_panel_drv_init(void) | ||
169 | { | ||
170 | return platform_driver_register(&overo_panel_driver); | ||
171 | } | ||
172 | |||
173 | static void __exit overo_panel_drv_exit(void) | ||
174 | { | ||
175 | platform_driver_unregister(&overo_panel_driver); | ||
176 | } | ||
177 | |||
178 | module_init(overo_panel_drv_init); | ||
179 | module_exit(overo_panel_drv_exit); | ||
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c index 218317366e6e..4bf3c79f3cc7 100644 --- a/drivers/video/omap/lcd_palmte.c +++ b/drivers/video/omap/lcd_palmte.c | |||
@@ -108,12 +108,12 @@ struct platform_driver palmte_panel_driver = { | |||
108 | }, | 108 | }, |
109 | }; | 109 | }; |
110 | 110 | ||
111 | static int palmte_panel_drv_init(void) | 111 | static int __init palmte_panel_drv_init(void) |
112 | { | 112 | { |
113 | return platform_driver_register(&palmte_panel_driver); | 113 | return platform_driver_register(&palmte_panel_driver); |
114 | } | 114 | } |
115 | 115 | ||
116 | static void palmte_panel_drv_cleanup(void) | 116 | static void __exit palmte_panel_drv_cleanup(void) |
117 | { | 117 | { |
118 | platform_driver_unregister(&palmte_panel_driver); | 118 | platform_driver_unregister(&palmte_panel_driver); |
119 | } | 119 | } |
diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c index 57b0f6cf6a5a..48ea1f9f2cbf 100644 --- a/drivers/video/omap/lcd_palmtt.c +++ b/drivers/video/omap/lcd_palmtt.c | |||
@@ -113,12 +113,12 @@ struct platform_driver palmtt_panel_driver = { | |||
113 | }, | 113 | }, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static int palmtt_panel_drv_init(void) | 116 | static int __init palmtt_panel_drv_init(void) |
117 | { | 117 | { |
118 | return platform_driver_register(&palmtt_panel_driver); | 118 | return platform_driver_register(&palmtt_panel_driver); |
119 | } | 119 | } |
120 | 120 | ||
121 | static void palmtt_panel_drv_cleanup(void) | 121 | static void __exit palmtt_panel_drv_cleanup(void) |
122 | { | 122 | { |
123 | platform_driver_unregister(&palmtt_panel_driver); | 123 | platform_driver_unregister(&palmtt_panel_driver); |
124 | } | 124 | } |
diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c index d33d78b11723..0697d29b4d3b 100644 --- a/drivers/video/omap/lcd_palmz71.c +++ b/drivers/video/omap/lcd_palmz71.c | |||
@@ -109,12 +109,12 @@ struct platform_driver palmz71_panel_driver = { | |||
109 | }, | 109 | }, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static int palmz71_panel_drv_init(void) | 112 | static int __init palmz71_panel_drv_init(void) |
113 | { | 113 | { |
114 | return platform_driver_register(&palmz71_panel_driver); | 114 | return platform_driver_register(&palmz71_panel_driver); |
115 | } | 115 | } |
116 | 116 | ||
117 | static void palmz71_panel_drv_cleanup(void) | 117 | static void __exit palmz71_panel_drv_cleanup(void) |
118 | { | 118 | { |
119 | platform_driver_unregister(&palmz71_panel_driver); | 119 | platform_driver_unregister(&palmz71_panel_driver); |
120 | } | 120 | } |
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 060d72fe57cb..0d0c8c8b9b56 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
@@ -67,6 +67,7 @@ static struct caps_table_struct ctrl_caps[] = { | |||
67 | { OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" }, | 67 | { OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" }, |
68 | { OMAPFB_CAPS_WINDOW_SCALE, "scale window" }, | 68 | { OMAPFB_CAPS_WINDOW_SCALE, "scale window" }, |
69 | { OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" }, | 69 | { OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" }, |
70 | { OMAPFB_CAPS_WINDOW_ROTATE, "rotate window" }, | ||
70 | { OMAPFB_CAPS_SET_BACKLIGHT, "backlight setting" }, | 71 | { OMAPFB_CAPS_SET_BACKLIGHT, "backlight setting" }, |
71 | }; | 72 | }; |
72 | 73 | ||
@@ -215,6 +216,15 @@ static int ctrl_change_mode(struct fb_info *fbi) | |||
215 | offset, var->xres_virtual, | 216 | offset, var->xres_virtual, |
216 | plane->info.pos_x, plane->info.pos_y, | 217 | plane->info.pos_x, plane->info.pos_y, |
217 | var->xres, var->yres, plane->color_mode); | 218 | var->xres, var->yres, plane->color_mode); |
219 | if (r < 0) | ||
220 | return r; | ||
221 | |||
222 | if (fbdev->ctrl->set_rotate != NULL) { | ||
223 | r = fbdev->ctrl->set_rotate(var->rotate); | ||
224 | if (r < 0) | ||
225 | return r; | ||
226 | } | ||
227 | |||
218 | if (fbdev->ctrl->set_scale != NULL) | 228 | if (fbdev->ctrl->set_scale != NULL) |
219 | r = fbdev->ctrl->set_scale(plane->idx, | 229 | r = fbdev->ctrl->set_scale(plane->idx, |
220 | var->xres, var->yres, | 230 | var->xres, var->yres, |
@@ -383,7 +393,7 @@ static void omapfb_sync(struct fb_info *fbi) | |||
383 | * Set fb_info.fix fields and also updates fbdev. | 393 | * Set fb_info.fix fields and also updates fbdev. |
384 | * When calling this fb_info.var must be set up already. | 394 | * When calling this fb_info.var must be set up already. |
385 | */ | 395 | */ |
386 | static void set_fb_fix(struct fb_info *fbi) | 396 | static void set_fb_fix(struct fb_info *fbi, int from_init) |
387 | { | 397 | { |
388 | struct fb_fix_screeninfo *fix = &fbi->fix; | 398 | struct fb_fix_screeninfo *fix = &fbi->fix; |
389 | struct fb_var_screeninfo *var = &fbi->var; | 399 | struct fb_var_screeninfo *var = &fbi->var; |
@@ -393,8 +403,16 @@ static void set_fb_fix(struct fb_info *fbi) | |||
393 | 403 | ||
394 | rg = &plane->fbdev->mem_desc.region[plane->idx]; | 404 | rg = &plane->fbdev->mem_desc.region[plane->idx]; |
395 | fbi->screen_base = rg->vaddr; | 405 | fbi->screen_base = rg->vaddr; |
396 | fix->smem_start = rg->paddr; | 406 | |
397 | fix->smem_len = rg->size; | 407 | if (!from_init) { |
408 | mutex_lock(&fbi->mm_lock); | ||
409 | fix->smem_start = rg->paddr; | ||
410 | fix->smem_len = rg->size; | ||
411 | mutex_unlock(&fbi->mm_lock); | ||
412 | } else { | ||
413 | fix->smem_start = rg->paddr; | ||
414 | fix->smem_len = rg->size; | ||
415 | } | ||
398 | 416 | ||
399 | fix->type = FB_TYPE_PACKED_PIXELS; | 417 | fix->type = FB_TYPE_PACKED_PIXELS; |
400 | bpp = var->bits_per_pixel; | 418 | bpp = var->bits_per_pixel; |
@@ -552,7 +570,6 @@ static int set_fb_var(struct fb_info *fbi, | |||
552 | var->xoffset = var->xres_virtual - var->xres; | 570 | var->xoffset = var->xres_virtual - var->xres; |
553 | if (var->yres + var->yoffset > var->yres_virtual) | 571 | if (var->yres + var->yoffset > var->yres_virtual) |
554 | var->yoffset = var->yres_virtual - var->yres; | 572 | var->yoffset = var->yres_virtual - var->yres; |
555 | line_size = var->xres * bpp / 8; | ||
556 | 573 | ||
557 | if (plane->color_mode == OMAPFB_COLOR_RGB444) { | 574 | if (plane->color_mode == OMAPFB_COLOR_RGB444) { |
558 | var->red.offset = 8; var->red.length = 4; | 575 | var->red.offset = 8; var->red.length = 4; |
@@ -598,7 +615,7 @@ static void omapfb_rotate(struct fb_info *fbi, int rotate) | |||
598 | struct omapfb_device *fbdev = plane->fbdev; | 615 | struct omapfb_device *fbdev = plane->fbdev; |
599 | 616 | ||
600 | omapfb_rqueue_lock(fbdev); | 617 | omapfb_rqueue_lock(fbdev); |
601 | if (cpu_is_omap15xx() && rotate != fbi->var.rotate) { | 618 | if (rotate != fbi->var.rotate) { |
602 | struct fb_var_screeninfo *new_var = &fbdev->new_var; | 619 | struct fb_var_screeninfo *new_var = &fbdev->new_var; |
603 | 620 | ||
604 | memcpy(new_var, &fbi->var, sizeof(*new_var)); | 621 | memcpy(new_var, &fbi->var, sizeof(*new_var)); |
@@ -693,7 +710,7 @@ static int omapfb_set_par(struct fb_info *fbi) | |||
693 | int r = 0; | 710 | int r = 0; |
694 | 711 | ||
695 | omapfb_rqueue_lock(fbdev); | 712 | omapfb_rqueue_lock(fbdev); |
696 | set_fb_fix(fbi); | 713 | set_fb_fix(fbi, 0); |
697 | r = ctrl_change_mode(fbi); | 714 | r = ctrl_change_mode(fbi); |
698 | omapfb_rqueue_unlock(fbdev); | 715 | omapfb_rqueue_unlock(fbdev); |
699 | 716 | ||
@@ -705,28 +722,42 @@ int omapfb_update_window_async(struct fb_info *fbi, | |||
705 | void (*callback)(void *), | 722 | void (*callback)(void *), |
706 | void *callback_data) | 723 | void *callback_data) |
707 | { | 724 | { |
725 | int xres, yres; | ||
708 | struct omapfb_plane_struct *plane = fbi->par; | 726 | struct omapfb_plane_struct *plane = fbi->par; |
709 | struct omapfb_device *fbdev = plane->fbdev; | 727 | struct omapfb_device *fbdev = plane->fbdev; |
710 | struct fb_var_screeninfo *var; | 728 | struct fb_var_screeninfo *var = &fbi->var; |
711 | 729 | ||
712 | var = &fbi->var; | 730 | switch (var->rotate) { |
713 | if (win->x >= var->xres || win->y >= var->yres || | 731 | case 0: |
714 | win->out_x > var->xres || win->out_y >= var->yres) | 732 | case 180: |
733 | xres = fbdev->panel->x_res; | ||
734 | yres = fbdev->panel->y_res; | ||
735 | break; | ||
736 | case 90: | ||
737 | case 270: | ||
738 | xres = fbdev->panel->y_res; | ||
739 | yres = fbdev->panel->x_res; | ||
740 | break; | ||
741 | default: | ||
742 | return -EINVAL; | ||
743 | } | ||
744 | |||
745 | if (win->x >= xres || win->y >= yres || | ||
746 | win->out_x > xres || win->out_y > yres) | ||
715 | return -EINVAL; | 747 | return -EINVAL; |
716 | 748 | ||
717 | if (!fbdev->ctrl->update_window || | 749 | if (!fbdev->ctrl->update_window || |
718 | fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE) | 750 | fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE) |
719 | return -ENODEV; | 751 | return -ENODEV; |
720 | 752 | ||
721 | if (win->x + win->width >= var->xres) | 753 | if (win->x + win->width > xres) |
722 | win->width = var->xres - win->x; | 754 | win->width = xres - win->x; |
723 | if (win->y + win->height >= var->yres) | 755 | if (win->y + win->height > yres) |
724 | win->height = var->yres - win->y; | 756 | win->height = yres - win->y; |
725 | /* The out sizes should be cropped to the LCD size */ | 757 | if (win->out_x + win->out_width > xres) |
726 | if (win->out_x + win->out_width > fbdev->panel->x_res) | 758 | win->out_width = xres - win->out_x; |
727 | win->out_width = fbdev->panel->x_res - win->out_x; | 759 | if (win->out_y + win->out_height > yres) |
728 | if (win->out_y + win->out_height > fbdev->panel->y_res) | 760 | win->out_height = yres - win->out_y; |
729 | win->out_height = fbdev->panel->y_res - win->out_y; | ||
730 | if (!win->width || !win->height || !win->out_width || !win->out_height) | 761 | if (!win->width || !win->height || !win->out_width || !win->out_height) |
731 | return 0; | 762 | return 0; |
732 | 763 | ||
@@ -879,15 +910,17 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) | |||
879 | if (old_size != size) { | 910 | if (old_size != size) { |
880 | if (size) { | 911 | if (size) { |
881 | memcpy(&fbi->var, new_var, sizeof(fbi->var)); | 912 | memcpy(&fbi->var, new_var, sizeof(fbi->var)); |
882 | set_fb_fix(fbi); | 913 | set_fb_fix(fbi, 0); |
883 | } else { | 914 | } else { |
884 | /* | 915 | /* |
885 | * Set these explicitly to indicate that the | 916 | * Set these explicitly to indicate that the |
886 | * plane memory is dealloce'd, the other | 917 | * plane memory is dealloce'd, the other |
887 | * screen parameters in var / fix are invalid. | 918 | * screen parameters in var / fix are invalid. |
888 | */ | 919 | */ |
920 | mutex_lock(&fbi->mm_lock); | ||
889 | fbi->fix.smem_start = 0; | 921 | fbi->fix.smem_start = 0; |
890 | fbi->fix.smem_len = 0; | 922 | fbi->fix.smem_len = 0; |
923 | mutex_unlock(&fbi->mm_lock); | ||
891 | } | 924 | } |
892 | } | 925 | } |
893 | } | 926 | } |
@@ -1250,7 +1283,7 @@ static struct fb_ops omapfb_ops = { | |||
1250 | static ssize_t omapfb_show_caps_num(struct device *dev, | 1283 | static ssize_t omapfb_show_caps_num(struct device *dev, |
1251 | struct device_attribute *attr, char *buf) | 1284 | struct device_attribute *attr, char *buf) |
1252 | { | 1285 | { |
1253 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1286 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1254 | int plane; | 1287 | int plane; |
1255 | size_t size; | 1288 | size_t size; |
1256 | struct omapfb_caps caps; | 1289 | struct omapfb_caps caps; |
@@ -1270,7 +1303,7 @@ static ssize_t omapfb_show_caps_num(struct device *dev, | |||
1270 | static ssize_t omapfb_show_caps_text(struct device *dev, | 1303 | static ssize_t omapfb_show_caps_text(struct device *dev, |
1271 | struct device_attribute *attr, char *buf) | 1304 | struct device_attribute *attr, char *buf) |
1272 | { | 1305 | { |
1273 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1306 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1274 | int i; | 1307 | int i; |
1275 | struct omapfb_caps caps; | 1308 | struct omapfb_caps caps; |
1276 | int plane; | 1309 | int plane; |
@@ -1317,7 +1350,7 @@ static DEVICE_ATTR(caps_text, 0444, omapfb_show_caps_text, NULL); | |||
1317 | static ssize_t omapfb_show_panel_name(struct device *dev, | 1350 | static ssize_t omapfb_show_panel_name(struct device *dev, |
1318 | struct device_attribute *attr, char *buf) | 1351 | struct device_attribute *attr, char *buf) |
1319 | { | 1352 | { |
1320 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1353 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1321 | 1354 | ||
1322 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); | 1355 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); |
1323 | } | 1356 | } |
@@ -1326,7 +1359,7 @@ static ssize_t omapfb_show_bklight_level(struct device *dev, | |||
1326 | struct device_attribute *attr, | 1359 | struct device_attribute *attr, |
1327 | char *buf) | 1360 | char *buf) |
1328 | { | 1361 | { |
1329 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1362 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1330 | int r; | 1363 | int r; |
1331 | 1364 | ||
1332 | if (fbdev->panel->get_bklight_level) { | 1365 | if (fbdev->panel->get_bklight_level) { |
@@ -1341,7 +1374,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, | |||
1341 | struct device_attribute *attr, | 1374 | struct device_attribute *attr, |
1342 | const char *buf, size_t size) | 1375 | const char *buf, size_t size) |
1343 | { | 1376 | { |
1344 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1377 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1345 | int r; | 1378 | int r; |
1346 | 1379 | ||
1347 | if (fbdev->panel->set_bklight_level) { | 1380 | if (fbdev->panel->set_bklight_level) { |
@@ -1360,7 +1393,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, | |||
1360 | static ssize_t omapfb_show_bklight_max(struct device *dev, | 1393 | static ssize_t omapfb_show_bklight_max(struct device *dev, |
1361 | struct device_attribute *attr, char *buf) | 1394 | struct device_attribute *attr, char *buf) |
1362 | { | 1395 | { |
1363 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1396 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1364 | int r; | 1397 | int r; |
1365 | 1398 | ||
1366 | if (fbdev->panel->get_bklight_level) { | 1399 | if (fbdev->panel->get_bklight_level) { |
@@ -1393,7 +1426,7 @@ static struct attribute_group panel_attr_grp = { | |||
1393 | static ssize_t omapfb_show_ctrl_name(struct device *dev, | 1426 | static ssize_t omapfb_show_ctrl_name(struct device *dev, |
1394 | struct device_attribute *attr, char *buf) | 1427 | struct device_attribute *attr, char *buf) |
1395 | { | 1428 | { |
1396 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1429 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1397 | 1430 | ||
1398 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); | 1431 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); |
1399 | } | 1432 | } |
@@ -1477,7 +1510,7 @@ static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info) | |||
1477 | var->bits_per_pixel = fbdev->panel->bpp; | 1510 | var->bits_per_pixel = fbdev->panel->bpp; |
1478 | 1511 | ||
1479 | set_fb_var(info, var); | 1512 | set_fb_var(info, var); |
1480 | set_fb_fix(info); | 1513 | set_fb_fix(info, 1); |
1481 | 1514 | ||
1482 | r = fb_alloc_cmap(&info->cmap, 16, 0); | 1515 | r = fb_alloc_cmap(&info->cmap, 16, 0); |
1483 | if (r != 0) | 1516 | if (r != 0) |
@@ -1695,8 +1728,8 @@ static int omapfb_do_probe(struct platform_device *pdev, | |||
1695 | 1728 | ||
1696 | pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); | 1729 | pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); |
1697 | 1730 | ||
1698 | def_vxres = def_vxres ? : fbdev->panel->x_res; | 1731 | def_vxres = def_vxres ? def_vxres : fbdev->panel->x_res; |
1699 | def_vyres = def_vyres ? : fbdev->panel->y_res; | 1732 | def_vyres = def_vyres ? def_vyres : fbdev->panel->y_res; |
1700 | 1733 | ||
1701 | init_state++; | 1734 | init_state++; |
1702 | 1735 | ||
@@ -1818,8 +1851,8 @@ static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1818 | { | 1851 | { |
1819 | struct omapfb_device *fbdev = platform_get_drvdata(pdev); | 1852 | struct omapfb_device *fbdev = platform_get_drvdata(pdev); |
1820 | 1853 | ||
1821 | omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]); | 1854 | if (fbdev != NULL) |
1822 | 1855 | omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]); | |
1823 | return 0; | 1856 | return 0; |
1824 | } | 1857 | } |
1825 | 1858 | ||
@@ -1828,7 +1861,8 @@ static int omapfb_resume(struct platform_device *pdev) | |||
1828 | { | 1861 | { |
1829 | struct omapfb_device *fbdev = platform_get_drvdata(pdev); | 1862 | struct omapfb_device *fbdev = platform_get_drvdata(pdev); |
1830 | 1863 | ||
1831 | omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]); | 1864 | if (fbdev != NULL) |
1865 | omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]); | ||
1832 | return 0; | 1866 | return 0; |
1833 | } | 1867 | } |
1834 | 1868 | ||
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index 9332d6ca6456..ee01e84e19c1 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c | |||
@@ -57,6 +57,7 @@ | |||
57 | 57 | ||
58 | #define DISPC_BASE 0x48050400 | 58 | #define DISPC_BASE 0x48050400 |
59 | #define DISPC_CONTROL 0x0040 | 59 | #define DISPC_CONTROL 0x0040 |
60 | #define DISPC_IRQ_FRAMEMASK 0x0001 | ||
60 | 61 | ||
61 | static struct { | 62 | static struct { |
62 | void __iomem *base; | 63 | void __iomem *base; |
@@ -553,7 +554,9 @@ static int rfbi_init(struct omapfb_device *fbdev) | |||
553 | l = (0x01 << 2); | 554 | l = (0x01 << 2); |
554 | rfbi_write_reg(RFBI_CONTROL, l); | 555 | rfbi_write_reg(RFBI_CONTROL, l); |
555 | 556 | ||
556 | if ((r = omap_dispc_request_irq(rfbi_dma_callback, NULL)) < 0) { | 557 | r = omap_dispc_request_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, |
558 | NULL); | ||
559 | if (r < 0) { | ||
557 | dev_err(fbdev->dev, "can't get DISPC irq\n"); | 560 | dev_err(fbdev->dev, "can't get DISPC irq\n"); |
558 | rfbi_enable_clocks(0); | 561 | rfbi_enable_clocks(0); |
559 | return r; | 562 | return r; |
@@ -570,7 +573,7 @@ static int rfbi_init(struct omapfb_device *fbdev) | |||
570 | 573 | ||
571 | static void rfbi_cleanup(void) | 574 | static void rfbi_cleanup(void) |
572 | { | 575 | { |
573 | omap_dispc_free_irq(); | 576 | omap_dispc_free_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, NULL); |
574 | rfbi_put_clocks(); | 577 | rfbi_put_clocks(); |
575 | iounmap(rfbi.base); | 578 | iounmap(rfbi.base); |
576 | } | 579 | } |
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 03b3670130a0..0a366d86f08e 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
@@ -141,7 +141,9 @@ static int platinumfb_set_par (struct fb_info *info) | |||
141 | offset = 0x10; | 141 | offset = 0x10; |
142 | 142 | ||
143 | info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; | 143 | info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; |
144 | mutex_lock(&info->mm_lock); | ||
144 | info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; | 145 | info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; |
146 | mutex_unlock(&info->mm_lock); | ||
145 | info->fix.visual = (pinfo->cmode == CMODE_8) ? | 147 | info->fix.visual = (pinfo->cmode == CMODE_8) ? |
146 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; | 148 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; |
147 | info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode) | 149 | info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode) |
@@ -221,10 +223,14 @@ static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
221 | 223 | ||
222 | static inline int platinum_vram_reqd(int video_mode, int color_mode) | 224 | static inline int platinum_vram_reqd(int video_mode, int color_mode) |
223 | { | 225 | { |
224 | return vmode_attrs[video_mode-1].vres * | 226 | int baseval = vmode_attrs[video_mode-1].hres * (1<<color_mode); |
225 | (vmode_attrs[video_mode-1].hres * (1<<color_mode) + | 227 | |
226 | ((video_mode == VMODE_832_624_75) && | 228 | if ((video_mode == VMODE_832_624_75) && (color_mode > CMODE_8)) |
227 | (color_mode > CMODE_8)) ? 0x10 : 0x20) + 0x1000; | 229 | baseval += 0x10; |
230 | else | ||
231 | baseval += 0x20; | ||
232 | |||
233 | return vmode_attrs[video_mode-1].vres * baseval + 0x1000; | ||
228 | } | 234 | } |
229 | 235 | ||
230 | #define STORE_D2(a, d) { \ | 236 | #define STORE_D2(a, d) { \ |
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index c0af638fe702..9c0144ee7ae5 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | 33 | ||
34 | #include <asm/abs_addr.h> | 34 | #include <asm/abs_addr.h> |
35 | #include <asm/iommu.h> | 35 | #include <asm/cell-regs.h> |
36 | #include <asm/lv1call.h> | 36 | #include <asm/lv1call.h> |
37 | #include <asm/ps3av.h> | 37 | #include <asm/ps3av.h> |
38 | #include <asm/ps3fb.h> | 38 | #include <asm/ps3fb.h> |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 0889d50c3288..1820c4a24434 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -815,8 +815,10 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) | |||
815 | ofb->video_mem_phys = virt_to_phys(ofb->video_mem); | 815 | ofb->video_mem_phys = virt_to_phys(ofb->video_mem); |
816 | ofb->video_mem_size = size; | 816 | ofb->video_mem_size = size; |
817 | 817 | ||
818 | mutex_lock(&ofb->fb.mm_lock); | ||
818 | ofb->fb.fix.smem_start = ofb->video_mem_phys; | 819 | ofb->fb.fix.smem_start = ofb->video_mem_phys; |
819 | ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; | 820 | ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; |
821 | mutex_unlock(&ofb->fb.mm_lock); | ||
820 | ofb->fb.screen_base = ofb->video_mem; | 822 | ofb->fb.screen_base = ofb->video_mem; |
821 | return 0; | 823 | return 0; |
822 | } | 824 | } |
@@ -1636,24 +1638,26 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data) | |||
1636 | * Power management hooks. Note that we won't be called from IRQ context, | 1638 | * Power management hooks. Note that we won't be called from IRQ context, |
1637 | * unlike the blank functions above, so we may sleep. | 1639 | * unlike the blank functions above, so we may sleep. |
1638 | */ | 1640 | */ |
1639 | static int pxafb_suspend(struct platform_device *dev, pm_message_t state) | 1641 | static int pxafb_suspend(struct device *dev) |
1640 | { | 1642 | { |
1641 | struct pxafb_info *fbi = platform_get_drvdata(dev); | 1643 | struct pxafb_info *fbi = dev_get_drvdata(dev); |
1642 | 1644 | ||
1643 | set_ctrlr_state(fbi, C_DISABLE_PM); | 1645 | set_ctrlr_state(fbi, C_DISABLE_PM); |
1644 | return 0; | 1646 | return 0; |
1645 | } | 1647 | } |
1646 | 1648 | ||
1647 | static int pxafb_resume(struct platform_device *dev) | 1649 | static int pxafb_resume(struct device *dev) |
1648 | { | 1650 | { |
1649 | struct pxafb_info *fbi = platform_get_drvdata(dev); | 1651 | struct pxafb_info *fbi = dev_get_drvdata(dev); |
1650 | 1652 | ||
1651 | set_ctrlr_state(fbi, C_ENABLE_PM); | 1653 | set_ctrlr_state(fbi, C_ENABLE_PM); |
1652 | return 0; | 1654 | return 0; |
1653 | } | 1655 | } |
1654 | #else | 1656 | |
1655 | #define pxafb_suspend NULL | 1657 | static struct dev_pm_ops pxafb_pm_ops = { |
1656 | #define pxafb_resume NULL | 1658 | .suspend = pxafb_suspend, |
1659 | .resume = pxafb_resume, | ||
1660 | }; | ||
1657 | #endif | 1661 | #endif |
1658 | 1662 | ||
1659 | static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi) | 1663 | static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi) |
@@ -2079,6 +2083,9 @@ static int __devinit pxafb_probe(struct platform_device *dev) | |||
2079 | goto failed; | 2083 | goto failed; |
2080 | } | 2084 | } |
2081 | 2085 | ||
2086 | if (cpu_is_pxa3xx() && inf->acceleration_enabled) | ||
2087 | fbi->fb.fix.accel = FB_ACCEL_PXA3XX; | ||
2088 | |||
2082 | fbi->backlight_power = inf->pxafb_backlight_power; | 2089 | fbi->backlight_power = inf->pxafb_backlight_power; |
2083 | fbi->lcd_power = inf->pxafb_lcd_power; | 2090 | fbi->lcd_power = inf->pxafb_lcd_power; |
2084 | 2091 | ||
@@ -2089,14 +2096,14 @@ static int __devinit pxafb_probe(struct platform_device *dev) | |||
2089 | goto failed_fbi; | 2096 | goto failed_fbi; |
2090 | } | 2097 | } |
2091 | 2098 | ||
2092 | r = request_mem_region(r->start, r->end - r->start + 1, dev->name); | 2099 | r = request_mem_region(r->start, resource_size(r), dev->name); |
2093 | if (r == NULL) { | 2100 | if (r == NULL) { |
2094 | dev_err(&dev->dev, "failed to request I/O memory\n"); | 2101 | dev_err(&dev->dev, "failed to request I/O memory\n"); |
2095 | ret = -EBUSY; | 2102 | ret = -EBUSY; |
2096 | goto failed_fbi; | 2103 | goto failed_fbi; |
2097 | } | 2104 | } |
2098 | 2105 | ||
2099 | fbi->mmio_base = ioremap(r->start, r->end - r->start + 1); | 2106 | fbi->mmio_base = ioremap(r->start, resource_size(r)); |
2100 | if (fbi->mmio_base == NULL) { | 2107 | if (fbi->mmio_base == NULL) { |
2101 | dev_err(&dev->dev, "failed to map I/O memory\n"); | 2108 | dev_err(&dev->dev, "failed to map I/O memory\n"); |
2102 | ret = -EBUSY; | 2109 | ret = -EBUSY; |
@@ -2195,7 +2202,7 @@ failed_free_dma: | |||
2195 | failed_free_io: | 2202 | failed_free_io: |
2196 | iounmap(fbi->mmio_base); | 2203 | iounmap(fbi->mmio_base); |
2197 | failed_free_res: | 2204 | failed_free_res: |
2198 | release_mem_region(r->start, r->end - r->start + 1); | 2205 | release_mem_region(r->start, resource_size(r)); |
2199 | failed_fbi: | 2206 | failed_fbi: |
2200 | clk_put(fbi->clk); | 2207 | clk_put(fbi->clk); |
2201 | platform_set_drvdata(dev, NULL); | 2208 | platform_set_drvdata(dev, NULL); |
@@ -2235,7 +2242,7 @@ static int __devexit pxafb_remove(struct platform_device *dev) | |||
2235 | iounmap(fbi->mmio_base); | 2242 | iounmap(fbi->mmio_base); |
2236 | 2243 | ||
2237 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | 2244 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); |
2238 | release_mem_region(r->start, r->end - r->start + 1); | 2245 | release_mem_region(r->start, resource_size(r)); |
2239 | 2246 | ||
2240 | clk_put(fbi->clk); | 2247 | clk_put(fbi->clk); |
2241 | kfree(fbi); | 2248 | kfree(fbi); |
@@ -2246,11 +2253,12 @@ static int __devexit pxafb_remove(struct platform_device *dev) | |||
2246 | static struct platform_driver pxafb_driver = { | 2253 | static struct platform_driver pxafb_driver = { |
2247 | .probe = pxafb_probe, | 2254 | .probe = pxafb_probe, |
2248 | .remove = __devexit_p(pxafb_remove), | 2255 | .remove = __devexit_p(pxafb_remove), |
2249 | .suspend = pxafb_suspend, | ||
2250 | .resume = pxafb_resume, | ||
2251 | .driver = { | 2256 | .driver = { |
2252 | .owner = THIS_MODULE, | 2257 | .owner = THIS_MODULE, |
2253 | .name = "pxa2xx-fb", | 2258 | .name = "pxa2xx-fb", |
2259 | #ifdef CONFIG_PM | ||
2260 | .pm = &pxafb_pm_ops, | ||
2261 | #endif | ||
2254 | }, | 2262 | }, |
2255 | }; | 2263 | }; |
2256 | 2264 | ||
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 43680e545427..adf9632c6b1f 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -211,23 +211,21 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, | |||
211 | 211 | ||
212 | /** | 212 | /** |
213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. | 213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. |
214 | * @id: window id. | ||
214 | * @sfb: The hardware state. | 215 | * @sfb: The hardware state. |
215 | * @pixclock: The pixel clock wanted, in picoseconds. | 216 | * @pixclock: The pixel clock wanted, in picoseconds. |
216 | * | 217 | * |
217 | * Given the specified pixel clock, work out the necessary divider to get | 218 | * Given the specified pixel clock, work out the necessary divider to get |
218 | * close to the output frequency. | 219 | * close to the output frequency. |
219 | */ | 220 | */ |
220 | static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) | 221 | static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk) |
221 | { | 222 | { |
223 | struct s3c_fb_pd_win *win = sfb->pdata->win[id]; | ||
222 | unsigned long clk = clk_get_rate(sfb->bus_clk); | 224 | unsigned long clk = clk_get_rate(sfb->bus_clk); |
223 | unsigned long long tmp; | ||
224 | unsigned int result; | 225 | unsigned int result; |
225 | 226 | ||
226 | tmp = (unsigned long long)clk; | 227 | pixclk *= win->win_mode.refresh; |
227 | tmp *= pixclk; | 228 | result = clk / pixclk; |
228 | |||
229 | do_div(tmp, 1000000000UL); | ||
230 | result = (unsigned int)tmp / 1000; | ||
231 | 229 | ||
232 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", | 230 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", |
233 | pixclk, clk, result, clk / result); | 231 | pixclk, clk, result, clk / result); |
@@ -267,6 +265,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
267 | struct s3c_fb *sfb = win->parent; | 265 | struct s3c_fb *sfb = win->parent; |
268 | void __iomem *regs = sfb->regs; | 266 | void __iomem *regs = sfb->regs; |
269 | int win_no = win->index; | 267 | int win_no = win->index; |
268 | u32 osdc_data = 0; | ||
270 | u32 data; | 269 | u32 data; |
271 | u32 pagewidth; | 270 | u32 pagewidth; |
272 | int clkdiv; | 271 | int clkdiv; |
@@ -302,7 +301,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
302 | /* use window 0 as the basis for the lcd output timings */ | 301 | /* use window 0 as the basis for the lcd output timings */ |
303 | 302 | ||
304 | if (win_no == 0) { | 303 | if (win_no == 0) { |
305 | clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); | 304 | clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock); |
306 | 305 | ||
307 | data = sfb->pdata->vidcon0; | 306 | data = sfb->pdata->vidcon0; |
308 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); | 307 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); |
@@ -359,8 +358,6 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
359 | 358 | ||
360 | data = var->xres * var->yres; | 359 | data = var->xres * var->yres; |
361 | 360 | ||
362 | u32 osdc_data = 0; | ||
363 | |||
364 | osdc_data = VIDISD14C_ALPHA1_R(0xf) | | 361 | osdc_data = VIDISD14C_ALPHA1_R(0xf) | |
365 | VIDISD14C_ALPHA1_G(0xf) | | 362 | VIDISD14C_ALPHA1_G(0xf) | |
366 | VIDISD14C_ALPHA1_B(0xf); | 363 | VIDISD14C_ALPHA1_B(0xf); |
@@ -967,7 +964,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) | |||
967 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | 964 | struct s3c_fb *sfb = platform_get_drvdata(pdev); |
968 | int win; | 965 | int win; |
969 | 966 | ||
970 | for (win = 0; win <= S3C_FB_MAX_WIN; win++) | 967 | for (win = 0; win < S3C_FB_MAX_WIN; win++) |
971 | if (sfb->windows[win]) | 968 | if (sfb->windows[win]) |
972 | s3c_fb_release_win(sfb, sfb->windows[win]); | 969 | s3c_fb_release_win(sfb, sfb->windows[win]); |
973 | 970 | ||
@@ -991,7 +988,7 @@ static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state) | |||
991 | struct s3c_fb_win *win; | 988 | struct s3c_fb_win *win; |
992 | int win_no; | 989 | int win_no; |
993 | 990 | ||
994 | for (win_no = S3C_FB_MAX_WIN; win_no >= 0; win_no--) { | 991 | for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) { |
995 | win = sfb->windows[win_no]; | 992 | win = sfb->windows[win_no]; |
996 | if (!win) | 993 | if (!win) |
997 | continue; | 994 | continue; |
@@ -1039,7 +1036,7 @@ static int s3c_fb_resume(struct platform_device *pdev) | |||
1039 | 1036 | ||
1040 | static struct platform_driver s3c_fb_driver = { | 1037 | static struct platform_driver s3c_fb_driver = { |
1041 | .probe = s3c_fb_probe, | 1038 | .probe = s3c_fb_probe, |
1042 | .remove = s3c_fb_remove, | 1039 | .remove = __devexit_p(s3c_fb_remove), |
1043 | .suspend = s3c_fb_suspend, | 1040 | .suspend = s3c_fb_suspend, |
1044 | .resume = s3c_fb_resume, | 1041 | .resume = s3c_fb_resume, |
1045 | .driver = { | 1042 | .driver = { |
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 7da0027e2409..aac661225c78 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -369,7 +369,9 @@ static void s3c2410fb_activate_var(struct fb_info *info) | |||
369 | void __iomem *regs = fbi->io; | 369 | void __iomem *regs = fbi->io; |
370 | int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT; | 370 | int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT; |
371 | struct fb_var_screeninfo *var = &info->var; | 371 | struct fb_var_screeninfo *var = &info->var; |
372 | int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock) / 2; | 372 | int clkdiv; |
373 | |||
374 | clkdiv = DIV_ROUND_UP(s3c2410fb_calc_pixclk(fbi, var->pixclock), 2); | ||
373 | 375 | ||
374 | dprintk("%s: var->xres = %d\n", __func__, var->xres); | 376 | dprintk("%s: var->xres = %d\n", __func__, var->xres); |
375 | dprintk("%s: var->yres = %d\n", __func__, var->yres); | 377 | dprintk("%s: var->yres = %d\n", __func__, var->yres); |
@@ -1119,7 +1121,7 @@ int __init s3c2410fb_init(void) | |||
1119 | int ret = platform_driver_register(&s3c2410fb_driver); | 1121 | int ret = platform_driver_register(&s3c2410fb_driver); |
1120 | 1122 | ||
1121 | if (ret == 0) | 1123 | if (ret == 0) |
1122 | ret = platform_driver_register(&s3c2412fb_driver);; | 1124 | ret = platform_driver_register(&s3c2412fb_driver); |
1123 | 1125 | ||
1124 | return ret; | 1126 | return ret; |
1125 | } | 1127 | } |
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 10ddad8e17d6..cdaa873a6054 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c | |||
@@ -66,7 +66,7 @@ | |||
66 | * - FrameBuffer memory is now allocated at run-time when the | 66 | * - FrameBuffer memory is now allocated at run-time when the |
67 | * driver is initialized. | 67 | * driver is initialized. |
68 | * | 68 | * |
69 | * 2000/04/10: Nicolas Pitre <nico@cam.org> | 69 | * 2000/04/10: Nicolas Pitre <nico@fluxnic.net> |
70 | * - Big cleanup for dynamic selection of machine type at run time. | 70 | * - Big cleanup for dynamic selection of machine type at run time. |
71 | * | 71 | * |
72 | * 2000/07/19: Jamey Hicks <jamey@crl.dec.com> | 72 | * 2000/07/19: Jamey Hicks <jamey@crl.dec.com> |
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 37b135d5d12e..842d157e1025 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c | |||
@@ -1565,7 +1565,7 @@ static int savagefb_blank(int blank, struct fb_info *info) | |||
1565 | vga_out8(0x3c5, sr8, par); | 1565 | vga_out8(0x3c5, sr8, par); |
1566 | vga_out8(0x3c4, 0x0d, par); | 1566 | vga_out8(0x3c4, 0x0d, par); |
1567 | srd = vga_in8(0x3c5, par); | 1567 | srd = vga_in8(0x3c5, par); |
1568 | srd &= 0x03; | 1568 | srd &= 0x50; |
1569 | 1569 | ||
1570 | switch (blank) { | 1570 | switch (blank) { |
1571 | case FB_BLANK_UNBLANK: | 1571 | case FB_BLANK_UNBLANK: |
@@ -1606,22 +1606,6 @@ static int savagefb_blank(int blank, struct fb_info *info) | |||
1606 | return (blank == FB_BLANK_NORMAL) ? 1 : 0; | 1606 | return (blank == FB_BLANK_NORMAL) ? 1 : 0; |
1607 | } | 1607 | } |
1608 | 1608 | ||
1609 | static void savagefb_save_state(struct fb_info *info) | ||
1610 | { | ||
1611 | struct savagefb_par *par = info->par; | ||
1612 | |||
1613 | savage_get_default_par(par, &par->save); | ||
1614 | } | ||
1615 | |||
1616 | static void savagefb_restore_state(struct fb_info *info) | ||
1617 | { | ||
1618 | struct savagefb_par *par = info->par; | ||
1619 | |||
1620 | savagefb_blank(FB_BLANK_POWERDOWN, info); | ||
1621 | savage_set_default_par(par, &par->save); | ||
1622 | savagefb_blank(FB_BLANK_UNBLANK, info); | ||
1623 | } | ||
1624 | |||
1625 | static int savagefb_open(struct fb_info *info, int user) | 1609 | static int savagefb_open(struct fb_info *info, int user) |
1626 | { | 1610 | { |
1627 | struct savagefb_par *par = info->par; | 1611 | struct savagefb_par *par = info->par; |
@@ -1667,8 +1651,6 @@ static struct fb_ops savagefb_ops = { | |||
1667 | .fb_setcolreg = savagefb_setcolreg, | 1651 | .fb_setcolreg = savagefb_setcolreg, |
1668 | .fb_pan_display = savagefb_pan_display, | 1652 | .fb_pan_display = savagefb_pan_display, |
1669 | .fb_blank = savagefb_blank, | 1653 | .fb_blank = savagefb_blank, |
1670 | .fb_save_state = savagefb_save_state, | ||
1671 | .fb_restore_state = savagefb_restore_state, | ||
1672 | #if defined(CONFIG_FB_SAVAGE_ACCEL) | 1654 | #if defined(CONFIG_FB_SAVAGE_ACCEL) |
1673 | .fb_fillrect = savagefb_fillrect, | 1655 | .fb_fillrect = savagefb_fillrect, |
1674 | .fb_copyarea = savagefb_copyarea, | 1656 | .fb_copyarea = savagefb_copyarea, |
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c index 653bdfee3057..9f6d6e61f0cc 100644 --- a/drivers/video/sh7760fb.c +++ b/drivers/video/sh7760fb.c | |||
@@ -120,18 +120,6 @@ static int sh7760_setcolreg (u_int regno, | |||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, | ||
124 | unsigned long stride) | ||
125 | { | ||
126 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | ||
127 | strcpy(fix->id, "sh7760-lcdc"); | ||
128 | |||
129 | fix->smem_start = (unsigned long)info->screen_base; | ||
130 | fix->smem_len = info->screen_size; | ||
131 | |||
132 | fix->line_length = stride; | ||
133 | } | ||
134 | |||
135 | static int sh7760fb_get_color_info(struct device *dev, | 123 | static int sh7760fb_get_color_info(struct device *dev, |
136 | u16 lddfr, int *bpp, int *gray) | 124 | u16 lddfr, int *bpp, int *gray) |
137 | { | 125 | { |
@@ -334,7 +322,8 @@ static int sh7760fb_set_par(struct fb_info *info) | |||
334 | 322 | ||
335 | iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */ | 323 | iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */ |
336 | 324 | ||
337 | encode_fix(&info->fix, info, stride); | 325 | info->fix.line_length = stride; |
326 | |||
338 | sh7760fb_check_var(&info->var, info); | 327 | sh7760fb_check_var(&info->var, info); |
339 | 328 | ||
340 | sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */ | 329 | sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */ |
@@ -435,6 +424,8 @@ static int sh7760fb_alloc_mem(struct fb_info *info) | |||
435 | 424 | ||
436 | info->screen_base = fbmem; | 425 | info->screen_base = fbmem; |
437 | info->screen_size = vram; | 426 | info->screen_size = vram; |
427 | info->fix.smem_start = (unsigned long)info->screen_base; | ||
428 | info->fix.smem_len = info->screen_size; | ||
438 | 429 | ||
439 | return 0; | 430 | return 0; |
440 | } | 431 | } |
@@ -520,6 +511,8 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev) | |||
520 | info->var.transp.length = 0; | 511 | info->var.transp.length = 0; |
521 | info->var.transp.msb_right = 0; | 512 | info->var.transp.msb_right = 0; |
522 | 513 | ||
514 | strcpy(info->fix.id, "sh7760-lcdc"); | ||
515 | |||
523 | /* set the DON2 bit now, before cmap allocation, as it will randomize | 516 | /* set the DON2 bit now, before cmap allocation, as it will randomize |
524 | * palette memory. | 517 | * palette memory. |
525 | */ | 518 | */ |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index f10d2fbeda06..3ad5157f9899 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -14,41 +14,17 @@ | |||
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/pm_runtime.h> | ||
17 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
18 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
19 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/vmalloc.h> | ||
20 | #include <video/sh_mobile_lcdc.h> | 22 | #include <video/sh_mobile_lcdc.h> |
21 | #include <asm/atomic.h> | 23 | #include <asm/atomic.h> |
22 | 24 | ||
23 | #define PALETTE_NR 16 | 25 | #define PALETTE_NR 16 |
24 | 26 | #define SIDE_B_OFFSET 0x1000 | |
25 | struct sh_mobile_lcdc_priv; | 27 | #define MIRROR_OFFSET 0x2000 |
26 | struct sh_mobile_lcdc_chan { | ||
27 | struct sh_mobile_lcdc_priv *lcdc; | ||
28 | unsigned long *reg_offs; | ||
29 | unsigned long ldmt1r_value; | ||
30 | unsigned long enabled; /* ME and SE in LDCNT2R */ | ||
31 | struct sh_mobile_lcdc_chan_cfg cfg; | ||
32 | u32 pseudo_palette[PALETTE_NR]; | ||
33 | struct fb_info info; | ||
34 | dma_addr_t dma_handle; | ||
35 | struct fb_deferred_io defio; | ||
36 | unsigned long frame_end; | ||
37 | wait_queue_head_t frame_end_wait; | ||
38 | }; | ||
39 | |||
40 | struct sh_mobile_lcdc_priv { | ||
41 | void __iomem *base; | ||
42 | int irq; | ||
43 | #ifdef CONFIG_HAVE_CLK | ||
44 | atomic_t clk_usecnt; | ||
45 | struct clk *dot_clk; | ||
46 | struct clk *clk; | ||
47 | #endif | ||
48 | unsigned long lddckr; | ||
49 | struct sh_mobile_lcdc_chan ch[2]; | ||
50 | int started; | ||
51 | }; | ||
52 | 28 | ||
53 | /* shared registers */ | 29 | /* shared registers */ |
54 | #define _LDDCKR 0x410 | 30 | #define _LDDCKR 0x410 |
@@ -57,17 +33,30 @@ struct sh_mobile_lcdc_priv { | |||
57 | #define _LDSR 0x46c | 33 | #define _LDSR 0x46c |
58 | #define _LDCNT1R 0x470 | 34 | #define _LDCNT1R 0x470 |
59 | #define _LDCNT2R 0x474 | 35 | #define _LDCNT2R 0x474 |
36 | #define _LDRCNTR 0x478 | ||
60 | #define _LDDDSR 0x47c | 37 | #define _LDDDSR 0x47c |
61 | #define _LDDWD0R 0x800 | 38 | #define _LDDWD0R 0x800 |
62 | #define _LDDRDR 0x840 | 39 | #define _LDDRDR 0x840 |
63 | #define _LDDWAR 0x900 | 40 | #define _LDDWAR 0x900 |
64 | #define _LDDRAR 0x904 | 41 | #define _LDDRAR 0x904 |
65 | 42 | ||
43 | /* shared registers and their order for context save/restore */ | ||
44 | static int lcdc_shared_regs[] = { | ||
45 | _LDDCKR, | ||
46 | _LDDCKSTPR, | ||
47 | _LDINTR, | ||
48 | _LDDDSR, | ||
49 | _LDCNT1R, | ||
50 | _LDCNT2R, | ||
51 | }; | ||
52 | #define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) | ||
53 | |||
66 | /* per-channel registers */ | 54 | /* per-channel registers */ |
67 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, | 55 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, |
68 | LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR }; | 56 | LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, |
57 | NR_CH_REGS }; | ||
69 | 58 | ||
70 | static unsigned long lcdc_offs_mainlcd[] = { | 59 | static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { |
71 | [LDDCKPAT1R] = 0x400, | 60 | [LDDCKPAT1R] = 0x400, |
72 | [LDDCKPAT2R] = 0x404, | 61 | [LDDCKPAT2R] = 0x404, |
73 | [LDMT1R] = 0x418, | 62 | [LDMT1R] = 0x418, |
@@ -85,7 +74,7 @@ static unsigned long lcdc_offs_mainlcd[] = { | |||
85 | [LDPMR] = 0x460, | 74 | [LDPMR] = 0x460, |
86 | }; | 75 | }; |
87 | 76 | ||
88 | static unsigned long lcdc_offs_sublcd[] = { | 77 | static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = { |
89 | [LDDCKPAT1R] = 0x408, | 78 | [LDDCKPAT1R] = 0x408, |
90 | [LDDCKPAT2R] = 0x40c, | 79 | [LDDCKPAT2R] = 0x40c, |
91 | [LDMT1R] = 0x600, | 80 | [LDMT1R] = 0x600, |
@@ -108,12 +97,80 @@ static unsigned long lcdc_offs_sublcd[] = { | |||
108 | #define DISPLAY_BEU 0x00000008 | 97 | #define DISPLAY_BEU 0x00000008 |
109 | #define LCDC_ENABLE 0x00000001 | 98 | #define LCDC_ENABLE 0x00000001 |
110 | #define LDINTR_FE 0x00000400 | 99 | #define LDINTR_FE 0x00000400 |
100 | #define LDINTR_VSE 0x00000200 | ||
101 | #define LDINTR_VEE 0x00000100 | ||
111 | #define LDINTR_FS 0x00000004 | 102 | #define LDINTR_FS 0x00000004 |
103 | #define LDINTR_VSS 0x00000002 | ||
104 | #define LDINTR_VES 0x00000001 | ||
105 | #define LDRCNTR_SRS 0x00020000 | ||
106 | #define LDRCNTR_SRC 0x00010000 | ||
107 | #define LDRCNTR_MRS 0x00000002 | ||
108 | #define LDRCNTR_MRC 0x00000001 | ||
109 | |||
110 | struct sh_mobile_lcdc_priv; | ||
111 | struct sh_mobile_lcdc_chan { | ||
112 | struct sh_mobile_lcdc_priv *lcdc; | ||
113 | unsigned long *reg_offs; | ||
114 | unsigned long ldmt1r_value; | ||
115 | unsigned long enabled; /* ME and SE in LDCNT2R */ | ||
116 | struct sh_mobile_lcdc_chan_cfg cfg; | ||
117 | u32 pseudo_palette[PALETTE_NR]; | ||
118 | unsigned long saved_ch_regs[NR_CH_REGS]; | ||
119 | struct fb_info *info; | ||
120 | dma_addr_t dma_handle; | ||
121 | struct fb_deferred_io defio; | ||
122 | struct scatterlist *sglist; | ||
123 | unsigned long frame_end; | ||
124 | unsigned long pan_offset; | ||
125 | unsigned long new_pan_offset; | ||
126 | wait_queue_head_t frame_end_wait; | ||
127 | }; | ||
128 | |||
129 | struct sh_mobile_lcdc_priv { | ||
130 | void __iomem *base; | ||
131 | int irq; | ||
132 | atomic_t hw_usecnt; | ||
133 | struct device *dev; | ||
134 | struct clk *dot_clk; | ||
135 | unsigned long lddckr; | ||
136 | struct sh_mobile_lcdc_chan ch[2]; | ||
137 | unsigned long saved_shared_regs[NR_SHARED_REGS]; | ||
138 | int started; | ||
139 | }; | ||
140 | |||
141 | static bool banked(int reg_nr) | ||
142 | { | ||
143 | switch (reg_nr) { | ||
144 | case LDMT1R: | ||
145 | case LDMT2R: | ||
146 | case LDMT3R: | ||
147 | case LDDFR: | ||
148 | case LDSM1R: | ||
149 | case LDSA1R: | ||
150 | case LDMLSR: | ||
151 | case LDHCNR: | ||
152 | case LDHSYNR: | ||
153 | case LDVLNR: | ||
154 | case LDVSYNR: | ||
155 | return true; | ||
156 | } | ||
157 | return false; | ||
158 | } | ||
112 | 159 | ||
113 | static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, | 160 | static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, |
114 | int reg_nr, unsigned long data) | 161 | int reg_nr, unsigned long data) |
115 | { | 162 | { |
116 | iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); | 163 | iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); |
164 | if (banked(reg_nr)) | ||
165 | iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + | ||
166 | SIDE_B_OFFSET); | ||
167 | } | ||
168 | |||
169 | static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan, | ||
170 | int reg_nr, unsigned long data) | ||
171 | { | ||
172 | iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + | ||
173 | MIRROR_OFFSET); | ||
117 | } | 174 | } |
118 | 175 | ||
119 | static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan, | 176 | static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan, |
@@ -154,6 +211,7 @@ static void lcdc_sys_write_index(void *handle, unsigned long data) | |||
154 | lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000); | 211 | lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000); |
155 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); | 212 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); |
156 | lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); | 213 | lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); |
214 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); | ||
157 | } | 215 | } |
158 | 216 | ||
159 | static void lcdc_sys_write_data(void *handle, unsigned long data) | 217 | static void lcdc_sys_write_data(void *handle, unsigned long data) |
@@ -163,6 +221,7 @@ static void lcdc_sys_write_data(void *handle, unsigned long data) | |||
163 | lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000); | 221 | lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000); |
164 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); | 222 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); |
165 | lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); | 223 | lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); |
224 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); | ||
166 | } | 225 | } |
167 | 226 | ||
168 | static unsigned long lcdc_sys_read_data(void *handle) | 227 | static unsigned long lcdc_sys_read_data(void *handle) |
@@ -173,8 +232,9 @@ static unsigned long lcdc_sys_read_data(void *handle) | |||
173 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); | 232 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); |
174 | lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); | 233 | lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); |
175 | udelay(1); | 234 | udelay(1); |
235 | lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); | ||
176 | 236 | ||
177 | return lcdc_read(ch->lcdc, _LDDRDR) & 0xffff; | 237 | return lcdc_read(ch->lcdc, _LDDRDR) & 0x3ffff; |
178 | } | 238 | } |
179 | 239 | ||
180 | struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { | 240 | struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { |
@@ -183,11 +243,10 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { | |||
183 | lcdc_sys_read_data, | 243 | lcdc_sys_read_data, |
184 | }; | 244 | }; |
185 | 245 | ||
186 | #ifdef CONFIG_HAVE_CLK | ||
187 | static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) | 246 | static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) |
188 | { | 247 | { |
189 | if (atomic_inc_and_test(&priv->clk_usecnt)) { | 248 | if (atomic_inc_and_test(&priv->hw_usecnt)) { |
190 | clk_enable(priv->clk); | 249 | pm_runtime_get_sync(priv->dev); |
191 | if (priv->dot_clk) | 250 | if (priv->dot_clk) |
192 | clk_enable(priv->dot_clk); | 251 | clk_enable(priv->dot_clk); |
193 | } | 252 | } |
@@ -195,27 +254,45 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) | |||
195 | 254 | ||
196 | static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) | 255 | static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) |
197 | { | 256 | { |
198 | if (atomic_sub_return(1, &priv->clk_usecnt) == -1) { | 257 | if (atomic_sub_return(1, &priv->hw_usecnt) == -1) { |
199 | if (priv->dot_clk) | 258 | if (priv->dot_clk) |
200 | clk_disable(priv->dot_clk); | 259 | clk_disable(priv->dot_clk); |
201 | clk_disable(priv->clk); | 260 | pm_runtime_put(priv->dev); |
202 | } | 261 | } |
203 | } | 262 | } |
204 | #else | 263 | |
205 | static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {} | 264 | static int sh_mobile_lcdc_sginit(struct fb_info *info, |
206 | static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {} | 265 | struct list_head *pagelist) |
207 | #endif | 266 | { |
267 | struct sh_mobile_lcdc_chan *ch = info->par; | ||
268 | unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT; | ||
269 | struct page *page; | ||
270 | int nr_pages = 0; | ||
271 | |||
272 | sg_init_table(ch->sglist, nr_pages_max); | ||
273 | |||
274 | list_for_each_entry(page, pagelist, lru) | ||
275 | sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0); | ||
276 | |||
277 | return nr_pages; | ||
278 | } | ||
208 | 279 | ||
209 | static void sh_mobile_lcdc_deferred_io(struct fb_info *info, | 280 | static void sh_mobile_lcdc_deferred_io(struct fb_info *info, |
210 | struct list_head *pagelist) | 281 | struct list_head *pagelist) |
211 | { | 282 | { |
212 | struct sh_mobile_lcdc_chan *ch = info->par; | 283 | struct sh_mobile_lcdc_chan *ch = info->par; |
284 | unsigned int nr_pages; | ||
213 | 285 | ||
214 | /* enable clocks before accessing hardware */ | 286 | /* enable clocks before accessing hardware */ |
215 | sh_mobile_lcdc_clk_on(ch->lcdc); | 287 | sh_mobile_lcdc_clk_on(ch->lcdc); |
216 | 288 | ||
289 | nr_pages = sh_mobile_lcdc_sginit(info, pagelist); | ||
290 | dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | ||
291 | |||
217 | /* trigger panel update */ | 292 | /* trigger panel update */ |
218 | lcdc_write_chan(ch, LDSM2R, 1); | 293 | lcdc_write_chan(ch, LDSM2R, 1); |
294 | |||
295 | dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | ||
219 | } | 296 | } |
220 | 297 | ||
221 | static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) | 298 | static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) |
@@ -231,30 +308,52 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) | |||
231 | struct sh_mobile_lcdc_priv *priv = data; | 308 | struct sh_mobile_lcdc_priv *priv = data; |
232 | struct sh_mobile_lcdc_chan *ch; | 309 | struct sh_mobile_lcdc_chan *ch; |
233 | unsigned long tmp; | 310 | unsigned long tmp; |
311 | unsigned long ldintr; | ||
234 | int is_sub; | 312 | int is_sub; |
235 | int k; | 313 | int k; |
236 | 314 | ||
237 | /* acknowledge interrupt */ | 315 | /* acknowledge interrupt */ |
238 | tmp = lcdc_read(priv, _LDINTR); | 316 | ldintr = tmp = lcdc_read(priv, _LDINTR); |
239 | tmp &= 0xffffff00; /* mask in high 24 bits */ | 317 | /* |
240 | tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */ | 318 | * disable further VSYNC End IRQs, preserve all other enabled IRQs, |
319 | * write 0 to bits 0-6 to ack all triggered IRQs. | ||
320 | */ | ||
321 | tmp &= 0xffffff00 & ~LDINTR_VEE; | ||
241 | lcdc_write(priv, _LDINTR, tmp); | 322 | lcdc_write(priv, _LDINTR, tmp); |
242 | 323 | ||
243 | /* figure out if this interrupt is for main or sub lcd */ | 324 | /* figure out if this interrupt is for main or sub lcd */ |
244 | is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0; | 325 | is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0; |
245 | 326 | ||
246 | /* wake up channel and disable clocks*/ | 327 | /* wake up channel and disable clocks */ |
247 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 328 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
248 | ch = &priv->ch[k]; | 329 | ch = &priv->ch[k]; |
249 | 330 | ||
250 | if (!ch->enabled) | 331 | if (!ch->enabled) |
251 | continue; | 332 | continue; |
252 | 333 | ||
253 | if (is_sub == lcdc_chan_is_sublcd(ch)) { | 334 | /* Frame Start */ |
254 | ch->frame_end = 1; | 335 | if (ldintr & LDINTR_FS) { |
255 | wake_up(&ch->frame_end_wait); | 336 | if (is_sub == lcdc_chan_is_sublcd(ch)) { |
337 | ch->frame_end = 1; | ||
338 | wake_up(&ch->frame_end_wait); | ||
256 | 339 | ||
257 | sh_mobile_lcdc_clk_off(priv); | 340 | sh_mobile_lcdc_clk_off(priv); |
341 | } | ||
342 | } | ||
343 | |||
344 | /* VSYNC End */ | ||
345 | if (ldintr & LDINTR_VES) { | ||
346 | unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR); | ||
347 | /* Set the source address for the next refresh */ | ||
348 | lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + | ||
349 | ch->new_pan_offset); | ||
350 | if (lcdc_chan_is_sublcd(ch)) | ||
351 | lcdc_write(ch->lcdc, _LDRCNTR, | ||
352 | ldrcntr ^ LDRCNTR_SRS); | ||
353 | else | ||
354 | lcdc_write(ch->lcdc, _LDRCNTR, | ||
355 | ldrcntr ^ LDRCNTR_MRS); | ||
356 | ch->pan_offset = ch->new_pan_offset; | ||
258 | } | 357 | } |
259 | } | 358 | } |
260 | 359 | ||
@@ -418,22 +517,22 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
418 | /* set bpp format in PKF[4:0] */ | 517 | /* set bpp format in PKF[4:0] */ |
419 | tmp = lcdc_read_chan(ch, LDDFR); | 518 | tmp = lcdc_read_chan(ch, LDDFR); |
420 | tmp &= ~(0x0001001f); | 519 | tmp &= ~(0x0001001f); |
421 | tmp |= (priv->ch[k].info.var.bits_per_pixel == 16) ? 3 : 0; | 520 | tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0; |
422 | lcdc_write_chan(ch, LDDFR, tmp); | 521 | lcdc_write_chan(ch, LDDFR, tmp); |
423 | 522 | ||
424 | /* point out our frame buffer */ | 523 | /* point out our frame buffer */ |
425 | lcdc_write_chan(ch, LDSA1R, ch->info.fix.smem_start); | 524 | lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start); |
426 | 525 | ||
427 | /* set line size */ | 526 | /* set line size */ |
428 | lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length); | 527 | lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length); |
429 | 528 | ||
430 | /* setup deferred io if SYS bus */ | 529 | /* setup deferred io if SYS bus */ |
431 | tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; | 530 | tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; |
432 | if (ch->ldmt1r_value & (1 << 12) && tmp) { | 531 | if (ch->ldmt1r_value & (1 << 12) && tmp) { |
433 | ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; | 532 | ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; |
434 | ch->defio.delay = msecs_to_jiffies(tmp); | 533 | ch->defio.delay = msecs_to_jiffies(tmp); |
435 | ch->info.fbdefio = &ch->defio; | 534 | ch->info->fbdefio = &ch->defio; |
436 | fb_deferred_io_init(&ch->info); | 535 | fb_deferred_io_init(ch->info); |
437 | 536 | ||
438 | /* one-shot mode */ | 537 | /* one-shot mode */ |
439 | lcdc_write_chan(ch, LDSM1R, 1); | 538 | lcdc_write_chan(ch, LDSM1R, 1); |
@@ -457,6 +556,9 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
457 | /* tell the board code to enable the panel */ | 556 | /* tell the board code to enable the panel */ |
458 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 557 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
459 | ch = &priv->ch[k]; | 558 | ch = &priv->ch[k]; |
559 | if (!ch->enabled) | ||
560 | continue; | ||
561 | |||
460 | board_cfg = &ch->cfg.board_cfg; | 562 | board_cfg = &ch->cfg.board_cfg; |
461 | if (board_cfg->display_on) | 563 | if (board_cfg->display_on) |
462 | board_cfg->display_on(board_cfg->board_data); | 564 | board_cfg->display_on(board_cfg->board_data); |
@@ -474,24 +576,25 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
474 | /* clean up deferred io and ask board code to disable panel */ | 576 | /* clean up deferred io and ask board code to disable panel */ |
475 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 577 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
476 | ch = &priv->ch[k]; | 578 | ch = &priv->ch[k]; |
579 | if (!ch->enabled) | ||
580 | continue; | ||
477 | 581 | ||
478 | /* deferred io mode: | 582 | /* deferred io mode: |
479 | * flush frame, and wait for frame end interrupt | 583 | * flush frame, and wait for frame end interrupt |
480 | * clean up deferred io and enable clock | 584 | * clean up deferred io and enable clock |
481 | */ | 585 | */ |
482 | if (ch->info.fbdefio) { | 586 | if (ch->info->fbdefio) { |
483 | ch->frame_end = 0; | 587 | ch->frame_end = 0; |
484 | schedule_delayed_work(&ch->info.deferred_work, 0); | 588 | schedule_delayed_work(&ch->info->deferred_work, 0); |
485 | wait_event(ch->frame_end_wait, ch->frame_end); | 589 | wait_event(ch->frame_end_wait, ch->frame_end); |
486 | fb_deferred_io_cleanup(&ch->info); | 590 | fb_deferred_io_cleanup(ch->info); |
487 | ch->info.fbdefio = NULL; | 591 | ch->info->fbdefio = NULL; |
488 | sh_mobile_lcdc_clk_on(priv); | 592 | sh_mobile_lcdc_clk_on(priv); |
489 | } | 593 | } |
490 | 594 | ||
491 | board_cfg = &ch->cfg.board_cfg; | 595 | board_cfg = &ch->cfg.board_cfg; |
492 | if (board_cfg->display_off) | 596 | if (board_cfg->display_off) |
493 | board_cfg->display_off(board_cfg->board_data); | 597 | board_cfg->display_off(board_cfg->board_data); |
494 | |||
495 | } | 598 | } |
496 | 599 | ||
497 | /* stop the lcdc */ | 600 | /* stop the lcdc */ |
@@ -550,9 +653,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, | |||
550 | int clock_source, | 653 | int clock_source, |
551 | struct sh_mobile_lcdc_priv *priv) | 654 | struct sh_mobile_lcdc_priv *priv) |
552 | { | 655 | { |
553 | #ifdef CONFIG_HAVE_CLK | ||
554 | char clk_name[8]; | ||
555 | #endif | ||
556 | char *str; | 656 | char *str; |
557 | int icksel; | 657 | int icksel; |
558 | 658 | ||
@@ -566,25 +666,21 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, | |||
566 | 666 | ||
567 | priv->lddckr = icksel << 16; | 667 | priv->lddckr = icksel << 16; |
568 | 668 | ||
569 | #ifdef CONFIG_HAVE_CLK | ||
570 | atomic_set(&priv->clk_usecnt, -1); | ||
571 | snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id); | ||
572 | priv->clk = clk_get(&pdev->dev, clk_name); | ||
573 | if (IS_ERR(priv->clk)) { | ||
574 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | ||
575 | return PTR_ERR(priv->clk); | ||
576 | } | ||
577 | |||
578 | if (str) { | 669 | if (str) { |
579 | priv->dot_clk = clk_get(&pdev->dev, str); | 670 | priv->dot_clk = clk_get(&pdev->dev, str); |
580 | if (IS_ERR(priv->dot_clk)) { | 671 | if (IS_ERR(priv->dot_clk)) { |
581 | dev_err(&pdev->dev, "cannot get dot clock %s\n", str); | 672 | dev_err(&pdev->dev, "cannot get dot clock %s\n", str); |
582 | clk_put(priv->clk); | ||
583 | return PTR_ERR(priv->dot_clk); | 673 | return PTR_ERR(priv->dot_clk); |
584 | } | 674 | } |
585 | } | 675 | } |
586 | #endif | 676 | atomic_set(&priv->hw_usecnt, -1); |
587 | 677 | ||
678 | /* Runtime PM support involves two step for this driver: | ||
679 | * 1) Enable Runtime PM | ||
680 | * 2) Force Runtime PM Resume since hardware is accessed from probe() | ||
681 | */ | ||
682 | pm_runtime_enable(priv->dev); | ||
683 | pm_runtime_resume(priv->dev); | ||
588 | return 0; | 684 | return 0; |
589 | } | 685 | } |
590 | 686 | ||
@@ -617,6 +713,9 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { | |||
617 | .type = FB_TYPE_PACKED_PIXELS, | 713 | .type = FB_TYPE_PACKED_PIXELS, |
618 | .visual = FB_VISUAL_TRUECOLOR, | 714 | .visual = FB_VISUAL_TRUECOLOR, |
619 | .accel = FB_ACCEL_NONE, | 715 | .accel = FB_ACCEL_NONE, |
716 | .xpanstep = 0, | ||
717 | .ypanstep = 1, | ||
718 | .ywrapstep = 0, | ||
620 | }; | 719 | }; |
621 | 720 | ||
622 | static void sh_mobile_lcdc_fillrect(struct fb_info *info, | 721 | static void sh_mobile_lcdc_fillrect(struct fb_info *info, |
@@ -640,13 +739,38 @@ static void sh_mobile_lcdc_imageblit(struct fb_info *info, | |||
640 | sh_mobile_lcdc_deferred_io_touch(info); | 739 | sh_mobile_lcdc_deferred_io_touch(info); |
641 | } | 740 | } |
642 | 741 | ||
742 | static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var, | ||
743 | struct fb_info *info) | ||
744 | { | ||
745 | struct sh_mobile_lcdc_chan *ch = info->par; | ||
746 | |||
747 | if (info->var.xoffset == var->xoffset && | ||
748 | info->var.yoffset == var->yoffset) | ||
749 | return 0; /* No change, do nothing */ | ||
750 | |||
751 | ch->new_pan_offset = (var->yoffset * info->fix.line_length) + | ||
752 | (var->xoffset * (info->var.bits_per_pixel / 8)); | ||
753 | |||
754 | if (ch->new_pan_offset != ch->pan_offset) { | ||
755 | unsigned long ldintr; | ||
756 | ldintr = lcdc_read(ch->lcdc, _LDINTR); | ||
757 | ldintr |= LDINTR_VEE; | ||
758 | lcdc_write(ch->lcdc, _LDINTR, ldintr); | ||
759 | sh_mobile_lcdc_deferred_io_touch(info); | ||
760 | } | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
643 | static struct fb_ops sh_mobile_lcdc_ops = { | 765 | static struct fb_ops sh_mobile_lcdc_ops = { |
766 | .owner = THIS_MODULE, | ||
644 | .fb_setcolreg = sh_mobile_lcdc_setcolreg, | 767 | .fb_setcolreg = sh_mobile_lcdc_setcolreg, |
645 | .fb_read = fb_sys_read, | 768 | .fb_read = fb_sys_read, |
646 | .fb_write = fb_sys_write, | 769 | .fb_write = fb_sys_write, |
647 | .fb_fillrect = sh_mobile_lcdc_fillrect, | 770 | .fb_fillrect = sh_mobile_lcdc_fillrect, |
648 | .fb_copyarea = sh_mobile_lcdc_copyarea, | 771 | .fb_copyarea = sh_mobile_lcdc_copyarea, |
649 | .fb_imageblit = sh_mobile_lcdc_imageblit, | 772 | .fb_imageblit = sh_mobile_lcdc_imageblit, |
773 | .fb_pan_display = sh_mobile_fb_pan_display, | ||
650 | }; | 774 | }; |
651 | 775 | ||
652 | static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) | 776 | static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) |
@@ -702,9 +826,59 @@ static int sh_mobile_lcdc_resume(struct device *dev) | |||
702 | return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); | 826 | return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); |
703 | } | 827 | } |
704 | 828 | ||
829 | static int sh_mobile_lcdc_runtime_suspend(struct device *dev) | ||
830 | { | ||
831 | struct platform_device *pdev = to_platform_device(dev); | ||
832 | struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev); | ||
833 | struct sh_mobile_lcdc_chan *ch; | ||
834 | int k, n; | ||
835 | |||
836 | /* save per-channel registers */ | ||
837 | for (k = 0; k < ARRAY_SIZE(p->ch); k++) { | ||
838 | ch = &p->ch[k]; | ||
839 | if (!ch->enabled) | ||
840 | continue; | ||
841 | for (n = 0; n < NR_CH_REGS; n++) | ||
842 | ch->saved_ch_regs[n] = lcdc_read_chan(ch, n); | ||
843 | } | ||
844 | |||
845 | /* save shared registers */ | ||
846 | for (n = 0; n < NR_SHARED_REGS; n++) | ||
847 | p->saved_shared_regs[n] = lcdc_read(p, lcdc_shared_regs[n]); | ||
848 | |||
849 | /* turn off LCDC hardware */ | ||
850 | lcdc_write(p, _LDCNT1R, 0); | ||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int sh_mobile_lcdc_runtime_resume(struct device *dev) | ||
855 | { | ||
856 | struct platform_device *pdev = to_platform_device(dev); | ||
857 | struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev); | ||
858 | struct sh_mobile_lcdc_chan *ch; | ||
859 | int k, n; | ||
860 | |||
861 | /* restore per-channel registers */ | ||
862 | for (k = 0; k < ARRAY_SIZE(p->ch); k++) { | ||
863 | ch = &p->ch[k]; | ||
864 | if (!ch->enabled) | ||
865 | continue; | ||
866 | for (n = 0; n < NR_CH_REGS; n++) | ||
867 | lcdc_write_chan(ch, n, ch->saved_ch_regs[n]); | ||
868 | } | ||
869 | |||
870 | /* restore shared registers */ | ||
871 | for (n = 0; n < NR_SHARED_REGS; n++) | ||
872 | lcdc_write(p, lcdc_shared_regs[n], p->saved_shared_regs[n]); | ||
873 | |||
874 | return 0; | ||
875 | } | ||
876 | |||
705 | static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { | 877 | static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { |
706 | .suspend = sh_mobile_lcdc_suspend, | 878 | .suspend = sh_mobile_lcdc_suspend, |
707 | .resume = sh_mobile_lcdc_resume, | 879 | .resume = sh_mobile_lcdc_resume, |
880 | .runtime_suspend = sh_mobile_lcdc_runtime_suspend, | ||
881 | .runtime_resume = sh_mobile_lcdc_runtime_resume, | ||
708 | }; | 882 | }; |
709 | 883 | ||
710 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); | 884 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); |
@@ -749,6 +923,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
749 | } | 923 | } |
750 | 924 | ||
751 | priv->irq = i; | 925 | priv->irq = i; |
926 | priv->dev = &pdev->dev; | ||
752 | platform_set_drvdata(pdev, priv); | 927 | platform_set_drvdata(pdev, priv); |
753 | pdata = pdev->dev.platform_data; | 928 | pdata = pdev->dev.platform_data; |
754 | 929 | ||
@@ -763,6 +938,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
763 | goto err1; | 938 | goto err1; |
764 | } | 939 | } |
765 | init_waitqueue_head(&priv->ch[i].frame_end_wait); | 940 | init_waitqueue_head(&priv->ch[i].frame_end_wait); |
941 | priv->ch[j].pan_offset = 0; | ||
942 | priv->ch[j].new_pan_offset = 0; | ||
766 | 943 | ||
767 | switch (pdata->ch[i].chan) { | 944 | switch (pdata->ch[i].chan) { |
768 | case LCDC_CHAN_MAINLCD: | 945 | case LCDC_CHAN_MAINLCD: |
@@ -793,12 +970,21 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
793 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); | 970 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); |
794 | 971 | ||
795 | for (i = 0; i < j; i++) { | 972 | for (i = 0; i < j; i++) { |
796 | info = &priv->ch[i].info; | ||
797 | cfg = &priv->ch[i].cfg; | 973 | cfg = &priv->ch[i].cfg; |
798 | 974 | ||
975 | priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); | ||
976 | if (!priv->ch[i].info) { | ||
977 | dev_err(&pdev->dev, "unable to allocate fb_info\n"); | ||
978 | error = -ENOMEM; | ||
979 | break; | ||
980 | } | ||
981 | |||
982 | info = priv->ch[i].info; | ||
799 | info->fbops = &sh_mobile_lcdc_ops; | 983 | info->fbops = &sh_mobile_lcdc_ops; |
800 | info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; | 984 | info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; |
801 | info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres; | 985 | info->var.yres = cfg->lcd_cfg.yres; |
986 | /* Default Y virtual resolution is 2x panel size */ | ||
987 | info->var.yres_virtual = info->var.yres * 2; | ||
802 | info->var.width = cfg->lcd_size_cfg.width; | 988 | info->var.width = cfg->lcd_size_cfg.width; |
803 | info->var.height = cfg->lcd_size_cfg.height; | 989 | info->var.height = cfg->lcd_size_cfg.height; |
804 | info->var.activate = FB_ACTIVATE_NOW; | 990 | info->var.activate = FB_ACTIVATE_NOW; |
@@ -808,7 +994,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
808 | 994 | ||
809 | info->fix = sh_mobile_lcdc_fix; | 995 | info->fix = sh_mobile_lcdc_fix; |
810 | info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8); | 996 | info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8); |
811 | info->fix.smem_len = info->fix.line_length * cfg->lcd_cfg.yres; | 997 | info->fix.smem_len = info->fix.line_length * |
998 | info->var.yres_virtual; | ||
812 | 999 | ||
813 | buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, | 1000 | buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, |
814 | &priv->ch[i].dma_handle, GFP_KERNEL); | 1001 | &priv->ch[i].dma_handle, GFP_KERNEL); |
@@ -846,21 +1033,31 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
846 | } | 1033 | } |
847 | 1034 | ||
848 | for (i = 0; i < j; i++) { | 1035 | for (i = 0; i < j; i++) { |
849 | error = register_framebuffer(&priv->ch[i].info); | 1036 | struct sh_mobile_lcdc_chan *ch = priv->ch + i; |
1037 | |||
1038 | info = ch->info; | ||
1039 | |||
1040 | if (info->fbdefio) { | ||
1041 | priv->ch->sglist = vmalloc(sizeof(struct scatterlist) * | ||
1042 | info->fix.smem_len >> PAGE_SHIFT); | ||
1043 | if (!priv->ch->sglist) { | ||
1044 | dev_err(&pdev->dev, "cannot allocate sglist\n"); | ||
1045 | goto err1; | ||
1046 | } | ||
1047 | } | ||
1048 | |||
1049 | error = register_framebuffer(info); | ||
850 | if (error < 0) | 1050 | if (error < 0) |
851 | goto err1; | 1051 | goto err1; |
852 | } | ||
853 | 1052 | ||
854 | for (i = 0; i < j; i++) { | ||
855 | info = &priv->ch[i].info; | ||
856 | dev_info(info->dev, | 1053 | dev_info(info->dev, |
857 | "registered %s/%s as %dx%d %dbpp.\n", | 1054 | "registered %s/%s as %dx%d %dbpp.\n", |
858 | pdev->name, | 1055 | pdev->name, |
859 | (priv->ch[i].cfg.chan == LCDC_CHAN_MAINLCD) ? | 1056 | (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? |
860 | "mainlcd" : "sublcd", | 1057 | "mainlcd" : "sublcd", |
861 | (int) priv->ch[i].cfg.lcd_cfg.xres, | 1058 | (int) ch->cfg.lcd_cfg.xres, |
862 | (int) priv->ch[i].cfg.lcd_cfg.yres, | 1059 | (int) ch->cfg.lcd_cfg.yres, |
863 | priv->ch[i].cfg.bpp); | 1060 | ch->cfg.bpp); |
864 | 1061 | ||
865 | /* deferred io mode: disable clock to save power */ | 1062 | /* deferred io mode: disable clock to save power */ |
866 | if (info->fbdefio) | 1063 | if (info->fbdefio) |
@@ -881,27 +1078,30 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
881 | int i; | 1078 | int i; |
882 | 1079 | ||
883 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) | 1080 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) |
884 | if (priv->ch[i].info.dev) | 1081 | if (priv->ch[i].info->dev) |
885 | unregister_framebuffer(&priv->ch[i].info); | 1082 | unregister_framebuffer(priv->ch[i].info); |
886 | 1083 | ||
887 | sh_mobile_lcdc_stop(priv); | 1084 | sh_mobile_lcdc_stop(priv); |
888 | 1085 | ||
889 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { | 1086 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { |
890 | info = &priv->ch[i].info; | 1087 | info = priv->ch[i].info; |
891 | 1088 | ||
892 | if (!info->device) | 1089 | if (!info || !info->device) |
893 | continue; | 1090 | continue; |
894 | 1091 | ||
1092 | if (priv->ch[i].sglist) | ||
1093 | vfree(priv->ch[i].sglist); | ||
1094 | |||
895 | dma_free_coherent(&pdev->dev, info->fix.smem_len, | 1095 | dma_free_coherent(&pdev->dev, info->fix.smem_len, |
896 | info->screen_base, priv->ch[i].dma_handle); | 1096 | info->screen_base, priv->ch[i].dma_handle); |
897 | fb_dealloc_cmap(&info->cmap); | 1097 | fb_dealloc_cmap(&info->cmap); |
1098 | framebuffer_release(info); | ||
898 | } | 1099 | } |
899 | 1100 | ||
900 | #ifdef CONFIG_HAVE_CLK | ||
901 | if (priv->dot_clk) | 1101 | if (priv->dot_clk) |
902 | clk_put(priv->dot_clk); | 1102 | clk_put(priv->dot_clk); |
903 | clk_put(priv->clk); | 1103 | |
904 | #endif | 1104 | pm_runtime_disable(priv->dev); |
905 | 1105 | ||
906 | if (priv->base) | 1106 | if (priv->base) |
907 | iounmap(priv->base); | 1107 | iounmap(priv->base); |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 7072d19080d5..a4e05e4d7501 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -698,8 +698,8 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int | |||
698 | rate, sisfb_vrate[i].refresh); | 698 | rate, sisfb_vrate[i].refresh); |
699 | ivideo->rate_idx = sisfb_vrate[i].idx; | 699 | ivideo->rate_idx = sisfb_vrate[i].idx; |
700 | ivideo->refresh_rate = sisfb_vrate[i].refresh; | 700 | ivideo->refresh_rate = sisfb_vrate[i].refresh; |
701 | } else if(((rate - sisfb_vrate[i-1].refresh) <= 2) | 701 | } else if((sisfb_vrate[i].idx != 1) && |
702 | && (sisfb_vrate[i].idx != 1)) { | 702 | ((rate - sisfb_vrate[i-1].refresh) <= 2)) { |
703 | DPRINTK("sisfb: Adjusting rate from %d down to %d\n", | 703 | DPRINTK("sisfb: Adjusting rate from %d down to %d\n", |
704 | rate, sisfb_vrate[i-1].refresh); | 704 | rate, sisfb_vrate[i-1].refresh); |
705 | ivideo->rate_idx = sisfb_vrate[i-1].idx; | 705 | ivideo->rate_idx = sisfb_vrate[i-1].idx; |
@@ -1847,8 +1847,10 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) | |||
1847 | 1847 | ||
1848 | strcpy(fix->id, ivideo->myid); | 1848 | strcpy(fix->id, ivideo->myid); |
1849 | 1849 | ||
1850 | mutex_lock(&info->mm_lock); | ||
1850 | fix->smem_start = ivideo->video_base + ivideo->video_offset; | 1851 | fix->smem_start = ivideo->video_base + ivideo->video_offset; |
1851 | fix->smem_len = ivideo->sisfb_mem; | 1852 | fix->smem_len = ivideo->sisfb_mem; |
1853 | mutex_unlock(&info->mm_lock); | ||
1852 | fix->type = FB_TYPE_PACKED_PIXELS; | 1854 | fix->type = FB_TYPE_PACKED_PIXELS; |
1853 | fix->type_aux = 0; | 1855 | fix->type_aux = 0; |
1854 | fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | 1856 | fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; |
@@ -6365,7 +6367,6 @@ error_3: vfree(ivideo->bios_abase); | |||
6365 | sis_fb_info->fix = ivideo->sisfb_fix; | 6367 | sis_fb_info->fix = ivideo->sisfb_fix; |
6366 | sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; | 6368 | sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; |
6367 | sis_fb_info->fbops = &sisfb_ops; | 6369 | sis_fb_info->fbops = &sisfb_ops; |
6368 | sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info); | ||
6369 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; | 6370 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; |
6370 | 6371 | ||
6371 | fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); | 6372 | fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); |
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h index 705c85360526..bef4aae388d0 100644 --- a/drivers/video/sis/vstruct.h +++ b/drivers/video/sis/vstruct.h | |||
@@ -342,7 +342,7 @@ struct SiS_Private | |||
342 | unsigned short SiS_RY4COE; | 342 | unsigned short SiS_RY4COE; |
343 | unsigned short SiS_LCDHDES; | 343 | unsigned short SiS_LCDHDES; |
344 | unsigned short SiS_LCDVDES; | 344 | unsigned short SiS_LCDVDES; |
345 | unsigned short SiS_DDC_Port; | 345 | SISIOADDRESS SiS_DDC_Port; |
346 | unsigned short SiS_DDC_Index; | 346 | unsigned short SiS_DDC_Index; |
347 | unsigned short SiS_DDC_Data; | 347 | unsigned short SiS_DDC_Data; |
348 | unsigned short SiS_DDC_NData; | 348 | unsigned short SiS_DDC_NData; |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index eb5d73a06702..924d79462780 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -145,7 +145,7 @@ static inline void sm501fb_sync_regs(struct sm501fb_info *info) | |||
145 | #define SM501_MEMF_ACCEL (8) | 145 | #define SM501_MEMF_ACCEL (8) |
146 | 146 | ||
147 | static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | 147 | static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, |
148 | unsigned int why, size_t size) | 148 | unsigned int why, size_t size, u32 smem_len) |
149 | { | 149 | { |
150 | struct sm501fb_par *par; | 150 | struct sm501fb_par *par; |
151 | struct fb_info *fbi; | 151 | struct fb_info *fbi; |
@@ -172,7 +172,7 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | |||
172 | if (ptr > 0) | 172 | if (ptr > 0) |
173 | ptr &= ~(PAGE_SIZE - 1); | 173 | ptr &= ~(PAGE_SIZE - 1); |
174 | 174 | ||
175 | if (fbi && ptr < fbi->fix.smem_len) | 175 | if (fbi && ptr < smem_len) |
176 | return -ENOMEM; | 176 | return -ENOMEM; |
177 | 177 | ||
178 | break; | 178 | break; |
@@ -197,7 +197,7 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | |||
197 | 197 | ||
198 | case SM501_MEMF_ACCEL: | 198 | case SM501_MEMF_ACCEL: |
199 | fbi = inf->fb[HEAD_CRT]; | 199 | fbi = inf->fb[HEAD_CRT]; |
200 | ptr = fbi ? fbi->fix.smem_len : 0; | 200 | ptr = fbi ? smem_len : 0; |
201 | 201 | ||
202 | fbi = inf->fb[HEAD_PANEL]; | 202 | fbi = inf->fb[HEAD_PANEL]; |
203 | if (fbi) { | 203 | if (fbi) { |
@@ -413,6 +413,7 @@ static int sm501fb_set_par_common(struct fb_info *info, | |||
413 | unsigned int mem_type; | 413 | unsigned int mem_type; |
414 | unsigned int clock_type; | 414 | unsigned int clock_type; |
415 | unsigned int head_addr; | 415 | unsigned int head_addr; |
416 | unsigned int smem_len; | ||
416 | 417 | ||
417 | dev_dbg(fbi->dev, "%s: %dx%d, bpp = %d, virtual %dx%d\n", | 418 | dev_dbg(fbi->dev, "%s: %dx%d, bpp = %d, virtual %dx%d\n", |
418 | __func__, var->xres, var->yres, var->bits_per_pixel, | 419 | __func__, var->xres, var->yres, var->bits_per_pixel, |
@@ -453,18 +454,20 @@ static int sm501fb_set_par_common(struct fb_info *info, | |||
453 | 454 | ||
454 | /* allocate fb memory within 501 */ | 455 | /* allocate fb memory within 501 */ |
455 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel)/8; | 456 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel)/8; |
456 | info->fix.smem_len = info->fix.line_length * var->yres_virtual; | 457 | smem_len = info->fix.line_length * var->yres_virtual; |
457 | 458 | ||
458 | dev_dbg(fbi->dev, "%s: line length = %u\n", __func__, | 459 | dev_dbg(fbi->dev, "%s: line length = %u\n", __func__, |
459 | info->fix.line_length); | 460 | info->fix.line_length); |
460 | 461 | ||
461 | if (sm501_alloc_mem(fbi, &par->screen, mem_type, | 462 | if (sm501_alloc_mem(fbi, &par->screen, mem_type, smem_len, smem_len)) { |
462 | info->fix.smem_len)) { | ||
463 | dev_err(fbi->dev, "no memory available\n"); | 463 | dev_err(fbi->dev, "no memory available\n"); |
464 | return -ENOMEM; | 464 | return -ENOMEM; |
465 | } | 465 | } |
466 | 466 | ||
467 | mutex_lock(&info->mm_lock); | ||
467 | info->fix.smem_start = fbi->fbmem_res->start + par->screen.sm_addr; | 468 | info->fix.smem_start = fbi->fbmem_res->start + par->screen.sm_addr; |
469 | info->fix.smem_len = smem_len; | ||
470 | mutex_unlock(&info->mm_lock); | ||
468 | 471 | ||
469 | info->screen_base = fbi->fbmem + par->screen.sm_addr; | 472 | info->screen_base = fbi->fbmem + par->screen.sm_addr; |
470 | info->screen_size = info->fix.smem_len; | 473 | info->screen_size = info->fix.smem_len; |
@@ -637,7 +640,8 @@ static int sm501fb_set_par_crt(struct fb_info *info) | |||
637 | if ((control & SM501_DC_CRT_CONTROL_SEL) == 0) { | 640 | if ((control & SM501_DC_CRT_CONTROL_SEL) == 0) { |
638 | /* the head is displaying panel data... */ | 641 | /* the head is displaying panel data... */ |
639 | 642 | ||
640 | sm501_alloc_mem(fbi, &par->screen, SM501_MEMF_CRT, 0); | 643 | sm501_alloc_mem(fbi, &par->screen, SM501_MEMF_CRT, 0, |
644 | info->fix.smem_len); | ||
641 | goto out_update; | 645 | goto out_update; |
642 | } | 646 | } |
643 | 647 | ||
@@ -1289,7 +1293,8 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base) | |||
1289 | 1293 | ||
1290 | par->cursor_regs = info->regs + reg_base; | 1294 | par->cursor_regs = info->regs + reg_base; |
1291 | 1295 | ||
1292 | ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024); | 1296 | ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024, |
1297 | fbi->fix.smem_len); | ||
1293 | if (ret < 0) | 1298 | if (ret < 0) |
1294 | return ret; | 1299 | return ret; |
1295 | 1300 | ||
@@ -1535,9 +1540,6 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1535 | if (ret) | 1540 | if (ret) |
1536 | dev_err(info->dev, "check_var() failed on initial setup?\n"); | 1541 | dev_err(info->dev, "check_var() failed on initial setup?\n"); |
1537 | 1542 | ||
1538 | /* ensure we've activated our new configuration */ | ||
1539 | (fb->fbops->fb_set_par)(fb); | ||
1540 | |||
1541 | return 0; | 1543 | return 0; |
1542 | } | 1544 | } |
1543 | 1545 | ||
@@ -1619,6 +1621,8 @@ static int __devinit sm501fb_start_one(struct sm501fb_info *info, | |||
1619 | if (!fbi) | 1621 | if (!fbi) |
1620 | return 0; | 1622 | return 0; |
1621 | 1623 | ||
1624 | mutex_init(&info->fb[head]->mm_lock); | ||
1625 | |||
1622 | ret = sm501fb_init_fb(info->fb[head], head, drvname); | 1626 | ret = sm501fb_init_fb(info->fb[head], head, drvname); |
1623 | if (ret) { | 1627 | if (ret) { |
1624 | dev_err(info->dev, "cannot initialise fb %s\n", drvname); | 1628 | dev_err(info->dev, "cannot initialise fb %s\n", drvname); |
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index eec9dcb7f599..6120f0c526fe 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c | |||
@@ -1115,10 +1115,9 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) | |||
1115 | if the device name contains the string "DX" and tell the | 1115 | if the device name contains the string "DX" and tell the |
1116 | user how to reconfigure the card. */ | 1116 | user how to reconfigure the card. */ |
1117 | if (strstr(sti->outptr.dev_name, "DX")) { | 1117 | if (strstr(sti->outptr.dev_name, "DX")) { |
1118 | printk(KERN_WARNING "WARNING: stifb framebuffer driver does not " | 1118 | printk(KERN_WARNING |
1119 | "support '%s' in double-buffer mode.\n" | 1119 | "WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n" |
1120 | KERN_WARNING "WARNING: Please disable the double-buffer mode " | 1120 | "WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n", |
1121 | "in IPL menu (the PARISC-BIOS).\n", | ||
1122 | sti->outptr.dev_name); | 1121 | sti->outptr.dev_name); |
1123 | goto out_err0; | 1122 | goto out_err0; |
1124 | } | 1123 | } |
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c index a1eb0862255b..6913fe168c25 100644 --- a/drivers/video/tmiofb.c +++ b/drivers/video/tmiofb.c | |||
@@ -974,7 +974,7 @@ static int tmiofb_resume(struct platform_device *dev) | |||
974 | { | 974 | { |
975 | struct fb_info *info = platform_get_drvdata(dev); | 975 | struct fb_info *info = platform_get_drvdata(dev); |
976 | struct mfd_cell *cell = dev->dev.platform_data; | 976 | struct mfd_cell *cell = dev->dev.platform_data; |
977 | int retval; | 977 | int retval = 0; |
978 | 978 | ||
979 | acquire_console_sem(); | 979 | acquire_console_sem(); |
980 | 980 | ||
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index ca5b4643a401..54fbb2995a5f 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c | |||
@@ -67,12 +67,14 @@ static DEFINE_MUTEX(uvfb_lock); | |||
67 | * find the kernel part of the task struct, copy the registers and | 67 | * find the kernel part of the task struct, copy the registers and |
68 | * the buffer contents and then complete the task. | 68 | * the buffer contents and then complete the task. |
69 | */ | 69 | */ |
70 | static void uvesafb_cn_callback(void *data) | 70 | static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) |
71 | { | 71 | { |
72 | struct cn_msg *msg = data; | ||
73 | struct uvesafb_task *utask; | 72 | struct uvesafb_task *utask; |
74 | struct uvesafb_ktask *task; | 73 | struct uvesafb_ktask *task; |
75 | 74 | ||
75 | if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) | ||
76 | return; | ||
77 | |||
76 | if (msg->seq >= UVESAFB_TASKS_MAX) | 78 | if (msg->seq >= UVESAFB_TASKS_MAX) |
77 | return; | 79 | return; |
78 | 80 | ||
@@ -1409,23 +1411,6 @@ static int uvesafb_check_var(struct fb_var_screeninfo *var, | |||
1409 | return 0; | 1411 | return 0; |
1410 | } | 1412 | } |
1411 | 1413 | ||
1412 | static void uvesafb_save_state(struct fb_info *info) | ||
1413 | { | ||
1414 | struct uvesafb_par *par = info->par; | ||
1415 | |||
1416 | if (par->vbe_state_saved) | ||
1417 | kfree(par->vbe_state_saved); | ||
1418 | |||
1419 | par->vbe_state_saved = uvesafb_vbe_state_save(par); | ||
1420 | } | ||
1421 | |||
1422 | static void uvesafb_restore_state(struct fb_info *info) | ||
1423 | { | ||
1424 | struct uvesafb_par *par = info->par; | ||
1425 | |||
1426 | uvesafb_vbe_state_restore(par, par->vbe_state_saved); | ||
1427 | } | ||
1428 | |||
1429 | static struct fb_ops uvesafb_ops = { | 1414 | static struct fb_ops uvesafb_ops = { |
1430 | .owner = THIS_MODULE, | 1415 | .owner = THIS_MODULE, |
1431 | .fb_open = uvesafb_open, | 1416 | .fb_open = uvesafb_open, |
@@ -1439,8 +1424,6 @@ static struct fb_ops uvesafb_ops = { | |||
1439 | .fb_imageblit = cfb_imageblit, | 1424 | .fb_imageblit = cfb_imageblit, |
1440 | .fb_check_var = uvesafb_check_var, | 1425 | .fb_check_var = uvesafb_check_var, |
1441 | .fb_set_par = uvesafb_set_par, | 1426 | .fb_set_par = uvesafb_set_par, |
1442 | .fb_save_state = uvesafb_save_state, | ||
1443 | .fb_restore_state = uvesafb_restore_state, | ||
1444 | }; | 1427 | }; |
1445 | 1428 | ||
1446 | static void __devinit uvesafb_init_info(struct fb_info *info, | 1429 | static void __devinit uvesafb_init_info(struct fb_info *info, |
@@ -1457,15 +1440,6 @@ static void __devinit uvesafb_init_info(struct fb_info *info, | |||
1457 | info->fix.ypanstep = par->ypan ? 1 : 0; | 1440 | info->fix.ypanstep = par->ypan ? 1 : 0; |
1458 | info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0; | 1441 | info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0; |
1459 | 1442 | ||
1460 | /* | ||
1461 | * If we were unable to get the state buffer size, disable | ||
1462 | * functions for saving and restoring the hardware state. | ||
1463 | */ | ||
1464 | if (par->vbe_state_size == 0) { | ||
1465 | info->fbops->fb_save_state = NULL; | ||
1466 | info->fbops->fb_restore_state = NULL; | ||
1467 | } | ||
1468 | |||
1469 | /* Disable blanking if the user requested so. */ | 1443 | /* Disable blanking if the user requested so. */ |
1470 | if (!blank) | 1444 | if (!blank) |
1471 | info->fbops->fb_blank = NULL; | 1445 | info->fbops->fb_blank = NULL; |
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index 45c54bfe99bb..9d4f3a49ba4a 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c | |||
@@ -20,229 +20,430 @@ | |||
20 | */ | 20 | */ |
21 | #include "global.h" | 21 | #include "global.h" |
22 | 22 | ||
23 | void viafb_init_accel(void) | 23 | static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, |
24 | u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, | ||
25 | u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, | ||
26 | u32 fg_color, u32 bg_color, u8 fill_rop) | ||
24 | { | 27 | { |
25 | viaparinfo->fbmem_free -= CURSOR_SIZE; | 28 | u32 ge_cmd = 0, tmp, i; |
26 | viaparinfo->cursor_start = viaparinfo->fbmem_free; | ||
27 | viaparinfo->fbmem_used += CURSOR_SIZE; | ||
28 | 29 | ||
29 | /* Reverse 8*1024 memory space for cursor image */ | 30 | if (!op || op > 3) { |
30 | viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE); | 31 | printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op); |
31 | viaparinfo->VQ_start = viaparinfo->fbmem_free; | 32 | return -EINVAL; |
32 | viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1; | 33 | } |
33 | viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); } | ||
34 | |||
35 | void viafb_init_2d_engine(void) | ||
36 | { | ||
37 | u32 dwVQStartAddr, dwVQEndAddr; | ||
38 | u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; | ||
39 | |||
40 | /* init 2D engine regs to reset 2D engine */ | ||
41 | writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE); | ||
42 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
43 | writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
44 | writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
45 | writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR); | ||
46 | writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR); | ||
47 | writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR); | ||
48 | writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL); | ||
49 | writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR); | ||
50 | writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET); | ||
51 | writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL); | ||
52 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
53 | writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
54 | writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH); | ||
55 | writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1); | ||
56 | |||
57 | /* Init AGP and VQ regs */ | ||
58 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
59 | case UNICHROME_K8M890: | ||
60 | case UNICHROME_P4M900: | ||
61 | writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET); | ||
62 | writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
63 | writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
64 | break; | ||
65 | 34 | ||
66 | default: | 35 | if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) { |
67 | writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET); | 36 | if (src_x < dst_x) { |
68 | writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 37 | ge_cmd |= 0x00008000; |
69 | writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 38 | src_x += width - 1; |
70 | writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 39 | dst_x += width - 1; |
71 | writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 40 | } |
72 | writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 41 | if (src_y < dst_y) { |
73 | writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 42 | ge_cmd |= 0x00004000; |
74 | writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 43 | src_y += height - 1; |
75 | writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | 44 | dst_y += height - 1; |
76 | 45 | } | |
77 | writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET); | ||
78 | writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
79 | break; | ||
80 | } | 46 | } |
81 | if (viaparinfo->VQ_start != 0) { | 47 | |
82 | /* Enable VQ */ | 48 | if (op == VIA_BITBLT_FILL) { |
83 | dwVQStartAddr = viaparinfo->VQ_start; | 49 | switch (fill_rop) { |
84 | dwVQEndAddr = viaparinfo->VQ_end; | 50 | case 0x00: /* blackness */ |
85 | 51 | case 0x5A: /* pattern inversion */ | |
86 | dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); | 52 | case 0xF0: /* pattern copy */ |
87 | dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); | 53 | case 0xFF: /* whiteness */ |
88 | dwVQStartEndH = 0x52000000 | | ||
89 | ((dwVQStartAddr & 0xFF000000) >> 24) | | ||
90 | ((dwVQEndAddr & 0xFF000000) >> 16); | ||
91 | dwVQLen = 0x53000000 | (VQ_SIZE >> 3); | ||
92 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
93 | case UNICHROME_K8M890: | ||
94 | case UNICHROME_P4M900: | ||
95 | dwVQStartL |= 0x20000000; | ||
96 | dwVQEndL |= 0x20000000; | ||
97 | dwVQStartEndH |= 0x20000000; | ||
98 | dwVQLen |= 0x20000000; | ||
99 | break; | 54 | break; |
100 | default: | 55 | default: |
101 | break; | 56 | printk(KERN_WARNING "hw_bitblt_1: Invalid fill rop: " |
57 | "%u\n", fill_rop); | ||
58 | return -EINVAL; | ||
102 | } | 59 | } |
60 | } | ||
103 | 61 | ||
104 | switch (viaparinfo->chip_info->gfx_chip_name) { | 62 | switch (dst_bpp) { |
105 | case UNICHROME_K8M890: | 63 | case 8: |
106 | case UNICHROME_P4M900: | 64 | tmp = 0x00000000; |
107 | writel(0x00100000, | 65 | break; |
108 | viaparinfo->io_virt + VIA_REG_CR_TRANSET); | 66 | case 16: |
109 | writel(dwVQStartEndH, | 67 | tmp = 0x00000100; |
110 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | 68 | break; |
111 | writel(dwVQStartL, | 69 | case 32: |
112 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | 70 | tmp = 0x00000300; |
113 | writel(dwVQEndL, | 71 | break; |
114 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | 72 | default: |
115 | writel(dwVQLen, | 73 | printk(KERN_WARNING "hw_bitblt_1: Unsupported bpp %d\n", |
116 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | 74 | dst_bpp); |
117 | writel(0x74301001, | 75 | return -EINVAL; |
118 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | 76 | } |
119 | writel(0x00000000, | 77 | writel(tmp, engine + 0x04); |
120 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | 78 | |
121 | break; | 79 | if (op != VIA_BITBLT_FILL) { |
122 | default: | 80 | if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000) |
123 | writel(0x00FE0000, | 81 | || src_y & 0xFFFFF000) { |
124 | viaparinfo->io_virt + VIA_REG_TRANSET); | 82 | printk(KERN_WARNING "hw_bitblt_1: Unsupported source " |
125 | writel(0x080003FE, | 83 | "x/y %d %d\n", src_x, src_y); |
126 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | 84 | return -EINVAL; |
127 | writel(0x0A00027C, | ||
128 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
129 | writel(0x0B000260, | ||
130 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
131 | writel(0x0C000274, | ||
132 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
133 | writel(0x0D000264, | ||
134 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
135 | writel(0x0E000000, | ||
136 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
137 | writel(0x0F000020, | ||
138 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
139 | writel(0x1000027E, | ||
140 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
141 | writel(0x110002FE, | ||
142 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
143 | writel(0x200F0060, | ||
144 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
145 | |||
146 | writel(0x00000006, | ||
147 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
148 | writel(0x40008C0F, | ||
149 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
150 | writel(0x44000000, | ||
151 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
152 | writel(0x45080C04, | ||
153 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
154 | writel(0x46800408, | ||
155 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
156 | |||
157 | writel(dwVQStartEndH, | ||
158 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
159 | writel(dwVQStartL, | ||
160 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
161 | writel(dwVQEndL, | ||
162 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
163 | writel(dwVQLen, | ||
164 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
165 | break; | ||
166 | } | 85 | } |
167 | } else { | 86 | tmp = src_x | (src_y << 16); |
168 | /* Disable VQ */ | 87 | writel(tmp, engine + 0x08); |
169 | switch (viaparinfo->chip_info->gfx_chip_name) { | 88 | } |
170 | case UNICHROME_K8M890: | 89 | |
171 | case UNICHROME_P4M900: | 90 | if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) { |
172 | writel(0x00100000, | 91 | printk(KERN_WARNING "hw_bitblt_1: Unsupported destination x/y " |
173 | viaparinfo->io_virt + VIA_REG_CR_TRANSET); | 92 | "%d %d\n", dst_x, dst_y); |
174 | writel(0x74301000, | 93 | return -EINVAL; |
175 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | 94 | } |
176 | break; | 95 | tmp = dst_x | (dst_y << 16); |
177 | default: | 96 | writel(tmp, engine + 0x0C); |
178 | writel(0x00FE0000, | 97 | |
179 | viaparinfo->io_virt + VIA_REG_TRANSET); | 98 | if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) { |
180 | writel(0x00000004, | 99 | printk(KERN_WARNING "hw_bitblt_1: Unsupported width/height " |
181 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | 100 | "%d %d\n", width, height); |
182 | writel(0x40008C0F, | 101 | return -EINVAL; |
183 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | 102 | } |
184 | writel(0x44000000, | 103 | tmp = (width - 1) | ((height - 1) << 16); |
185 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | 104 | writel(tmp, engine + 0x10); |
186 | writel(0x45080C04, | 105 | |
187 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | 106 | if (op != VIA_BITBLT_COLOR) |
188 | writel(0x46800408, | 107 | writel(fg_color, engine + 0x18); |
189 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | 108 | |
190 | break; | 109 | if (op == VIA_BITBLT_MONO) |
110 | writel(bg_color, engine + 0x1C); | ||
111 | |||
112 | if (op != VIA_BITBLT_FILL) { | ||
113 | tmp = src_mem ? 0 : src_addr; | ||
114 | if (dst_addr & 0xE0000007) { | ||
115 | printk(KERN_WARNING "hw_bitblt_1: Unsupported source " | ||
116 | "address %X\n", tmp); | ||
117 | return -EINVAL; | ||
191 | } | 118 | } |
119 | tmp >>= 3; | ||
120 | writel(tmp, engine + 0x30); | ||
121 | } | ||
122 | |||
123 | if (dst_addr & 0xE0000007) { | ||
124 | printk(KERN_WARNING "hw_bitblt_1: Unsupported destination " | ||
125 | "address %X\n", dst_addr); | ||
126 | return -EINVAL; | ||
192 | } | 127 | } |
128 | tmp = dst_addr >> 3; | ||
129 | writel(tmp, engine + 0x34); | ||
193 | 130 | ||
194 | viafb_set_2d_color_depth(viaparinfo->bpp); | 131 | if (op == VIA_BITBLT_FILL) |
132 | tmp = 0; | ||
133 | else | ||
134 | tmp = src_pitch; | ||
135 | if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) { | ||
136 | printk(KERN_WARNING "hw_bitblt_1: Unsupported pitch %X %X\n", | ||
137 | tmp, dst_pitch); | ||
138 | return -EINVAL; | ||
139 | } | ||
140 | tmp = (tmp >> 3) | (dst_pitch << (16 - 3)); | ||
141 | writel(tmp, engine + 0x38); | ||
142 | |||
143 | if (op == VIA_BITBLT_FILL) | ||
144 | ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001; | ||
145 | else { | ||
146 | ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */ | ||
147 | if (src_mem) | ||
148 | ge_cmd |= 0x00000040; | ||
149 | if (op == VIA_BITBLT_MONO) | ||
150 | ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000; | ||
151 | else | ||
152 | ge_cmd |= 0x00000001; | ||
153 | } | ||
154 | writel(ge_cmd, engine); | ||
195 | 155 | ||
196 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | 156 | if (op == VIA_BITBLT_FILL || !src_mem) |
197 | writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE); | 157 | return 0; |
198 | 158 | ||
199 | writel(VIA_PITCH_ENABLE | | 159 | tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) + |
200 | (((viaparinfo->hres * | 160 | 3) >> 2; |
201 | viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres * | 161 | |
202 | viaparinfo-> | 162 | for (i = 0; i < tmp; i++) |
203 | bpp >> 3) >> 3) << 16)), | 163 | writel(src_mem[i], engine + VIA_MMIO_BLTBASE); |
204 | viaparinfo->io_virt + VIA_REG_PITCH); | 164 | |
165 | return 0; | ||
205 | } | 166 | } |
206 | 167 | ||
207 | void viafb_set_2d_color_depth(int bpp) | 168 | static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height, |
169 | u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, | ||
170 | u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, | ||
171 | u32 fg_color, u32 bg_color, u8 fill_rop) | ||
208 | { | 172 | { |
209 | u32 dwGEMode; | 173 | u32 ge_cmd = 0, tmp, i; |
174 | |||
175 | if (!op || op > 3) { | ||
176 | printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op); | ||
177 | return -EINVAL; | ||
178 | } | ||
210 | 179 | ||
211 | dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF; | 180 | if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) { |
181 | if (src_x < dst_x) { | ||
182 | ge_cmd |= 0x00008000; | ||
183 | src_x += width - 1; | ||
184 | dst_x += width - 1; | ||
185 | } | ||
186 | if (src_y < dst_y) { | ||
187 | ge_cmd |= 0x00004000; | ||
188 | src_y += height - 1; | ||
189 | dst_y += height - 1; | ||
190 | } | ||
191 | } | ||
212 | 192 | ||
213 | switch (bpp) { | 193 | if (op == VIA_BITBLT_FILL) { |
194 | switch (fill_rop) { | ||
195 | case 0x00: /* blackness */ | ||
196 | case 0x5A: /* pattern inversion */ | ||
197 | case 0xF0: /* pattern copy */ | ||
198 | case 0xFF: /* whiteness */ | ||
199 | break; | ||
200 | default: | ||
201 | printk(KERN_WARNING "hw_bitblt_2: Invalid fill rop: " | ||
202 | "%u\n", fill_rop); | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | switch (dst_bpp) { | ||
208 | case 8: | ||
209 | tmp = 0x00000000; | ||
210 | break; | ||
214 | case 16: | 211 | case 16: |
215 | dwGEMode |= VIA_GEM_16bpp; | 212 | tmp = 0x00000100; |
216 | break; | 213 | break; |
217 | case 32: | 214 | case 32: |
218 | dwGEMode |= VIA_GEM_32bpp; | 215 | tmp = 0x00000300; |
219 | break; | 216 | break; |
220 | default: | 217 | default: |
221 | dwGEMode |= VIA_GEM_8bpp; | 218 | printk(KERN_WARNING "hw_bitblt_2: Unsupported bpp %d\n", |
222 | break; | 219 | dst_bpp); |
220 | return -EINVAL; | ||
221 | } | ||
222 | writel(tmp, engine + 0x04); | ||
223 | |||
224 | if (op == VIA_BITBLT_FILL) | ||
225 | tmp = 0; | ||
226 | else | ||
227 | tmp = src_pitch; | ||
228 | if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) { | ||
229 | printk(KERN_WARNING "hw_bitblt_2: Unsupported pitch %X %X\n", | ||
230 | tmp, dst_pitch); | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | tmp = (tmp >> 3) | (dst_pitch << (16 - 3)); | ||
234 | writel(tmp, engine + 0x08); | ||
235 | |||
236 | if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) { | ||
237 | printk(KERN_WARNING "hw_bitblt_2: Unsupported width/height " | ||
238 | "%d %d\n", width, height); | ||
239 | return -EINVAL; | ||
240 | } | ||
241 | tmp = (width - 1) | ((height - 1) << 16); | ||
242 | writel(tmp, engine + 0x0C); | ||
243 | |||
244 | if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) { | ||
245 | printk(KERN_WARNING "hw_bitblt_2: Unsupported destination x/y " | ||
246 | "%d %d\n", dst_x, dst_y); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | tmp = dst_x | (dst_y << 16); | ||
250 | writel(tmp, engine + 0x10); | ||
251 | |||
252 | if (dst_addr & 0xE0000007) { | ||
253 | printk(KERN_WARNING "hw_bitblt_2: Unsupported destination " | ||
254 | "address %X\n", dst_addr); | ||
255 | return -EINVAL; | ||
256 | } | ||
257 | tmp = dst_addr >> 3; | ||
258 | writel(tmp, engine + 0x14); | ||
259 | |||
260 | if (op != VIA_BITBLT_FILL) { | ||
261 | if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000) | ||
262 | || src_y & 0xFFFFF000) { | ||
263 | printk(KERN_WARNING "hw_bitblt_2: Unsupported source " | ||
264 | "x/y %d %d\n", src_x, src_y); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | tmp = src_x | (src_y << 16); | ||
268 | writel(tmp, engine + 0x18); | ||
269 | |||
270 | tmp = src_mem ? 0 : src_addr; | ||
271 | if (dst_addr & 0xE0000007) { | ||
272 | printk(KERN_WARNING "hw_bitblt_2: Unsupported source " | ||
273 | "address %X\n", tmp); | ||
274 | return -EINVAL; | ||
275 | } | ||
276 | tmp >>= 3; | ||
277 | writel(tmp, engine + 0x1C); | ||
223 | } | 278 | } |
224 | 279 | ||
225 | /* Set BPP and Pitch */ | 280 | if (op != VIA_BITBLT_COLOR) |
226 | writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE); | 281 | writel(fg_color, engine + 0x4C); |
282 | |||
283 | if (op == VIA_BITBLT_MONO) | ||
284 | writel(bg_color, engine + 0x50); | ||
285 | |||
286 | if (op == VIA_BITBLT_FILL) | ||
287 | ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001; | ||
288 | else { | ||
289 | ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */ | ||
290 | if (src_mem) | ||
291 | ge_cmd |= 0x00000040; | ||
292 | if (op == VIA_BITBLT_MONO) | ||
293 | ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000; | ||
294 | else | ||
295 | ge_cmd |= 0x00000001; | ||
296 | } | ||
297 | writel(ge_cmd, engine); | ||
298 | |||
299 | if (op == VIA_BITBLT_FILL || !src_mem) | ||
300 | return 0; | ||
301 | |||
302 | tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) + | ||
303 | 3) >> 2; | ||
304 | |||
305 | for (i = 0; i < tmp; i++) | ||
306 | writel(src_mem[i], engine + VIA_MMIO_BLTBASE); | ||
307 | |||
308 | return 0; | ||
227 | } | 309 | } |
228 | 310 | ||
229 | void viafb_hw_cursor_init(void) | 311 | int viafb_init_engine(struct fb_info *info) |
230 | { | 312 | { |
313 | struct viafb_par *viapar = info->par; | ||
314 | void __iomem *engine; | ||
315 | u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, | ||
316 | vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; | ||
317 | |||
318 | engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); | ||
319 | viapar->shared->engine_mmio = engine; | ||
320 | if (!engine) { | ||
321 | printk(KERN_WARNING "viafb_init_accel: ioremap failed, " | ||
322 | "hardware acceleration disabled\n"); | ||
323 | return -ENOMEM; | ||
324 | } | ||
325 | |||
326 | switch (chip_name) { | ||
327 | case UNICHROME_CLE266: | ||
328 | case UNICHROME_K400: | ||
329 | case UNICHROME_K800: | ||
330 | case UNICHROME_PM800: | ||
331 | case UNICHROME_CN700: | ||
332 | case UNICHROME_CX700: | ||
333 | case UNICHROME_CN750: | ||
334 | case UNICHROME_K8M890: | ||
335 | case UNICHROME_P4M890: | ||
336 | case UNICHROME_P4M900: | ||
337 | viapar->shared->hw_bitblt = hw_bitblt_1; | ||
338 | break; | ||
339 | case UNICHROME_VX800: | ||
340 | case UNICHROME_VX855: | ||
341 | viapar->shared->hw_bitblt = hw_bitblt_2; | ||
342 | break; | ||
343 | default: | ||
344 | viapar->shared->hw_bitblt = NULL; | ||
345 | } | ||
346 | |||
347 | viapar->fbmem_free -= CURSOR_SIZE; | ||
348 | viapar->shared->cursor_vram_addr = viapar->fbmem_free; | ||
349 | viapar->fbmem_used += CURSOR_SIZE; | ||
350 | |||
351 | viapar->fbmem_free -= VQ_SIZE; | ||
352 | viapar->shared->vq_vram_addr = viapar->fbmem_free; | ||
353 | viapar->fbmem_used += VQ_SIZE; | ||
354 | |||
355 | /* Init AGP and VQ regs */ | ||
356 | switch (chip_name) { | ||
357 | case UNICHROME_K8M890: | ||
358 | case UNICHROME_P4M900: | ||
359 | writel(0x00100000, engine + VIA_REG_CR_TRANSET); | ||
360 | writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE); | ||
361 | writel(0x02000000, engine + VIA_REG_CR_TRANSPACE); | ||
362 | break; | ||
363 | |||
364 | default: | ||
365 | writel(0x00100000, engine + VIA_REG_TRANSET); | ||
366 | writel(0x00000000, engine + VIA_REG_TRANSPACE); | ||
367 | writel(0x00333004, engine + VIA_REG_TRANSPACE); | ||
368 | writel(0x60000000, engine + VIA_REG_TRANSPACE); | ||
369 | writel(0x61000000, engine + VIA_REG_TRANSPACE); | ||
370 | writel(0x62000000, engine + VIA_REG_TRANSPACE); | ||
371 | writel(0x63000000, engine + VIA_REG_TRANSPACE); | ||
372 | writel(0x64000000, engine + VIA_REG_TRANSPACE); | ||
373 | writel(0x7D000000, engine + VIA_REG_TRANSPACE); | ||
374 | |||
375 | writel(0xFE020000, engine + VIA_REG_TRANSET); | ||
376 | writel(0x00000000, engine + VIA_REG_TRANSPACE); | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | /* Enable VQ */ | ||
381 | vq_start_addr = viapar->shared->vq_vram_addr; | ||
382 | vq_end_addr = viapar->shared->vq_vram_addr + VQ_SIZE - 1; | ||
383 | |||
384 | vq_start_low = 0x50000000 | (vq_start_addr & 0xFFFFFF); | ||
385 | vq_end_low = 0x51000000 | (vq_end_addr & 0xFFFFFF); | ||
386 | vq_high = 0x52000000 | ((vq_start_addr & 0xFF000000) >> 24) | | ||
387 | ((vq_end_addr & 0xFF000000) >> 16); | ||
388 | vq_len = 0x53000000 | (VQ_SIZE >> 3); | ||
389 | |||
390 | switch (chip_name) { | ||
391 | case UNICHROME_K8M890: | ||
392 | case UNICHROME_P4M900: | ||
393 | vq_start_low |= 0x20000000; | ||
394 | vq_end_low |= 0x20000000; | ||
395 | vq_high |= 0x20000000; | ||
396 | vq_len |= 0x20000000; | ||
397 | |||
398 | writel(0x00100000, engine + VIA_REG_CR_TRANSET); | ||
399 | writel(vq_high, engine + VIA_REG_CR_TRANSPACE); | ||
400 | writel(vq_start_low, engine + VIA_REG_CR_TRANSPACE); | ||
401 | writel(vq_end_low, engine + VIA_REG_CR_TRANSPACE); | ||
402 | writel(vq_len, engine + VIA_REG_CR_TRANSPACE); | ||
403 | writel(0x74301001, engine + VIA_REG_CR_TRANSPACE); | ||
404 | writel(0x00000000, engine + VIA_REG_CR_TRANSPACE); | ||
405 | break; | ||
406 | default: | ||
407 | writel(0x00FE0000, engine + VIA_REG_TRANSET); | ||
408 | writel(0x080003FE, engine + VIA_REG_TRANSPACE); | ||
409 | writel(0x0A00027C, engine + VIA_REG_TRANSPACE); | ||
410 | writel(0x0B000260, engine + VIA_REG_TRANSPACE); | ||
411 | writel(0x0C000274, engine + VIA_REG_TRANSPACE); | ||
412 | writel(0x0D000264, engine + VIA_REG_TRANSPACE); | ||
413 | writel(0x0E000000, engine + VIA_REG_TRANSPACE); | ||
414 | writel(0x0F000020, engine + VIA_REG_TRANSPACE); | ||
415 | writel(0x1000027E, engine + VIA_REG_TRANSPACE); | ||
416 | writel(0x110002FE, engine + VIA_REG_TRANSPACE); | ||
417 | writel(0x200F0060, engine + VIA_REG_TRANSPACE); | ||
418 | |||
419 | writel(0x00000006, engine + VIA_REG_TRANSPACE); | ||
420 | writel(0x40008C0F, engine + VIA_REG_TRANSPACE); | ||
421 | writel(0x44000000, engine + VIA_REG_TRANSPACE); | ||
422 | writel(0x45080C04, engine + VIA_REG_TRANSPACE); | ||
423 | writel(0x46800408, engine + VIA_REG_TRANSPACE); | ||
424 | |||
425 | writel(vq_high, engine + VIA_REG_TRANSPACE); | ||
426 | writel(vq_start_low, engine + VIA_REG_TRANSPACE); | ||
427 | writel(vq_end_low, engine + VIA_REG_TRANSPACE); | ||
428 | writel(vq_len, engine + VIA_REG_TRANSPACE); | ||
429 | break; | ||
430 | } | ||
431 | |||
231 | /* Set Cursor Image Base Address */ | 432 | /* Set Cursor Image Base Address */ |
232 | writel(viaparinfo->cursor_start, | 433 | writel(viapar->shared->cursor_vram_addr, engine + VIA_REG_CURSOR_MODE); |
233 | viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | 434 | writel(0x0, engine + VIA_REG_CURSOR_POS); |
234 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS); | 435 | writel(0x0, engine + VIA_REG_CURSOR_ORG); |
235 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); | 436 | writel(0x0, engine + VIA_REG_CURSOR_BG); |
236 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG); | 437 | writel(0x0, engine + VIA_REG_CURSOR_FG); |
237 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG); | 438 | return 0; |
238 | } | 439 | } |
239 | 440 | ||
240 | void viafb_show_hw_cursor(struct fb_info *info, int Status) | 441 | void viafb_show_hw_cursor(struct fb_info *info, int Status) |
241 | { | 442 | { |
242 | u32 temp; | 443 | struct viafb_par *viapar = info->par; |
243 | u32 iga_path = ((struct viafb_par *)(info->par))->iga_path; | 444 | u32 temp, iga_path = viapar->iga_path; |
244 | 445 | ||
245 | temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | 446 | temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); |
246 | switch (Status) { | 447 | switch (Status) { |
247 | case HW_Cursor_ON: | 448 | case HW_Cursor_ON: |
248 | temp |= 0x1; | 449 | temp |= 0x1; |
@@ -259,25 +460,27 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status) | |||
259 | default: | 460 | default: |
260 | temp &= 0x7FFFFFFF; | 461 | temp &= 0x7FFFFFFF; |
261 | } | 462 | } |
262 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | 463 | writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); |
263 | } | 464 | } |
264 | 465 | ||
265 | int viafb_wait_engine_idle(void) | 466 | void viafb_wait_engine_idle(struct fb_info *info) |
266 | { | 467 | { |
468 | struct viafb_par *viapar = info->par; | ||
267 | int loop = 0; | 469 | int loop = 0; |
268 | 470 | ||
269 | while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) & | 471 | while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & |
270 | VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { | 472 | VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { |
271 | loop++; | 473 | loop++; |
272 | cpu_relax(); | 474 | cpu_relax(); |
273 | } | 475 | } |
274 | 476 | ||
275 | while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) & | 477 | while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & |
276 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && | 478 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && |
277 | (loop < MAXLOOP)) { | 479 | (loop < MAXLOOP)) { |
278 | loop++; | 480 | loop++; |
279 | cpu_relax(); | 481 | cpu_relax(); |
280 | } | 482 | } |
281 | 483 | ||
282 | return loop >= MAXLOOP; | 484 | if (loop >= MAXLOOP) |
485 | printk(KERN_ERR "viafb_wait_engine_idle: not syncing\n"); | ||
283 | } | 486 | } |
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h index 29bf854e8ccf..615c84ad0f01 100644 --- a/drivers/video/via/accel.h +++ b/drivers/video/via/accel.h | |||
@@ -159,11 +159,12 @@ | |||
159 | 159 | ||
160 | #define MAXLOOP 0xFFFFFF | 160 | #define MAXLOOP 0xFFFFFF |
161 | 161 | ||
162 | void viafb_init_accel(void); | 162 | #define VIA_BITBLT_COLOR 1 |
163 | void viafb_init_2d_engine(void); | 163 | #define VIA_BITBLT_MONO 2 |
164 | void set_2d_color_depth(int); | 164 | #define VIA_BITBLT_FILL 3 |
165 | void viafb_hw_cursor_init(void); | 165 | |
166 | void viafb_show_hw_cursor(struct fb_info *info, int Status); int | 166 | int viafb_init_engine(struct fb_info *info); |
167 | viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp); | 167 | void viafb_show_hw_cursor(struct fb_info *info, int Status); |
168 | void viafb_wait_engine_idle(struct fb_info *info); | ||
168 | 169 | ||
169 | #endif /* __ACCEL_H__ */ | 170 | #endif /* __ACCEL_H__ */ |
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index dde95edc387a..474f428aea92 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h | |||
@@ -68,6 +68,9 @@ | |||
68 | #define UNICHROME_VX800 11 | 68 | #define UNICHROME_VX800 11 |
69 | #define UNICHROME_VX800_DID 0x1122 | 69 | #define UNICHROME_VX800_DID 0x1122 |
70 | 70 | ||
71 | #define UNICHROME_VX855 12 | ||
72 | #define UNICHROME_VX855_DID 0x5122 | ||
73 | |||
71 | /**************************************************/ | 74 | /**************************************************/ |
72 | /* Definition TMDS Trasmitter Information */ | 75 | /* Definition TMDS Trasmitter Information */ |
73 | /**************************************************/ | 76 | /**************************************************/ |
@@ -122,7 +125,6 @@ struct lvds_chip_information { | |||
122 | struct chip_information { | 125 | struct chip_information { |
123 | int gfx_chip_name; | 126 | int gfx_chip_name; |
124 | int gfx_chip_revision; | 127 | int gfx_chip_revision; |
125 | int chip_on_slot; | ||
126 | struct tmds_chip_information tmds_chip_info; | 128 | struct tmds_chip_information tmds_chip_info; |
127 | struct lvds_chip_information lvds_chip_info; | 129 | struct lvds_chip_information lvds_chip_info; |
128 | struct lvds_chip_information lvds_chip_info2; | 130 | struct lvds_chip_information lvds_chip_info2; |
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index d6965447ca69..c5c32b6b6e6c 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c | |||
@@ -160,7 +160,7 @@ int viafb_tmds_trasmitter_identify(void) | |||
160 | 160 | ||
161 | static void tmds_register_write(int index, u8 data) | 161 | static void tmds_register_write(int index, u8 data) |
162 | { | 162 | { |
163 | viaparinfo->i2c_stuff.i2c_port = | 163 | viaparinfo->shared->i2c_stuff.i2c_port = |
164 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | 164 | viaparinfo->chip_info->tmds_chip_info.i2c_port; |
165 | 165 | ||
166 | viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info. | 166 | viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info. |
@@ -172,7 +172,7 @@ static int tmds_register_read(int index) | |||
172 | { | 172 | { |
173 | u8 data; | 173 | u8 data; |
174 | 174 | ||
175 | viaparinfo->i2c_stuff.i2c_port = | 175 | viaparinfo->shared->i2c_stuff.i2c_port = |
176 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | 176 | viaparinfo->chip_info->tmds_chip_info.i2c_port; |
177 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> | 177 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> |
178 | tmds_chip_info.tmds_chip_slave_addr, | 178 | tmds_chip_info.tmds_chip_slave_addr, |
@@ -182,7 +182,7 @@ static int tmds_register_read(int index) | |||
182 | 182 | ||
183 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) | 183 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) |
184 | { | 184 | { |
185 | viaparinfo->i2c_stuff.i2c_port = | 185 | viaparinfo->shared->i2c_stuff.i2c_port = |
186 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | 186 | viaparinfo->chip_info->tmds_chip_info.i2c_port; |
187 | viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. | 187 | viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. |
188 | tmds_chip_slave_addr, (u8) index, buff, buff_len); | 188 | tmds_chip_slave_addr, (u8) index, buff, buff_len); |
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c index 468be2425af3..b675cdbb03ad 100644 --- a/drivers/video/via/global.c +++ b/drivers/video/via/global.c | |||
@@ -32,7 +32,6 @@ int viafb_lcd_dsp_method = LCD_EXPANDSION; | |||
32 | int viafb_lcd_mode = LCD_OPENLDI; | 32 | int viafb_lcd_mode = LCD_OPENLDI; |
33 | int viafb_bpp = 32; | 33 | int viafb_bpp = 32; |
34 | int viafb_bpp1 = 32; | 34 | int viafb_bpp1 = 32; |
35 | int viafb_accel = 1; | ||
36 | int viafb_CRT_ON = 1; | 35 | int viafb_CRT_ON = 1; |
37 | int viafb_DVI_ON; | 36 | int viafb_DVI_ON; |
38 | int viafb_LCD_ON ; | 37 | int viafb_LCD_ON ; |
@@ -46,13 +45,11 @@ int viafb_hotplug_refresh = 60; | |||
46 | unsigned int viafb_second_offset; | 45 | unsigned int viafb_second_offset; |
47 | int viafb_second_size; | 46 | int viafb_second_size; |
48 | int viafb_primary_dev = None_Device; | 47 | int viafb_primary_dev = None_Device; |
49 | void __iomem *viafb_FB_MM; | ||
50 | unsigned int viafb_second_xres = 640; | 48 | unsigned int viafb_second_xres = 640; |
51 | unsigned int viafb_second_yres = 480; | 49 | unsigned int viafb_second_yres = 480; |
52 | unsigned int viafb_second_virtual_xres; | 50 | unsigned int viafb_second_virtual_xres; |
53 | unsigned int viafb_second_virtual_yres; | 51 | unsigned int viafb_second_virtual_yres; |
54 | int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; | 52 | int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; |
55 | struct fb_cursor viacursor; | ||
56 | struct fb_info *viafbinfo; | 53 | struct fb_info *viafbinfo; |
57 | struct fb_info *viafbinfo1; | 54 | struct fb_info *viafbinfo1; |
58 | struct viafb_par *viaparinfo; | 55 | struct viafb_par *viaparinfo; |
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 7543d5f7e309..d69d0ca99c2f 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h | |||
@@ -77,8 +77,6 @@ extern int viafb_hotplug_Yres; | |||
77 | extern int viafb_hotplug_bpp; | 77 | extern int viafb_hotplug_bpp; |
78 | extern int viafb_hotplug_refresh; | 78 | extern int viafb_hotplug_refresh; |
79 | extern int viafb_primary_dev; | 79 | extern int viafb_primary_dev; |
80 | extern void __iomem *viafb_FB_MM; | ||
81 | extern struct fb_cursor viacursor; | ||
82 | 80 | ||
83 | extern unsigned int viafb_second_xres; | 81 | extern unsigned int viafb_second_xres; |
84 | extern unsigned int viafb_second_yres; | 82 | extern unsigned int viafb_second_yres; |
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index fcd53ceb88fa..3e083ff67ae2 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
@@ -21,125 +21,143 @@ | |||
21 | 21 | ||
22 | #include "global.h" | 22 | #include "global.h" |
23 | 23 | ||
24 | static const struct pci_device_id_info pciidlist[] = { | ||
25 | {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266}, | ||
26 | {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800}, | ||
27 | {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400}, | ||
28 | {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800}, | ||
29 | {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700}, | ||
30 | {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890}, | ||
31 | {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890}, | ||
32 | {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700}, | ||
33 | {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900}, | ||
34 | {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750}, | ||
35 | {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800}, | ||
36 | {0, 0, 0} | ||
37 | }; | ||
38 | |||
39 | struct offset offset_reg = { | ||
40 | /* IGA1 Offset Register */ | ||
41 | {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } }, | ||
42 | /* IGA2 Offset Register */ | ||
43 | {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } } | ||
44 | }; | ||
45 | |||
46 | static struct pll_map pll_value[] = { | 24 | static struct pll_map pll_value[] = { |
47 | {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M}, | 25 | {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, |
48 | {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M}, | 26 | CX700_25_175M, VX855_25_175M}, |
49 | {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M}, | 27 | {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, |
50 | {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M}, | 28 | CX700_29_581M, VX855_29_581M}, |
51 | {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M}, | 29 | {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, |
52 | {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M}, | 30 | CX700_26_880M, VX855_26_880M}, |
53 | {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M}, | 31 | {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, |
54 | {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M}, | 32 | CX700_31_490M, VX855_31_490M}, |
55 | {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M}, | 33 | {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, |
56 | {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M}, | 34 | CX700_31_500M, VX855_31_500M}, |
57 | {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M}, | 35 | {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, |
58 | {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M}, | 36 | CX700_31_728M, VX855_31_728M}, |
59 | {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M}, | 37 | {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, |
60 | {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M}, | 38 | CX700_32_668M, VX855_32_668M}, |
61 | {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M}, | 39 | {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, |
62 | {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M}, | 40 | CX700_36_000M, VX855_36_000M}, |
63 | {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M}, | 41 | {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, |
64 | {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M}, | 42 | CX700_40_000M, VX855_40_000M}, |
65 | {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M}, | 43 | {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, |
66 | {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M}, | 44 | CX700_41_291M, VX855_41_291M}, |
67 | {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M}, | 45 | {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, |
68 | {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M}, | 46 | CX700_43_163M, VX855_43_163M}, |
69 | {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M}, | 47 | {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, |
70 | {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M}, | 48 | CX700_45_250M, VX855_45_250M}, |
71 | {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M}, | 49 | {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, |
72 | {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M}, | 50 | CX700_46_000M, VX855_46_000M}, |
73 | {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M}, | 51 | {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, |
74 | {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M}, | 52 | CX700_46_996M, VX855_46_996M}, |
75 | {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M}, | 53 | {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, |
76 | {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M}, | 54 | CX700_48_000M, VX855_48_000M}, |
77 | {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M}, | 55 | {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, |
78 | {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M}, | 56 | CX700_48_875M, VX855_48_875M}, |
79 | {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M}, | 57 | {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, |
80 | {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M}, | 58 | CX700_49_500M, VX855_49_500M}, |
81 | {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M}, | 59 | {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, |
82 | {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M}, | 60 | CX700_52_406M, VX855_52_406M}, |
83 | {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M}, | 61 | {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, |
84 | {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M}, | 62 | CX700_52_977M, VX855_52_977M}, |
63 | {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, | ||
64 | CX700_56_250M, VX855_56_250M}, | ||
65 | {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, | ||
66 | CX700_60_466M, VX855_60_466M}, | ||
67 | {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, | ||
68 | CX700_61_500M, VX855_61_500M}, | ||
69 | {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, | ||
70 | CX700_65_000M, VX855_65_000M}, | ||
71 | {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, | ||
72 | CX700_65_178M, VX855_65_178M}, | ||
73 | {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, | ||
74 | CX700_66_750M, VX855_66_750M}, | ||
75 | {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, | ||
76 | CX700_68_179M, VX855_68_179M}, | ||
77 | {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, | ||
78 | CX700_69_924M, VX855_69_924M}, | ||
79 | {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, | ||
80 | CX700_70_159M, VX855_70_159M}, | ||
81 | {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, | ||
82 | CX700_72_000M, VX855_72_000M}, | ||
83 | {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, | ||
84 | CX700_78_750M, VX855_78_750M}, | ||
85 | {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, | ||
86 | CX700_80_136M, VX855_80_136M}, | ||
87 | {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, | ||
88 | CX700_83_375M, VX855_83_375M}, | ||
89 | {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, | ||
90 | CX700_83_950M, VX855_83_950M}, | ||
91 | {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, | ||
92 | CX700_84_750M, VX855_84_750M}, | ||
93 | {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, | ||
94 | CX700_85_860M, VX855_85_860M}, | ||
95 | {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, | ||
96 | CX700_88_750M, VX855_88_750M}, | ||
97 | {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, | ||
98 | CX700_94_500M, VX855_94_500M}, | ||
99 | {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, | ||
100 | CX700_97_750M, VX855_97_750M}, | ||
85 | {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M, | 101 | {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M, |
86 | CX700_101_000M}, | 102 | CX700_101_000M, VX855_101_000M}, |
87 | {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M, | 103 | {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M, |
88 | CX700_106_500M}, | 104 | CX700_106_500M, VX855_106_500M}, |
89 | {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M, | 105 | {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M, |
90 | CX700_108_000M}, | 106 | CX700_108_000M, VX855_108_000M}, |
91 | {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M, | 107 | {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M, |
92 | CX700_113_309M}, | 108 | CX700_113_309M, VX855_113_309M}, |
93 | {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M, | 109 | {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M, |
94 | CX700_118_840M}, | 110 | CX700_118_840M, VX855_118_840M}, |
95 | {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M, | 111 | {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M, |
96 | CX700_119_000M}, | 112 | CX700_119_000M, VX855_119_000M}, |
97 | {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M, | 113 | {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M, |
98 | CX700_121_750M}, | 114 | CX700_121_750M, 0}, |
99 | {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M, | 115 | {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M, |
100 | CX700_125_104M}, | 116 | CX700_125_104M, 0}, |
101 | {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M, | 117 | {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M, |
102 | CX700_133_308M}, | 118 | CX700_133_308M, 0}, |
103 | {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M, | 119 | {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M, |
104 | CX700_135_000M}, | 120 | CX700_135_000M, VX855_135_000M}, |
105 | {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M, | 121 | {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M, |
106 | CX700_136_700M}, | 122 | CX700_136_700M, VX855_136_700M}, |
107 | {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M, | 123 | {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M, |
108 | CX700_138_400M}, | 124 | CX700_138_400M, VX855_138_400M}, |
109 | {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M, | 125 | {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M, |
110 | CX700_146_760M}, | 126 | CX700_146_760M, VX855_146_760M}, |
111 | {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M, | 127 | {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M, |
112 | CX700_153_920M}, | 128 | CX700_153_920M, VX855_153_920M}, |
113 | {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M, | 129 | {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M, |
114 | CX700_156_000M}, | 130 | CX700_156_000M, VX855_156_000M}, |
115 | {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M, | 131 | {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M, |
116 | CX700_157_500M}, | 132 | CX700_157_500M, VX855_157_500M}, |
117 | {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M, | 133 | {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M, |
118 | CX700_162_000M}, | 134 | CX700_162_000M, VX855_162_000M}, |
119 | {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M, | 135 | {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M, |
120 | CX700_187_000M}, | 136 | CX700_187_000M, VX855_187_000M}, |
121 | {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M, | 137 | {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M, |
122 | CX700_193_295M}, | 138 | CX700_193_295M, VX855_193_295M}, |
123 | {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M, | 139 | {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M, |
124 | CX700_202_500M}, | 140 | CX700_202_500M, VX855_202_500M}, |
125 | {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M, | 141 | {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M, |
126 | CX700_204_000M}, | 142 | CX700_204_000M, VX855_204_000M}, |
127 | {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M, | 143 | {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M, |
128 | CX700_218_500M}, | 144 | CX700_218_500M, VX855_218_500M}, |
129 | {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M, | 145 | {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M, |
130 | CX700_234_000M}, | 146 | CX700_234_000M, VX855_234_000M}, |
131 | {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M, | 147 | {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M, |
132 | CX700_267_250M}, | 148 | CX700_267_250M, VX855_267_250M}, |
133 | {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M, | 149 | {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M, |
134 | CX700_297_500M}, | 150 | CX700_297_500M, VX855_297_500M}, |
135 | {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M}, | 151 | {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, |
152 | CX700_74_481M, VX855_74_481M}, | ||
136 | {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M, | 153 | {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M, |
137 | CX700_172_798M}, | 154 | CX700_172_798M, VX855_172_798M}, |
138 | {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M, | 155 | {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M, |
139 | CX700_122_614M}, | 156 | CX700_122_614M, VX855_122_614M}, |
140 | {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M}, | 157 | {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, |
158 | CX700_74_270M, 0}, | ||
141 | {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M, | 159 | {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M, |
142 | CX700_148_500M} | 160 | CX700_148_500M, VX855_148_500M} |
143 | }; | 161 | }; |
144 | 162 | ||
145 | static struct fifo_depth_select display_fifo_depth_reg = { | 163 | static struct fifo_depth_select display_fifo_depth_reg = { |
@@ -508,7 +526,8 @@ static void set_dvi_output_path(int set_iga, int output_interface); | |||
508 | static void set_lcd_output_path(int set_iga, int output_interface); | 526 | static void set_lcd_output_path(int set_iga, int output_interface); |
509 | static int search_mode_setting(int ModeInfoIndex); | 527 | static int search_mode_setting(int ModeInfoIndex); |
510 | static void load_fix_bit_crtc_reg(void); | 528 | static void load_fix_bit_crtc_reg(void); |
511 | static void init_gfx_chip_info(void); | 529 | static void init_gfx_chip_info(struct pci_dev *pdev, |
530 | const struct pci_device_id *pdi); | ||
512 | static void init_tmds_chip_info(void); | 531 | static void init_tmds_chip_info(void); |
513 | static void init_lvds_chip_info(void); | 532 | static void init_lvds_chip_info(void); |
514 | static void device_screen_off(void); | 533 | static void device_screen_off(void); |
@@ -518,7 +537,6 @@ static void device_off(void); | |||
518 | static void device_on(void); | 537 | static void device_on(void); |
519 | static void enable_second_display_channel(void); | 538 | static void enable_second_display_channel(void); |
520 | static void disable_second_display_channel(void); | 539 | static void disable_second_display_channel(void); |
521 | static int get_fb_size_from_pci(void); | ||
522 | 540 | ||
523 | void viafb_write_reg(u8 index, u16 io_port, u8 data) | 541 | void viafb_write_reg(u8 index, u16 io_port, u8 data) |
524 | { | 542 | { |
@@ -629,70 +647,43 @@ void viafb_set_iga_path(void) | |||
629 | } | 647 | } |
630 | } | 648 | } |
631 | 649 | ||
632 | void viafb_set_start_addr(void) | 650 | void viafb_set_primary_address(u32 addr) |
633 | { | 651 | { |
634 | unsigned long offset = 0, tmp = 0, size = 0; | 652 | DEBUG_MSG(KERN_DEBUG "viafb_set_primary_address(0x%08X)\n", addr); |
635 | unsigned long length; | 653 | viafb_write_reg(CR0D, VIACR, addr & 0xFF); |
636 | 654 | viafb_write_reg(CR0C, VIACR, (addr >> 8) & 0xFF); | |
637 | DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n"); | 655 | viafb_write_reg(CR34, VIACR, (addr >> 16) & 0xFF); |
638 | viafb_unlock_crt(); | 656 | viafb_write_reg_mask(CR48, VIACR, (addr >> 24) & 0x1F, 0x1F); |
639 | /* update starting address of IGA1 */ | 657 | } |
640 | viafb_write_reg(CR0C, VIACR, 0x00); /*initial starting address */ | ||
641 | viafb_write_reg(CR0D, VIACR, 0x00); | ||
642 | viafb_write_reg(CR34, VIACR, 0x00); | ||
643 | viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F); | ||
644 | |||
645 | if (viafb_dual_fb) { | ||
646 | viaparinfo->iga_path = IGA1; | ||
647 | viaparinfo1->iga_path = IGA2; | ||
648 | } | ||
649 | |||
650 | if (viafb_SAMM_ON == 1) { | ||
651 | if (!viafb_dual_fb) { | ||
652 | if (viafb_second_size) | ||
653 | size = viafb_second_size * 1024 * 1024; | ||
654 | else | ||
655 | size = 8 * 1024 * 1024; | ||
656 | } else { | ||
657 | 658 | ||
658 | size = viaparinfo1->memsize; | 659 | void viafb_set_secondary_address(u32 addr) |
659 | } | 660 | { |
660 | offset = viafb_second_offset; | 661 | DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_address(0x%08X)\n", addr); |
661 | DEBUG_MSG(KERN_INFO | 662 | /* secondary display supports only quadword aligned memory */ |
662 | "viafb_second_size=%lx, second start_adddress=%lx\n", | 663 | viafb_write_reg_mask(CR62, VIACR, (addr >> 2) & 0xFE, 0xFE); |
663 | size, offset); | 664 | viafb_write_reg(CR63, VIACR, (addr >> 10) & 0xFF); |
664 | } | 665 | viafb_write_reg(CR64, VIACR, (addr >> 18) & 0xFF); |
665 | if (viafb_SAMM_ON == 1) { | 666 | viafb_write_reg_mask(CRA3, VIACR, (addr >> 26) & 0x07, 0x07); |
666 | offset = offset >> 3; | 667 | } |
667 | |||
668 | tmp = viafb_read_reg(VIACR, 0x62) & 0x01; | ||
669 | tmp |= (offset & 0x7F) << 1; | ||
670 | viafb_write_reg(CR62, VIACR, tmp); | ||
671 | viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7)); | ||
672 | viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15)); | ||
673 | viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23)); | ||
674 | } else { | ||
675 | /* update starting address */ | ||
676 | viafb_write_reg(CR62, VIACR, 0x00); | ||
677 | viafb_write_reg(CR63, VIACR, 0x00); | ||
678 | viafb_write_reg(CR64, VIACR, 0x00); | ||
679 | viafb_write_reg(CRA3, VIACR, 0x00); | ||
680 | } | ||
681 | 668 | ||
682 | if (viafb_SAMM_ON == 1) { | 669 | void viafb_set_primary_pitch(u32 pitch) |
683 | if (viafb_accel) { | 670 | { |
684 | if (!viafb_dual_fb) | 671 | DEBUG_MSG(KERN_DEBUG "viafb_set_primary_pitch(0x%08X)\n", pitch); |
685 | length = size - viaparinfo->fbmem_used; | 672 | /* spec does not say that first adapter skips 3 bits but old |
686 | else | 673 | * code did it and seems to be reasonable in analogy to 2nd adapter |
687 | length = size - viaparinfo1->fbmem_used; | 674 | */ |
688 | } else | 675 | pitch = pitch >> 3; |
689 | length = size; | 676 | viafb_write_reg(0x13, VIACR, pitch & 0xFF); |
690 | offset = (unsigned long)(void *)viafb_FB_MM + | 677 | viafb_write_reg_mask(0x35, VIACR, (pitch >> (8 - 5)) & 0xE0, 0xE0); |
691 | viafb_second_offset; | 678 | } |
692 | memset((void *)offset, 0, length); | ||
693 | } | ||
694 | 679 | ||
695 | viafb_lock_crt(); | 680 | void viafb_set_secondary_pitch(u32 pitch) |
681 | { | ||
682 | DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_pitch(0x%08X)\n", pitch); | ||
683 | pitch = pitch >> 3; | ||
684 | viafb_write_reg(0x66, VIACR, pitch & 0xFF); | ||
685 | viafb_write_reg_mask(0x67, VIACR, (pitch >> 8) & 0x03, 0x03); | ||
686 | viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80); | ||
696 | } | 687 | } |
697 | 688 | ||
698 | void viafb_set_output_path(int device, int set_iga, int output_interface) | 689 | void viafb_set_output_path(int device, int set_iga, int output_interface) |
@@ -1123,30 +1114,6 @@ void viafb_write_regx(struct io_reg RegTable[], int ItemNum) | |||
1123 | } | 1114 | } |
1124 | } | 1115 | } |
1125 | 1116 | ||
1126 | void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga) | ||
1127 | { | ||
1128 | int reg_value; | ||
1129 | int viafb_load_reg_num; | ||
1130 | struct io_register *reg; | ||
1131 | |||
1132 | switch (set_iga) { | ||
1133 | case IGA1_IGA2: | ||
1134 | case IGA1: | ||
1135 | reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte); | ||
1136 | viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num; | ||
1137 | reg = offset_reg.iga1_offset_reg.reg; | ||
1138 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1139 | if (set_iga == IGA1) | ||
1140 | break; | ||
1141 | case IGA2: | ||
1142 | reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte); | ||
1143 | viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num; | ||
1144 | reg = offset_reg.iga2_offset_reg.reg; | ||
1145 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1146 | break; | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) | 1117 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) |
1151 | { | 1118 | { |
1152 | int reg_value; | 1119 | int reg_value; |
@@ -1277,6 +1244,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) | |||
1277 | VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | 1244 | VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; |
1278 | } | 1245 | } |
1279 | 1246 | ||
1247 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) { | ||
1248 | iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH; | ||
1249 | iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD; | ||
1250 | iga1_fifo_high_threshold = | ||
1251 | VX855_IGA1_FIFO_HIGH_THRESHOLD; | ||
1252 | iga1_display_queue_expire_num = | ||
1253 | VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1254 | } | ||
1255 | |||
1280 | /* Set Display FIFO Depath Select */ | 1256 | /* Set Display FIFO Depath Select */ |
1281 | reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); | 1257 | reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); |
1282 | viafb_load_reg_num = | 1258 | viafb_load_reg_num = |
@@ -1408,6 +1384,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) | |||
1408 | VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | 1384 | VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; |
1409 | } | 1385 | } |
1410 | 1386 | ||
1387 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) { | ||
1388 | iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH; | ||
1389 | iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD; | ||
1390 | iga2_fifo_high_threshold = | ||
1391 | VX855_IGA2_FIFO_HIGH_THRESHOLD; | ||
1392 | iga2_display_queue_expire_num = | ||
1393 | VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1394 | } | ||
1395 | |||
1411 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { | 1396 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { |
1412 | /* Set Display FIFO Depath Select */ | 1397 | /* Set Display FIFO Depath Select */ |
1413 | reg_value = | 1398 | reg_value = |
@@ -1496,6 +1481,8 @@ u32 viafb_get_clk_value(int clk) | |||
1496 | case UNICHROME_P4M900: | 1481 | case UNICHROME_P4M900: |
1497 | case UNICHROME_VX800: | 1482 | case UNICHROME_VX800: |
1498 | return pll_value[i].cx700_pll; | 1483 | return pll_value[i].cx700_pll; |
1484 | case UNICHROME_VX855: | ||
1485 | return pll_value[i].vx855_pll; | ||
1499 | } | 1486 | } |
1500 | } | 1487 | } |
1501 | } | 1488 | } |
@@ -1529,6 +1516,7 @@ void viafb_set_vclock(u32 CLK, int set_iga) | |||
1529 | case UNICHROME_P4M890: | 1516 | case UNICHROME_P4M890: |
1530 | case UNICHROME_P4M900: | 1517 | case UNICHROME_P4M900: |
1531 | case UNICHROME_VX800: | 1518 | case UNICHROME_VX800: |
1519 | case UNICHROME_VX855: | ||
1532 | viafb_write_reg(SR44, VIASR, CLK / 0x10000); | 1520 | viafb_write_reg(SR44, VIASR, CLK / 0x10000); |
1533 | DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000); | 1521 | DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000); |
1534 | viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100); | 1522 | viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100); |
@@ -1557,6 +1545,7 @@ void viafb_set_vclock(u32 CLK, int set_iga) | |||
1557 | case UNICHROME_P4M890: | 1545 | case UNICHROME_P4M890: |
1558 | case UNICHROME_P4M900: | 1546 | case UNICHROME_P4M900: |
1559 | case UNICHROME_VX800: | 1547 | case UNICHROME_VX800: |
1548 | case UNICHROME_VX855: | ||
1560 | viafb_write_reg(SR4A, VIASR, CLK / 0x10000); | 1549 | viafb_write_reg(SR4A, VIASR, CLK / 0x10000); |
1561 | viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100); | 1550 | viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100); |
1562 | viafb_write_reg(SR4C, VIASR, CLK % 0x100); | 1551 | viafb_write_reg(SR4C, VIASR, CLK % 0x100); |
@@ -1916,7 +1905,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1916 | load_fix_bit_crtc_reg(); | 1905 | load_fix_bit_crtc_reg(); |
1917 | viafb_lock_crt(); | 1906 | viafb_lock_crt(); |
1918 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | 1907 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); |
1919 | viafb_load_offset_reg(h_addr, bpp_byte, set_iga); | ||
1920 | viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); | 1908 | viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); |
1921 | 1909 | ||
1922 | /* load FIFO */ | 1910 | /* load FIFO */ |
@@ -1933,9 +1921,10 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1933 | 1921 | ||
1934 | } | 1922 | } |
1935 | 1923 | ||
1936 | void viafb_init_chip_info(void) | 1924 | void viafb_init_chip_info(struct pci_dev *pdev, |
1925 | const struct pci_device_id *pdi) | ||
1937 | { | 1926 | { |
1938 | init_gfx_chip_info(); | 1927 | init_gfx_chip_info(pdev, pdi); |
1939 | init_tmds_chip_info(); | 1928 | init_tmds_chip_info(); |
1940 | init_lvds_chip_info(); | 1929 | init_lvds_chip_info(); |
1941 | 1930 | ||
@@ -2008,24 +1997,12 @@ void viafb_update_device_setting(int hres, int vres, | |||
2008 | } | 1997 | } |
2009 | } | 1998 | } |
2010 | 1999 | ||
2011 | static void init_gfx_chip_info(void) | 2000 | static void init_gfx_chip_info(struct pci_dev *pdev, |
2001 | const struct pci_device_id *pdi) | ||
2012 | { | 2002 | { |
2013 | struct pci_dev *pdev = NULL; | ||
2014 | u32 i; | ||
2015 | u8 tmp; | 2003 | u8 tmp; |
2016 | 2004 | ||
2017 | /* Indentify GFX Chip Name */ | 2005 | viaparinfo->chip_info->gfx_chip_name = pdi->driver_data; |
2018 | for (i = 0; pciidlist[i].vendor != 0; i++) { | ||
2019 | pdev = pci_get_device(pciidlist[i].vendor, | ||
2020 | pciidlist[i].device, 0); | ||
2021 | if (pdev) | ||
2022 | break; | ||
2023 | } | ||
2024 | |||
2025 | if (!pciidlist[i].vendor) | ||
2026 | return ; | ||
2027 | |||
2028 | viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index; | ||
2029 | 2006 | ||
2030 | /* Check revision of CLE266 Chip */ | 2007 | /* Check revision of CLE266 Chip */ |
2031 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | 2008 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { |
@@ -2056,8 +2033,6 @@ static void init_gfx_chip_info(void) | |||
2056 | CX700_REVISION_700; | 2033 | CX700_REVISION_700; |
2057 | } | 2034 | } |
2058 | } | 2035 | } |
2059 | |||
2060 | pci_dev_put(pdev); | ||
2061 | } | 2036 | } |
2062 | 2037 | ||
2063 | static void init_tmds_chip_info(void) | 2038 | static void init_tmds_chip_info(void) |
@@ -2271,11 +2246,12 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2271 | break; | 2246 | break; |
2272 | 2247 | ||
2273 | case UNICHROME_CX700: | 2248 | case UNICHROME_CX700: |
2274 | viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs); | ||
2275 | |||
2276 | case UNICHROME_VX800: | 2249 | case UNICHROME_VX800: |
2277 | viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs); | 2250 | viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs); |
2251 | break; | ||
2278 | 2252 | ||
2253 | case UNICHROME_VX855: | ||
2254 | viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs); | ||
2279 | break; | 2255 | break; |
2280 | } | 2256 | } |
2281 | 2257 | ||
@@ -2291,7 +2267,8 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2291 | outb(VPIT.SR[i - 1], VIASR + 1); | 2267 | outb(VPIT.SR[i - 1], VIASR + 1); |
2292 | } | 2268 | } |
2293 | 2269 | ||
2294 | viafb_set_start_addr(); | 2270 | viafb_set_primary_address(0); |
2271 | viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); | ||
2295 | viafb_set_iga_path(); | 2272 | viafb_set_iga_path(); |
2296 | 2273 | ||
2297 | /* Write CRTC */ | 2274 | /* Write CRTC */ |
@@ -2371,6 +2348,9 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2371 | } | 2348 | } |
2372 | } | 2349 | } |
2373 | 2350 | ||
2351 | viafb_set_primary_pitch(viafbinfo->fix.line_length); | ||
2352 | viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length | ||
2353 | : viafbinfo->fix.line_length); | ||
2374 | /* Update Refresh Rate Setting */ | 2354 | /* Update Refresh Rate Setting */ |
2375 | 2355 | ||
2376 | /* Clear On Screen */ | 2356 | /* Clear On Screen */ |
@@ -2407,14 +2387,14 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2407 | viafb_dvi_set_mode(viafb_get_mode_index | 2387 | viafb_dvi_set_mode(viafb_get_mode_index |
2408 | (viaparinfo->tmds_setting_info->h_active, | 2388 | (viaparinfo->tmds_setting_info->h_active, |
2409 | viaparinfo->tmds_setting_info-> | 2389 | viaparinfo->tmds_setting_info-> |
2410 | v_active, 1), | 2390 | v_active), |
2411 | video_bpp1, viaparinfo-> | 2391 | video_bpp1, viaparinfo-> |
2412 | tmds_setting_info->iga_path); | 2392 | tmds_setting_info->iga_path); |
2413 | } else { | 2393 | } else { |
2414 | viafb_dvi_set_mode(viafb_get_mode_index | 2394 | viafb_dvi_set_mode(viafb_get_mode_index |
2415 | (viaparinfo->tmds_setting_info->h_active, | 2395 | (viaparinfo->tmds_setting_info->h_active, |
2416 | viaparinfo-> | 2396 | viaparinfo-> |
2417 | tmds_setting_info->v_active, 0), | 2397 | tmds_setting_info->v_active), |
2418 | video_bpp, viaparinfo-> | 2398 | video_bpp, viaparinfo-> |
2419 | tmds_setting_info->iga_path); | 2399 | tmds_setting_info->iga_path); |
2420 | } | 2400 | } |
@@ -2545,38 +2525,6 @@ void viafb_crt_enable(void) | |||
2545 | viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4); | 2525 | viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4); |
2546 | } | 2526 | } |
2547 | 2527 | ||
2548 | void viafb_get_mmio_info(unsigned long *mmio_base, | ||
2549 | unsigned long *mmio_len) | ||
2550 | { | ||
2551 | struct pci_dev *pdev = NULL; | ||
2552 | u32 vendor, device; | ||
2553 | u32 i; | ||
2554 | |||
2555 | for (i = 0; pciidlist[i].vendor != 0; i++) | ||
2556 | if (viaparinfo->chip_info->gfx_chip_name == | ||
2557 | pciidlist[i].chip_index) | ||
2558 | break; | ||
2559 | |||
2560 | if (!pciidlist[i].vendor) | ||
2561 | return ; | ||
2562 | |||
2563 | vendor = pciidlist[i].vendor; | ||
2564 | device = pciidlist[i].device; | ||
2565 | |||
2566 | pdev = pci_get_device(vendor, device, NULL); | ||
2567 | |||
2568 | if (!pdev) { | ||
2569 | *mmio_base = 0; | ||
2570 | *mmio_len = 0; | ||
2571 | return ; | ||
2572 | } | ||
2573 | |||
2574 | *mmio_base = pci_resource_start(pdev, 1); | ||
2575 | *mmio_len = pci_resource_len(pdev, 1); | ||
2576 | |||
2577 | pci_dev_put(pdev); | ||
2578 | } | ||
2579 | |||
2580 | static void enable_second_display_channel(void) | 2528 | static void enable_second_display_channel(void) |
2581 | { | 2529 | { |
2582 | /* to enable second display channel. */ | 2530 | /* to enable second display channel. */ |
@@ -2593,44 +2541,7 @@ static void disable_second_display_channel(void) | |||
2593 | viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); | 2541 | viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); |
2594 | } | 2542 | } |
2595 | 2543 | ||
2596 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len) | 2544 | int viafb_get_fb_size_from_pci(void) |
2597 | { | ||
2598 | struct pci_dev *pdev = NULL; | ||
2599 | u32 vendor, device; | ||
2600 | u32 i; | ||
2601 | |||
2602 | for (i = 0; pciidlist[i].vendor != 0; i++) | ||
2603 | if (viaparinfo->chip_info->gfx_chip_name == | ||
2604 | pciidlist[i].chip_index) | ||
2605 | break; | ||
2606 | |||
2607 | if (!pciidlist[i].vendor) | ||
2608 | return ; | ||
2609 | |||
2610 | vendor = pciidlist[i].vendor; | ||
2611 | device = pciidlist[i].device; | ||
2612 | |||
2613 | pdev = pci_get_device(vendor, device, NULL); | ||
2614 | |||
2615 | if (!pdev) { | ||
2616 | *fb_base = viafb_read_reg(VIASR, SR30) << 24; | ||
2617 | *fb_len = viafb_get_memsize(); | ||
2618 | DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n"); | ||
2619 | DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base); | ||
2620 | DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len); | ||
2621 | return ; | ||
2622 | } | ||
2623 | |||
2624 | *fb_base = (unsigned int)pci_resource_start(pdev, 0); | ||
2625 | *fb_len = get_fb_size_from_pci(); | ||
2626 | DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n"); | ||
2627 | DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base); | ||
2628 | DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len); | ||
2629 | |||
2630 | pci_dev_put(pdev); | ||
2631 | } | ||
2632 | |||
2633 | static int get_fb_size_from_pci(void) | ||
2634 | { | 2545 | { |
2635 | unsigned long configid, deviceid, FBSize = 0; | 2546 | unsigned long configid, deviceid, FBSize = 0; |
2636 | int VideoMemSize; | 2547 | int VideoMemSize; |
@@ -2656,6 +2567,7 @@ static int get_fb_size_from_pci(void) | |||
2656 | case P4M890_FUNCTION3: | 2567 | case P4M890_FUNCTION3: |
2657 | case P4M900_FUNCTION3: | 2568 | case P4M900_FUNCTION3: |
2658 | case VX800_FUNCTION3: | 2569 | case VX800_FUNCTION3: |
2570 | case VX855_FUNCTION3: | ||
2659 | /*case CN750_FUNCTION3: */ | 2571 | /*case CN750_FUNCTION3: */ |
2660 | outl(configid + 0xA0, (unsigned long)0xCF8); | 2572 | outl(configid + 0xA0, (unsigned long)0xCF8); |
2661 | FBSize = inl((unsigned long)0xCFC); | 2573 | FBSize = inl((unsigned long)0xCFC); |
@@ -2719,6 +2631,10 @@ static int get_fb_size_from_pci(void) | |||
2719 | VideoMemSize = (256 << 20); /*256M */ | 2631 | VideoMemSize = (256 << 20); /*256M */ |
2720 | break; | 2632 | break; |
2721 | 2633 | ||
2634 | case 0x00007000: /* Only on VX855/875 */ | ||
2635 | VideoMemSize = (512 << 20); /*512M */ | ||
2636 | break; | ||
2637 | |||
2722 | default: | 2638 | default: |
2723 | VideoMemSize = (32 << 20); /*32M */ | 2639 | VideoMemSize = (32 << 20); /*32M */ |
2724 | break; | 2640 | break; |
@@ -2788,24 +2704,6 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | |||
2788 | } | 2704 | } |
2789 | } | 2705 | } |
2790 | 2706 | ||
2791 | void viafb_memory_pitch_patch(struct fb_info *info) | ||
2792 | { | ||
2793 | if (info->var.xres != info->var.xres_virtual) { | ||
2794 | viafb_load_offset_reg(info->var.xres_virtual, | ||
2795 | info->var.bits_per_pixel >> 3, IGA1); | ||
2796 | |||
2797 | if (viafb_SAMM_ON) { | ||
2798 | viafb_load_offset_reg(viafb_second_virtual_xres, | ||
2799 | viafb_bpp1 >> 3, | ||
2800 | IGA2); | ||
2801 | } else { | ||
2802 | viafb_load_offset_reg(info->var.xres_virtual, | ||
2803 | info->var.bits_per_pixel >> 3, IGA2); | ||
2804 | } | ||
2805 | |||
2806 | } | ||
2807 | } | ||
2808 | |||
2809 | /*According var's xres, yres fill var's other timing information*/ | 2707 | /*According var's xres, yres fill var's other timing information*/ |
2810 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | 2708 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, |
2811 | int mode_index) | 2709 | int mode_index) |
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 6ff38fa8569a..b874d952b446 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h | |||
@@ -147,14 +147,8 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */ | |||
147 | /* location: {CR5F,0,4} */ | 147 | /* location: {CR5F,0,4} */ |
148 | #define IGA2_VER_SYNC_END_REG_NUM 1 | 148 | #define IGA2_VER_SYNC_END_REG_NUM 1 |
149 | 149 | ||
150 | /* Define Offset and Fetch Count Register*/ | 150 | /* Define Fetch Count Register*/ |
151 | 151 | ||
152 | /* location: {CR13,0,7},{CR35,5,7} */ | ||
153 | #define IGA1_OFFSET_REG_NUM 2 | ||
154 | /* 8 bytes alignment. */ | ||
155 | #define IGA1_OFFSER_ALIGN_BYTE 8 | ||
156 | /* x: H resolution, y: color depth */ | ||
157 | #define IGA1_OFFSET_FORMULA(x, y) ((x*y)/IGA1_OFFSER_ALIGN_BYTE) | ||
158 | /* location: {SR1C,0,7},{SR1D,0,1} */ | 152 | /* location: {SR1C,0,7},{SR1D,0,1} */ |
159 | #define IGA1_FETCH_COUNT_REG_NUM 2 | 153 | #define IGA1_FETCH_COUNT_REG_NUM 2 |
160 | /* 16 bytes alignment. */ | 154 | /* 16 bytes alignment. */ |
@@ -164,11 +158,6 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */ | |||
164 | #define IGA1_FETCH_COUNT_FORMULA(x, y) \ | 158 | #define IGA1_FETCH_COUNT_FORMULA(x, y) \ |
165 | (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE) | 159 | (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE) |
166 | 160 | ||
167 | /* location: {CR66,0,7},{CR67,0,1} */ | ||
168 | #define IGA2_OFFSET_REG_NUM 2 | ||
169 | #define IGA2_OFFSET_ALIGN_BYTE 8 | ||
170 | /* x: H resolution, y: color depth */ | ||
171 | #define IGA2_OFFSET_FORMULA(x, y) ((x*y)/IGA2_OFFSET_ALIGN_BYTE) | ||
172 | /* location: {CR65,0,7},{CR67,2,3} */ | 161 | /* location: {CR65,0,7},{CR67,2,3} */ |
173 | #define IGA2_FETCH_COUNT_REG_NUM 2 | 162 | #define IGA2_FETCH_COUNT_REG_NUM 2 |
174 | #define IGA2_FETCH_COUNT_ALIGN_BYTE 16 | 163 | #define IGA2_FETCH_COUNT_ALIGN_BYTE 16 |
@@ -335,6 +324,17 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */ | |||
335 | /* location: {CR94,0,6} */ | 324 | /* location: {CR94,0,6} */ |
336 | #define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 | 325 | #define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 |
337 | 326 | ||
327 | /* For VT3409 */ | ||
328 | #define VX855_IGA1_FIFO_MAX_DEPTH 400 | ||
329 | #define VX855_IGA1_FIFO_THRESHOLD 320 | ||
330 | #define VX855_IGA1_FIFO_HIGH_THRESHOLD 320 | ||
331 | #define VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 160 | ||
332 | |||
333 | #define VX855_IGA2_FIFO_MAX_DEPTH 200 | ||
334 | #define VX855_IGA2_FIFO_THRESHOLD 160 | ||
335 | #define VX855_IGA2_FIFO_HIGH_THRESHOLD 160 | ||
336 | #define VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 320 | ||
337 | |||
338 | #define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1 | 338 | #define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1 |
339 | #define IGA1_FIFO_THRESHOLD_REG_NUM 2 | 339 | #define IGA1_FIFO_THRESHOLD_REG_NUM 2 |
340 | #define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 | 340 | #define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 |
@@ -617,23 +617,6 @@ struct iga2_ver_sync_end { | |||
617 | struct io_register reg[IGA2_VER_SYNC_END_REG_NUM]; | 617 | struct io_register reg[IGA2_VER_SYNC_END_REG_NUM]; |
618 | }; | 618 | }; |
619 | 619 | ||
620 | /* IGA1 Offset Register */ | ||
621 | struct iga1_offset { | ||
622 | int reg_num; | ||
623 | struct io_register reg[IGA1_OFFSET_REG_NUM]; | ||
624 | }; | ||
625 | |||
626 | /* IGA2 Offset Register */ | ||
627 | struct iga2_offset { | ||
628 | int reg_num; | ||
629 | struct io_register reg[IGA2_OFFSET_REG_NUM]; | ||
630 | }; | ||
631 | |||
632 | struct offset { | ||
633 | struct iga1_offset iga1_offset_reg; | ||
634 | struct iga2_offset iga2_offset_reg; | ||
635 | }; | ||
636 | |||
637 | /* IGA1 Fetch Count Register */ | 620 | /* IGA1 Fetch Count Register */ |
638 | struct iga1_fetch_count { | 621 | struct iga1_fetch_count { |
639 | int reg_num; | 622 | int reg_num; |
@@ -716,6 +699,7 @@ struct pll_map { | |||
716 | u32 cle266_pll; | 699 | u32 cle266_pll; |
717 | u32 k800_pll; | 700 | u32 k800_pll; |
718 | u32 cx700_pll; | 701 | u32 cx700_pll; |
702 | u32 vx855_pll; | ||
719 | }; | 703 | }; |
720 | 704 | ||
721 | struct rgbLUT { | 705 | struct rgbLUT { |
@@ -860,6 +844,8 @@ struct iga2_crtc_timing { | |||
860 | #define P4M900_FUNCTION3 0x3364 | 844 | #define P4M900_FUNCTION3 0x3364 |
861 | /* VT3353 chipset*/ | 845 | /* VT3353 chipset*/ |
862 | #define VX800_FUNCTION3 0x3353 | 846 | #define VX800_FUNCTION3 0x3353 |
847 | /* VT3409 chipset*/ | ||
848 | #define VX855_FUNCTION3 0x3409 | ||
863 | 849 | ||
864 | #define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) | 850 | #define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) |
865 | 851 | ||
@@ -883,7 +869,6 @@ extern int viafb_dual_fb; | |||
883 | extern int viafb_LCD2_ON; | 869 | extern int viafb_LCD2_ON; |
884 | extern int viafb_LCD_ON; | 870 | extern int viafb_LCD_ON; |
885 | extern int viafb_DVI_ON; | 871 | extern int viafb_DVI_ON; |
886 | extern int viafb_accel; | ||
887 | extern int viafb_hotplug; | 872 | extern int viafb_hotplug; |
888 | 873 | ||
889 | void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask); | 874 | void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask); |
@@ -904,7 +889,6 @@ void viafb_write_reg(u8 index, u16 io_port, u8 data); | |||
904 | u8 viafb_read_reg(int io_port, u8 index); | 889 | u8 viafb_read_reg(int io_port, u8 index); |
905 | void viafb_lock_crt(void); | 890 | void viafb_lock_crt(void); |
906 | void viafb_unlock_crt(void); | 891 | void viafb_unlock_crt(void); |
907 | void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga); | ||
908 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); | 892 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); |
909 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum); | 893 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum); |
910 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index); | 894 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index); |
@@ -917,17 +901,20 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | |||
917 | int viafb_setmode(int vmode_index, int hor_res, int ver_res, | 901 | int viafb_setmode(int vmode_index, int hor_res, int ver_res, |
918 | int video_bpp, int vmode_index1, int hor_res1, | 902 | int video_bpp, int vmode_index1, int hor_res1, |
919 | int ver_res1, int video_bpp1); | 903 | int ver_res1, int video_bpp1); |
920 | void viafb_init_chip_info(void); | 904 | void viafb_init_chip_info(struct pci_dev *pdev, |
905 | const struct pci_device_id *pdi); | ||
921 | void viafb_init_dac(int set_iga); | 906 | void viafb_init_dac(int set_iga); |
922 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh); | 907 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh); |
923 | int viafb_get_refresh(int hres, int vres, u32 float_refresh); | 908 | int viafb_get_refresh(int hres, int vres, u32 float_refresh); |
924 | void viafb_update_device_setting(int hres, int vres, int bpp, | 909 | void viafb_update_device_setting(int hres, int vres, int bpp, |
925 | int vmode_refresh, int flag); | 910 | int vmode_refresh, int flag); |
926 | void viafb_get_mmio_info(unsigned long *mmio_base, | ||
927 | unsigned long *mmio_len); | ||
928 | 911 | ||
912 | int viafb_get_fb_size_from_pci(void); | ||
929 | void viafb_set_iga_path(void); | 913 | void viafb_set_iga_path(void); |
930 | void viafb_set_start_addr(void); | 914 | void viafb_set_primary_address(u32 addr); |
915 | void viafb_set_secondary_address(u32 addr); | ||
916 | void viafb_set_primary_pitch(u32 pitch); | ||
917 | void viafb_set_secondary_pitch(u32 pitch); | ||
931 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); | 918 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); |
932 | 919 | ||
933 | #endif /* __HW_H__ */ | 920 | #endif /* __HW_H__ */ |
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h index 842fe30b9868..de899807eade 100644 --- a/drivers/video/via/ioctl.h +++ b/drivers/video/via/ioctl.h | |||
@@ -50,8 +50,6 @@ | |||
50 | #define VIAFB_GET_GAMMA_LUT 0x56494124 | 50 | #define VIAFB_GET_GAMMA_LUT 0x56494124 |
51 | #define VIAFB_SET_GAMMA_LUT 0x56494125 | 51 | #define VIAFB_SET_GAMMA_LUT 0x56494125 |
52 | #define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126 | 52 | #define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126 |
53 | #define VIAFB_SET_VIDEO_DEVICE 0x56494127 | ||
54 | #define VIAFB_GET_VIDEO_DEVICE 0x56494128 | ||
55 | #define VIAFB_SET_SECOND_MODE 0x56494129 | 53 | #define VIAFB_SET_SECOND_MODE 0x56494129 |
56 | #define VIAFB_SYNC_SURFACE 0x56494130 | 54 | #define VIAFB_SYNC_SURFACE 0x56494130 |
57 | #define VIAFB_GET_DRIVER_CAPS 0x56494131 | 55 | #define VIAFB_GET_DRIVER_CAPS 0x56494131 |
@@ -179,9 +177,7 @@ struct viafb_ioctl_setting { | |||
179 | unsigned short second_dev_bpp; | 177 | unsigned short second_dev_bpp; |
180 | /* Indicate which device are primary display device. */ | 178 | /* Indicate which device are primary display device. */ |
181 | unsigned int primary_device; | 179 | unsigned int primary_device; |
182 | /* Indicate which device will show video. only valid in duoview mode */ | 180 | unsigned int struct_reserved[35]; |
183 | unsigned int video_device_status; | ||
184 | unsigned int struct_reserved[34]; | ||
185 | struct viafb_ioctl_lcd_attribute lcd_attributes; | 181 | struct viafb_ioctl_lcd_attribute lcd_attributes; |
186 | }; | 182 | }; |
187 | 183 | ||
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 6c7290a6a447..e3e597f937a5 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c | |||
@@ -207,13 +207,13 @@ static bool lvds_identify_integratedlvds(void) | |||
207 | 207 | ||
208 | int viafb_lvds_trasmitter_identify(void) | 208 | int viafb_lvds_trasmitter_identify(void) |
209 | { | 209 | { |
210 | viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX; | 210 | viaparinfo->shared->i2c_stuff.i2c_port = I2CPORTINDEX; |
211 | if (viafb_lvds_identify_vt1636()) { | 211 | if (viafb_lvds_identify_vt1636()) { |
212 | viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; | 212 | viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; |
213 | DEBUG_MSG(KERN_INFO | 213 | DEBUG_MSG(KERN_INFO |
214 | "Found VIA VT1636 LVDS on port i2c 0x31 \n"); | 214 | "Found VIA VT1636 LVDS on port i2c 0x31 \n"); |
215 | } else { | 215 | } else { |
216 | viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; | 216 | viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; |
217 | if (viafb_lvds_identify_vt1636()) { | 217 | if (viafb_lvds_identify_vt1636()) { |
218 | viaparinfo->chip_info->lvds_chip_info.i2c_port = | 218 | viaparinfo->chip_info->lvds_chip_info.i2c_port = |
219 | GPIOPORTINDEX; | 219 | GPIOPORTINDEX; |
@@ -470,7 +470,7 @@ static int lvds_register_read(int index) | |||
470 | { | 470 | { |
471 | u8 data; | 471 | u8 data; |
472 | 472 | ||
473 | viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; | 473 | viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; |
474 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> | 474 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> |
475 | lvds_chip_info.lvds_chip_slave_addr, | 475 | lvds_chip_info.lvds_chip_slave_addr, |
476 | (u8) index, &data); | 476 | (u8) index, &data); |
@@ -580,10 +580,7 @@ static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, | |||
580 | int reg_num = 0; | 580 | int reg_num = 0; |
581 | struct io_reg *lcd_patch_reg = NULL; | 581 | struct io_reg *lcd_patch_reg = NULL; |
582 | 582 | ||
583 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) | 583 | vmode_index = viafb_get_mode_index(set_hres, set_vres); |
584 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); | ||
585 | else | ||
586 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); | ||
587 | switch (panel_id) { | 584 | switch (panel_id) { |
588 | /* LCD 800x600 */ | 585 | /* LCD 800x600 */ |
589 | case LCD_PANEL_ID1_800X600: | 586 | case LCD_PANEL_ID1_800X600: |
@@ -761,10 +758,7 @@ static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, | |||
761 | int reg_num = 0; | 758 | int reg_num = 0; |
762 | struct io_reg *lcd_patch_reg = NULL; | 759 | struct io_reg *lcd_patch_reg = NULL; |
763 | 760 | ||
764 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) | 761 | vmode_index = viafb_get_mode_index(set_hres, set_vres); |
765 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); | ||
766 | else | ||
767 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); | ||
768 | 762 | ||
769 | switch (panel_id) { | 763 | switch (panel_id) { |
770 | case LCD_PANEL_ID5_1400X1050: | 764 | case LCD_PANEL_ID5_1400X1050: |
@@ -832,10 +826,7 @@ static void load_lcd_patch_regs(int set_hres, int set_vres, | |||
832 | { | 826 | { |
833 | int vmode_index; | 827 | int vmode_index; |
834 | 828 | ||
835 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) | 829 | vmode_index = viafb_get_mode_index(set_hres, set_vres); |
836 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); | ||
837 | else | ||
838 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); | ||
839 | 830 | ||
840 | viafb_unlock_crt(); | 831 | viafb_unlock_crt(); |
841 | 832 | ||
@@ -961,13 +952,10 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
961 | int video_index = plvds_setting_info->lcd_panel_size; | 952 | int video_index = plvds_setting_info->lcd_panel_size; |
962 | int set_iga = plvds_setting_info->iga_path; | 953 | int set_iga = plvds_setting_info->iga_path; |
963 | int mode_bpp = plvds_setting_info->bpp; | 954 | int mode_bpp = plvds_setting_info->bpp; |
964 | int viafb_load_reg_num = 0; | ||
965 | int reg_value = 0; | ||
966 | int set_hres, set_vres; | 955 | int set_hres, set_vres; |
967 | int panel_hres, panel_vres; | 956 | int panel_hres, panel_vres; |
968 | u32 pll_D_N; | 957 | u32 pll_D_N; |
969 | int offset; | 958 | int offset; |
970 | struct io_register *reg = NULL; | ||
971 | struct display_timing mode_crt_reg, panel_crt_reg; | 959 | struct display_timing mode_crt_reg, panel_crt_reg; |
972 | struct crt_mode_table *panel_crt_table = NULL; | 960 | struct crt_mode_table *panel_crt_table = NULL; |
973 | struct VideoModeTable *vmode_tbl = NULL; | 961 | struct VideoModeTable *vmode_tbl = NULL; |
@@ -1047,16 +1035,11 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
1047 | } | 1035 | } |
1048 | 1036 | ||
1049 | /* Offset for simultaneous */ | 1037 | /* Offset for simultaneous */ |
1050 | reg_value = offset; | 1038 | viafb_set_secondary_pitch(offset << 3); |
1051 | viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num; | ||
1052 | reg = offset_reg.iga2_offset_reg.reg; | ||
1053 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1054 | DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); | 1039 | DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); |
1055 | viafb_load_fetch_count_reg(set_hres, 4, IGA2); | 1040 | viafb_load_fetch_count_reg(set_hres, 4, IGA2); |
1056 | /* Fetch count for simultaneous */ | 1041 | /* Fetch count for simultaneous */ |
1057 | } else { /* SAMM */ | 1042 | } else { /* SAMM */ |
1058 | /* Offset for IGA2 only */ | ||
1059 | viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga); | ||
1060 | /* Fetch count for IGA2 only */ | 1043 | /* Fetch count for IGA2 only */ |
1061 | viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); | 1044 | viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); |
1062 | 1045 | ||
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h index 2e1254da9c8c..7cd03e2a1275 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/via/share.h | |||
@@ -167,6 +167,10 @@ | |||
167 | #define SR4B 0x4B | 167 | #define SR4B 0x4B |
168 | #define SR4C 0x4C | 168 | #define SR4C 0x4C |
169 | #define SR52 0x52 | 169 | #define SR52 0x52 |
170 | #define SR57 0x57 | ||
171 | #define SR58 0x58 | ||
172 | #define SR59 0x59 | ||
173 | #define SR5D 0x5D | ||
170 | #define SR5E 0x5E | 174 | #define SR5E 0x5E |
171 | #define SR65 0x65 | 175 | #define SR65 0x65 |
172 | 176 | ||
@@ -966,6 +970,100 @@ | |||
966 | #define CX700_297_500M 0x00CE0403 | 970 | #define CX700_297_500M 0x00CE0403 |
967 | #define CX700_122_614M 0x00870802 | 971 | #define CX700_122_614M 0x00870802 |
968 | 972 | ||
973 | /* PLL for VX855 */ | ||
974 | #define VX855_22_000M 0x007B1005 | ||
975 | #define VX855_25_175M 0x008D1005 | ||
976 | #define VX855_26_719M 0x00961005 | ||
977 | #define VX855_26_880M 0x00961005 | ||
978 | #define VX855_27_000M 0x00971005 | ||
979 | #define VX855_29_581M 0x00A51005 | ||
980 | #define VX855_29_829M 0x00641003 | ||
981 | #define VX855_31_490M 0x00B01005 | ||
982 | #define VX855_31_500M 0x00B01005 | ||
983 | #define VX855_31_728M 0x008E1004 | ||
984 | #define VX855_32_668M 0x00921004 | ||
985 | #define VX855_36_000M 0x00A11004 | ||
986 | #define VX855_40_000M 0x00700C05 | ||
987 | #define VX855_41_291M 0x00730C05 | ||
988 | #define VX855_43_163M 0x00790C05 | ||
989 | #define VX855_45_250M 0x007F0C05 /* 45.46MHz */ | ||
990 | #define VX855_46_000M 0x00670C04 | ||
991 | #define VX855_46_996M 0x00690C04 | ||
992 | #define VX855_48_000M 0x00860C05 | ||
993 | #define VX855_48_875M 0x00890C05 | ||
994 | #define VX855_49_500M 0x00530C03 | ||
995 | #define VX855_52_406M 0x00580C03 | ||
996 | #define VX855_52_977M 0x00940C05 | ||
997 | #define VX855_56_250M 0x009D0C05 | ||
998 | #define VX855_60_466M 0x00A90C05 | ||
999 | #define VX855_61_500M 0x00AC0C05 | ||
1000 | #define VX855_65_000M 0x006D0C03 | ||
1001 | #define VX855_65_178M 0x00B60C05 | ||
1002 | #define VX855_66_750M 0x00700C03 /*67.116MHz */ | ||
1003 | #define VX855_67_295M 0x00BC0C05 | ||
1004 | #define VX855_68_179M 0x00BF0C05 | ||
1005 | #define VX855_68_369M 0x00BF0C05 | ||
1006 | #define VX855_69_924M 0x00C30C05 | ||
1007 | #define VX855_70_159M 0x00C30C05 | ||
1008 | #define VX855_72_000M 0x00A10C04 | ||
1009 | #define VX855_73_023M 0x00CC0C05 | ||
1010 | #define VX855_74_481M 0x00D10C05 | ||
1011 | #define VX855_78_750M 0x006E0805 | ||
1012 | #define VX855_79_466M 0x006F0805 | ||
1013 | #define VX855_80_136M 0x00700805 | ||
1014 | #define VX855_81_627M 0x00720805 | ||
1015 | #define VX855_83_375M 0x00750805 | ||
1016 | #define VX855_83_527M 0x00750805 | ||
1017 | #define VX855_83_950M 0x00750805 | ||
1018 | #define VX855_84_537M 0x00760805 | ||
1019 | #define VX855_84_750M 0x00760805 /* 84.537Mhz */ | ||
1020 | #define VX855_85_500M 0x00760805 /* 85.909080 MHz*/ | ||
1021 | #define VX855_85_860M 0x00760805 | ||
1022 | #define VX855_85_909M 0x00760805 | ||
1023 | #define VX855_88_750M 0x007C0805 | ||
1024 | #define VX855_89_489M 0x007D0805 | ||
1025 | #define VX855_94_500M 0x00840805 | ||
1026 | #define VX855_96_648M 0x00870805 | ||
1027 | #define VX855_97_750M 0x00890805 | ||
1028 | #define VX855_101_000M 0x008D0805 | ||
1029 | #define VX855_106_500M 0x00950805 | ||
1030 | #define VX855_108_000M 0x00970805 | ||
1031 | #define VX855_110_125M 0x00990805 | ||
1032 | #define VX855_112_000M 0x009D0805 | ||
1033 | #define VX855_113_309M 0x009F0805 | ||
1034 | #define VX855_115_000M 0x00A10805 | ||
1035 | #define VX855_118_840M 0x00A60805 | ||
1036 | #define VX855_119_000M 0x00A70805 | ||
1037 | #define VX855_121_750M 0x00AA0805 /* 121.704MHz */ | ||
1038 | #define VX855_122_614M 0x00AC0805 | ||
1039 | #define VX855_126_266M 0x00B10805 | ||
1040 | #define VX855_130_250M 0x00B60805 /* 130.250 */ | ||
1041 | #define VX855_135_000M 0x00BD0805 | ||
1042 | #define VX855_136_700M 0x00BF0805 | ||
1043 | #define VX855_137_750M 0x00C10805 | ||
1044 | #define VX855_138_400M 0x00C20805 | ||
1045 | #define VX855_144_300M 0x00CA0805 | ||
1046 | #define VX855_146_760M 0x00CE0805 | ||
1047 | #define VX855_148_500M 0x00D00805 | ||
1048 | #define VX855_153_920M 0x00540402 | ||
1049 | #define VX855_156_000M 0x006C0405 | ||
1050 | #define VX855_156_867M 0x006E0405 | ||
1051 | #define VX855_157_500M 0x006E0405 | ||
1052 | #define VX855_162_000M 0x00710405 | ||
1053 | #define VX855_172_798M 0x00790405 | ||
1054 | #define VX855_187_000M 0x00830405 | ||
1055 | #define VX855_193_295M 0x00870405 | ||
1056 | #define VX855_202_500M 0x008E0405 | ||
1057 | #define VX855_204_000M 0x008F0405 | ||
1058 | #define VX855_218_500M 0x00990405 | ||
1059 | #define VX855_229_500M 0x00A10405 | ||
1060 | #define VX855_234_000M 0x00A40405 | ||
1061 | #define VX855_267_250M 0x00BB0405 | ||
1062 | #define VX855_297_500M 0x00D00405 | ||
1063 | #define VX855_339_500M 0x00770005 | ||
1064 | #define VX855_340_772M 0x00770005 | ||
1065 | |||
1066 | |||
969 | /* Definition CRTC Timing Index */ | 1067 | /* Definition CRTC Timing Index */ |
970 | #define H_TOTAL_INDEX 0 | 1068 | #define H_TOTAL_INDEX 0 |
971 | #define H_ADDR_INDEX 1 | 1069 | #define H_ADDR_INDEX 1 |
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 0f3ed4eb236d..15543e968248 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c | |||
@@ -97,7 +97,7 @@ int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) | |||
97 | mm1[0] = index; | 97 | mm1[0] = index; |
98 | msgs[0].len = 1; msgs[1].len = 1; | 98 | msgs[0].len = 1; msgs[1].len = 1; |
99 | msgs[0].buf = mm1; msgs[1].buf = pdata; | 99 | msgs[0].buf = mm1; msgs[1].buf = pdata; |
100 | i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2); | 100 | i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); |
101 | 101 | ||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
@@ -111,7 +111,7 @@ int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) | |||
111 | msgs.addr = slave_addr / 2; | 111 | msgs.addr = slave_addr / 2; |
112 | msgs.len = 2; | 112 | msgs.len = 2; |
113 | msgs.buf = msg; | 113 | msgs.buf = msg; |
114 | return i2c_transfer(&viaparinfo->i2c_stuff.adapter, &msgs, 1); | 114 | return i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, &msgs, 1); |
115 | } | 115 | } |
116 | 116 | ||
117 | int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) | 117 | int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) |
@@ -125,53 +125,53 @@ int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) | |||
125 | mm1[0] = index; | 125 | mm1[0] = index; |
126 | msgs[0].len = 1; msgs[1].len = buff_len; | 126 | msgs[0].len = 1; msgs[1].len = buff_len; |
127 | msgs[0].buf = mm1; msgs[1].buf = buff; | 127 | msgs[0].buf = mm1; msgs[1].buf = buff; |
128 | i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2); | 128 | i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); |
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | 131 | ||
132 | int viafb_create_i2c_bus(void *viapar) | 132 | int viafb_create_i2c_bus(void *viapar) |
133 | { | 133 | { |
134 | int ret; | 134 | int ret; |
135 | struct viafb_par *par = (struct viafb_par *)viapar; | 135 | struct via_i2c_stuff *i2c_stuff = |
136 | 136 | &((struct viafb_par *)viapar)->shared->i2c_stuff; | |
137 | strcpy(par->i2c_stuff.adapter.name, "via_i2c"); | 137 | |
138 | par->i2c_stuff.i2c_port = 0x0; | 138 | strcpy(i2c_stuff->adapter.name, "via_i2c"); |
139 | par->i2c_stuff.adapter.owner = THIS_MODULE; | 139 | i2c_stuff->i2c_port = 0x0; |
140 | par->i2c_stuff.adapter.id = 0x01FFFF; | 140 | i2c_stuff->adapter.owner = THIS_MODULE; |
141 | par->i2c_stuff.adapter.class = 0; | 141 | i2c_stuff->adapter.id = 0x01FFFF; |
142 | par->i2c_stuff.adapter.algo_data = &par->i2c_stuff.algo; | 142 | i2c_stuff->adapter.class = 0; |
143 | par->i2c_stuff.adapter.dev.parent = NULL; | 143 | i2c_stuff->adapter.algo_data = &i2c_stuff->algo; |
144 | par->i2c_stuff.algo.setsda = via_i2c_setsda; | 144 | i2c_stuff->adapter.dev.parent = NULL; |
145 | par->i2c_stuff.algo.setscl = via_i2c_setscl; | 145 | i2c_stuff->algo.setsda = via_i2c_setsda; |
146 | par->i2c_stuff.algo.getsda = via_i2c_getsda; | 146 | i2c_stuff->algo.setscl = via_i2c_setscl; |
147 | par->i2c_stuff.algo.getscl = via_i2c_getscl; | 147 | i2c_stuff->algo.getsda = via_i2c_getsda; |
148 | par->i2c_stuff.algo.udelay = 40; | 148 | i2c_stuff->algo.getscl = via_i2c_getscl; |
149 | par->i2c_stuff.algo.timeout = 20; | 149 | i2c_stuff->algo.udelay = 40; |
150 | par->i2c_stuff.algo.data = &par->i2c_stuff; | 150 | i2c_stuff->algo.timeout = 20; |
151 | 151 | i2c_stuff->algo.data = i2c_stuff; | |
152 | i2c_set_adapdata(&par->i2c_stuff.adapter, &par->i2c_stuff); | 152 | |
153 | i2c_set_adapdata(&i2c_stuff->adapter, i2c_stuff); | ||
153 | 154 | ||
154 | /* Raise SCL and SDA */ | 155 | /* Raise SCL and SDA */ |
155 | par->i2c_stuff.i2c_port = I2CPORTINDEX; | 156 | i2c_stuff->i2c_port = I2CPORTINDEX; |
156 | via_i2c_setsda(&par->i2c_stuff, 1); | 157 | via_i2c_setsda(i2c_stuff, 1); |
157 | via_i2c_setscl(&par->i2c_stuff, 1); | 158 | via_i2c_setscl(i2c_stuff, 1); |
158 | 159 | ||
159 | par->i2c_stuff.i2c_port = GPIOPORTINDEX; | 160 | i2c_stuff->i2c_port = GPIOPORTINDEX; |
160 | via_i2c_setsda(&par->i2c_stuff, 1); | 161 | via_i2c_setsda(i2c_stuff, 1); |
161 | via_i2c_setscl(&par->i2c_stuff, 1); | 162 | via_i2c_setscl(i2c_stuff, 1); |
162 | udelay(20); | 163 | udelay(20); |
163 | 164 | ||
164 | ret = i2c_bit_add_bus(&par->i2c_stuff.adapter); | 165 | ret = i2c_bit_add_bus(&i2c_stuff->adapter); |
165 | if (ret == 0) | 166 | if (ret == 0) |
166 | DEBUG_MSG("I2C bus %s registered.\n", | 167 | DEBUG_MSG("I2C bus %s registered.\n", i2c_stuff->adapter.name); |
167 | par->i2c_stuff.adapter.name); | ||
168 | else | 168 | else |
169 | DEBUG_MSG("Failed to register I2C bus %s.\n", | 169 | DEBUG_MSG("Failed to register I2C bus %s.\n", |
170 | par->i2c_stuff.adapter.name); | 170 | i2c_stuff->adapter.name); |
171 | return ret; | 171 | return ret; |
172 | } | 172 | } |
173 | 173 | ||
174 | void viafb_delete_i2c_buss(void *par) | 174 | void viafb_delete_i2c_buss(void *par) |
175 | { | 175 | { |
176 | i2c_del_adapter(&((struct viafb_par *)par)->i2c_stuff.adapter); | 176 | i2c_del_adapter(&((struct viafb_par *)par)->shared->i2c_stuff.adapter); |
177 | } | 177 | } |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index a0fec298216e..56ec696e8afa 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -20,11 +20,12 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/seq_file.h> | ||
24 | #include <linux/stat.h> | ||
23 | #define _MASTER_FILE | 25 | #define _MASTER_FILE |
24 | 26 | ||
25 | #include "global.h" | 27 | #include "global.h" |
26 | 28 | ||
27 | static int MAX_CURS = 32; | ||
28 | static struct fb_var_screeninfo default_var; | 29 | static struct fb_var_screeninfo default_var; |
29 | static char *viafb_name = "Via"; | 30 | static char *viafb_name = "Via"; |
30 | static u32 pseudo_pal[17]; | 31 | static u32 pseudo_pal[17]; |
@@ -32,14 +33,12 @@ static u32 pseudo_pal[17]; | |||
32 | /* video mode */ | 33 | /* video mode */ |
33 | static char *viafb_mode = "640x480"; | 34 | static char *viafb_mode = "640x480"; |
34 | static char *viafb_mode1 = "640x480"; | 35 | static char *viafb_mode1 = "640x480"; |
35 | static int viafb_resMode = VIA_RES_640X480; | 36 | |
37 | static int viafb_accel = 1; | ||
36 | 38 | ||
37 | /* Added for specifying active devices.*/ | 39 | /* Added for specifying active devices.*/ |
38 | char *viafb_active_dev = ""; | 40 | char *viafb_active_dev = ""; |
39 | 41 | ||
40 | /* Added for specifying video on devices.*/ | ||
41 | char *viafb_video_dev = ""; | ||
42 | |||
43 | /*Added for specify lcd output port*/ | 42 | /*Added for specify lcd output port*/ |
44 | char *viafb_lcd_port = ""; | 43 | char *viafb_lcd_port = ""; |
45 | char *viafb_dvi_port = ""; | 44 | char *viafb_dvi_port = ""; |
@@ -51,71 +50,20 @@ static void apply_second_mode_setting(struct fb_var_screeninfo | |||
51 | *sec_var); | 50 | *sec_var); |
52 | static void retrieve_device_setting(struct viafb_ioctl_setting | 51 | static void retrieve_device_setting(struct viafb_ioctl_setting |
53 | *setting_info); | 52 | *setting_info); |
54 | static void viafb_set_video_device(u32 video_dev_info); | ||
55 | static void viafb_get_video_device(u32 *video_dev_info); | ||
56 | |||
57 | /* Mode information */ | ||
58 | static const struct viafb_modeinfo viafb_modentry[] = { | ||
59 | {480, 640, VIA_RES_480X640, "480x640"}, | ||
60 | {640, 480, VIA_RES_640X480, "640x480"}, | ||
61 | {800, 480, VIA_RES_800X480, "800x480"}, | ||
62 | {800, 600, VIA_RES_800X600, "800x600"}, | ||
63 | {1024, 768, VIA_RES_1024X768, "1024x768"}, | ||
64 | {1152, 864, VIA_RES_1152X864, "1152x864"}, | ||
65 | {1280, 1024, VIA_RES_1280X1024, "1280x1024"}, | ||
66 | {1600, 1200, VIA_RES_1600X1200, "1600x1200"}, | ||
67 | {1440, 1050, VIA_RES_1440X1050, "1440x1050"}, | ||
68 | {1280, 768, VIA_RES_1280X768, "1280x768"}, | ||
69 | {1280, 800, VIA_RES_1280X800, "1280x800"}, | ||
70 | {1280, 960, VIA_RES_1280X960, "1280x960"}, | ||
71 | {1920, 1440, VIA_RES_1920X1440, "1920x1440"}, | ||
72 | {848, 480, VIA_RES_848X480, "848x480"}, | ||
73 | {1400, 1050, VIA_RES_1400X1050, "1400x1050"}, | ||
74 | {720, 480, VIA_RES_720X480, "720x480"}, | ||
75 | {720, 576, VIA_RES_720X576, "720x576"}, | ||
76 | {1024, 512, VIA_RES_1024X512, "1024x512"}, | ||
77 | {1024, 576, VIA_RES_1024X576, "1024x576"}, | ||
78 | {1024, 600, VIA_RES_1024X600, "1024x600"}, | ||
79 | {1280, 720, VIA_RES_1280X720, "1280x720"}, | ||
80 | {1920, 1080, VIA_RES_1920X1080, "1920x1080"}, | ||
81 | {1366, 768, VIA_RES_1368X768, "1368x768"}, | ||
82 | {1680, 1050, VIA_RES_1680X1050, "1680x1050"}, | ||
83 | {960, 600, VIA_RES_960X600, "960x600"}, | ||
84 | {1000, 600, VIA_RES_1000X600, "1000x600"}, | ||
85 | {1024, 576, VIA_RES_1024X576, "1024x576"}, | ||
86 | {1024, 600, VIA_RES_1024X600, "1024x600"}, | ||
87 | {1088, 612, VIA_RES_1088X612, "1088x612"}, | ||
88 | {1152, 720, VIA_RES_1152X720, "1152x720"}, | ||
89 | {1200, 720, VIA_RES_1200X720, "1200x720"}, | ||
90 | {1280, 600, VIA_RES_1280X600, "1280x600"}, | ||
91 | {1360, 768, VIA_RES_1360X768, "1360x768"}, | ||
92 | {1440, 900, VIA_RES_1440X900, "1440x900"}, | ||
93 | {1600, 900, VIA_RES_1600X900, "1600x900"}, | ||
94 | {1600, 1024, VIA_RES_1600X1024, "1600x1024"}, | ||
95 | {1792, 1344, VIA_RES_1792X1344, "1792x1344"}, | ||
96 | {1856, 1392, VIA_RES_1856X1392, "1856x1392"}, | ||
97 | {1920, 1200, VIA_RES_1920X1200, "1920x1200"}, | ||
98 | {2048, 1536, VIA_RES_2048X1536, "2048x1536"}, | ||
99 | {0, 0, VIA_RES_INVALID, "640x480"} | ||
100 | }; | ||
101 | 53 | ||
102 | static struct fb_ops viafb_ops; | 54 | static struct fb_ops viafb_ops; |
103 | 55 | ||
104 | static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | ||
105 | { | ||
106 | struct viafb_par *ppar; | ||
107 | ppar = info->par; | ||
108 | |||
109 | DEBUG_MSG(KERN_INFO "viafb_update_fix!\n"); | ||
110 | 56 | ||
111 | fix->visual = | 57 | static void viafb_update_fix(struct fb_info *info) |
112 | ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | 58 | { |
113 | fix->line_length = ppar->linelength; | 59 | u32 bpp = info->var.bits_per_pixel; |
114 | 60 | ||
115 | return 0; | 61 | info->fix.visual = |
62 | bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
63 | info->fix.line_length = | ||
64 | ((info->var.xres_virtual + 7) & ~7) * bpp / 8; | ||
116 | } | 65 | } |
117 | 66 | ||
118 | |||
119 | static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, | 67 | static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, |
120 | struct viafb_par *viaparinfo) | 68 | struct viafb_par *viaparinfo) |
121 | { | 69 | { |
@@ -124,8 +72,6 @@ static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, | |||
124 | 72 | ||
125 | fix->smem_start = viaparinfo->fbmem; | 73 | fix->smem_start = viaparinfo->fbmem; |
126 | fix->smem_len = viaparinfo->fbmem_free; | 74 | fix->smem_len = viaparinfo->fbmem_free; |
127 | fix->mmio_start = viaparinfo->mmio_base; | ||
128 | fix->mmio_len = viaparinfo->mmio_len; | ||
129 | 75 | ||
130 | fix->type = FB_TYPE_PACKED_PIXELS; | 76 | fix->type = FB_TYPE_PACKED_PIXELS; |
131 | fix->type_aux = 0; | 77 | fix->type_aux = 0; |
@@ -148,28 +94,12 @@ static int viafb_release(struct fb_info *info, int user) | |||
148 | return 0; | 94 | return 0; |
149 | } | 95 | } |
150 | 96 | ||
151 | static void viafb_update_viafb_par(struct fb_info *info) | ||
152 | { | ||
153 | struct viafb_par *ppar; | ||
154 | |||
155 | ppar = info->par; | ||
156 | ppar->bpp = info->var.bits_per_pixel; | ||
157 | ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8; | ||
158 | ppar->hres = info->var.xres; | ||
159 | ppar->vres = info->var.yres; | ||
160 | ppar->xoffset = info->var.xoffset; | ||
161 | ppar->yoffset = info->var.yoffset; | ||
162 | } | ||
163 | |||
164 | static int viafb_check_var(struct fb_var_screeninfo *var, | 97 | static int viafb_check_var(struct fb_var_screeninfo *var, |
165 | struct fb_info *info) | 98 | struct fb_info *info) |
166 | { | 99 | { |
167 | int vmode_index, htotal, vtotal; | 100 | int vmode_index, htotal, vtotal; |
168 | struct viafb_par *ppar; | 101 | struct viafb_par *ppar = info->par; |
169 | u32 long_refresh; | 102 | u32 long_refresh; |
170 | struct viafb_par *p_viafb_par; | ||
171 | ppar = info->par; | ||
172 | |||
173 | 103 | ||
174 | DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); | 104 | DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); |
175 | /* Sanity check */ | 105 | /* Sanity check */ |
@@ -177,7 +107,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
177 | if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) | 107 | if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) |
178 | return -EINVAL; | 108 | return -EINVAL; |
179 | 109 | ||
180 | vmode_index = viafb_get_mode_index(var->xres, var->yres, 0); | 110 | vmode_index = viafb_get_mode_index(var->xres, var->yres); |
181 | if (vmode_index == VIA_RES_INVALID) { | 111 | if (vmode_index == VIA_RES_INVALID) { |
182 | DEBUG_MSG(KERN_INFO | 112 | DEBUG_MSG(KERN_INFO |
183 | "viafb: Mode %dx%dx%d not supported!!\n", | 113 | "viafb: Mode %dx%dx%d not supported!!\n", |
@@ -213,34 +143,32 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
213 | 143 | ||
214 | /* Adjust var according to our driver's own table */ | 144 | /* Adjust var according to our driver's own table */ |
215 | viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); | 145 | viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); |
216 | 146 | if (info->var.accel_flags & FB_ACCELF_TEXT && | |
217 | /* This is indeed a patch for VT3353 */ | 147 | !ppar->shared->engine_mmio) |
218 | if (!info->par) | 148 | info->var.accel_flags = 0; |
219 | return -1; | ||
220 | p_viafb_par = (struct viafb_par *)info->par; | ||
221 | if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800) | ||
222 | var->accel_flags = 0; | ||
223 | 149 | ||
224 | return 0; | 150 | return 0; |
225 | } | 151 | } |
226 | 152 | ||
227 | static int viafb_set_par(struct fb_info *info) | 153 | static int viafb_set_par(struct fb_info *info) |
228 | { | 154 | { |
155 | struct viafb_par *viapar = info->par; | ||
229 | int vmode_index; | 156 | int vmode_index; |
230 | int vmode_index1 = 0; | 157 | int vmode_index1 = 0; |
231 | DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); | 158 | DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); |
232 | 159 | ||
160 | viapar->depth = fb_get_color_depth(&info->var, &info->fix); | ||
233 | viafb_update_device_setting(info->var.xres, info->var.yres, | 161 | viafb_update_device_setting(info->var.xres, info->var.yres, |
234 | info->var.bits_per_pixel, viafb_refresh, 0); | 162 | info->var.bits_per_pixel, viafb_refresh, 0); |
235 | 163 | ||
236 | vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres, 0); | 164 | vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres); |
237 | 165 | ||
238 | if (viafb_SAMM_ON == 1) { | 166 | if (viafb_SAMM_ON == 1) { |
239 | DEBUG_MSG(KERN_INFO | 167 | DEBUG_MSG(KERN_INFO |
240 | "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", | 168 | "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", |
241 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | 169 | viafb_second_xres, viafb_second_yres, viafb_bpp1); |
242 | vmode_index1 = viafb_get_mode_index(viafb_second_xres, | 170 | vmode_index1 = viafb_get_mode_index(viafb_second_xres, |
243 | viafb_second_yres, 1); | 171 | viafb_second_yres); |
244 | DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n", | 172 | DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n", |
245 | vmode_index1); | 173 | vmode_index1); |
246 | 174 | ||
@@ -253,21 +181,12 @@ static int viafb_set_par(struct fb_info *info) | |||
253 | info->var.bits_per_pixel, vmode_index1, | 181 | info->var.bits_per_pixel, vmode_index1, |
254 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | 182 | viafb_second_xres, viafb_second_yres, viafb_bpp1); |
255 | 183 | ||
256 | /*We should set memory offset according virtual_x */ | 184 | viafb_update_fix(info); |
257 | /*Fix me:put this function into viafb_setmode */ | ||
258 | viafb_memory_pitch_patch(info); | ||
259 | |||
260 | /* Update ***fb_par information */ | ||
261 | viafb_update_viafb_par(info); | ||
262 | |||
263 | /* Update other fixed information */ | ||
264 | viafb_update_fix(&info->fix, info); | ||
265 | viafb_bpp = info->var.bits_per_pixel; | 185 | viafb_bpp = info->var.bits_per_pixel; |
266 | /* Update viafb_accel, it is necessary to our 2D accelerate */ | 186 | if (info->var.accel_flags & FB_ACCELF_TEXT) |
267 | viafb_accel = info->var.accel_flags; | 187 | info->flags &= ~FBINFO_HWACCEL_DISABLED; |
268 | 188 | else | |
269 | if (viafb_accel) | 189 | info->flags |= FBINFO_HWACCEL_DISABLED; |
270 | viafb_set_2d_color_depth(info->var.bits_per_pixel); | ||
271 | } | 190 | } |
272 | 191 | ||
273 | return 0; | 192 | return 0; |
@@ -504,12 +423,7 @@ static int viafb_pan_display(struct fb_var_screeninfo *var, | |||
504 | var->bits_per_pixel / 16; | 423 | var->bits_per_pixel / 16; |
505 | 424 | ||
506 | DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset); | 425 | DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset); |
507 | 426 | viafb_set_primary_address(offset); | |
508 | viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3); | ||
509 | viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff); | ||
510 | viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff); | ||
511 | viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff); | ||
512 | |||
513 | return 0; | 427 | return 0; |
514 | } | 428 | } |
515 | 429 | ||
@@ -561,7 +475,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
561 | 475 | ||
562 | u32 __user *argp = (u32 __user *) arg; | 476 | u32 __user *argp = (u32 __user *) arg; |
563 | u32 gpu32; | 477 | u32 gpu32; |
564 | u32 video_dev_info = 0; | ||
565 | 478 | ||
566 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); | 479 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); |
567 | memset(&u, 0, sizeof(u)); | 480 | memset(&u, 0, sizeof(u)); |
@@ -793,15 +706,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
793 | if (put_user(state_info, argp)) | 706 | if (put_user(state_info, argp)) |
794 | return -EFAULT; | 707 | return -EFAULT; |
795 | break; | 708 | break; |
796 | case VIAFB_SET_VIDEO_DEVICE: | ||
797 | get_user(video_dev_info, argp); | ||
798 | viafb_set_video_device(video_dev_info); | ||
799 | break; | ||
800 | case VIAFB_GET_VIDEO_DEVICE: | ||
801 | viafb_get_video_device(&video_dev_info); | ||
802 | if (put_user(video_dev_info, argp)) | ||
803 | return -EFAULT; | ||
804 | break; | ||
805 | case VIAFB_SYNC_SURFACE: | 709 | case VIAFB_SYNC_SURFACE: |
806 | DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n"); | 710 | DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n"); |
807 | break; | 711 | break; |
@@ -867,10 +771,12 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
867 | static void viafb_fillrect(struct fb_info *info, | 771 | static void viafb_fillrect(struct fb_info *info, |
868 | const struct fb_fillrect *rect) | 772 | const struct fb_fillrect *rect) |
869 | { | 773 | { |
870 | u32 col = 0, rop = 0; | 774 | struct viafb_par *viapar = info->par; |
871 | int pitch; | 775 | struct viafb_shared *shared = viapar->shared; |
776 | u32 fg_color; | ||
777 | u8 rop; | ||
872 | 778 | ||
873 | if (!viafb_accel) { | 779 | if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) { |
874 | cfb_fillrect(info, rect); | 780 | cfb_fillrect(info, rect); |
875 | return; | 781 | return; |
876 | } | 782 | } |
@@ -878,68 +784,31 @@ static void viafb_fillrect(struct fb_info *info, | |||
878 | if (!rect->width || !rect->height) | 784 | if (!rect->width || !rect->height) |
879 | return; | 785 | return; |
880 | 786 | ||
881 | switch (rect->rop) { | 787 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) |
882 | case ROP_XOR: | 788 | fg_color = ((u32 *)info->pseudo_palette)[rect->color]; |
789 | else | ||
790 | fg_color = rect->color; | ||
791 | |||
792 | if (rect->rop == ROP_XOR) | ||
883 | rop = 0x5A; | 793 | rop = 0x5A; |
884 | break; | 794 | else |
885 | case ROP_COPY: | ||
886 | default: | ||
887 | rop = 0xF0; | 795 | rop = 0xF0; |
888 | break; | ||
889 | } | ||
890 | |||
891 | switch (info->var.bits_per_pixel) { | ||
892 | case 8: | ||
893 | col = rect->color; | ||
894 | break; | ||
895 | case 16: | ||
896 | col = ((u32 *) (info->pseudo_palette))[rect->color]; | ||
897 | break; | ||
898 | case 32: | ||
899 | col = ((u32 *) (info->pseudo_palette))[rect->color]; | ||
900 | break; | ||
901 | } | ||
902 | |||
903 | /* BitBlt Source Address */ | ||
904 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
905 | /* Source Base Address */ | ||
906 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
907 | /* Destination Base Address */ | ||
908 | writel(((unsigned long) (info->screen_base) - | ||
909 | (unsigned long) viafb_FB_MM) >> 3, | ||
910 | viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
911 | /* Pitch */ | ||
912 | pitch = (info->var.xres_virtual + 7) & ~7; | ||
913 | writel(VIA_PITCH_ENABLE | | ||
914 | (((pitch * | ||
915 | info->var.bits_per_pixel >> 3) >> 3) | | ||
916 | (((pitch * info-> | ||
917 | var.bits_per_pixel >> 3) >> 3) << 16)), | ||
918 | viaparinfo->io_virt + VIA_REG_PITCH); | ||
919 | /* BitBlt Destination Address */ | ||
920 | writel(((rect->dy << 16) | rect->dx), | ||
921 | viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
922 | /* Dimension: width & height */ | ||
923 | writel((((rect->height - 1) << 16) | (rect->width - 1)), | ||
924 | viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
925 | /* Forground color or Destination color */ | ||
926 | writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR); | ||
927 | /* GE Command */ | ||
928 | writel((0x01 | 0x2000 | (rop << 24)), | ||
929 | viaparinfo->io_virt + VIA_REG_GECMD); | ||
930 | 796 | ||
797 | DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n"); | ||
798 | if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_FILL, | ||
799 | rect->width, rect->height, info->var.bits_per_pixel, | ||
800 | viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy, | ||
801 | NULL, 0, 0, 0, 0, fg_color, 0, rop)) | ||
802 | cfb_fillrect(info, rect); | ||
931 | } | 803 | } |
932 | 804 | ||
933 | static void viafb_copyarea(struct fb_info *info, | 805 | static void viafb_copyarea(struct fb_info *info, |
934 | const struct fb_copyarea *area) | 806 | const struct fb_copyarea *area) |
935 | { | 807 | { |
936 | u32 dy = area->dy, sy = area->sy, direction = 0x0; | 808 | struct viafb_par *viapar = info->par; |
937 | u32 sx = area->sx, dx = area->dx, width = area->width; | 809 | struct viafb_shared *shared = viapar->shared; |
938 | int pitch; | ||
939 | |||
940 | DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n"); | ||
941 | 810 | ||
942 | if (!viafb_accel) { | 811 | if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) { |
943 | cfb_copyarea(info, area); | 812 | cfb_copyarea(info, area); |
944 | return; | 813 | return; |
945 | } | 814 | } |
@@ -947,263 +816,148 @@ static void viafb_copyarea(struct fb_info *info, | |||
947 | if (!area->width || !area->height) | 816 | if (!area->width || !area->height) |
948 | return; | 817 | return; |
949 | 818 | ||
950 | if (sy < dy) { | 819 | DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n"); |
951 | dy += area->height - 1; | 820 | if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_COLOR, |
952 | sy += area->height - 1; | 821 | area->width, area->height, info->var.bits_per_pixel, |
953 | direction |= 0x4000; | 822 | viapar->vram_addr, info->fix.line_length, area->dx, area->dy, |
954 | } | 823 | NULL, viapar->vram_addr, info->fix.line_length, |
955 | 824 | area->sx, area->sy, 0, 0, 0)) | |
956 | if (sx < dx) { | 825 | cfb_copyarea(info, area); |
957 | dx += width - 1; | ||
958 | sx += width - 1; | ||
959 | direction |= 0x8000; | ||
960 | } | ||
961 | |||
962 | /* Source Base Address */ | ||
963 | writel(((unsigned long) (info->screen_base) - | ||
964 | (unsigned long) viafb_FB_MM) >> 3, | ||
965 | viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
966 | /* Destination Base Address */ | ||
967 | writel(((unsigned long) (info->screen_base) - | ||
968 | (unsigned long) viafb_FB_MM) >> 3, | ||
969 | viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
970 | /* Pitch */ | ||
971 | pitch = (info->var.xres_virtual + 7) & ~7; | ||
972 | /* VIA_PITCH_ENABLE can be omitted now. */ | ||
973 | writel(VIA_PITCH_ENABLE | | ||
974 | (((pitch * | ||
975 | info->var.bits_per_pixel >> 3) >> 3) | (((pitch * | ||
976 | info->var. | ||
977 | bits_per_pixel | ||
978 | >> 3) >> 3) | ||
979 | << 16)), | ||
980 | viaparinfo->io_virt + VIA_REG_PITCH); | ||
981 | /* BitBlt Source Address */ | ||
982 | writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
983 | /* BitBlt Destination Address */ | ||
984 | writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
985 | /* Dimension: width & height */ | ||
986 | writel((((area->height - 1) << 16) | (area->width - 1)), | ||
987 | viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
988 | /* GE Command */ | ||
989 | writel((0x01 | direction | (0xCC << 24)), | ||
990 | viaparinfo->io_virt + VIA_REG_GECMD); | ||
991 | |||
992 | } | 826 | } |
993 | 827 | ||
994 | static void viafb_imageblit(struct fb_info *info, | 828 | static void viafb_imageblit(struct fb_info *info, |
995 | const struct fb_image *image) | 829 | const struct fb_image *image) |
996 | { | 830 | { |
997 | u32 size, bg_col = 0, fg_col = 0, *udata; | 831 | struct viafb_par *viapar = info->par; |
998 | int i; | 832 | struct viafb_shared *shared = viapar->shared; |
999 | int pitch; | 833 | u32 fg_color = 0, bg_color = 0; |
834 | u8 op; | ||
1000 | 835 | ||
1001 | if (!viafb_accel) { | 836 | if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt || |
837 | (image->depth != 1 && image->depth != viapar->depth)) { | ||
1002 | cfb_imageblit(info, image); | 838 | cfb_imageblit(info, image); |
1003 | return; | 839 | return; |
1004 | } | 840 | } |
1005 | 841 | ||
1006 | udata = (u32 *) image->data; | 842 | if (image->depth == 1) { |
1007 | 843 | op = VIA_BITBLT_MONO; | |
1008 | switch (info->var.bits_per_pixel) { | 844 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { |
1009 | case 8: | 845 | fg_color = |
1010 | bg_col = image->bg_color; | 846 | ((u32 *)info->pseudo_palette)[image->fg_color]; |
1011 | fg_col = image->fg_color; | 847 | bg_color = |
1012 | break; | 848 | ((u32 *)info->pseudo_palette)[image->bg_color]; |
1013 | case 16: | 849 | } else { |
1014 | bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; | 850 | fg_color = image->fg_color; |
1015 | fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; | 851 | bg_color = image->bg_color; |
1016 | break; | 852 | } |
1017 | case 32: | 853 | } else |
1018 | bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; | 854 | op = VIA_BITBLT_COLOR; |
1019 | fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; | ||
1020 | break; | ||
1021 | } | ||
1022 | size = image->width * image->height; | ||
1023 | |||
1024 | /* Source Base Address */ | ||
1025 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
1026 | /* Destination Base Address */ | ||
1027 | writel(((unsigned long) (info->screen_base) - | ||
1028 | (unsigned long) viafb_FB_MM) >> 3, | ||
1029 | viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
1030 | /* Pitch */ | ||
1031 | pitch = (info->var.xres_virtual + 7) & ~7; | ||
1032 | writel(VIA_PITCH_ENABLE | | ||
1033 | (((pitch * | ||
1034 | info->var.bits_per_pixel >> 3) >> 3) | (((pitch * | ||
1035 | info->var. | ||
1036 | bits_per_pixel | ||
1037 | >> 3) >> 3) | ||
1038 | << 16)), | ||
1039 | viaparinfo->io_virt + VIA_REG_PITCH); | ||
1040 | /* BitBlt Source Address */ | ||
1041 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
1042 | /* BitBlt Destination Address */ | ||
1043 | writel(((image->dy << 16) | image->dx), | ||
1044 | viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
1045 | /* Dimension: width & height */ | ||
1046 | writel((((image->height - 1) << 16) | (image->width - 1)), | ||
1047 | viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
1048 | /* fb color */ | ||
1049 | writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR); | ||
1050 | /* bg color */ | ||
1051 | writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR); | ||
1052 | /* GE Command */ | ||
1053 | writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD); | ||
1054 | |||
1055 | for (i = 0; i < size / 4; i++) { | ||
1056 | writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE); | ||
1057 | udata++; | ||
1058 | } | ||
1059 | 855 | ||
856 | DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n"); | ||
857 | if (shared->hw_bitblt(shared->engine_mmio, op, | ||
858 | image->width, image->height, info->var.bits_per_pixel, | ||
859 | viapar->vram_addr, info->fix.line_length, image->dx, image->dy, | ||
860 | (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0)) | ||
861 | cfb_imageblit(info, image); | ||
1060 | } | 862 | } |
1061 | 863 | ||
1062 | static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 864 | static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
1063 | { | 865 | { |
1064 | u32 temp, xx, yy, bg_col = 0, fg_col = 0; | 866 | struct viafb_par *viapar = info->par; |
1065 | int i, j = 0; | 867 | void __iomem *engine = viapar->shared->engine_mmio; |
1066 | static int hw_cursor; | 868 | u32 temp, xx, yy, bg_color = 0, fg_color = 0, |
1067 | struct viafb_par *p_viafb_par; | 869 | chip_name = viapar->shared->chip_info.gfx_chip_name; |
1068 | 870 | int i, j = 0, cur_size = 64; | |
1069 | if (viafb_accel) | ||
1070 | hw_cursor = 1; | ||
1071 | |||
1072 | if (!viafb_accel) { | ||
1073 | if (hw_cursor) { | ||
1074 | viafb_show_hw_cursor(info, HW_Cursor_OFF); | ||
1075 | hw_cursor = 0; | ||
1076 | } | ||
1077 | return -ENODEV; | ||
1078 | } | ||
1079 | 871 | ||
1080 | if ((((struct viafb_par *)(info->par))->iga_path == IGA2) | 872 | if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo) |
1081 | && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) | ||
1082 | return -ENODEV; | 873 | return -ENODEV; |
1083 | 874 | ||
1084 | /* When duoview and using lcd , use soft cursor */ | 875 | if (chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2) |
1085 | if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview) | ||
1086 | return -ENODEV; | 876 | return -ENODEV; |
1087 | 877 | ||
1088 | viafb_show_hw_cursor(info, HW_Cursor_OFF); | 878 | viafb_show_hw_cursor(info, HW_Cursor_OFF); |
1089 | viacursor = *cursor; | ||
1090 | 879 | ||
1091 | if (cursor->set & FB_CUR_SETHOT) { | 880 | if (cursor->set & FB_CUR_SETHOT) { |
1092 | viacursor.hot = cursor->hot; | 881 | temp = (cursor->hot.x << 16) + cursor->hot.y; |
1093 | temp = ((viacursor.hot.x) << 16) + viacursor.hot.y; | 882 | writel(temp, engine + VIA_REG_CURSOR_ORG); |
1094 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); | ||
1095 | } | 883 | } |
1096 | 884 | ||
1097 | if (cursor->set & FB_CUR_SETPOS) { | 885 | if (cursor->set & FB_CUR_SETPOS) { |
1098 | viacursor.image.dx = cursor->image.dx; | ||
1099 | viacursor.image.dy = cursor->image.dy; | ||
1100 | yy = cursor->image.dy - info->var.yoffset; | 886 | yy = cursor->image.dy - info->var.yoffset; |
1101 | xx = cursor->image.dx - info->var.xoffset; | 887 | xx = cursor->image.dx - info->var.xoffset; |
1102 | temp = yy & 0xFFFF; | 888 | temp = yy & 0xFFFF; |
1103 | temp |= (xx << 16); | 889 | temp |= (xx << 16); |
1104 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS); | 890 | writel(temp, engine + VIA_REG_CURSOR_POS); |
1105 | } | 891 | } |
1106 | 892 | ||
1107 | if (cursor->set & FB_CUR_SETSIZE) { | 893 | if (cursor->image.width <= 32 && cursor->image.height <= 32) |
1108 | temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | 894 | cur_size = 32; |
895 | else if (cursor->image.width <= 64 && cursor->image.height <= 64) | ||
896 | cur_size = 64; | ||
897 | else { | ||
898 | printk(KERN_WARNING "viafb_cursor: The cursor is too large " | ||
899 | "%dx%d", cursor->image.width, cursor->image.height); | ||
900 | return -ENXIO; | ||
901 | } | ||
1109 | 902 | ||
1110 | if ((cursor->image.width <= 32) | 903 | if (cursor->set & FB_CUR_SETSIZE) { |
1111 | && (cursor->image.height <= 32)) { | 904 | temp = readl(engine + VIA_REG_CURSOR_MODE); |
1112 | MAX_CURS = 32; | 905 | if (cur_size == 32) |
1113 | temp |= 0x2; | 906 | temp |= 0x2; |
1114 | } else if ((cursor->image.width <= 64) | 907 | else |
1115 | && (cursor->image.height <= 64)) { | 908 | temp &= ~0x2; |
1116 | MAX_CURS = 64; | ||
1117 | temp &= 0xFFFFFFFD; | ||
1118 | } else { | ||
1119 | DEBUG_MSG(KERN_INFO | ||
1120 | "The cursor image is biger than 64x64 bits...\n"); | ||
1121 | return -ENXIO; | ||
1122 | } | ||
1123 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | ||
1124 | 909 | ||
1125 | viacursor.image.height = cursor->image.height; | 910 | writel(temp, engine + VIA_REG_CURSOR_MODE); |
1126 | viacursor.image.width = cursor->image.width; | ||
1127 | } | 911 | } |
1128 | 912 | ||
1129 | if (cursor->set & FB_CUR_SETCMAP) { | 913 | if (cursor->set & FB_CUR_SETCMAP) { |
1130 | viacursor.image.fg_color = cursor->image.fg_color; | 914 | fg_color = cursor->image.fg_color; |
1131 | viacursor.image.bg_color = cursor->image.bg_color; | 915 | bg_color = cursor->image.bg_color; |
1132 | 916 | if (chip_name == UNICHROME_CX700 || | |
1133 | switch (info->var.bits_per_pixel) { | 917 | chip_name == UNICHROME_VX800 || |
1134 | case 8: | 918 | chip_name == UNICHROME_VX855) { |
1135 | case 16: | 919 | fg_color = |
1136 | case 32: | 920 | ((info->cmap.red[fg_color] & 0xFFC0) << 14) | |
1137 | bg_col = | 921 | ((info->cmap.green[fg_color] & 0xFFC0) << 4) | |
1138 | (0xFF << 24) | | 922 | ((info->cmap.blue[fg_color] & 0xFFC0) >> 6); |
1139 | (((info->cmap.red)[viacursor.image.bg_color] & | 923 | bg_color = |
1140 | 0xFF00) << 8) | | 924 | ((info->cmap.red[bg_color] & 0xFFC0) << 14) | |
1141 | ((info->cmap.green)[viacursor.image.bg_color] & | 925 | ((info->cmap.green[bg_color] & 0xFFC0) << 4) | |
1142 | 0xFF00) | | 926 | ((info->cmap.blue[bg_color] & 0xFFC0) >> 6); |
1143 | (((info->cmap.blue)[viacursor.image.bg_color] & | 927 | } else { |
1144 | 0xFF00) >> 8); | 928 | fg_color = |
1145 | fg_col = | 929 | ((info->cmap.red[fg_color] & 0xFF00) << 8) | |
1146 | (0xFF << 24) | | 930 | (info->cmap.green[fg_color] & 0xFF00) | |
1147 | (((info->cmap.red)[viacursor.image.fg_color] & | 931 | ((info->cmap.blue[fg_color] & 0xFF00) >> 8); |
1148 | 0xFF00) << 8) | | 932 | bg_color = |
1149 | ((info->cmap.green)[viacursor.image.fg_color] & | 933 | ((info->cmap.red[bg_color] & 0xFF00) << 8) | |
1150 | 0xFF00) | | 934 | (info->cmap.green[bg_color] & 0xFF00) | |
1151 | (((info->cmap.blue)[viacursor.image.fg_color] & | 935 | ((info->cmap.blue[bg_color] & 0xFF00) >> 8); |
1152 | 0xFF00) >> 8); | ||
1153 | break; | ||
1154 | default: | ||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | /* This is indeed a patch for VT3324/VT3353 */ | ||
1159 | if (!info->par) | ||
1160 | return 0; | ||
1161 | p_viafb_par = (struct viafb_par *)info->par; | ||
1162 | |||
1163 | if ((p_viafb_par->chip_info->gfx_chip_name == | ||
1164 | UNICHROME_CX700) || | ||
1165 | ((p_viafb_par->chip_info->gfx_chip_name == | ||
1166 | UNICHROME_VX800))) { | ||
1167 | bg_col = | ||
1168 | (((info->cmap.red)[viacursor.image.bg_color] & | ||
1169 | 0xFFC0) << 14) | | ||
1170 | (((info->cmap.green)[viacursor.image.bg_color] & | ||
1171 | 0xFFC0) << 4) | | ||
1172 | (((info->cmap.blue)[viacursor.image.bg_color] & | ||
1173 | 0xFFC0) >> 6); | ||
1174 | fg_col = | ||
1175 | (((info->cmap.red)[viacursor.image.fg_color] & | ||
1176 | 0xFFC0) << 14) | | ||
1177 | (((info->cmap.green)[viacursor.image.fg_color] & | ||
1178 | 0xFFC0) << 4) | | ||
1179 | (((info->cmap.blue)[viacursor.image.fg_color] & | ||
1180 | 0xFFC0) >> 6); | ||
1181 | } | 936 | } |
1182 | 937 | ||
1183 | writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG); | 938 | writel(bg_color, engine + VIA_REG_CURSOR_BG); |
1184 | writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG); | 939 | writel(fg_color, engine + VIA_REG_CURSOR_FG); |
1185 | } | 940 | } |
1186 | 941 | ||
1187 | if (cursor->set & FB_CUR_SETSHAPE) { | 942 | if (cursor->set & FB_CUR_SETSHAPE) { |
1188 | struct { | 943 | struct { |
1189 | u8 data[CURSOR_SIZE / 8]; | 944 | u8 data[CURSOR_SIZE]; |
1190 | u32 bak[CURSOR_SIZE / 32]; | 945 | u32 bak[CURSOR_SIZE / 4]; |
1191 | } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); | 946 | } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); |
1192 | int size = | 947 | int size = ((cursor->image.width + 7) >> 3) * |
1193 | ((viacursor.image.width + 7) >> 3) * | 948 | cursor->image.height; |
1194 | viacursor.image.height; | ||
1195 | 949 | ||
1196 | if (cr_data == NULL) | 950 | if (!cr_data) |
1197 | goto out; | 951 | return -ENOMEM; |
1198 | 952 | ||
1199 | if (MAX_CURS == 32) { | 953 | if (cur_size == 32) { |
1200 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | 954 | for (i = 0; i < (CURSOR_SIZE / 4); i++) { |
1201 | cr_data->bak[i] = 0x0; | 955 | cr_data->bak[i] = 0x0; |
1202 | cr_data->bak[i + 1] = 0xFFFFFFFF; | 956 | cr_data->bak[i + 1] = 0xFFFFFFFF; |
1203 | i += 1; | 957 | i += 1; |
1204 | } | 958 | } |
1205 | } else if (MAX_CURS == 64) { | 959 | } else { |
1206 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | 960 | for (i = 0; i < (CURSOR_SIZE / 4); i++) { |
1207 | cr_data->bak[i] = 0x0; | 961 | cr_data->bak[i] = 0x0; |
1208 | cr_data->bak[i + 1] = 0x0; | 962 | cr_data->bak[i + 1] = 0x0; |
1209 | cr_data->bak[i + 2] = 0xFFFFFFFF; | 963 | cr_data->bak[i + 2] = 0xFFFFFFFF; |
@@ -1212,27 +966,27 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1212 | } | 966 | } |
1213 | } | 967 | } |
1214 | 968 | ||
1215 | switch (viacursor.rop) { | 969 | switch (cursor->rop) { |
1216 | case ROP_XOR: | 970 | case ROP_XOR: |
1217 | for (i = 0; i < size; i++) | 971 | for (i = 0; i < size; i++) |
1218 | cr_data->data[i] = viacursor.mask[i]; | 972 | cr_data->data[i] = cursor->mask[i]; |
1219 | break; | 973 | break; |
1220 | case ROP_COPY: | 974 | case ROP_COPY: |
1221 | 975 | ||
1222 | for (i = 0; i < size; i++) | 976 | for (i = 0; i < size; i++) |
1223 | cr_data->data[i] = viacursor.mask[i]; | 977 | cr_data->data[i] = cursor->mask[i]; |
1224 | break; | 978 | break; |
1225 | default: | 979 | default: |
1226 | break; | 980 | break; |
1227 | } | 981 | } |
1228 | 982 | ||
1229 | if (MAX_CURS == 32) { | 983 | if (cur_size == 32) { |
1230 | for (i = 0; i < size; i++) { | 984 | for (i = 0; i < size; i++) { |
1231 | cr_data->bak[j] = (u32) cr_data->data[i]; | 985 | cr_data->bak[j] = (u32) cr_data->data[i]; |
1232 | cr_data->bak[j + 1] = ~cr_data->bak[j]; | 986 | cr_data->bak[j + 1] = ~cr_data->bak[j]; |
1233 | j += 2; | 987 | j += 2; |
1234 | } | 988 | } |
1235 | } else if (MAX_CURS == 64) { | 989 | } else { |
1236 | for (i = 0; i < size; i++) { | 990 | for (i = 0; i < size; i++) { |
1237 | cr_data->bak[j] = (u32) cr_data->data[i]; | 991 | cr_data->bak[j] = (u32) cr_data->data[i]; |
1238 | cr_data->bak[j + 1] = 0x0; | 992 | cr_data->bak[j + 1] = 0x0; |
@@ -1242,14 +996,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1242 | } | 996 | } |
1243 | } | 997 | } |
1244 | 998 | ||
1245 | memcpy(((struct viafb_par *)(info->par))->fbmem_virt + | 999 | memcpy_toio(viafbinfo->screen_base + viapar->shared-> |
1246 | ((struct viafb_par *)(info->par))->cursor_start, | 1000 | cursor_vram_addr, cr_data->bak, CURSOR_SIZE); |
1247 | cr_data->bak, CURSOR_SIZE); | ||
1248 | out: | ||
1249 | kfree(cr_data); | 1001 | kfree(cr_data); |
1250 | } | 1002 | } |
1251 | 1003 | ||
1252 | if (viacursor.enable) | 1004 | if (cursor->enable) |
1253 | viafb_show_hw_cursor(info, HW_Cursor_ON); | 1005 | viafb_show_hw_cursor(info, HW_Cursor_ON); |
1254 | 1006 | ||
1255 | return 0; | 1007 | return 0; |
@@ -1257,28 +1009,26 @@ out: | |||
1257 | 1009 | ||
1258 | static int viafb_sync(struct fb_info *info) | 1010 | static int viafb_sync(struct fb_info *info) |
1259 | { | 1011 | { |
1260 | if (viafb_accel) | 1012 | if (!(info->flags & FBINFO_HWACCEL_DISABLED)) |
1261 | viafb_wait_engine_idle(); | 1013 | viafb_wait_engine_idle(info); |
1262 | return 0; | 1014 | return 0; |
1263 | } | 1015 | } |
1264 | 1016 | ||
1265 | int viafb_get_mode_index(int hres, int vres, int flag) | 1017 | int viafb_get_mode_index(int hres, int vres) |
1266 | { | 1018 | { |
1267 | u32 i; | 1019 | u32 i; |
1268 | DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n"); | 1020 | DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n"); |
1269 | 1021 | ||
1270 | for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++) | 1022 | for (i = 0; i < NUM_TOTAL_MODETABLE; i++) |
1271 | if (viafb_modentry[i].xres == hres && | 1023 | if (CLE266Modes[i].mode_array && |
1272 | viafb_modentry[i].yres == vres) | 1024 | CLE266Modes[i].crtc[0].crtc.hor_addr == hres && |
1025 | CLE266Modes[i].crtc[0].crtc.ver_addr == vres) | ||
1273 | break; | 1026 | break; |
1274 | 1027 | ||
1275 | viafb_resMode = viafb_modentry[i].mode_index; | 1028 | if (i == NUM_TOTAL_MODETABLE) |
1276 | if (flag) | 1029 | return VIA_RES_INVALID; |
1277 | viafb_mode1 = viafb_modentry[i].mode_res; | ||
1278 | else | ||
1279 | viafb_mode = viafb_modentry[i].mode_res; | ||
1280 | 1030 | ||
1281 | return viafb_resMode; | 1031 | return CLE266Modes[i].ModeIndex; |
1282 | } | 1032 | } |
1283 | 1033 | ||
1284 | static void check_available_device_to_enable(int device_id) | 1034 | static void check_available_device_to_enable(int device_id) |
@@ -1382,36 +1132,11 @@ static void viafb_set_device(struct device_t active_dev) | |||
1382 | viafb_SAMM_ON = active_dev.samm; | 1132 | viafb_SAMM_ON = active_dev.samm; |
1383 | viafb_primary_dev = active_dev.primary_dev; | 1133 | viafb_primary_dev = active_dev.primary_dev; |
1384 | 1134 | ||
1385 | viafb_set_start_addr(); | 1135 | viafb_set_primary_address(0); |
1136 | viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); | ||
1386 | viafb_set_iga_path(); | 1137 | viafb_set_iga_path(); |
1387 | } | 1138 | } |
1388 | 1139 | ||
1389 | static void viafb_set_video_device(u32 video_dev_info) | ||
1390 | { | ||
1391 | viaparinfo->video_on_crt = STATE_OFF; | ||
1392 | viaparinfo->video_on_dvi = STATE_OFF; | ||
1393 | viaparinfo->video_on_lcd = STATE_OFF; | ||
1394 | |||
1395 | /* Check available device to enable: */ | ||
1396 | if ((video_dev_info & CRT_Device) == CRT_Device) | ||
1397 | viaparinfo->video_on_crt = STATE_ON; | ||
1398 | else if ((video_dev_info & DVI_Device) == DVI_Device) | ||
1399 | viaparinfo->video_on_dvi = STATE_ON; | ||
1400 | else if ((video_dev_info & LCD_Device) == LCD_Device) | ||
1401 | viaparinfo->video_on_lcd = STATE_ON; | ||
1402 | } | ||
1403 | |||
1404 | static void viafb_get_video_device(u32 *video_dev_info) | ||
1405 | { | ||
1406 | *video_dev_info = None_Device; | ||
1407 | if (viaparinfo->video_on_crt == STATE_ON) | ||
1408 | *video_dev_info |= CRT_Device; | ||
1409 | else if (viaparinfo->video_on_dvi == STATE_ON) | ||
1410 | *video_dev_info |= DVI_Device; | ||
1411 | else if (viaparinfo->video_on_lcd == STATE_ON) | ||
1412 | *video_dev_info |= LCD_Device; | ||
1413 | } | ||
1414 | |||
1415 | static int get_primary_device(void) | 1140 | static int get_primary_device(void) |
1416 | { | 1141 | { |
1417 | int primary_device = 0; | 1142 | int primary_device = 0; |
@@ -1453,18 +1178,6 @@ static int get_primary_device(void) | |||
1453 | return primary_device; | 1178 | return primary_device; |
1454 | } | 1179 | } |
1455 | 1180 | ||
1456 | static u8 is_duoview(void) | ||
1457 | { | ||
1458 | if (0 == viafb_SAMM_ON) { | ||
1459 | if (viafb_LCD_ON + viafb_LCD2_ON + | ||
1460 | viafb_DVI_ON + viafb_CRT_ON == 2) | ||
1461 | return true; | ||
1462 | return false; | ||
1463 | } else { | ||
1464 | return false; | ||
1465 | } | ||
1466 | } | ||
1467 | |||
1468 | static void apply_second_mode_setting(struct fb_var_screeninfo | 1181 | static void apply_second_mode_setting(struct fb_var_screeninfo |
1469 | *sec_var) | 1182 | *sec_var) |
1470 | { | 1183 | { |
@@ -1566,14 +1279,13 @@ static int apply_device_setting(struct viafb_ioctl_setting setting_info, | |||
1566 | if (viafb_SAMM_ON) | 1279 | if (viafb_SAMM_ON) |
1567 | viafb_primary_dev = setting_info.primary_device; | 1280 | viafb_primary_dev = setting_info.primary_device; |
1568 | 1281 | ||
1569 | viafb_set_start_addr(); | 1282 | viafb_set_primary_address(0); |
1283 | viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); | ||
1570 | viafb_set_iga_path(); | 1284 | viafb_set_iga_path(); |
1571 | } | 1285 | } |
1572 | need_set_mode = 1; | 1286 | need_set_mode = 1; |
1573 | } | 1287 | } |
1574 | 1288 | ||
1575 | viaparinfo->duoview = is_duoview(); | ||
1576 | |||
1577 | if (!need_set_mode) { | 1289 | if (!need_set_mode) { |
1578 | ; | 1290 | ; |
1579 | } else { | 1291 | } else { |
@@ -1596,18 +1308,6 @@ static void retrieve_device_setting(struct viafb_ioctl_setting | |||
1596 | setting_info->device_status |= LCD_Device; | 1308 | setting_info->device_status |= LCD_Device; |
1597 | if (viafb_LCD2_ON == 1) | 1309 | if (viafb_LCD2_ON == 1) |
1598 | setting_info->device_status |= LCD2_Device; | 1310 | setting_info->device_status |= LCD2_Device; |
1599 | if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) { | ||
1600 | setting_info->video_device_status = | ||
1601 | viaparinfo->crt_setting_info->iga_path; | ||
1602 | } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) { | ||
1603 | setting_info->video_device_status = | ||
1604 | viaparinfo->tmds_setting_info->iga_path; | ||
1605 | } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) { | ||
1606 | setting_info->video_device_status = | ||
1607 | viaparinfo->lvds_setting_info->iga_path; | ||
1608 | } else { | ||
1609 | setting_info->video_device_status = 0; | ||
1610 | } | ||
1611 | 1311 | ||
1612 | setting_info->samm_status = viafb_SAMM_ON; | 1312 | setting_info->samm_status = viafb_SAMM_ON; |
1613 | setting_info->primary_device = get_primary_device(); | 1313 | setting_info->primary_device = get_primary_device(); |
@@ -1694,25 +1394,6 @@ static void parse_active_dev(void) | |||
1694 | viafb_CRT_ON = STATE_ON; | 1394 | viafb_CRT_ON = STATE_ON; |
1695 | viafb_SAMM_ON = STATE_OFF; | 1395 | viafb_SAMM_ON = STATE_OFF; |
1696 | } | 1396 | } |
1697 | viaparinfo->duoview = is_duoview(); | ||
1698 | } | ||
1699 | |||
1700 | static void parse_video_dev(void) | ||
1701 | { | ||
1702 | viaparinfo->video_on_crt = STATE_OFF; | ||
1703 | viaparinfo->video_on_dvi = STATE_OFF; | ||
1704 | viaparinfo->video_on_lcd = STATE_OFF; | ||
1705 | |||
1706 | if (!strncmp(viafb_video_dev, "CRT", 3)) { | ||
1707 | /* Video on CRT */ | ||
1708 | viaparinfo->video_on_crt = STATE_ON; | ||
1709 | } else if (!strncmp(viafb_video_dev, "DVI", 3)) { | ||
1710 | /* Video on DVI */ | ||
1711 | viaparinfo->video_on_dvi = STATE_ON; | ||
1712 | } else if (!strncmp(viafb_video_dev, "LCD", 3)) { | ||
1713 | /* Video on LCD */ | ||
1714 | viaparinfo->video_on_lcd = STATE_ON; | ||
1715 | } | ||
1716 | } | 1397 | } |
1717 | 1398 | ||
1718 | static int parse_port(char *opt_str, int *output_interface) | 1399 | static int parse_port(char *opt_str, int *output_interface) |
@@ -1761,10 +1442,8 @@ static void parse_dvi_port(void) | |||
1761 | * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], | 1442 | * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], |
1762 | * CR9B, SR65, CR97, CR99 | 1443 | * CR9B, SR65, CR97, CR99 |
1763 | */ | 1444 | */ |
1764 | static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset, | 1445 | static int viafb_dvp0_proc_show(struct seq_file *m, void *v) |
1765 | int count, int *eof, void *data) | ||
1766 | { | 1446 | { |
1767 | int len = 0; | ||
1768 | u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0; | 1447 | u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0; |
1769 | dvp0_data_dri = | 1448 | dvp0_data_dri = |
1770 | (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 | | 1449 | (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 | |
@@ -1773,13 +1452,17 @@ int count, int *eof, void *data) | |||
1773 | (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 | | 1452 | (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 | |
1774 | (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2; | 1453 | (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2; |
1775 | dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f; | 1454 | dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f; |
1776 | len += | 1455 | seq_printf(m, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); |
1777 | sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); | 1456 | return 0; |
1778 | *eof = 1; /*Inform kernel end of data */ | ||
1779 | return len; | ||
1780 | } | 1457 | } |
1781 | static int viafb_dvp0_proc_write(struct file *file, | 1458 | |
1782 | const char __user *buffer, unsigned long count, void *data) | 1459 | static int viafb_dvp0_proc_open(struct inode *inode, struct file *file) |
1460 | { | ||
1461 | return single_open(file, viafb_dvp0_proc_show, NULL); | ||
1462 | } | ||
1463 | |||
1464 | static ssize_t viafb_dvp0_proc_write(struct file *file, | ||
1465 | const char __user *buffer, size_t count, loff_t *pos) | ||
1783 | { | 1466 | { |
1784 | char buf[20], *value, *pbuf; | 1467 | char buf[20], *value, *pbuf; |
1785 | u8 reg_val = 0; | 1468 | u8 reg_val = 0; |
@@ -1823,21 +1506,33 @@ static int viafb_dvp0_proc_write(struct file *file, | |||
1823 | } | 1506 | } |
1824 | return count; | 1507 | return count; |
1825 | } | 1508 | } |
1826 | static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset, | 1509 | |
1827 | int count, int *eof, void *data) | 1510 | static const struct file_operations viafb_dvp0_proc_fops = { |
1511 | .owner = THIS_MODULE, | ||
1512 | .open = viafb_dvp0_proc_open, | ||
1513 | .read = seq_read, | ||
1514 | .llseek = seq_lseek, | ||
1515 | .release = single_release, | ||
1516 | .write = viafb_dvp0_proc_write, | ||
1517 | }; | ||
1518 | |||
1519 | static int viafb_dvp1_proc_show(struct seq_file *m, void *v) | ||
1828 | { | 1520 | { |
1829 | int len = 0; | ||
1830 | u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0; | 1521 | u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0; |
1831 | dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f; | 1522 | dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f; |
1832 | dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2; | 1523 | dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2; |
1833 | dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03; | 1524 | dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03; |
1834 | len += | 1525 | seq_printf(m, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); |
1835 | sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); | 1526 | return 0; |
1836 | *eof = 1; /*Inform kernel end of data */ | ||
1837 | return len; | ||
1838 | } | 1527 | } |
1839 | static int viafb_dvp1_proc_write(struct file *file, | 1528 | |
1840 | const char __user *buffer, unsigned long count, void *data) | 1529 | static int viafb_dvp1_proc_open(struct inode *inode, struct file *file) |
1530 | { | ||
1531 | return single_open(file, viafb_dvp1_proc_show, NULL); | ||
1532 | } | ||
1533 | |||
1534 | static ssize_t viafb_dvp1_proc_write(struct file *file, | ||
1535 | const char __user *buffer, size_t count, loff_t *pos) | ||
1841 | { | 1536 | { |
1842 | char buf[20], *value, *pbuf; | 1537 | char buf[20], *value, *pbuf; |
1843 | u8 reg_val = 0; | 1538 | u8 reg_val = 0; |
@@ -1876,18 +1571,30 @@ static int viafb_dvp1_proc_write(struct file *file, | |||
1876 | return count; | 1571 | return count; |
1877 | } | 1572 | } |
1878 | 1573 | ||
1879 | static int viafb_dfph_proc_read(char *buf, char **start, off_t offset, | 1574 | static const struct file_operations viafb_dvp1_proc_fops = { |
1880 | int count, int *eof, void *data) | 1575 | .owner = THIS_MODULE, |
1576 | .open = viafb_dvp1_proc_open, | ||
1577 | .read = seq_read, | ||
1578 | .llseek = seq_lseek, | ||
1579 | .release = single_release, | ||
1580 | .write = viafb_dvp1_proc_write, | ||
1581 | }; | ||
1582 | |||
1583 | static int viafb_dfph_proc_show(struct seq_file *m, void *v) | ||
1881 | { | 1584 | { |
1882 | int len = 0; | ||
1883 | u8 dfp_high = 0; | 1585 | u8 dfp_high = 0; |
1884 | dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f; | 1586 | dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f; |
1885 | len += sprintf(buf + len, "%x\n", dfp_high); | 1587 | seq_printf(m, "%x\n", dfp_high); |
1886 | *eof = 1; /*Inform kernel end of data */ | 1588 | return 0; |
1887 | return len; | ||
1888 | } | 1589 | } |
1889 | static int viafb_dfph_proc_write(struct file *file, | 1590 | |
1890 | const char __user *buffer, unsigned long count, void *data) | 1591 | static int viafb_dfph_proc_open(struct inode *inode, struct file *file) |
1592 | { | ||
1593 | return single_open(file, viafb_dfph_proc_show, NULL); | ||
1594 | } | ||
1595 | |||
1596 | static ssize_t viafb_dfph_proc_write(struct file *file, | ||
1597 | const char __user *buffer, size_t count, loff_t *pos) | ||
1891 | { | 1598 | { |
1892 | char buf[20]; | 1599 | char buf[20]; |
1893 | u8 reg_val = 0; | 1600 | u8 reg_val = 0; |
@@ -1902,18 +1609,31 @@ static int viafb_dfph_proc_write(struct file *file, | |||
1902 | viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); | 1609 | viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); |
1903 | return count; | 1610 | return count; |
1904 | } | 1611 | } |
1905 | static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset, | 1612 | |
1906 | int count, int *eof, void *data) | 1613 | static const struct file_operations viafb_dfph_proc_fops = { |
1614 | .owner = THIS_MODULE, | ||
1615 | .open = viafb_dfph_proc_open, | ||
1616 | .read = seq_read, | ||
1617 | .llseek = seq_lseek, | ||
1618 | .release = single_release, | ||
1619 | .write = viafb_dfph_proc_write, | ||
1620 | }; | ||
1621 | |||
1622 | static int viafb_dfpl_proc_show(struct seq_file *m, void *v) | ||
1907 | { | 1623 | { |
1908 | int len = 0; | ||
1909 | u8 dfp_low = 0; | 1624 | u8 dfp_low = 0; |
1910 | dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f; | 1625 | dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f; |
1911 | len += sprintf(buf + len, "%x\n", dfp_low); | 1626 | seq_printf(m, "%x\n", dfp_low); |
1912 | *eof = 1; /*Inform kernel end of data */ | 1627 | return 0; |
1913 | return len; | ||
1914 | } | 1628 | } |
1915 | static int viafb_dfpl_proc_write(struct file *file, | 1629 | |
1916 | const char __user *buffer, unsigned long count, void *data) | 1630 | static int viafb_dfpl_proc_open(struct inode *inode, struct file *file) |
1631 | { | ||
1632 | return single_open(file, viafb_dfpl_proc_show, NULL); | ||
1633 | } | ||
1634 | |||
1635 | static ssize_t viafb_dfpl_proc_write(struct file *file, | ||
1636 | const char __user *buffer, size_t count, loff_t *pos) | ||
1917 | { | 1637 | { |
1918 | char buf[20]; | 1638 | char buf[20]; |
1919 | u8 reg_val = 0; | 1639 | u8 reg_val = 0; |
@@ -1928,10 +1648,18 @@ static int viafb_dfpl_proc_write(struct file *file, | |||
1928 | viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); | 1648 | viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); |
1929 | return count; | 1649 | return count; |
1930 | } | 1650 | } |
1931 | static int viafb_vt1636_proc_read(char *buf, char **start, | 1651 | |
1932 | off_t offset, int count, int *eof, void *data) | 1652 | static const struct file_operations viafb_dfpl_proc_fops = { |
1653 | .owner = THIS_MODULE, | ||
1654 | .open = viafb_dfpl_proc_open, | ||
1655 | .read = seq_read, | ||
1656 | .llseek = seq_lseek, | ||
1657 | .release = single_release, | ||
1658 | .write = viafb_dfpl_proc_write, | ||
1659 | }; | ||
1660 | |||
1661 | static int viafb_vt1636_proc_show(struct seq_file *m, void *v) | ||
1933 | { | 1662 | { |
1934 | int len = 0; | ||
1935 | u8 vt1636_08 = 0, vt1636_09 = 0; | 1663 | u8 vt1636_08 = 0, vt1636_09 = 0; |
1936 | switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | 1664 | switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { |
1937 | case VT1636_LVDS: | 1665 | case VT1636_LVDS: |
@@ -1941,7 +1669,7 @@ static int viafb_vt1636_proc_read(char *buf, char **start, | |||
1941 | vt1636_09 = | 1669 | vt1636_09 = |
1942 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, | 1670 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, |
1943 | &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f; | 1671 | &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f; |
1944 | len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09); | 1672 | seq_printf(m, "%x %x\n", vt1636_08, vt1636_09); |
1945 | break; | 1673 | break; |
1946 | default: | 1674 | default: |
1947 | break; | 1675 | break; |
@@ -1954,16 +1682,21 @@ static int viafb_vt1636_proc_read(char *buf, char **start, | |||
1954 | vt1636_09 = | 1682 | vt1636_09 = |
1955 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, | 1683 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, |
1956 | &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f; | 1684 | &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f; |
1957 | len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09); | 1685 | seq_printf(m, " %x %x\n", vt1636_08, vt1636_09); |
1958 | break; | 1686 | break; |
1959 | default: | 1687 | default: |
1960 | break; | 1688 | break; |
1961 | } | 1689 | } |
1962 | *eof = 1; /*Inform kernel end of data */ | 1690 | return 0; |
1963 | return len; | ||
1964 | } | 1691 | } |
1965 | static int viafb_vt1636_proc_write(struct file *file, | 1692 | |
1966 | const char __user *buffer, unsigned long count, void *data) | 1693 | static int viafb_vt1636_proc_open(struct inode *inode, struct file *file) |
1694 | { | ||
1695 | return single_open(file, viafb_vt1636_proc_show, NULL); | ||
1696 | } | ||
1697 | |||
1698 | static ssize_t viafb_vt1636_proc_write(struct file *file, | ||
1699 | const char __user *buffer, size_t count, loff_t *pos) | ||
1967 | { | 1700 | { |
1968 | char buf[30], *value, *pbuf; | 1701 | char buf[30], *value, *pbuf; |
1969 | struct IODATA reg_val; | 1702 | struct IODATA reg_val; |
@@ -2052,39 +1785,27 @@ static int viafb_vt1636_proc_write(struct file *file, | |||
2052 | return count; | 1785 | return count; |
2053 | } | 1786 | } |
2054 | 1787 | ||
1788 | static const struct file_operations viafb_vt1636_proc_fops = { | ||
1789 | .owner = THIS_MODULE, | ||
1790 | .open = viafb_vt1636_proc_open, | ||
1791 | .read = seq_read, | ||
1792 | .llseek = seq_lseek, | ||
1793 | .release = single_release, | ||
1794 | .write = viafb_vt1636_proc_write, | ||
1795 | }; | ||
1796 | |||
2055 | static void viafb_init_proc(struct proc_dir_entry **viafb_entry) | 1797 | static void viafb_init_proc(struct proc_dir_entry **viafb_entry) |
2056 | { | 1798 | { |
2057 | struct proc_dir_entry *entry; | ||
2058 | *viafb_entry = proc_mkdir("viafb", NULL); | 1799 | *viafb_entry = proc_mkdir("viafb", NULL); |
2059 | if (viafb_entry) { | 1800 | if (viafb_entry) { |
2060 | entry = create_proc_entry("dvp0", 0, *viafb_entry); | 1801 | proc_create("dvp0", 0, *viafb_entry, &viafb_dvp0_proc_fops); |
2061 | if (entry) { | 1802 | proc_create("dvp1", 0, *viafb_entry, &viafb_dvp1_proc_fops); |
2062 | entry->read_proc = viafb_dvp0_proc_read; | 1803 | proc_create("dfph", 0, *viafb_entry, &viafb_dfph_proc_fops); |
2063 | entry->write_proc = viafb_dvp0_proc_write; | 1804 | proc_create("dfpl", 0, *viafb_entry, &viafb_dfpl_proc_fops); |
2064 | } | ||
2065 | entry = create_proc_entry("dvp1", 0, *viafb_entry); | ||
2066 | if (entry) { | ||
2067 | entry->read_proc = viafb_dvp1_proc_read; | ||
2068 | entry->write_proc = viafb_dvp1_proc_write; | ||
2069 | } | ||
2070 | entry = create_proc_entry("dfph", 0, *viafb_entry); | ||
2071 | if (entry) { | ||
2072 | entry->read_proc = viafb_dfph_proc_read; | ||
2073 | entry->write_proc = viafb_dfph_proc_write; | ||
2074 | } | ||
2075 | entry = create_proc_entry("dfpl", 0, *viafb_entry); | ||
2076 | if (entry) { | ||
2077 | entry->read_proc = viafb_dfpl_proc_read; | ||
2078 | entry->write_proc = viafb_dfpl_proc_write; | ||
2079 | } | ||
2080 | if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. | 1805 | if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. |
2081 | lvds_chip_name || VT1636_LVDS == | 1806 | lvds_chip_name || VT1636_LVDS == |
2082 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { | 1807 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { |
2083 | entry = create_proc_entry("vt1636", 0, *viafb_entry); | 1808 | proc_create("vt1636", 0, *viafb_entry, &viafb_vt1636_proc_fops); |
2084 | if (entry) { | ||
2085 | entry->read_proc = viafb_vt1636_proc_read; | ||
2086 | entry->write_proc = viafb_vt1636_proc_write; | ||
2087 | } | ||
2088 | } | 1809 | } |
2089 | 1810 | ||
2090 | } | 1811 | } |
@@ -2101,51 +1822,61 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) | |||
2101 | remove_proc_entry("viafb", NULL); | 1822 | remove_proc_entry("viafb", NULL); |
2102 | } | 1823 | } |
2103 | 1824 | ||
2104 | static int __devinit via_pci_probe(void) | 1825 | static void parse_mode(const char *str, u32 *xres, u32 *yres) |
2105 | { | 1826 | { |
2106 | unsigned long default_xres, default_yres; | 1827 | char *ptr; |
2107 | char *tmpc, *tmpm; | 1828 | |
2108 | char *tmpc_sec, *tmpm_sec; | 1829 | *xres = simple_strtoul(str, &ptr, 10); |
1830 | if (ptr[0] != 'x') | ||
1831 | goto out_default; | ||
1832 | |||
1833 | *yres = simple_strtoul(&ptr[1], &ptr, 10); | ||
1834 | if (ptr[0]) | ||
1835 | goto out_default; | ||
1836 | |||
1837 | return; | ||
1838 | |||
1839 | out_default: | ||
1840 | printk(KERN_WARNING "viafb received invalid mode string: %s\n", str); | ||
1841 | *xres = 640; | ||
1842 | *yres = 480; | ||
1843 | } | ||
1844 | |||
1845 | static int __devinit via_pci_probe(struct pci_dev *pdev, | ||
1846 | const struct pci_device_id *ent) | ||
1847 | { | ||
1848 | u32 default_xres, default_yres; | ||
2109 | int vmode_index; | 1849 | int vmode_index; |
2110 | u32 tmds_length, lvds_length, crt_length, chip_length, viafb_par_length; | 1850 | u32 viafb_par_length; |
2111 | 1851 | ||
2112 | DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); | 1852 | DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); |
2113 | 1853 | ||
2114 | viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); | 1854 | viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); |
2115 | tmds_length = ALIGN(sizeof(struct tmds_setting_information), | ||
2116 | BITS_PER_LONG/8); | ||
2117 | lvds_length = ALIGN(sizeof(struct lvds_setting_information), | ||
2118 | BITS_PER_LONG/8); | ||
2119 | crt_length = ALIGN(sizeof(struct lvds_setting_information), | ||
2120 | BITS_PER_LONG/8); | ||
2121 | chip_length = ALIGN(sizeof(struct chip_information), BITS_PER_LONG/8); | ||
2122 | 1855 | ||
2123 | /* Allocate fb_info and ***_par here, also including some other needed | 1856 | /* Allocate fb_info and ***_par here, also including some other needed |
2124 | * variables | 1857 | * variables |
2125 | */ | 1858 | */ |
2126 | viafbinfo = framebuffer_alloc(viafb_par_length + 2 * lvds_length + | 1859 | viafbinfo = framebuffer_alloc(viafb_par_length + |
2127 | tmds_length + crt_length + chip_length, NULL); | 1860 | ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8), |
1861 | &pdev->dev); | ||
2128 | if (!viafbinfo) { | 1862 | if (!viafbinfo) { |
2129 | printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); | 1863 | printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); |
2130 | return -ENODEV; | 1864 | return -ENODEV; |
2131 | } | 1865 | } |
2132 | 1866 | ||
2133 | viaparinfo = (struct viafb_par *)viafbinfo->par; | 1867 | viaparinfo = (struct viafb_par *)viafbinfo->par; |
2134 | viaparinfo->tmds_setting_info = (struct tmds_setting_information *) | 1868 | viaparinfo->shared = viafbinfo->par + viafb_par_length; |
2135 | ((unsigned long)viaparinfo + viafb_par_length); | 1869 | viaparinfo->vram_addr = 0; |
2136 | viaparinfo->lvds_setting_info = (struct lvds_setting_information *) | 1870 | viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info; |
2137 | ((unsigned long)viaparinfo->tmds_setting_info + tmds_length); | 1871 | viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; |
2138 | viaparinfo->lvds_setting_info2 = (struct lvds_setting_information *) | 1872 | viaparinfo->lvds_setting_info2 = |
2139 | ((unsigned long)viaparinfo->lvds_setting_info + lvds_length); | 1873 | &viaparinfo->shared->lvds_setting_info2; |
2140 | viaparinfo->crt_setting_info = (struct crt_setting_information *) | 1874 | viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info; |
2141 | ((unsigned long)viaparinfo->lvds_setting_info2 + lvds_length); | 1875 | viaparinfo->chip_info = &viaparinfo->shared->chip_info; |
2142 | viaparinfo->chip_info = (struct chip_information *) | ||
2143 | ((unsigned long)viaparinfo->crt_setting_info + crt_length); | ||
2144 | 1876 | ||
2145 | if (viafb_dual_fb) | 1877 | if (viafb_dual_fb) |
2146 | viafb_SAMM_ON = 1; | 1878 | viafb_SAMM_ON = 1; |
2147 | parse_active_dev(); | 1879 | parse_active_dev(); |
2148 | parse_video_dev(); | ||
2149 | parse_lcd_port(); | 1880 | parse_lcd_port(); |
2150 | parse_dvi_port(); | 1881 | parse_dvi_port(); |
2151 | 1882 | ||
@@ -2156,32 +1887,32 @@ static int __devinit via_pci_probe(void) | |||
2156 | /* Set up I2C bus stuff */ | 1887 | /* Set up I2C bus stuff */ |
2157 | viafb_create_i2c_bus(viaparinfo); | 1888 | viafb_create_i2c_bus(viaparinfo); |
2158 | 1889 | ||
2159 | viafb_init_chip_info(); | 1890 | viafb_init_chip_info(pdev, ent); |
2160 | viafb_get_fb_info(&viaparinfo->fbmem, &viaparinfo->memsize); | 1891 | viaparinfo->fbmem = pci_resource_start(pdev, 0); |
1892 | viaparinfo->memsize = viafb_get_fb_size_from_pci(); | ||
2161 | viaparinfo->fbmem_free = viaparinfo->memsize; | 1893 | viaparinfo->fbmem_free = viaparinfo->memsize; |
2162 | viaparinfo->fbmem_used = 0; | 1894 | viaparinfo->fbmem_used = 0; |
2163 | viaparinfo->fbmem_virt = ioremap_nocache(viaparinfo->fbmem, | 1895 | viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem, |
2164 | viaparinfo->memsize); | 1896 | viaparinfo->memsize); |
2165 | viafbinfo->screen_base = (char *)viaparinfo->fbmem_virt; | 1897 | if (!viafbinfo->screen_base) { |
2166 | |||
2167 | if (!viaparinfo->fbmem_virt) { | ||
2168 | printk(KERN_INFO "ioremap failed\n"); | 1898 | printk(KERN_INFO "ioremap failed\n"); |
2169 | return -1; | 1899 | return -ENOMEM; |
2170 | } | 1900 | } |
2171 | 1901 | ||
2172 | viafb_get_mmio_info(&viaparinfo->mmio_base, &viaparinfo->mmio_len); | 1902 | viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1); |
2173 | viaparinfo->io_virt = ioremap_nocache(viaparinfo->mmio_base, | 1903 | viafbinfo->fix.mmio_len = pci_resource_len(pdev, 1); |
2174 | viaparinfo->mmio_len); | ||
2175 | |||
2176 | viafbinfo->node = 0; | 1904 | viafbinfo->node = 0; |
2177 | viafbinfo->fbops = &viafb_ops; | 1905 | viafbinfo->fbops = &viafb_ops; |
2178 | viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 1906 | viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
2179 | 1907 | ||
2180 | viafbinfo->pseudo_palette = pseudo_pal; | 1908 | viafbinfo->pseudo_palette = pseudo_pal; |
2181 | if (viafb_accel) { | 1909 | if (viafb_accel && !viafb_init_engine(viafbinfo)) { |
2182 | viafb_init_accel(); | 1910 | viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA | |
2183 | viafb_init_2d_engine(); | 1911 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; |
2184 | viafb_hw_cursor_init(); | 1912 | default_var.accel_flags = FB_ACCELF_TEXT; |
1913 | } else { | ||
1914 | viafbinfo->flags |= FBINFO_HWACCEL_DISABLED; | ||
1915 | default_var.accel_flags = 0; | ||
2185 | } | 1916 | } |
2186 | 1917 | ||
2187 | if (viafb_second_size && (viafb_second_size < 8)) { | 1918 | if (viafb_second_size && (viafb_second_size < 8)) { |
@@ -2193,27 +1924,14 @@ static int __devinit via_pci_probe(void) | |||
2193 | viafb_second_size * 1024 * 1024; | 1924 | viafb_second_size * 1024 * 1024; |
2194 | } | 1925 | } |
2195 | 1926 | ||
2196 | viafb_FB_MM = viaparinfo->fbmem_virt; | 1927 | parse_mode(viafb_mode, &default_xres, &default_yres); |
2197 | tmpm = viafb_mode; | 1928 | vmode_index = viafb_get_mode_index(default_xres, default_yres); |
2198 | tmpc = strsep(&tmpm, "x"); | ||
2199 | strict_strtoul(tmpc, 0, &default_xres); | ||
2200 | strict_strtoul(tmpm, 0, &default_yres); | ||
2201 | |||
2202 | vmode_index = viafb_get_mode_index(default_xres, default_yres, 0); | ||
2203 | DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); | 1929 | DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); |
2204 | 1930 | ||
2205 | if (viafb_SAMM_ON == 1) { | 1931 | if (viafb_SAMM_ON == 1) { |
2206 | if (strcmp(viafb_mode, viafb_mode1)) { | 1932 | parse_mode(viafb_mode1, &viafb_second_xres, |
2207 | tmpm_sec = viafb_mode1; | 1933 | &viafb_second_yres); |
2208 | tmpc_sec = strsep(&tmpm_sec, "x"); | 1934 | |
2209 | strict_strtoul(tmpc_sec, 0, | ||
2210 | (unsigned long *)&viafb_second_xres); | ||
2211 | strict_strtoul(tmpm_sec, 0, | ||
2212 | (unsigned long *)&viafb_second_yres); | ||
2213 | } else { | ||
2214 | viafb_second_xres = default_xres; | ||
2215 | viafb_second_yres = default_yres; | ||
2216 | } | ||
2217 | if (0 == viafb_second_virtual_xres) { | 1935 | if (0 == viafb_second_virtual_xres) { |
2218 | switch (viafb_second_xres) { | 1936 | switch (viafb_second_xres) { |
2219 | case 1400: | 1937 | case 1400: |
@@ -2263,18 +1981,9 @@ static int __devinit via_pci_probe(void) | |||
2263 | default_var.lower_margin = 4; | 1981 | default_var.lower_margin = 4; |
2264 | default_var.hsync_len = default_var.left_margin; | 1982 | default_var.hsync_len = default_var.left_margin; |
2265 | default_var.vsync_len = 4; | 1983 | default_var.vsync_len = 4; |
2266 | default_var.accel_flags = 0; | ||
2267 | |||
2268 | if (viafb_accel) { | ||
2269 | viafbinfo->flags |= | ||
2270 | (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | | ||
2271 | FBINFO_HWACCEL_IMAGEBLIT); | ||
2272 | default_var.accel_flags |= FB_ACCELF_TEXT; | ||
2273 | } else | ||
2274 | viafbinfo->flags |= FBINFO_HWACCEL_DISABLED; | ||
2275 | 1984 | ||
2276 | if (viafb_dual_fb) { | 1985 | if (viafb_dual_fb) { |
2277 | viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL); | 1986 | viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); |
2278 | if (!viafbinfo1) { | 1987 | if (!viafbinfo1) { |
2279 | printk(KERN_ERR | 1988 | printk(KERN_ERR |
2280 | "allocate the second framebuffer struct error\n"); | 1989 | "allocate the second framebuffer struct error\n"); |
@@ -2283,11 +1992,10 @@ static int __devinit via_pci_probe(void) | |||
2283 | } | 1992 | } |
2284 | viaparinfo1 = viafbinfo1->par; | 1993 | viaparinfo1 = viafbinfo1->par; |
2285 | memcpy(viaparinfo1, viaparinfo, viafb_par_length); | 1994 | memcpy(viaparinfo1, viaparinfo, viafb_par_length); |
1995 | viaparinfo1->vram_addr = viafb_second_offset; | ||
2286 | viaparinfo1->memsize = viaparinfo->memsize - | 1996 | viaparinfo1->memsize = viaparinfo->memsize - |
2287 | viafb_second_offset; | 1997 | viafb_second_offset; |
2288 | viaparinfo->memsize = viafb_second_offset; | 1998 | viaparinfo->memsize = viafb_second_offset; |
2289 | viaparinfo1->fbmem_virt = viaparinfo->fbmem_virt + | ||
2290 | viafb_second_offset; | ||
2291 | viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset; | 1999 | viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset; |
2292 | 2000 | ||
2293 | viaparinfo1->fbmem_used = viaparinfo->fbmem_used; | 2001 | viaparinfo1->fbmem_used = viaparinfo->fbmem_used; |
@@ -2295,20 +2003,13 @@ static int __devinit via_pci_probe(void) | |||
2295 | viaparinfo1->fbmem_used; | 2003 | viaparinfo1->fbmem_used; |
2296 | viaparinfo->fbmem_free = viaparinfo->memsize; | 2004 | viaparinfo->fbmem_free = viaparinfo->memsize; |
2297 | viaparinfo->fbmem_used = 0; | 2005 | viaparinfo->fbmem_used = 0; |
2298 | if (viafb_accel) { | ||
2299 | viaparinfo1->cursor_start = | ||
2300 | viaparinfo->cursor_start - viafb_second_offset; | ||
2301 | viaparinfo1->VQ_start = viaparinfo->VQ_start - | ||
2302 | viafb_second_offset; | ||
2303 | viaparinfo1->VQ_end = viaparinfo->VQ_end - | ||
2304 | viafb_second_offset; | ||
2305 | } | ||
2306 | 2006 | ||
2007 | viaparinfo->iga_path = IGA1; | ||
2008 | viaparinfo1->iga_path = IGA2; | ||
2307 | memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info)); | 2009 | memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info)); |
2010 | viafbinfo1->par = viaparinfo1; | ||
2308 | viafbinfo1->screen_base = viafbinfo->screen_base + | 2011 | viafbinfo1->screen_base = viafbinfo->screen_base + |
2309 | viafb_second_offset; | 2012 | viafb_second_offset; |
2310 | viafbinfo1->fix.smem_start = viaparinfo1->fbmem; | ||
2311 | viafbinfo1->fix.smem_len = viaparinfo1->fbmem_free; | ||
2312 | 2013 | ||
2313 | default_var.xres = viafb_second_xres; | 2014 | default_var.xres = viafb_second_xres; |
2314 | default_var.yres = viafb_second_yres; | 2015 | default_var.yres = viafb_second_yres; |
@@ -2330,15 +2031,17 @@ static int __devinit via_pci_probe(void) | |||
2330 | viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); | 2031 | viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); |
2331 | viafb_check_var(&default_var, viafbinfo1); | 2032 | viafb_check_var(&default_var, viafbinfo1); |
2332 | viafbinfo1->var = default_var; | 2033 | viafbinfo1->var = default_var; |
2333 | viafb_update_viafb_par(viafbinfo); | 2034 | viafb_update_fix(viafbinfo1); |
2334 | viafb_update_fix(&viafbinfo1->fix, viafbinfo1); | 2035 | viaparinfo1->depth = fb_get_color_depth(&viafbinfo1->var, |
2036 | &viafbinfo1->fix); | ||
2335 | } | 2037 | } |
2336 | 2038 | ||
2337 | viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); | 2039 | viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); |
2338 | viafb_check_var(&default_var, viafbinfo); | 2040 | viafb_check_var(&default_var, viafbinfo); |
2339 | viafbinfo->var = default_var; | 2041 | viafbinfo->var = default_var; |
2340 | viafb_update_viafb_par(viafbinfo); | 2042 | viafb_update_fix(viafbinfo); |
2341 | viafb_update_fix(&viafbinfo->fix, viafbinfo); | 2043 | viaparinfo->depth = fb_get_color_depth(&viafbinfo->var, |
2044 | &viafbinfo->fix); | ||
2342 | default_var.activate = FB_ACTIVATE_NOW; | 2045 | default_var.activate = FB_ACTIVATE_NOW; |
2343 | fb_alloc_cmap(&viafbinfo->cmap, 256, 0); | 2046 | fb_alloc_cmap(&viafbinfo->cmap, 256, 0); |
2344 | 2047 | ||
@@ -2360,20 +2063,20 @@ static int __devinit via_pci_probe(void) | |||
2360 | viafbinfo->node, viafbinfo->fix.id, default_var.xres, | 2063 | viafbinfo->node, viafbinfo->fix.id, default_var.xres, |
2361 | default_var.yres, default_var.bits_per_pixel); | 2064 | default_var.yres, default_var.bits_per_pixel); |
2362 | 2065 | ||
2363 | viafb_init_proc(&viaparinfo->proc_entry); | 2066 | viafb_init_proc(&viaparinfo->shared->proc_entry); |
2364 | viafb_init_dac(IGA2); | 2067 | viafb_init_dac(IGA2); |
2365 | return 0; | 2068 | return 0; |
2366 | } | 2069 | } |
2367 | 2070 | ||
2368 | static void __devexit via_pci_remove(void) | 2071 | static void __devexit via_pci_remove(struct pci_dev *pdev) |
2369 | { | 2072 | { |
2370 | DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); | 2073 | DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); |
2371 | fb_dealloc_cmap(&viafbinfo->cmap); | 2074 | fb_dealloc_cmap(&viafbinfo->cmap); |
2372 | unregister_framebuffer(viafbinfo); | 2075 | unregister_framebuffer(viafbinfo); |
2373 | if (viafb_dual_fb) | 2076 | if (viafb_dual_fb) |
2374 | unregister_framebuffer(viafbinfo1); | 2077 | unregister_framebuffer(viafbinfo1); |
2375 | iounmap((void *)viaparinfo->fbmem_virt); | 2078 | iounmap((void *)viafbinfo->screen_base); |
2376 | iounmap(viaparinfo->io_virt); | 2079 | iounmap(viaparinfo->shared->engine_mmio); |
2377 | 2080 | ||
2378 | viafb_delete_i2c_buss(viaparinfo); | 2081 | viafb_delete_i2c_buss(viaparinfo); |
2379 | 2082 | ||
@@ -2381,7 +2084,7 @@ static void __devexit via_pci_remove(void) | |||
2381 | if (viafb_dual_fb) | 2084 | if (viafb_dual_fb) |
2382 | framebuffer_release(viafbinfo1); | 2085 | framebuffer_release(viafbinfo1); |
2383 | 2086 | ||
2384 | viafb_remove_proc(viaparinfo->proc_entry); | 2087 | viafb_remove_proc(viaparinfo->shared->proc_entry); |
2385 | } | 2088 | } |
2386 | 2089 | ||
2387 | #ifndef MODULE | 2090 | #ifndef MODULE |
@@ -2448,8 +2151,6 @@ static int __init viafb_setup(char *options) | |||
2448 | else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) | 2151 | else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) |
2449 | strict_strtoul(this_opt + 15, 0, | 2152 | strict_strtoul(this_opt + 15, 0, |
2450 | (unsigned long *)&viafb_lcd_mode); | 2153 | (unsigned long *)&viafb_lcd_mode); |
2451 | else if (!strncmp(this_opt, "viafb_video_dev=", 16)) | ||
2452 | viafb_video_dev = kstrdup(this_opt + 16, GFP_KERNEL); | ||
2453 | else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) | 2154 | else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) |
2454 | viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL); | 2155 | viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL); |
2455 | else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) | 2156 | else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) |
@@ -2459,6 +2160,40 @@ static int __init viafb_setup(char *options) | |||
2459 | } | 2160 | } |
2460 | #endif | 2161 | #endif |
2461 | 2162 | ||
2163 | static struct pci_device_id viafb_pci_table[] __devinitdata = { | ||
2164 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID), | ||
2165 | .driver_data = UNICHROME_CLE266 }, | ||
2166 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID), | ||
2167 | .driver_data = UNICHROME_PM800 }, | ||
2168 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID), | ||
2169 | .driver_data = UNICHROME_K400 }, | ||
2170 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID), | ||
2171 | .driver_data = UNICHROME_K800 }, | ||
2172 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID), | ||
2173 | .driver_data = UNICHROME_CN700 }, | ||
2174 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID), | ||
2175 | .driver_data = UNICHROME_K8M890 }, | ||
2176 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID), | ||
2177 | .driver_data = UNICHROME_CX700 }, | ||
2178 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID), | ||
2179 | .driver_data = UNICHROME_P4M900 }, | ||
2180 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID), | ||
2181 | .driver_data = UNICHROME_CN750 }, | ||
2182 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID), | ||
2183 | .driver_data = UNICHROME_VX800 }, | ||
2184 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), | ||
2185 | .driver_data = UNICHROME_VX855 }, | ||
2186 | { } | ||
2187 | }; | ||
2188 | MODULE_DEVICE_TABLE(pci, viafb_pci_table); | ||
2189 | |||
2190 | static struct pci_driver viafb_driver = { | ||
2191 | .name = "viafb", | ||
2192 | .id_table = viafb_pci_table, | ||
2193 | .probe = via_pci_probe, | ||
2194 | .remove = __devexit_p(via_pci_remove), | ||
2195 | }; | ||
2196 | |||
2462 | static int __init viafb_init(void) | 2197 | static int __init viafb_init(void) |
2463 | { | 2198 | { |
2464 | #ifndef MODULE | 2199 | #ifndef MODULE |
@@ -2470,13 +2205,13 @@ static int __init viafb_init(void) | |||
2470 | printk(KERN_INFO | 2205 | printk(KERN_INFO |
2471 | "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", | 2206 | "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", |
2472 | VERSION_MAJOR, VERSION_MINOR); | 2207 | VERSION_MAJOR, VERSION_MINOR); |
2473 | return via_pci_probe(); | 2208 | return pci_register_driver(&viafb_driver); |
2474 | } | 2209 | } |
2475 | 2210 | ||
2476 | static void __exit viafb_exit(void) | 2211 | static void __exit viafb_exit(void) |
2477 | { | 2212 | { |
2478 | DEBUG_MSG(KERN_INFO "viafb_exit!\n"); | 2213 | DEBUG_MSG(KERN_INFO "viafb_exit!\n"); |
2479 | via_pci_remove(); | 2214 | pci_unregister_driver(&viafb_driver); |
2480 | } | 2215 | } |
2481 | 2216 | ||
2482 | static struct fb_ops viafb_ops = { | 2217 | static struct fb_ops viafb_ops = { |
@@ -2501,82 +2236,79 @@ module_init(viafb_init); | |||
2501 | module_exit(viafb_exit); | 2236 | module_exit(viafb_exit); |
2502 | 2237 | ||
2503 | #ifdef MODULE | 2238 | #ifdef MODULE |
2504 | module_param(viafb_memsize, int, 0); | 2239 | module_param(viafb_memsize, int, S_IRUSR); |
2505 | 2240 | ||
2506 | module_param(viafb_mode, charp, 0); | 2241 | module_param(viafb_mode, charp, S_IRUSR); |
2507 | MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); | 2242 | MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); |
2508 | 2243 | ||
2509 | module_param(viafb_mode1, charp, 0); | 2244 | module_param(viafb_mode1, charp, S_IRUSR); |
2510 | MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)"); | 2245 | MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)"); |
2511 | 2246 | ||
2512 | module_param(viafb_bpp, int, 0); | 2247 | module_param(viafb_bpp, int, S_IRUSR); |
2513 | MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)"); | 2248 | MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)"); |
2514 | 2249 | ||
2515 | module_param(viafb_bpp1, int, 0); | 2250 | module_param(viafb_bpp1, int, S_IRUSR); |
2516 | MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)"); | 2251 | MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)"); |
2517 | 2252 | ||
2518 | module_param(viafb_refresh, int, 0); | 2253 | module_param(viafb_refresh, int, S_IRUSR); |
2519 | MODULE_PARM_DESC(viafb_refresh, | 2254 | MODULE_PARM_DESC(viafb_refresh, |
2520 | "Set CRT viafb_refresh rate (default = 60)"); | 2255 | "Set CRT viafb_refresh rate (default = 60)"); |
2521 | 2256 | ||
2522 | module_param(viafb_refresh1, int, 0); | 2257 | module_param(viafb_refresh1, int, S_IRUSR); |
2523 | MODULE_PARM_DESC(viafb_refresh1, | 2258 | MODULE_PARM_DESC(viafb_refresh1, |
2524 | "Set CRT refresh rate (default = 60)"); | 2259 | "Set CRT refresh rate (default = 60)"); |
2525 | 2260 | ||
2526 | module_param(viafb_lcd_panel_id, int, 0); | 2261 | module_param(viafb_lcd_panel_id, int, S_IRUSR); |
2527 | MODULE_PARM_DESC(viafb_lcd_panel_id, | 2262 | MODULE_PARM_DESC(viafb_lcd_panel_id, |
2528 | "Set Flat Panel type(Default=1024x768)"); | 2263 | "Set Flat Panel type(Default=1024x768)"); |
2529 | 2264 | ||
2530 | module_param(viafb_lcd_dsp_method, int, 0); | 2265 | module_param(viafb_lcd_dsp_method, int, S_IRUSR); |
2531 | MODULE_PARM_DESC(viafb_lcd_dsp_method, | 2266 | MODULE_PARM_DESC(viafb_lcd_dsp_method, |
2532 | "Set Flat Panel display scaling method.(Default=Expandsion)"); | 2267 | "Set Flat Panel display scaling method.(Default=Expandsion)"); |
2533 | 2268 | ||
2534 | module_param(viafb_SAMM_ON, int, 0); | 2269 | module_param(viafb_SAMM_ON, int, S_IRUSR); |
2535 | MODULE_PARM_DESC(viafb_SAMM_ON, | 2270 | MODULE_PARM_DESC(viafb_SAMM_ON, |
2536 | "Turn on/off flag of SAMM(Default=OFF)"); | 2271 | "Turn on/off flag of SAMM(Default=OFF)"); |
2537 | 2272 | ||
2538 | module_param(viafb_accel, int, 0); | 2273 | module_param(viafb_accel, int, S_IRUSR); |
2539 | MODULE_PARM_DESC(viafb_accel, | 2274 | MODULE_PARM_DESC(viafb_accel, |
2540 | "Set 2D Hardware Acceleration.(Default = OFF)"); | 2275 | "Set 2D Hardware Acceleration: 0 = OFF, 1 = ON (default)"); |
2541 | 2276 | ||
2542 | module_param(viafb_active_dev, charp, 0); | 2277 | module_param(viafb_active_dev, charp, S_IRUSR); |
2543 | MODULE_PARM_DESC(viafb_active_dev, "Specify active devices."); | 2278 | MODULE_PARM_DESC(viafb_active_dev, "Specify active devices."); |
2544 | 2279 | ||
2545 | module_param(viafb_display_hardware_layout, int, 0); | 2280 | module_param(viafb_display_hardware_layout, int, S_IRUSR); |
2546 | MODULE_PARM_DESC(viafb_display_hardware_layout, | 2281 | MODULE_PARM_DESC(viafb_display_hardware_layout, |
2547 | "Display Hardware Layout (LCD Only, DVI Only...,etc)"); | 2282 | "Display Hardware Layout (LCD Only, DVI Only...,etc)"); |
2548 | 2283 | ||
2549 | module_param(viafb_second_size, int, 0); | 2284 | module_param(viafb_second_size, int, S_IRUSR); |
2550 | MODULE_PARM_DESC(viafb_second_size, | 2285 | MODULE_PARM_DESC(viafb_second_size, |
2551 | "Set secondary device memory size"); | 2286 | "Set secondary device memory size"); |
2552 | 2287 | ||
2553 | module_param(viafb_dual_fb, int, 0); | 2288 | module_param(viafb_dual_fb, int, S_IRUSR); |
2554 | MODULE_PARM_DESC(viafb_dual_fb, | 2289 | MODULE_PARM_DESC(viafb_dual_fb, |
2555 | "Turn on/off flag of dual framebuffer devices.(Default = OFF)"); | 2290 | "Turn on/off flag of dual framebuffer devices.(Default = OFF)"); |
2556 | 2291 | ||
2557 | module_param(viafb_platform_epia_dvi, int, 0); | 2292 | module_param(viafb_platform_epia_dvi, int, S_IRUSR); |
2558 | MODULE_PARM_DESC(viafb_platform_epia_dvi, | 2293 | MODULE_PARM_DESC(viafb_platform_epia_dvi, |
2559 | "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)"); | 2294 | "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)"); |
2560 | 2295 | ||
2561 | module_param(viafb_device_lcd_dualedge, int, 0); | 2296 | module_param(viafb_device_lcd_dualedge, int, S_IRUSR); |
2562 | MODULE_PARM_DESC(viafb_device_lcd_dualedge, | 2297 | MODULE_PARM_DESC(viafb_device_lcd_dualedge, |
2563 | "Turn on/off flag of dual edge panel.(Default = OFF)"); | 2298 | "Turn on/off flag of dual edge panel.(Default = OFF)"); |
2564 | 2299 | ||
2565 | module_param(viafb_bus_width, int, 0); | 2300 | module_param(viafb_bus_width, int, S_IRUSR); |
2566 | MODULE_PARM_DESC(viafb_bus_width, | 2301 | MODULE_PARM_DESC(viafb_bus_width, |
2567 | "Set bus width of panel.(Default = 12)"); | 2302 | "Set bus width of panel.(Default = 12)"); |
2568 | 2303 | ||
2569 | module_param(viafb_lcd_mode, int, 0); | 2304 | module_param(viafb_lcd_mode, int, S_IRUSR); |
2570 | MODULE_PARM_DESC(viafb_lcd_mode, | 2305 | MODULE_PARM_DESC(viafb_lcd_mode, |
2571 | "Set Flat Panel mode(Default=OPENLDI)"); | 2306 | "Set Flat Panel mode(Default=OPENLDI)"); |
2572 | 2307 | ||
2573 | module_param(viafb_video_dev, charp, 0); | 2308 | module_param(viafb_lcd_port, charp, S_IRUSR); |
2574 | MODULE_PARM_DESC(viafb_video_dev, "Specify video devices."); | ||
2575 | |||
2576 | module_param(viafb_lcd_port, charp, 0); | ||
2577 | MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port."); | 2309 | MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port."); |
2578 | 2310 | ||
2579 | module_param(viafb_dvi_port, charp, 0); | 2311 | module_param(viafb_dvi_port, charp, S_IRUSR); |
2580 | MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port."); | 2312 | MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port."); |
2581 | 2313 | ||
2582 | MODULE_LICENSE("GPL"); | 2314 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index a4158e872878..0c94d2441922 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
@@ -37,52 +37,50 @@ | |||
37 | #define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ | 37 | #define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ |
38 | #define VERSION_MINOR 4 | 38 | #define VERSION_MINOR 4 |
39 | 39 | ||
40 | struct viafb_shared { | ||
41 | struct proc_dir_entry *proc_entry; /*viafb proc entry */ | ||
42 | |||
43 | /* I2C stuff */ | ||
44 | struct via_i2c_stuff i2c_stuff; | ||
45 | |||
46 | /* All the information will be needed to set engine */ | ||
47 | struct tmds_setting_information tmds_setting_info; | ||
48 | struct crt_setting_information crt_setting_info; | ||
49 | struct lvds_setting_information lvds_setting_info; | ||
50 | struct lvds_setting_information lvds_setting_info2; | ||
51 | struct chip_information chip_info; | ||
52 | |||
53 | /* hardware acceleration stuff */ | ||
54 | void __iomem *engine_mmio; | ||
55 | u32 cursor_vram_addr; | ||
56 | u32 vq_vram_addr; /* virtual queue address in video ram */ | ||
57 | int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height, | ||
58 | u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, | ||
59 | u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, | ||
60 | u32 fg_color, u32 bg_color, u8 fill_rop); | ||
61 | }; | ||
62 | |||
40 | struct viafb_par { | 63 | struct viafb_par { |
41 | int bpp; | 64 | u8 depth; |
42 | int hres; | 65 | u32 vram_addr; |
43 | int vres; | 66 | |
44 | int linelength; | ||
45 | u32 xoffset; | ||
46 | u32 yoffset; | ||
47 | |||
48 | void __iomem *fbmem_virt; /*framebuffer virtual memory address */ | ||
49 | void __iomem *io_virt; /*iospace virtual memory address */ | ||
50 | unsigned int fbmem; /*framebuffer physical memory address */ | 67 | unsigned int fbmem; /*framebuffer physical memory address */ |
51 | unsigned int memsize; /*size of fbmem */ | 68 | unsigned int memsize; /*size of fbmem */ |
52 | unsigned int io; /*io space address */ | ||
53 | unsigned long mmio_base; /*mmio base address */ | ||
54 | unsigned long mmio_len; /*mmio base length */ | ||
55 | u32 fbmem_free; /* Free FB memory */ | 69 | u32 fbmem_free; /* Free FB memory */ |
56 | u32 fbmem_used; /* Use FB memory size */ | 70 | u32 fbmem_used; /* Use FB memory size */ |
57 | u32 cursor_start; /* Cursor Start Address */ | ||
58 | u32 VQ_start; /* Virtual Queue Start Address */ | ||
59 | u32 VQ_end; /* Virtual Queue End Address */ | ||
60 | u32 iga_path; | 71 | u32 iga_path; |
61 | struct proc_dir_entry *proc_entry; /*viafb proc entry */ | ||
62 | u8 duoview; /*Is working in duoview mode? */ | ||
63 | 72 | ||
64 | /* I2C stuff */ | 73 | struct viafb_shared *shared; |
65 | struct via_i2c_stuff i2c_stuff; | ||
66 | 74 | ||
67 | /* All the information will be needed to set engine */ | 75 | /* All the information will be needed to set engine */ |
76 | /* depreciated, use the ones in shared directly */ | ||
68 | struct tmds_setting_information *tmds_setting_info; | 77 | struct tmds_setting_information *tmds_setting_info; |
69 | struct crt_setting_information *crt_setting_info; | 78 | struct crt_setting_information *crt_setting_info; |
70 | struct lvds_setting_information *lvds_setting_info; | 79 | struct lvds_setting_information *lvds_setting_info; |
71 | struct lvds_setting_information *lvds_setting_info2; | 80 | struct lvds_setting_information *lvds_setting_info2; |
72 | struct chip_information *chip_info; | 81 | struct chip_information *chip_info; |
73 | |||
74 | /* some information related to video playing */ | ||
75 | int video_on_crt; | ||
76 | int video_on_dvi; | ||
77 | int video_on_lcd; | ||
78 | |||
79 | }; | ||
80 | struct viafb_modeinfo { | ||
81 | u32 xres; | ||
82 | u32 yres; | ||
83 | int mode_index; | ||
84 | char *mode_res; | ||
85 | }; | 82 | }; |
83 | |||
86 | extern unsigned int viafb_second_virtual_yres; | 84 | extern unsigned int viafb_second_virtual_yres; |
87 | extern unsigned int viafb_second_virtual_xres; | 85 | extern unsigned int viafb_second_virtual_xres; |
88 | extern unsigned int viafb_second_offset; | 86 | extern unsigned int viafb_second_offset; |
@@ -92,17 +90,15 @@ extern int viafb_dual_fb; | |||
92 | extern int viafb_LCD2_ON; | 90 | extern int viafb_LCD2_ON; |
93 | extern int viafb_LCD_ON; | 91 | extern int viafb_LCD_ON; |
94 | extern int viafb_DVI_ON; | 92 | extern int viafb_DVI_ON; |
95 | extern int viafb_accel; | ||
96 | extern int viafb_hotplug; | 93 | extern int viafb_hotplug; |
97 | extern int viafb_memsize; | 94 | extern int viafb_memsize; |
98 | 95 | ||
99 | extern int strict_strtoul(const char *cp, unsigned int base, | 96 | extern int strict_strtoul(const char *cp, unsigned int base, |
100 | unsigned long *res); | 97 | unsigned long *res); |
101 | 98 | ||
102 | void viafb_memory_pitch_patch(struct fb_info *info); | ||
103 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | 99 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, |
104 | int mode_index); | 100 | int mode_index); |
105 | int viafb_get_mode_index(int hres, int vres, int flag); | 101 | int viafb_get_mode_index(int hres, int vres); |
106 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | 102 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information |
107 | *plvds_setting_info, struct lvds_chip_information | 103 | *plvds_setting_info, struct lvds_chip_information |
108 | *plvds_chip_info, u8 index); | 104 | *plvds_chip_info, u8 index); |
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index 6dcf583a837d..b74f8a67923c 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c | |||
@@ -100,12 +100,8 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | |||
100 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ | 100 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ |
101 | {VIACR, CR32, 0xFF, 0x00}, | 101 | {VIACR, CR32, 0xFF, 0x00}, |
102 | {VIACR, CR33, 0xFF, 0x00}, | 102 | {VIACR, CR33, 0xFF, 0x00}, |
103 | {VIACR, CR34, 0xFF, 0x00}, | ||
104 | {VIACR, CR35, 0xFF, 0x00}, | 103 | {VIACR, CR35, 0xFF, 0x00}, |
105 | {VIACR, CR36, 0x08, 0x00}, | 104 | {VIACR, CR36, 0x08, 0x00}, |
106 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
107 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
108 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
109 | {VIACR, CR69, 0xFF, 0x00}, | 105 | {VIACR, CR69, 0xFF, 0x00}, |
110 | {VIACR, CR6A, 0xFF, 0x40}, | 106 | {VIACR, CR6A, 0xFF, 0x40}, |
111 | {VIACR, CR6B, 0xFF, 0x00}, | 107 | {VIACR, CR6B, 0xFF, 0x00}, |
@@ -159,16 +155,12 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | |||
159 | {VIASR, CR30, 0xFF, 0x04}, | 155 | {VIASR, CR30, 0xFF, 0x04}, |
160 | {VIACR, CR32, 0xFF, 0x00}, | 156 | {VIACR, CR32, 0xFF, 0x00}, |
161 | {VIACR, CR33, 0x7F, 0x00}, | 157 | {VIACR, CR33, 0x7F, 0x00}, |
162 | {VIACR, CR34, 0xFF, 0x00}, | ||
163 | {VIACR, CR35, 0xFF, 0x00}, | 158 | {VIACR, CR35, 0xFF, 0x00}, |
164 | {VIACR, CR36, 0xFF, 0x31}, | 159 | {VIACR, CR36, 0xFF, 0x31}, |
165 | {VIACR, CR41, 0xFF, 0x80}, | 160 | {VIACR, CR41, 0xFF, 0x80}, |
166 | {VIACR, CR42, 0xFF, 0x00}, | 161 | {VIACR, CR42, 0xFF, 0x00}, |
167 | {VIACR, CR55, 0x80, 0x00}, | 162 | {VIACR, CR55, 0x80, 0x00}, |
168 | {VIACR, CR5D, 0x80, 0x00}, /*Horizontal Retrace Start bit[11] should be 0*/ | 163 | {VIACR, CR5D, 0x80, 0x00}, /*Horizontal Retrace Start bit[11] should be 0*/ |
169 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
170 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
171 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
172 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ | 164 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ |
173 | {VIACR, CR69, 0xFF, 0x00}, | 165 | {VIACR, CR69, 0xFF, 0x00}, |
174 | {VIACR, CR6A, 0xFD, 0x40}, | 166 | {VIACR, CR6A, 0xFD, 0x40}, |
@@ -233,9 +225,6 @@ struct io_reg KM400_ModeXregs[] = { | |||
233 | {VIACR, CR55, 0x80, 0x00}, | 225 | {VIACR, CR55, 0x80, 0x00}, |
234 | {VIACR, CR5D, 0x80, 0x00}, | 226 | {VIACR, CR5D, 0x80, 0x00}, |
235 | {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */ | 227 | {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */ |
236 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
237 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
238 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
239 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ | 228 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ |
240 | {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */ | 229 | {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */ |
241 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | 230 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ |
@@ -285,14 +274,9 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | |||
285 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ | 274 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ |
286 | {VIACR, CR32, 0xFF, 0x00}, | 275 | {VIACR, CR32, 0xFF, 0x00}, |
287 | {VIACR, CR33, 0xFF, 0x00}, | 276 | {VIACR, CR33, 0xFF, 0x00}, |
288 | {VIACR, CR34, 0xFF, 0x00}, | ||
289 | {VIACR, CR35, 0xFF, 0x00}, | 277 | {VIACR, CR35, 0xFF, 0x00}, |
290 | {VIACR, CR36, 0x08, 0x00}, | 278 | {VIACR, CR36, 0x08, 0x00}, |
291 | {VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */ | 279 | {VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */ |
292 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
293 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
294 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
295 | {VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
296 | {VIACR, CR69, 0xFF, 0x00}, | 280 | {VIACR, CR69, 0xFF, 0x00}, |
297 | {VIACR, CR6A, 0xFF, 0x40}, | 281 | {VIACR, CR6A, 0xFF, 0x40}, |
298 | {VIACR, CR6B, 0xFF, 0x00}, | 282 | {VIACR, CR6B, 0xFF, 0x00}, |
@@ -325,69 +309,61 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | |||
325 | {VIACR, CR96, 0xFF, 0x00}, | 309 | {VIACR, CR96, 0xFF, 0x00}, |
326 | {VIACR, CR97, 0xFF, 0x00}, | 310 | {VIACR, CR97, 0xFF, 0x00}, |
327 | {VIACR, CR99, 0xFF, 0x00}, | 311 | {VIACR, CR99, 0xFF, 0x00}, |
328 | {VIACR, CR9B, 0xFF, 0x00}, | 312 | {VIACR, CR9B, 0xFF, 0x00} |
329 | {VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */ | ||
330 | }; | 313 | }; |
331 | 314 | ||
332 | /* For VT3353: Common Setting for Video Mode */ | 315 | struct io_reg VX855_ModeXregs[] = { |
333 | struct io_reg VX800_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | 316 | {VIASR, SR10, 0xFF, 0x01}, |
334 | {VIASR, SR15, 0x02, 0x02}, | 317 | {VIASR, SR15, 0x02, 0x02}, |
335 | {VIASR, SR16, 0xBF, 0x08}, | 318 | {VIASR, SR16, 0xBF, 0x08}, |
336 | {VIASR, SR17, 0xFF, 0x1F}, | 319 | {VIASR, SR17, 0xFF, 0x1F}, |
337 | {VIASR, SR18, 0xFF, 0x4E}, | 320 | {VIASR, SR18, 0xFF, 0x4E}, |
338 | {VIASR, SR1A, 0xFB, 0x08}, | 321 | {VIASR, SR1A, 0xFB, 0x08}, |
339 | {VIASR, SR1B, 0xFF, 0xF0}, | 322 | {VIASR, SR1B, 0xFF, 0xF0}, |
340 | {VIASR, SR1E, 0xFF, 0x01}, | 323 | {VIASR, SR1E, 0x07, 0x01}, |
341 | {VIASR, SR2A, 0xFF, 0x00}, | 324 | {VIASR, SR2A, 0xF0, 0x00}, |
325 | {VIASR, SR58, 0xFF, 0x00}, | ||
326 | {VIASR, SR59, 0xFF, 0x00}, | ||
342 | {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ | 327 | {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ |
328 | {VIACR, CR09, 0xFF, 0x00}, /* Initial CR09=0*/ | ||
329 | {VIACR, CR11, 0x8F, 0x00}, /* IGA1 initial Vertical end */ | ||
330 | {VIACR, CR17, 0x7F, 0x00}, /* IGA1 CRT Mode control init */ | ||
343 | {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ | 331 | {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ |
344 | {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ | 332 | {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ |
345 | {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ | 333 | {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ |
346 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ | 334 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ |
347 | {VIACR, CR32, 0xFF, 0x00}, | 335 | {VIACR, CR32, 0xFF, 0x00}, |
348 | {VIACR, CR33, 0xFF, 0x00}, | 336 | {VIACR, CR33, 0x7F, 0x00}, |
349 | {VIACR, CR34, 0xFF, 0x00}, | ||
350 | {VIACR, CR35, 0xFF, 0x00}, | 337 | {VIACR, CR35, 0xFF, 0x00}, |
351 | {VIACR, CR36, 0x08, 0x00}, | 338 | {VIACR, CR36, 0x08, 0x00}, |
352 | {VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */ | ||
353 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
354 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
355 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
356 | {VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
357 | {VIACR, CR69, 0xFF, 0x00}, | 339 | {VIACR, CR69, 0xFF, 0x00}, |
358 | {VIACR, CR6A, 0xFF, 0x40}, | 340 | {VIACR, CR6A, 0xFD, 0x60}, |
359 | {VIACR, CR6B, 0xFF, 0x00}, | 341 | {VIACR, CR6B, 0xFF, 0x00}, |
360 | {VIACR, CR6C, 0xFF, 0x00}, | 342 | {VIACR, CR6C, 0xFF, 0x00}, |
361 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | 343 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ |
362 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | 344 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ |
363 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | 345 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ |
364 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | 346 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ |
365 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | 347 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ |
366 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | 348 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ |
367 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | 349 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ |
368 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | 350 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ |
369 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | 351 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ |
370 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | 352 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ |
371 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | 353 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ |
372 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | 354 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ |
373 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | 355 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ |
374 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | 356 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ |
375 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | 357 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ |
376 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | 358 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ |
377 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | 359 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ |
378 | {VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */ | 360 | {VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */ |
379 | {VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */ | 361 | {VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */ |
380 | {VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */ | ||
381 | {VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */ | ||
382 | {VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */ | ||
383 | {VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */ | ||
384 | {VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */ | ||
385 | {VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */ | ||
386 | {VIACR, CR96, 0xFF, 0x00}, | 362 | {VIACR, CR96, 0xFF, 0x00}, |
387 | {VIACR, CR97, 0xFF, 0x00}, | 363 | {VIACR, CR97, 0xFF, 0x00}, |
388 | {VIACR, CR99, 0xFF, 0x00}, | 364 | {VIACR, CR99, 0xFF, 0x00}, |
389 | {VIACR, CR9B, 0xFF, 0x00}, | 365 | {VIACR, CR9B, 0xFF, 0x00}, |
390 | {VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */ | 366 | {VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */ |
391 | }; | 367 | }; |
392 | 368 | ||
393 | /* Video Mode Table */ | 369 | /* Video Mode Table */ |
@@ -401,7 +377,6 @@ struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00}, | |||
401 | {VIASR, SR1A, 0xFB, 0x08}, | 377 | {VIASR, SR1A, 0xFB, 0x08}, |
402 | 378 | ||
403 | {VIACR, CR32, 0xFF, 0x00}, | 379 | {VIACR, CR32, 0xFF, 0x00}, |
404 | {VIACR, CR34, 0xFF, 0x00}, | ||
405 | {VIACR, CR35, 0xFF, 0x00}, | 380 | {VIACR, CR35, 0xFF, 0x00}, |
406 | {VIACR, CR36, 0x08, 0x00}, | 381 | {VIACR, CR36, 0x08, 0x00}, |
407 | {VIACR, CR6A, 0xFF, 0x80}, | 382 | {VIACR, CR6A, 0xFF, 0x80}, |
@@ -1084,3 +1059,14 @@ struct VideoModeTable CEA_HDMI_Modes[] = { | |||
1084 | {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, | 1059 | {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, |
1085 | {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} | 1060 | {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} |
1086 | }; | 1061 | }; |
1062 | |||
1063 | int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl); | ||
1064 | int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes); | ||
1065 | int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs); | ||
1066 | int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs); | ||
1067 | int NUM_TOTAL_KM400_ModeXregs = ARRAY_SIZE(KM400_ModeXregs); | ||
1068 | int NUM_TOTAL_CX700_ModeXregs = ARRAY_SIZE(CX700_ModeXregs); | ||
1069 | int NUM_TOTAL_VX855_ModeXregs = ARRAY_SIZE(VX855_ModeXregs); | ||
1070 | int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs); | ||
1071 | int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table); | ||
1072 | int NUM_TOTAL_MODETABLE = ARRAY_SIZE(CLE266Modes); | ||
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h index 1a5de50a23a2..a9d6554fabdf 100644 --- a/drivers/video/via/viamode.h +++ b/drivers/video/via/viamode.h | |||
@@ -50,128 +50,35 @@ struct res_map_refresh { | |||
50 | int vmode_refresh; | 50 | int vmode_refresh; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | #define NUM_TOTAL_RES_MAP_REFRESH ARRAY_SIZE(res_map_refresh_tbl) | 53 | extern int NUM_TOTAL_RES_MAP_REFRESH; |
54 | #define NUM_TOTAL_CEA_MODES ARRAY_SIZE(CEA_HDMI_Modes) | 54 | extern int NUM_TOTAL_CEA_MODES; |
55 | #define NUM_TOTAL_CN400_ModeXregs ARRAY_SIZE(CN400_ModeXregs) | 55 | extern int NUM_TOTAL_CN400_ModeXregs; |
56 | #define NUM_TOTAL_CN700_ModeXregs ARRAY_SIZE(CN700_ModeXregs) | 56 | extern int NUM_TOTAL_CN700_ModeXregs; |
57 | #define NUM_TOTAL_KM400_ModeXregs ARRAY_SIZE(KM400_ModeXregs) | 57 | extern int NUM_TOTAL_KM400_ModeXregs; |
58 | #define NUM_TOTAL_CX700_ModeXregs ARRAY_SIZE(CX700_ModeXregs) | 58 | extern int NUM_TOTAL_CX700_ModeXregs; |
59 | #define NUM_TOTAL_VX800_ModeXregs ARRAY_SIZE(VX800_ModeXregs) | 59 | extern int NUM_TOTAL_VX855_ModeXregs; |
60 | #define NUM_TOTAL_CLE266_ModeXregs ARRAY_SIZE(CLE266_ModeXregs) | 60 | extern int NUM_TOTAL_CLE266_ModeXregs; |
61 | #define NUM_TOTAL_PATCH_MODE ARRAY_SIZE(res_patch_table) | 61 | extern int NUM_TOTAL_PATCH_MODE; |
62 | #define NUM_TOTAL_MODETABLE ARRAY_SIZE(CLE266Modes) | 62 | extern int NUM_TOTAL_MODETABLE; |
63 | 63 | ||
64 | /********************/ | 64 | /********************/ |
65 | /* Mode Table */ | 65 | /* Mode Table */ |
66 | /********************/ | 66 | /********************/ |
67 | 67 | ||
68 | /* 480x640 */ | 68 | extern struct VideoModeTable CLE266Modes[]; |
69 | extern struct crt_mode_table CRTM480x640[1]; | 69 | extern struct crt_mode_table CEAM1280x720[]; |
70 | /* 640x480*/ | 70 | extern struct crt_mode_table CEAM1920x1080[]; |
71 | extern struct crt_mode_table CRTM640x480[5]; | 71 | extern struct VideoModeTable CEA_HDMI_Modes[]; |
72 | /*720x480 (GTF)*/ | ||
73 | extern struct crt_mode_table CRTM720x480[1]; | ||
74 | /*720x576 (GTF)*/ | ||
75 | extern struct crt_mode_table CRTM720x576[1]; | ||
76 | /* 800x480 (CVT) */ | ||
77 | extern struct crt_mode_table CRTM800x480[1]; | ||
78 | /* 800x600*/ | ||
79 | extern struct crt_mode_table CRTM800x600[5]; | ||
80 | /* 848x480 (CVT) */ | ||
81 | extern struct crt_mode_table CRTM848x480[1]; | ||
82 | /*856x480 (GTF) convert to 852x480*/ | ||
83 | extern struct crt_mode_table CRTM852x480[1]; | ||
84 | /*1024x512 (GTF)*/ | ||
85 | extern struct crt_mode_table CRTM1024x512[1]; | ||
86 | /* 1024x600*/ | ||
87 | extern struct crt_mode_table CRTM1024x600[1]; | ||
88 | /* 1024x768*/ | ||
89 | extern struct crt_mode_table CRTM1024x768[4]; | ||
90 | /* 1152x864*/ | ||
91 | extern struct crt_mode_table CRTM1152x864[1]; | ||
92 | /* 1280x720 (HDMI 720P)*/ | ||
93 | extern struct crt_mode_table CRTM1280x720[2]; | ||
94 | /*1280x768 (GTF)*/ | ||
95 | extern struct crt_mode_table CRTM1280x768[2]; | ||
96 | /* 1280x800 (CVT) */ | ||
97 | extern struct crt_mode_table CRTM1280x800[1]; | ||
98 | /*1280x960*/ | ||
99 | extern struct crt_mode_table CRTM1280x960[1]; | ||
100 | /* 1280x1024*/ | ||
101 | extern struct crt_mode_table CRTM1280x1024[3]; | ||
102 | /* 1368x768 (GTF) */ | ||
103 | extern struct crt_mode_table CRTM1368x768[1]; | ||
104 | /*1440x1050 (GTF)*/ | ||
105 | extern struct crt_mode_table CRTM1440x1050[1]; | ||
106 | /* 1600x1200*/ | ||
107 | extern struct crt_mode_table CRTM1600x1200[2]; | ||
108 | /* 1680x1050 (CVT) */ | ||
109 | extern struct crt_mode_table CRTM1680x1050[2]; | ||
110 | /* 1680x1050 (CVT Reduce Blanking) */ | ||
111 | extern struct crt_mode_table CRTM1680x1050_RB[1]; | ||
112 | /* 1920x1080 (CVT)*/ | ||
113 | extern struct crt_mode_table CRTM1920x1080[1]; | ||
114 | /* 1920x1080 (CVT with Reduce Blanking) */ | ||
115 | extern struct crt_mode_table CRTM1920x1080_RB[1]; | ||
116 | /* 1920x1440*/ | ||
117 | extern struct crt_mode_table CRTM1920x1440[2]; | ||
118 | /* 1400x1050 (CVT) */ | ||
119 | extern struct crt_mode_table CRTM1400x1050[2]; | ||
120 | /* 1400x1050 (CVT Reduce Blanking) */ | ||
121 | extern struct crt_mode_table CRTM1400x1050_RB[1]; | ||
122 | /* 960x600 (CVT) */ | ||
123 | extern struct crt_mode_table CRTM960x600[1]; | ||
124 | /* 1000x600 (GTF) */ | ||
125 | extern struct crt_mode_table CRTM1000x600[1]; | ||
126 | /* 1024x576 (GTF) */ | ||
127 | extern struct crt_mode_table CRTM1024x576[1]; | ||
128 | /* 1088x612 (CVT) */ | ||
129 | extern struct crt_mode_table CRTM1088x612[1]; | ||
130 | /* 1152x720 (CVT) */ | ||
131 | extern struct crt_mode_table CRTM1152x720[1]; | ||
132 | /* 1200x720 (GTF) */ | ||
133 | extern struct crt_mode_table CRTM1200x720[1]; | ||
134 | /* 1280x600 (GTF) */ | ||
135 | extern struct crt_mode_table CRTM1280x600[1]; | ||
136 | /* 1360x768 (CVT) */ | ||
137 | extern struct crt_mode_table CRTM1360x768[1]; | ||
138 | /* 1360x768 (CVT Reduce Blanking) */ | ||
139 | extern struct crt_mode_table CRTM1360x768_RB[1]; | ||
140 | /* 1366x768 (GTF) */ | ||
141 | extern struct crt_mode_table CRTM1366x768[2]; | ||
142 | /* 1440x900 (CVT) */ | ||
143 | extern struct crt_mode_table CRTM1440x900[2]; | ||
144 | /* 1440x900 (CVT Reduce Blanking) */ | ||
145 | extern struct crt_mode_table CRTM1440x900_RB[1]; | ||
146 | /* 1600x900 (CVT) */ | ||
147 | extern struct crt_mode_table CRTM1600x900[1]; | ||
148 | /* 1600x900 (CVT Reduce Blanking) */ | ||
149 | extern struct crt_mode_table CRTM1600x900_RB[1]; | ||
150 | /* 1600x1024 (GTF) */ | ||
151 | extern struct crt_mode_table CRTM1600x1024[1]; | ||
152 | /* 1792x1344 (DMT) */ | ||
153 | extern struct crt_mode_table CRTM1792x1344[1]; | ||
154 | /* 1856x1392 (DMT) */ | ||
155 | extern struct crt_mode_table CRTM1856x1392[1]; | ||
156 | /* 1920x1200 (CVT) */ | ||
157 | extern struct crt_mode_table CRTM1920x1200[1]; | ||
158 | /* 1920x1200 (CVT with Reduce Blanking) */ | ||
159 | extern struct crt_mode_table CRTM1920x1200_RB[1]; | ||
160 | /* 2048x1536 (CVT) */ | ||
161 | extern struct crt_mode_table CRTM2048x1536[1]; | ||
162 | extern struct VideoModeTable CLE266Modes[47]; | ||
163 | extern struct crt_mode_table CEAM1280x720[1]; | ||
164 | extern struct crt_mode_table CEAM1920x1080[1]; | ||
165 | extern struct VideoModeTable CEA_HDMI_Modes[2]; | ||
166 | 72 | ||
167 | extern struct res_map_refresh res_map_refresh_tbl[61]; | 73 | extern struct res_map_refresh res_map_refresh_tbl[]; |
168 | extern struct io_reg CN400_ModeXregs[52]; | 74 | extern struct io_reg CN400_ModeXregs[]; |
169 | extern struct io_reg CN700_ModeXregs[66]; | 75 | extern struct io_reg CN700_ModeXregs[]; |
170 | extern struct io_reg KM400_ModeXregs[55]; | 76 | extern struct io_reg KM400_ModeXregs[]; |
171 | extern struct io_reg CX700_ModeXregs[58]; | 77 | extern struct io_reg CX700_ModeXregs[]; |
172 | extern struct io_reg VX800_ModeXregs[58]; | 78 | extern struct io_reg VX800_ModeXregs[]; |
173 | extern struct io_reg CLE266_ModeXregs[32]; | 79 | extern struct io_reg VX855_ModeXregs[]; |
174 | extern struct io_reg PM1024x768[2]; | 80 | extern struct io_reg CLE266_ModeXregs[]; |
175 | extern struct patch_table res_patch_table[1]; | 81 | extern struct io_reg PM1024x768[]; |
82 | extern struct patch_table res_patch_table[]; | ||
176 | extern struct VPITTable VPIT; | 83 | extern struct VPITTable VPIT; |
177 | #endif /* __VIAMODE_H__ */ | 84 | #endif /* __VIAMODE_H__ */ |
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index 322a9f993550..a6b37494e79a 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c | |||
@@ -27,7 +27,7 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | |||
27 | { | 27 | { |
28 | u8 data; | 28 | u8 data; |
29 | 29 | ||
30 | viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; | 30 | viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; |
31 | viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); | 31 | viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); |
32 | 32 | ||
33 | return data; | 33 | return data; |
@@ -39,7 +39,7 @@ void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information | |||
39 | { | 39 | { |
40 | int index, data; | 40 | int index, data; |
41 | 41 | ||
42 | viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; | 42 | viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; |
43 | 43 | ||
44 | index = io_data.Index; | 44 | index = io_data.Index; |
45 | data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, | 45 | data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, |
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index d0674f1e3f10..2376f688ec8b 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c | |||
@@ -523,6 +523,7 @@ static int w100fb_set_par(struct fb_info *info) | |||
523 | info->fix.ywrapstep = 0; | 523 | info->fix.ywrapstep = 0; |
524 | info->fix.line_length = par->xres * BITS_PER_PIXEL / 8; | 524 | info->fix.line_length = par->xres * BITS_PER_PIXEL / 8; |
525 | 525 | ||
526 | mutex_lock(&info->mm_lock); | ||
526 | if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) { | 527 | if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) { |
527 | par->extmem_active = 1; | 528 | par->extmem_active = 1; |
528 | info->fix.smem_len = par->mach->mem->size+1; | 529 | info->fix.smem_len = par->mach->mem->size+1; |
@@ -530,6 +531,7 @@ static int w100fb_set_par(struct fb_info *info) | |||
530 | par->extmem_active = 0; | 531 | par->extmem_active = 0; |
531 | info->fix.smem_len = MEM_INT_SIZE+1; | 532 | info->fix.smem_len = MEM_INT_SIZE+1; |
532 | } | 533 | } |
534 | mutex_unlock(&info->mm_lock); | ||
533 | 535 | ||
534 | w100fb_activate_var(par); | 536 | w100fb_activate_var(par); |
535 | } | 537 | } |
@@ -746,8 +748,6 @@ int __init w100fb_probe(struct platform_device *pdev) | |||
746 | goto out; | 748 | goto out; |
747 | } | 749 | } |
748 | 750 | ||
749 | w100fb_set_par(info); | ||
750 | |||
751 | if (register_framebuffer(info) < 0) { | 751 | if (register_framebuffer(info) < 0) { |
752 | err = -EINVAL; | 752 | err = -EINVAL; |
753 | goto out; | 753 | goto out; |
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index 15502d5e3641..54cd91610174 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
@@ -454,6 +454,10 @@ static int __devinit xenfb_probe(struct xenbus_device *dev, | |||
454 | 454 | ||
455 | xenfb_init_shared_page(info, fb_info); | 455 | xenfb_init_shared_page(info, fb_info); |
456 | 456 | ||
457 | ret = xenfb_connect_backend(dev, info); | ||
458 | if (ret < 0) | ||
459 | goto error; | ||
460 | |||
457 | ret = register_framebuffer(fb_info); | 461 | ret = register_framebuffer(fb_info); |
458 | if (ret) { | 462 | if (ret) { |
459 | fb_deferred_io_cleanup(fb_info); | 463 | fb_deferred_io_cleanup(fb_info); |
@@ -464,10 +468,6 @@ static int __devinit xenfb_probe(struct xenbus_device *dev, | |||
464 | } | 468 | } |
465 | info->fb_info = fb_info; | 469 | info->fb_info = fb_info; |
466 | 470 | ||
467 | ret = xenfb_connect_backend(dev, info); | ||
468 | if (ret < 0) | ||
469 | goto error; | ||
470 | |||
471 | xenfb_make_preferred_console(); | 471 | xenfb_make_preferred_console(); |
472 | return 0; | 472 | return 0; |
473 | 473 | ||