aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/i810/i810_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/i810/i810_main.c')
-rw-r--r--drivers/video/i810/i810_main.c185
1 files changed, 137 insertions, 48 deletions
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 6db183462b92..7018ffffcbc4 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -92,20 +92,21 @@ static struct pci_driver i810fb_driver = {
92 .resume = i810fb_resume, 92 .resume = i810fb_resume,
93}; 93};
94 94
95static int vram __initdata = 4; 95static char *mode_option __devinitdata = NULL;
96static int bpp __initdata = 8; 96static int vram __devinitdata = 4;
97static int mtrr __initdata = 0; 97static int bpp __devinitdata = 8;
98static int accel __initdata = 0; 98static int mtrr __devinitdata = 0;
99static int hsync1 __initdata = 0; 99static int accel __devinitdata = 0;
100static int hsync2 __initdata = 0; 100static int hsync1 __devinitdata = 0;
101static int vsync1 __initdata = 0; 101static int hsync2 __devinitdata = 0;
102static int vsync2 __initdata = 0; 102static int vsync1 __devinitdata = 0;
103static int xres __initdata = 640; 103static int vsync2 __devinitdata = 0;
104static int yres __initdata = 480; 104static int xres __devinitdata = 640;
105static int vyres __initdata = 0; 105static int yres __devinitdata = 480;
106static int sync __initdata = 0; 106static int vyres __devinitdata = 0;
107static int ext_vga __initdata = 0; 107static int sync __devinitdata = 0;
108static int dcolor __initdata = 0; 108static int ext_vga __devinitdata = 0;
109static int dcolor __devinitdata = 0;
109 110
110/*------------------------------------------------------------*/ 111/*------------------------------------------------------------*/
111 112
@@ -310,6 +311,8 @@ static void i810_hires(u8 __iomem *mmio)
310 val = i810_readb(CR_DATA_CGA, mmio); 311 val = i810_readb(CR_DATA_CGA, mmio);
311 i810_writeb(CR_INDEX_CGA, mmio, CR80); 312 i810_writeb(CR_INDEX_CGA, mmio, CR80);
312 i810_writeb(CR_DATA_CGA, mmio, val | 1); 313 i810_writeb(CR_DATA_CGA, mmio, val | 1);
314 /* Stop LCD displays from flickering */
315 i810_writel(MEM_MODE, mmio, i810_readl(MEM_MODE, mmio) | 4);
313} 316}
314 317
315/** 318/**
@@ -947,31 +950,24 @@ static int i810_check_params(struct fb_var_screeninfo *var,
947 struct fb_info *info) 950 struct fb_info *info)
948{ 951{
949 struct i810fb_par *par = (struct i810fb_par *) info->par; 952 struct i810fb_par *par = (struct i810fb_par *) info->par;
950 int line_length, vidmem; 953 int line_length, vidmem, mode_valid = 0;
951 u32 xres, yres, vxres, vyres; 954 u32 vyres = var->yres_virtual, vxres = var->xres_virtual;
952
953 xres = var->xres;
954 yres = var->yres;
955 vxres = var->xres_virtual;
956 vyres = var->yres_virtual;
957
958 /* 955 /*
959 * Memory limit 956 * Memory limit
960 */ 957 */
961 line_length = get_line_length(par, vxres, 958 line_length = get_line_length(par, vxres, var->bits_per_pixel);
962 var->bits_per_pixel);
963
964 vidmem = line_length*vyres; 959 vidmem = line_length*vyres;
960
965 if (vidmem > par->fb.size) { 961 if (vidmem > par->fb.size) {
966 vyres = par->fb.size/line_length; 962 vyres = par->fb.size/line_length;
967 if (vyres < yres) { 963 if (vyres < var->yres) {
968 vyres = yres; 964 vyres = yres;
969 vxres = par->fb.size/vyres; 965 vxres = par->fb.size/vyres;
970 vxres /= var->bits_per_pixel >> 3; 966 vxres /= var->bits_per_pixel >> 3;
971 line_length = get_line_length(par, vxres, 967 line_length = get_line_length(par, vxres,
972 var->bits_per_pixel); 968 var->bits_per_pixel);
973 vidmem = line_length * yres; 969 vidmem = line_length * yres;
974 if (vxres < xres) { 970 if (vxres < var->xres) {
975 printk("i810fb: required video memory, " 971 printk("i810fb: required video memory, "
976 "%d bytes, for %dx%d-%d (virtual) " 972 "%d bytes, for %dx%d-%d (virtual) "
977 "is out of range\n", 973 "is out of range\n",
@@ -981,6 +977,10 @@ static int i810_check_params(struct fb_var_screeninfo *var,
981 } 977 }
982 } 978 }
983 } 979 }
980
981 var->xres_virtual = vxres;
982 var->yres_virtual = vyres;
983
984 /* 984 /*
985 * Monitor limit 985 * Monitor limit
986 */ 986 */
@@ -996,25 +996,39 @@ static int i810_check_params(struct fb_var_screeninfo *var,
996 info->monspecs.dclkmax = 204000000; 996 info->monspecs.dclkmax = 204000000;
997 break; 997 break;
998 } 998 }
999
999 info->monspecs.dclkmin = 15000000; 1000 info->monspecs.dclkmin = 15000000;
1000 1001
1001 if (fb_validate_mode(var, info)) { 1002 if (!fb_validate_mode(var, info))
1003 mode_valid = 1;
1004
1005#ifdef CONFIG_FB_I810_I2C
1006 if (!mode_valid && info->monspecs.gtf &&
1007 !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1008 mode_valid = 1;
1009
1010 if (!mode_valid && info->monspecs.modedb_len) {
1011 struct fb_videomode *mode;
1012
1013 mode = fb_find_best_mode(var, &info->modelist);
1014 if (mode) {
1015 fb_videomode_to_var(var, mode);
1016 mode_valid = 1;
1017 }
1018 }
1019#endif
1020 if (!mode_valid && info->monspecs.modedb_len == 0) {
1002 if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) { 1021 if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {
1003 int default_sync = (info->monspecs.hfmin-HFMIN) 1022 int default_sync = (info->monspecs.hfmin-HFMIN)
1004 |(info->monspecs.hfmax-HFMAX) 1023 |(info->monspecs.hfmax-HFMAX)
1005 |(info->monspecs.vfmin-VFMIN) 1024 |(info->monspecs.vfmin-VFMIN)
1006 |(info->monspecs.vfmax-VFMAX); 1025 |(info->monspecs.vfmax-VFMAX);
1007 printk("i810fb: invalid video mode%s\n", 1026 printk("i810fb: invalid video mode%s\n",
1008 default_sync ? "" : 1027 default_sync ? "" : ". Specifying "
1009 ". Specifying vsyncN/hsyncN parameters may help"); 1028 "vsyncN/hsyncN parameters may help");
1010 return -EINVAL;
1011 } 1029 }
1012 } 1030 }
1013 1031
1014 var->xres = xres;
1015 var->yres = yres;
1016 var->xres_virtual = vxres;
1017 var->yres_virtual = vyres;
1018 return 0; 1032 return 0;
1019} 1033}
1020 1034
@@ -1375,7 +1389,6 @@ static int i810fb_set_par(struct fb_info *info)
1375 decode_var(&info->var, par); 1389 decode_var(&info->var, par);
1376 i810_load_regs(par); 1390 i810_load_regs(par);
1377 i810_init_cursor(par); 1391 i810_init_cursor(par);
1378
1379 encode_fix(&info->fix, info); 1392 encode_fix(&info->fix, info);
1380 1393
1381 if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) { 1394 if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) {
@@ -1418,9 +1431,8 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1418 struct i810fb_par *par = (struct i810fb_par *)info->par; 1431 struct i810fb_par *par = (struct i810fb_par *)info->par;
1419 u8 __iomem *mmio = par->mmio_start_virtual; 1432 u8 __iomem *mmio = par->mmio_start_virtual;
1420 1433
1421 if (!(par->dev_flags & USE_HWCUR) || !info->var.accel_flags || 1434 if (!par->dev_flags & LOCKUP)
1422 par->dev_flags & LOCKUP) 1435 return -ENXIO;
1423 return soft_cursor(info, cursor);
1424 1436
1425 if (cursor->image.width > 64 || cursor->image.height > 64) 1437 if (cursor->image.width > 64 || cursor->image.height > 64)
1426 return -ENXIO; 1438 return -ENXIO;
@@ -1814,8 +1826,72 @@ i810_allocate_pci_resource(struct i810fb_par *par,
1814 return 0; 1826 return 0;
1815} 1827}
1816 1828
1829static void __devinit i810fb_find_init_mode(struct fb_info *info)
1830{
1831 struct fb_videomode mode;
1832 struct fb_var_screeninfo var;
1833 struct fb_monspecs *specs = NULL;
1834 int found = 0;
1835#ifdef CONFIG_FB_I810_I2C
1836 int i;
1837 int err;
1838 struct i810fb_par *par = info->par;
1839#endif
1840
1841 INIT_LIST_HEAD(&info->modelist);
1842 memset(&mode, 0, sizeof(struct fb_videomode));
1843 var = info->var;
1844#ifdef CONFIG_FB_I810_I2C
1845 i810_create_i2c_busses(par);
1846
1847 for (i = 0; i < 3; i++) {
1848 err = i810_probe_i2c_connector(info, &par->edid, i+1);
1849 if (!err)
1850 break;
1851 }
1852
1853 if (!err)
1854 printk("i810fb_init_pci: DDC probe successful\n");
1855
1856 fb_edid_to_monspecs(par->edid, &info->monspecs);
1857
1858 if (info->monspecs.modedb == NULL)
1859 printk("i810fb_init_pci: Unable to get Mode Database\n");
1860
1861 specs = &info->monspecs;
1862 fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
1863 &info->modelist);
1864 if (specs->modedb != NULL) {
1865 if (specs->misc & FB_MISC_1ST_DETAIL) {
1866 for (i = 0; i < specs->modedb_len; i++) {
1867 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1868 mode = specs->modedb[i];
1869 found = 1;
1870 break;
1871 }
1872 }
1873 }
1874
1875 if (!found) {
1876 mode = specs->modedb[0];
1877 found = 1;
1878 }
1879
1880 fb_videomode_to_var(&var, &mode);
1881 }
1882#endif
1883 if (mode_option)
1884 fb_find_mode(&var, info, mode_option, specs->modedb,
1885 specs->modedb_len, (found) ? &mode : NULL,
1886 info->var.bits_per_pixel);
1887
1888 info->var = var;
1889 fb_destroy_modedb(specs->modedb);
1890 specs->modedb = NULL;
1891}
1892
1817#ifndef MODULE 1893#ifndef MODULE
1818static int __init i810fb_setup(char *options) 1894static int __devinit i810fb_setup(char *options)
1819{ 1895{
1820 char *this_opt, *suffix = NULL; 1896 char *this_opt, *suffix = NULL;
1821 1897
@@ -1857,6 +1933,8 @@ static int __init i810fb_setup(char *options)
1857 vsync2 = simple_strtoul(this_opt+7, NULL, 0); 1933 vsync2 = simple_strtoul(this_opt+7, NULL, 0);
1858 else if (!strncmp(this_opt, "dcolor", 6)) 1934 else if (!strncmp(this_opt, "dcolor", 6))
1859 dcolor = 1; 1935 dcolor = 1;
1936 else
1937 mode_option = this_opt;
1860 } 1938 }
1861 return 0; 1939 return 0;
1862} 1940}
@@ -1867,6 +1945,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1867{ 1945{
1868 struct fb_info *info; 1946 struct fb_info *info;
1869 struct i810fb_par *par = NULL; 1947 struct i810fb_par *par = NULL;
1948 struct fb_videomode mode;
1870 int i, err = -1, vfreq, hfreq, pixclock; 1949 int i, err = -1, vfreq, hfreq, pixclock;
1871 1950
1872 i = 0; 1951 i = 0;
@@ -1875,7 +1954,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1875 if (!info) 1954 if (!info)
1876 return -ENOMEM; 1955 return -ENOMEM;
1877 1956
1878 par = (struct i810fb_par *) info->par; 1957 par = info->par;
1879 par->dev = dev; 1958 par->dev = dev;
1880 1959
1881 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) { 1960 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
@@ -1906,15 +1985,20 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1906 info->fbops = &par->i810fb_ops; 1985 info->fbops = &par->i810fb_ops;
1907 info->pseudo_palette = par->pseudo_palette; 1986 info->pseudo_palette = par->pseudo_palette;
1908 fb_alloc_cmap(&info->cmap, 256, 0); 1987 fb_alloc_cmap(&info->cmap, 256, 0);
1988 i810fb_find_init_mode(info);
1909 1989
1910 if ((err = info->fbops->fb_check_var(&info->var, info))) { 1990 if ((err = info->fbops->fb_check_var(&info->var, info))) {
1911 i810fb_release_resource(info, par); 1991 i810fb_release_resource(info, par);
1912 return err; 1992 return err;
1913 } 1993 }
1994
1995 fb_var_to_videomode(&mode, &info->var);
1996 fb_add_videomode(&mode, &info->modelist);
1914 encode_fix(&info->fix, info); 1997 encode_fix(&info->fix, info);
1915 1998
1916 i810fb_init_ringbuffer(info); 1999 i810fb_init_ringbuffer(info);
1917 err = register_framebuffer(info); 2000 err = register_framebuffer(info);
2001
1918 if (err < 0) { 2002 if (err < 0) {
1919 i810fb_release_resource(info, par); 2003 i810fb_release_resource(info, par);
1920 printk("i810fb_init: cannot register framebuffer device\n"); 2004 printk("i810fb_init: cannot register framebuffer device\n");
@@ -1953,6 +2037,8 @@ static void i810fb_release_resource(struct fb_info *info,
1953 struct gtt_data *gtt = &par->i810_gtt; 2037 struct gtt_data *gtt = &par->i810_gtt;
1954 unset_mtrr(par); 2038 unset_mtrr(par);
1955 2039
2040 i810_delete_i2c_busses(par);
2041
1956 if (par->i810_gtt.i810_cursor_memory) 2042 if (par->i810_gtt.i810_cursor_memory)
1957 agp_free_memory(gtt->i810_cursor_memory); 2043 agp_free_memory(gtt->i810_cursor_memory);
1958 if (par->i810_gtt.i810_fb_memory) 2044 if (par->i810_gtt.i810_fb_memory)
@@ -1962,7 +2048,8 @@ static void i810fb_release_resource(struct fb_info *info,
1962 iounmap(par->mmio_start_virtual); 2048 iounmap(par->mmio_start_virtual);
1963 if (par->aperture.virtual) 2049 if (par->aperture.virtual)
1964 iounmap(par->aperture.virtual); 2050 iounmap(par->aperture.virtual);
1965 2051 if (par->edid)
2052 kfree(par->edid);
1966 if (par->res_flags & FRAMEBUFFER_REQ) 2053 if (par->res_flags & FRAMEBUFFER_REQ)
1967 release_mem_region(par->aperture.physical, 2054 release_mem_region(par->aperture.physical,
1968 par->aperture.size); 2055 par->aperture.size);
@@ -1988,7 +2075,7 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)
1988} 2075}
1989 2076
1990#ifndef MODULE 2077#ifndef MODULE
1991static int __init i810fb_init(void) 2078static int __devinit i810fb_init(void)
1992{ 2079{
1993 char *option = NULL; 2080 char *option = NULL;
1994 2081
@@ -2006,7 +2093,7 @@ static int __init i810fb_init(void)
2006 2093
2007#ifdef MODULE 2094#ifdef MODULE
2008 2095
2009static int __init i810fb_init(void) 2096static int __devinit i810fb_init(void)
2010{ 2097{
2011 hsync1 *= 1000; 2098 hsync1 *= 1000;
2012 hsync2 *= 1000; 2099 hsync2 *= 1000;
@@ -2054,6 +2141,8 @@ MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"
2054module_param(dcolor, bool, 0); 2141module_param(dcolor, bool, 0);
2055MODULE_PARM_DESC(dcolor, "use DirectColor visuals" 2142MODULE_PARM_DESC(dcolor, "use DirectColor visuals"
2056 " (default = 0 = TrueColor)"); 2143 " (default = 0 = TrueColor)");
2144module_param(mode_option, charp, 0);
2145MODULE_PARM_DESC(mode_option, "Specify initial video mode");
2057 2146
2058MODULE_AUTHOR("Tony A. Daplas"); 2147MODULE_AUTHOR("Tony A. Daplas");
2059MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and" 2148MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and"