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.c223
1 files changed, 165 insertions, 58 deletions
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 6db183462b92..0dbc9ddb6766 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;
99static int hsync1 __initdata = 0; 99static int accel __devinitdata;
100static int hsync2 __initdata = 0; 100static int hsync1 __devinitdata;
101static int vsync1 __initdata = 0; 101static int hsync2 __devinitdata;
102static int vsync2 __initdata = 0; 102static int vsync1 __devinitdata;
103static int xres __initdata = 640; 103static int vsync2 __devinitdata;
104static int yres __initdata = 480; 104static int xres __devinitdata;
105static int vyres __initdata = 0; 105static int yres __devinitdata;
106static int sync __initdata = 0; 106static int vyres __devinitdata;
107static int ext_vga __initdata = 0; 107static int sync __devinitdata;
108static int dcolor __initdata = 0; 108static int extvga __devinitdata;
109static int dcolor __devinitdata;
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, retval = 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,26 +996,41 @@ 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; 1029 retval = -EINVAL;
1011 } 1030 }
1012 } 1031 }
1013 1032
1014 var->xres = xres; 1033 return retval;
1015 var->yres = yres;
1016 var->xres_virtual = vxres;
1017 var->yres_virtual = vyres;
1018 return 0;
1019} 1034}
1020 1035
1021/** 1036/**
@@ -1375,7 +1390,6 @@ static int i810fb_set_par(struct fb_info *info)
1375 decode_var(&info->var, par); 1390 decode_var(&info->var, par);
1376 i810_load_regs(par); 1391 i810_load_regs(par);
1377 i810_init_cursor(par); 1392 i810_init_cursor(par);
1378
1379 encode_fix(&info->fix, info); 1393 encode_fix(&info->fix, info);
1380 1394
1381 if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) { 1395 if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) {
@@ -1418,9 +1432,8 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1418 struct i810fb_par *par = (struct i810fb_par *)info->par; 1432 struct i810fb_par *par = (struct i810fb_par *)info->par;
1419 u8 __iomem *mmio = par->mmio_start_virtual; 1433 u8 __iomem *mmio = par->mmio_start_virtual;
1420 1434
1421 if (!(par->dev_flags & USE_HWCUR) || !info->var.accel_flags || 1435 if (!par->dev_flags & LOCKUP)
1422 par->dev_flags & LOCKUP) 1436 return -ENXIO;
1423 return soft_cursor(info, cursor);
1424 1437
1425 if (cursor->image.width > 64 || cursor->image.height > 64) 1438 if (cursor->image.width > 64 || cursor->image.height > 64)
1426 return -ENXIO; 1439 return -ENXIO;
@@ -1712,12 +1725,21 @@ static void __devinit i810_init_defaults(struct i810fb_par *par,
1712 if (bpp < 8) 1725 if (bpp < 8)
1713 bpp = 8; 1726 bpp = 8;
1714 1727
1728 par->i810fb_ops = i810fb_ops;
1729
1730 if (xres)
1731 info->var.xres = xres;
1732 else
1733 info->var.xres = 640;
1734
1735 if (yres)
1736 info->var.yres = yres;
1737 else
1738 info->var.yres = 480;
1739
1715 if (!vyres) 1740 if (!vyres)
1716 vyres = (vram << 20)/(xres*bpp >> 3); 1741 vyres = (vram << 20)/(info->var.xres*bpp >> 3);
1717 1742
1718 par->i810fb_ops = i810fb_ops;
1719 info->var.xres = xres;
1720 info->var.yres = yres;
1721 info->var.yres_virtual = vyres; 1743 info->var.yres_virtual = vyres;
1722 info->var.bits_per_pixel = bpp; 1744 info->var.bits_per_pixel = bpp;
1723 1745
@@ -1744,7 +1766,7 @@ static void __devinit i810_init_device(struct i810fb_par *par)
1744 i810_init_cursor(par); 1766 i810_init_cursor(par);
1745 1767
1746 /* mvo: enable external vga-connector (for laptops) */ 1768 /* mvo: enable external vga-connector (for laptops) */
1747 if (ext_vga) { 1769 if (extvga) {
1748 i810_writel(HVSYNC, mmio, 0); 1770 i810_writel(HVSYNC, mmio, 0);
1749 i810_writel(PWR_CLKC, mmio, 3); 1771 i810_writel(PWR_CLKC, mmio, 3);
1750 } 1772 }
@@ -1814,8 +1836,80 @@ i810_allocate_pci_resource(struct i810fb_par *par,
1814 return 0; 1836 return 0;
1815} 1837}
1816 1838
1839static void __devinit i810fb_find_init_mode(struct fb_info *info)
1840{
1841 struct fb_videomode mode;
1842 struct fb_var_screeninfo var;
1843 struct fb_monspecs *specs = &info->monspecs;
1844 int found = 0;
1845#ifdef CONFIG_FB_I810_I2C
1846 int i;
1847 int err;
1848 struct i810fb_par *par = info->par;
1849#endif
1850
1851 INIT_LIST_HEAD(&info->modelist);
1852 memset(&mode, 0, sizeof(struct fb_videomode));
1853 var = info->var;
1854#ifdef CONFIG_FB_I810_I2C
1855 i810_create_i2c_busses(par);
1856
1857 for (i = 0; i < 3; i++) {
1858 err = i810_probe_i2c_connector(info, &par->edid, i+1);
1859 if (!err)
1860 break;
1861 }
1862
1863 if (!err)
1864 printk("i810fb_init_pci: DDC probe successful\n");
1865
1866 fb_edid_to_monspecs(par->edid, specs);
1867
1868 if (specs->modedb == NULL)
1869 printk("i810fb_init_pci: Unable to get Mode Database\n");
1870
1871 fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
1872 &info->modelist);
1873 if (specs->modedb != NULL) {
1874 if (xres && yres) {
1875 struct fb_videomode *m;
1876
1877 if ((m = fb_find_best_mode(&var, &info->modelist))) {
1878 mode = *m;
1879 found = 1;
1880 }
1881 }
1882
1883 if (!found && specs->misc & FB_MISC_1ST_DETAIL) {
1884 for (i = 0; i < specs->modedb_len; i++) {
1885 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1886 mode = specs->modedb[i];
1887 found = 1;
1888 break;
1889 }
1890 }
1891 }
1892
1893 if (!found) {
1894 mode = specs->modedb[0];
1895 found = 1;
1896 }
1897
1898 fb_videomode_to_var(&var, &mode);
1899 }
1900#endif
1901 if (mode_option)
1902 fb_find_mode(&var, info, mode_option, specs->modedb,
1903 specs->modedb_len, (found) ? &mode : NULL,
1904 info->var.bits_per_pixel);
1905
1906 info->var = var;
1907 fb_destroy_modedb(specs->modedb);
1908 specs->modedb = NULL;
1909}
1910
1817#ifndef MODULE 1911#ifndef MODULE
1818static int __init i810fb_setup(char *options) 1912static int __devinit i810fb_setup(char *options)
1819{ 1913{
1820 char *this_opt, *suffix = NULL; 1914 char *this_opt, *suffix = NULL;
1821 1915
@@ -1827,8 +1921,8 @@ static int __init i810fb_setup(char *options)
1827 mtrr = 1; 1921 mtrr = 1;
1828 else if (!strncmp(this_opt, "accel", 5)) 1922 else if (!strncmp(this_opt, "accel", 5))
1829 accel = 1; 1923 accel = 1;
1830 else if (!strncmp(this_opt, "ext_vga", 7)) 1924 else if (!strncmp(this_opt, "extvga", 6))
1831 ext_vga = 1; 1925 extvga = 1;
1832 else if (!strncmp(this_opt, "sync", 4)) 1926 else if (!strncmp(this_opt, "sync", 4))
1833 sync = 1; 1927 sync = 1;
1834 else if (!strncmp(this_opt, "vram:", 5)) 1928 else if (!strncmp(this_opt, "vram:", 5))
@@ -1857,6 +1951,8 @@ static int __init i810fb_setup(char *options)
1857 vsync2 = simple_strtoul(this_opt+7, NULL, 0); 1951 vsync2 = simple_strtoul(this_opt+7, NULL, 0);
1858 else if (!strncmp(this_opt, "dcolor", 6)) 1952 else if (!strncmp(this_opt, "dcolor", 6))
1859 dcolor = 1; 1953 dcolor = 1;
1954 else
1955 mode_option = this_opt;
1860 } 1956 }
1861 return 0; 1957 return 0;
1862} 1958}
@@ -1867,6 +1963,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1867{ 1963{
1868 struct fb_info *info; 1964 struct fb_info *info;
1869 struct i810fb_par *par = NULL; 1965 struct i810fb_par *par = NULL;
1966 struct fb_videomode mode;
1870 int i, err = -1, vfreq, hfreq, pixclock; 1967 int i, err = -1, vfreq, hfreq, pixclock;
1871 1968
1872 i = 0; 1969 i = 0;
@@ -1875,7 +1972,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1875 if (!info) 1972 if (!info)
1876 return -ENOMEM; 1973 return -ENOMEM;
1877 1974
1878 par = (struct i810fb_par *) info->par; 1975 par = info->par;
1879 par->dev = dev; 1976 par->dev = dev;
1880 1977
1881 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) { 1978 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
@@ -1906,15 +2003,20 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1906 info->fbops = &par->i810fb_ops; 2003 info->fbops = &par->i810fb_ops;
1907 info->pseudo_palette = par->pseudo_palette; 2004 info->pseudo_palette = par->pseudo_palette;
1908 fb_alloc_cmap(&info->cmap, 256, 0); 2005 fb_alloc_cmap(&info->cmap, 256, 0);
2006 i810fb_find_init_mode(info);
1909 2007
1910 if ((err = info->fbops->fb_check_var(&info->var, info))) { 2008 if ((err = info->fbops->fb_check_var(&info->var, info))) {
1911 i810fb_release_resource(info, par); 2009 i810fb_release_resource(info, par);
1912 return err; 2010 return err;
1913 } 2011 }
2012
2013 fb_var_to_videomode(&mode, &info->var);
2014 fb_add_videomode(&mode, &info->modelist);
1914 encode_fix(&info->fix, info); 2015 encode_fix(&info->fix, info);
1915 2016
1916 i810fb_init_ringbuffer(info); 2017 i810fb_init_ringbuffer(info);
1917 err = register_framebuffer(info); 2018 err = register_framebuffer(info);
2019
1918 if (err < 0) { 2020 if (err < 0) {
1919 i810fb_release_resource(info, par); 2021 i810fb_release_resource(info, par);
1920 printk("i810fb_init: cannot register framebuffer device\n"); 2022 printk("i810fb_init: cannot register framebuffer device\n");
@@ -1953,6 +2055,8 @@ static void i810fb_release_resource(struct fb_info *info,
1953 struct gtt_data *gtt = &par->i810_gtt; 2055 struct gtt_data *gtt = &par->i810_gtt;
1954 unset_mtrr(par); 2056 unset_mtrr(par);
1955 2057
2058 i810_delete_i2c_busses(par);
2059
1956 if (par->i810_gtt.i810_cursor_memory) 2060 if (par->i810_gtt.i810_cursor_memory)
1957 agp_free_memory(gtt->i810_cursor_memory); 2061 agp_free_memory(gtt->i810_cursor_memory);
1958 if (par->i810_gtt.i810_fb_memory) 2062 if (par->i810_gtt.i810_fb_memory)
@@ -1962,7 +2066,8 @@ static void i810fb_release_resource(struct fb_info *info,
1962 iounmap(par->mmio_start_virtual); 2066 iounmap(par->mmio_start_virtual);
1963 if (par->aperture.virtual) 2067 if (par->aperture.virtual)
1964 iounmap(par->aperture.virtual); 2068 iounmap(par->aperture.virtual);
1965 2069 if (par->edid)
2070 kfree(par->edid);
1966 if (par->res_flags & FRAMEBUFFER_REQ) 2071 if (par->res_flags & FRAMEBUFFER_REQ)
1967 release_mem_region(par->aperture.physical, 2072 release_mem_region(par->aperture.physical,
1968 par->aperture.size); 2073 par->aperture.size);
@@ -1988,7 +2093,7 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)
1988} 2093}
1989 2094
1990#ifndef MODULE 2095#ifndef MODULE
1991static int __init i810fb_init(void) 2096static int __devinit i810fb_init(void)
1992{ 2097{
1993 char *option = NULL; 2098 char *option = NULL;
1994 2099
@@ -2006,7 +2111,7 @@ static int __init i810fb_init(void)
2006 2111
2007#ifdef MODULE 2112#ifdef MODULE
2008 2113
2009static int __init i810fb_init(void) 2114static int __devinit i810fb_init(void)
2010{ 2115{
2011 hsync1 *= 1000; 2116 hsync1 *= 1000;
2012 hsync2 *= 1000; 2117 hsync2 *= 1000;
@@ -2046,14 +2151,16 @@ module_param(accel, bool, 0);
2046MODULE_PARM_DESC(accel, "Use Acceleration (BLIT) engine (default = 0)"); 2151MODULE_PARM_DESC(accel, "Use Acceleration (BLIT) engine (default = 0)");
2047module_param(mtrr, bool, 0); 2152module_param(mtrr, bool, 0);
2048MODULE_PARM_DESC(mtrr, "Use MTRR (default = 0)"); 2153MODULE_PARM_DESC(mtrr, "Use MTRR (default = 0)");
2049module_param(ext_vga, bool, 0); 2154module_param(extvga, bool, 0);
2050MODULE_PARM_DESC(ext_vga, "Enable external VGA connector (default = 0)"); 2155MODULE_PARM_DESC(extvga, "Enable external VGA connector (default = 0)");
2051module_param(sync, bool, 0); 2156module_param(sync, bool, 0);
2052MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing" 2157MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"
2053 " (default = 0)"); 2158 " (default = 0)");
2054module_param(dcolor, bool, 0); 2159module_param(dcolor, bool, 0);
2055MODULE_PARM_DESC(dcolor, "use DirectColor visuals" 2160MODULE_PARM_DESC(dcolor, "use DirectColor visuals"
2056 " (default = 0 = TrueColor)"); 2161 " (default = 0 = TrueColor)");
2162module_param(mode_option, charp, 0);
2163MODULE_PARM_DESC(mode_option, "Specify initial video mode");
2057 2164
2058MODULE_AUTHOR("Tony A. Daplas"); 2165MODULE_AUTHOR("Tony A. Daplas");
2059MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and" 2166MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and"