aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/i810/i810_main.c
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2005-09-09 16:10:04 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 17:03:41 -0400
commit74f6ae84b2315c2fa8a4110b09a1c0f3dca92674 (patch)
tree47b3bae44b4c57a699d2c130510ff0fbe110fa97 /drivers/video/i810/i810_main.c
parent829e79b680210c4f4de435af6e1f90451922fc7d (diff)
[PATCH] i810fb: Add i2c/DDC support
Add ddc/i2c support for i810fb. This will allow the driver to get display information, especially for monitors with fickle timings. The i2c support depends on CONFIG_FB_I810_GTF. Changed __init* to __devinit* Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Alexander Nyberg <alexn@telia.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/i810/i810_main.c')
-rw-r--r--drivers/video/i810/i810_main.c177
1 files changed, 133 insertions, 44 deletions
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index d07b1f203fc4..082ddd2089a5 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
@@ -947,31 +948,24 @@ static int i810_check_params(struct fb_var_screeninfo *var,
947 struct fb_info *info) 948 struct fb_info *info)
948{ 949{
949 struct i810fb_par *par = (struct i810fb_par *) info->par; 950 struct i810fb_par *par = (struct i810fb_par *) info->par;
950 int line_length, vidmem; 951 int line_length, vidmem, mode_valid = 0;
951 u32 xres, yres, vxres, vyres; 952 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 /* 953 /*
959 * Memory limit 954 * Memory limit
960 */ 955 */
961 line_length = get_line_length(par, vxres, 956 line_length = get_line_length(par, vxres, var->bits_per_pixel);
962 var->bits_per_pixel);
963
964 vidmem = line_length*vyres; 957 vidmem = line_length*vyres;
958
965 if (vidmem > par->fb.size) { 959 if (vidmem > par->fb.size) {
966 vyres = par->fb.size/line_length; 960 vyres = par->fb.size/line_length;
967 if (vyres < yres) { 961 if (vyres < var->yres) {
968 vyres = yres; 962 vyres = yres;
969 vxres = par->fb.size/vyres; 963 vxres = par->fb.size/vyres;
970 vxres /= var->bits_per_pixel >> 3; 964 vxres /= var->bits_per_pixel >> 3;
971 line_length = get_line_length(par, vxres, 965 line_length = get_line_length(par, vxres,
972 var->bits_per_pixel); 966 var->bits_per_pixel);
973 vidmem = line_length * yres; 967 vidmem = line_length * yres;
974 if (vxres < xres) { 968 if (vxres < var->xres) {
975 printk("i810fb: required video memory, " 969 printk("i810fb: required video memory, "
976 "%d bytes, for %dx%d-%d (virtual) " 970 "%d bytes, for %dx%d-%d (virtual) "
977 "is out of range\n", 971 "is out of range\n",
@@ -981,6 +975,10 @@ static int i810_check_params(struct fb_var_screeninfo *var,
981 } 975 }
982 } 976 }
983 } 977 }
978
979 var->xres_virtual = vxres;
980 var->yres_virtual = vyres;
981
984 /* 982 /*
985 * Monitor limit 983 * Monitor limit
986 */ 984 */
@@ -996,25 +994,39 @@ static int i810_check_params(struct fb_var_screeninfo *var,
996 info->monspecs.dclkmax = 204000000; 994 info->monspecs.dclkmax = 204000000;
997 break; 995 break;
998 } 996 }
997
999 info->monspecs.dclkmin = 15000000; 998 info->monspecs.dclkmin = 15000000;
1000 999
1001 if (fb_validate_mode(var, info)) { 1000 if (!fb_validate_mode(var, info))
1001 mode_valid = 1;
1002
1003#ifdef CONFIG_FB_I810_I2C
1004 if (!mode_valid && info->monspecs.gtf &&
1005 !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1006 mode_valid = 1;
1007
1008 if (!mode_valid && info->monspecs.modedb_len) {
1009 struct fb_videomode *mode;
1010
1011 mode = fb_find_best_mode(var, &info->modelist);
1012 if (mode) {
1013 fb_videomode_to_var(var, mode);
1014 mode_valid = 1;
1015 }
1016 }
1017#endif
1018 if (!mode_valid && info->monspecs.modedb_len == 0) {
1002 if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) { 1019 if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {
1003 int default_sync = (info->monspecs.hfmin-HFMIN) 1020 int default_sync = (info->monspecs.hfmin-HFMIN)
1004 |(info->monspecs.hfmax-HFMAX) 1021 |(info->monspecs.hfmax-HFMAX)
1005 |(info->monspecs.vfmin-VFMIN) 1022 |(info->monspecs.vfmin-VFMIN)
1006 |(info->monspecs.vfmax-VFMAX); 1023 |(info->monspecs.vfmax-VFMAX);
1007 printk("i810fb: invalid video mode%s\n", 1024 printk("i810fb: invalid video mode%s\n",
1008 default_sync ? "" : 1025 default_sync ? "" : ". Specifying "
1009 ". Specifying vsyncN/hsyncN parameters may help"); 1026 "vsyncN/hsyncN parameters may help");
1010 return -EINVAL;
1011 } 1027 }
1012 } 1028 }
1013 1029
1014 var->xres = xres;
1015 var->yres = yres;
1016 var->xres_virtual = vxres;
1017 var->yres_virtual = vyres;
1018 return 0; 1030 return 0;
1019} 1031}
1020 1032
@@ -1812,8 +1824,72 @@ i810_allocate_pci_resource(struct i810fb_par *par,
1812 return 0; 1824 return 0;
1813} 1825}
1814 1826
1827static void __devinit i810fb_find_init_mode(struct fb_info *info)
1828{
1829 struct fb_videomode mode;
1830 struct fb_var_screeninfo var;
1831 struct fb_monspecs *specs = NULL;
1832 int found = 0;
1833#ifdef CONFIG_FB_I810_I2C
1834 int i;
1835 int err;
1836 struct i810fb_par *par = info->par;
1837#endif
1838
1839 INIT_LIST_HEAD(&info->modelist);
1840 memset(&mode, 0, sizeof(struct fb_videomode));
1841 var = info->var;
1842#ifdef CONFIG_FB_I810_I2C
1843 i810_create_i2c_busses(par);
1844
1845 for (i = 0; i < 3; i++) {
1846 err = i810_probe_i2c_connector(info, &par->edid, i+1);
1847 if (!err)
1848 break;
1849 }
1850
1851 if (!err)
1852 printk("i810fb_init_pci: DDC probe successful\n");
1853
1854 fb_edid_to_monspecs(par->edid, &info->monspecs);
1855
1856 if (info->monspecs.modedb == NULL)
1857 printk("i810fb_init_pci: Unable to get Mode Database\n");
1858
1859 specs = &info->monspecs;
1860 fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
1861 &info->modelist);
1862 if (specs->modedb != NULL) {
1863 if (specs->misc & FB_MISC_1ST_DETAIL) {
1864 for (i = 0; i < specs->modedb_len; i++) {
1865 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1866 mode = specs->modedb[i];
1867 found = 1;
1868 break;
1869 }
1870 }
1871 }
1872
1873 if (!found) {
1874 mode = specs->modedb[0];
1875 found = 1;
1876 }
1877
1878 fb_videomode_to_var(&var, &mode);
1879 }
1880#endif
1881 if (mode_option)
1882 fb_find_mode(&var, info, mode_option, specs->modedb,
1883 specs->modedb_len, (found) ? &mode : NULL,
1884 info->var.bits_per_pixel);
1885
1886 info->var = var;
1887 fb_destroy_modedb(specs->modedb);
1888 specs->modedb = NULL;
1889}
1890
1815#ifndef MODULE 1891#ifndef MODULE
1816static int __init i810fb_setup(char *options) 1892static int __devinit i810fb_setup(char *options)
1817{ 1893{
1818 char *this_opt, *suffix = NULL; 1894 char *this_opt, *suffix = NULL;
1819 1895
@@ -1855,6 +1931,8 @@ static int __init i810fb_setup(char *options)
1855 vsync2 = simple_strtoul(this_opt+7, NULL, 0); 1931 vsync2 = simple_strtoul(this_opt+7, NULL, 0);
1856 else if (!strncmp(this_opt, "dcolor", 6)) 1932 else if (!strncmp(this_opt, "dcolor", 6))
1857 dcolor = 1; 1933 dcolor = 1;
1934 else
1935 mode_option = this_opt;
1858 } 1936 }
1859 return 0; 1937 return 0;
1860} 1938}
@@ -1865,6 +1943,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1865{ 1943{
1866 struct fb_info *info; 1944 struct fb_info *info;
1867 struct i810fb_par *par = NULL; 1945 struct i810fb_par *par = NULL;
1946 struct fb_videomode mode;
1868 int i, err = -1, vfreq, hfreq, pixclock; 1947 int i, err = -1, vfreq, hfreq, pixclock;
1869 1948
1870 i = 0; 1949 i = 0;
@@ -1873,7 +1952,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1873 if (!info) 1952 if (!info)
1874 return -ENOMEM; 1953 return -ENOMEM;
1875 1954
1876 par = (struct i810fb_par *) info->par; 1955 par = info->par;
1877 par->dev = dev; 1956 par->dev = dev;
1878 1957
1879 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) { 1958 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
@@ -1904,15 +1983,20 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1904 info->fbops = &par->i810fb_ops; 1983 info->fbops = &par->i810fb_ops;
1905 info->pseudo_palette = par->pseudo_palette; 1984 info->pseudo_palette = par->pseudo_palette;
1906 fb_alloc_cmap(&info->cmap, 256, 0); 1985 fb_alloc_cmap(&info->cmap, 256, 0);
1986 i810fb_find_init_mode(info);
1907 1987
1908 if ((err = info->fbops->fb_check_var(&info->var, info))) { 1988 if ((err = info->fbops->fb_check_var(&info->var, info))) {
1909 i810fb_release_resource(info, par); 1989 i810fb_release_resource(info, par);
1910 return err; 1990 return err;
1911 } 1991 }
1992
1993 fb_var_to_videomode(&mode, &info->var);
1994 fb_add_videomode(&mode, &info->modelist);
1912 encode_fix(&info->fix, info); 1995 encode_fix(&info->fix, info);
1913 1996
1914 i810fb_init_ringbuffer(info); 1997 i810fb_init_ringbuffer(info);
1915 err = register_framebuffer(info); 1998 err = register_framebuffer(info);
1999
1916 if (err < 0) { 2000 if (err < 0) {
1917 i810fb_release_resource(info, par); 2001 i810fb_release_resource(info, par);
1918 printk("i810fb_init: cannot register framebuffer device\n"); 2002 printk("i810fb_init: cannot register framebuffer device\n");
@@ -1951,6 +2035,8 @@ static void i810fb_release_resource(struct fb_info *info,
1951 struct gtt_data *gtt = &par->i810_gtt; 2035 struct gtt_data *gtt = &par->i810_gtt;
1952 unset_mtrr(par); 2036 unset_mtrr(par);
1953 2037
2038 i810_delete_i2c_busses(par);
2039
1954 if (par->i810_gtt.i810_cursor_memory) 2040 if (par->i810_gtt.i810_cursor_memory)
1955 agp_free_memory(gtt->i810_cursor_memory); 2041 agp_free_memory(gtt->i810_cursor_memory);
1956 if (par->i810_gtt.i810_fb_memory) 2042 if (par->i810_gtt.i810_fb_memory)
@@ -1960,7 +2046,8 @@ static void i810fb_release_resource(struct fb_info *info,
1960 iounmap(par->mmio_start_virtual); 2046 iounmap(par->mmio_start_virtual);
1961 if (par->aperture.virtual) 2047 if (par->aperture.virtual)
1962 iounmap(par->aperture.virtual); 2048 iounmap(par->aperture.virtual);
1963 2049 if (par->edid)
2050 kfree(par->edid);
1964 if (par->res_flags & FRAMEBUFFER_REQ) 2051 if (par->res_flags & FRAMEBUFFER_REQ)
1965 release_mem_region(par->aperture.physical, 2052 release_mem_region(par->aperture.physical,
1966 par->aperture.size); 2053 par->aperture.size);
@@ -1986,7 +2073,7 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)
1986} 2073}
1987 2074
1988#ifndef MODULE 2075#ifndef MODULE
1989static int __init i810fb_init(void) 2076static int __devinit i810fb_init(void)
1990{ 2077{
1991 char *option = NULL; 2078 char *option = NULL;
1992 2079
@@ -2004,7 +2091,7 @@ static int __init i810fb_init(void)
2004 2091
2005#ifdef MODULE 2092#ifdef MODULE
2006 2093
2007static int __init i810fb_init(void) 2094static int __devinit i810fb_init(void)
2008{ 2095{
2009 hsync1 *= 1000; 2096 hsync1 *= 1000;
2010 hsync2 *= 1000; 2097 hsync2 *= 1000;
@@ -2052,6 +2139,8 @@ MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"
2052module_param(dcolor, bool, 0); 2139module_param(dcolor, bool, 0);
2053MODULE_PARM_DESC(dcolor, "use DirectColor visuals" 2140MODULE_PARM_DESC(dcolor, "use DirectColor visuals"
2054 " (default = 0 = TrueColor)"); 2141 " (default = 0 = TrueColor)");
2142module_param(mode_option, charp, 0);
2143MODULE_PARM_DESC(mode_option, "Specify initial video mode");
2055 2144
2056MODULE_AUTHOR("Tony A. Daplas"); 2145MODULE_AUTHOR("Tony A. Daplas");
2057MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and" 2146MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and"