31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/string.h>
36 #include <linux/slab.h>
39 #include <linux/pci.h>
41 #include <linux/resource.h>
46 #include <asm/div64.h>
91 static int i810fb_setcolreg (
unsigned regno,
unsigned red,
unsigned green,
unsigned blue,
94 static int i810fb_blank (
int blank_mode,
struct fb_info *
info);
101 "Intel(R) 810 Framebuffer Device" ,
102 "Intel(R) 810-DC100 Framebuffer Device" ,
103 "Intel(R) 810E Framebuffer Device" ,
104 "Intel(R) 815 (Internal Graphics 100Mhz FSB) Framebuffer Device" ,
105 "Intel(R) 815 (Internal Graphics only) Framebuffer Device" ,
106 "Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device"
128 .id_table = i810fb_pci_tbl,
129 .probe = i810fb_init_pci,
130 .remove =
__exit_p(i810fb_remove_pci),
131 .suspend = i810fb_suspend,
132 .resume = i810fb_resume,
190 static void i810_dram_off(
u8 __iomem *mmio,
u8 mode)
209 static void i810_protect_regs(
u8 __iomem *mmio,
int mode)
215 reg = (mode ==
OFF) ? reg & ~0x80 :
229 static void i810_load_pll(
struct i810fb_par *par)
234 tmp1 = par->
regs.M | par->
regs.N << 16;
241 tmp2 &= ~(
P_OR << 16);
255 static void i810_load_vga(
struct i810fb_par *par)
298 static void i810_load_vgax(
struct i810fb_par *par)
323 static void i810_load_2d(
struct i810fb_par *par)
366 static void i810_load_pitch(
struct i810fb_par *par)
372 pitch = par->
pitch >> 3;
398 static void i810_load_color(
struct i810fb_par *par)
420 static void i810_load_regs(
struct i810fb_par *par)
424 i810_screen_off(mmio,
OFF);
425 i810_protect_regs(mmio,
OFF);
426 i810_dram_off(mmio,
OFF);
430 i810_dram_off(mmio,
ON);
433 i810_screen_off(mmio,
ON);
434 i810_protect_regs(mmio,
ON);
435 i810_load_color(par);
436 i810_load_pitch(par);
460 static void i810_restore_pll(
struct i810fb_par *par)
480 static void i810_restore_dac(
struct i810fb_par *par)
492 static void i810_restore_vgax(
struct i810fb_par *par)
497 for (i = 0; i < 4; i++) {
526 static void i810_restore_vga(
struct i810fb_par *par)
531 for (i = 0; i < 10; i++) {
535 for (i = 0; i < 8; i++) {
541 static void i810_restore_addr_map(
struct i810fb_par *par)
554 static void i810_restore_2d(
struct i810fb_par *par)
561 tmp_word &= ~(3 << 4);
565 i810_dram_off(mmio,
OFF);
567 i810_dram_off(mmio,
ON);
585 static void i810_restore_vga_state(
struct i810fb_par *par)
589 i810_screen_off(mmio,
OFF);
590 i810_protect_regs(mmio,
OFF);
591 i810_dram_off(mmio,
OFF);
592 i810_restore_pll(par);
593 i810_restore_dac(par);
594 i810_restore_vga(par);
595 i810_restore_vgax(par);
596 i810_restore_addr_map(par);
597 i810_dram_off(mmio,
ON);
598 i810_restore_2d(par);
599 i810_screen_off(mmio,
ON);
600 i810_protect_regs(mmio,
ON);
607 static void i810_save_vgax(
struct i810fb_par *par)
612 for (i = 0; i < 4; i++) {
631 static void i810_save_vga(
struct i810fb_par *par)
636 for (i = 0; i < 10; i++) {
640 for (i = 0; i < 8; i++) {
646 static void i810_save_2d(
struct i810fb_par *par)
663 static void i810_save_vga_state(
struct i810fb_par *par)
682 static u32 get_line_length(
struct i810fb_par *par,
int xres_virtual,
int bpp)
686 length = xres_virtual*
bpp;
687 length = (length+31)&-32;
707 u32 m_reg, n_reg, p_divisor, n_target_max;
708 u32 m_target, n_target, p_target, n_best, m_best,
mod;
709 u32 f_out, target_freq, diff = 0, mod_min, diff_min;
711 diff_min = mod_min = 0xFFFFFFFF;
712 n_best = m_best = m_target = f_out = 0;
722 while(!((1000000 * p_divisor)/(16 * 24 * target_freq)) &&
728 n_reg = m_reg = n_target = 3;
729 while (diff_min && mod_min && (n_target < n_target_max)) {
730 f_out = (p_divisor * n_reg * 1000000)/(4 * 24 * m_reg);
731 mod = (p_divisor * n_reg * 1000000) % (4 * 24 * m_reg);
734 if (f_out <= target_freq) {
736 diff = target_freq - f_out;
739 diff = f_out - target_freq;
742 if (diff_min > diff) {
748 if (!diff && mod_min > mod) {
754 if (m) *m = (m_best - 2) & 0x3FF;
755 if (n) *n = (n_best - 2) & 0x3FF;
756 if (p) *p = (p_target << 4);
771 static void i810_enable_cursor(
u8 __iomem *mmio,
int mode)
782 static void i810_reset_cursor_image(
struct i810fb_par *par)
787 for (i = 64; i--; ) {
788 for (j = 0; j < 8; j++) {
800 int i,
j,
w = width/8;
801 int mod = width % 8, t_mask, d_mask;
803 t_mask = 0xff >>
mod;
804 d_mask = ~(0xff >>
mod);
805 for (i = height; i--; ) {
806 for (j = 0; j <
w; j++) {
818 static void i810_load_cursor_colors(
int fg,
int bg,
struct fb_info *
info)
824 i810fb_getcolreg(bg, &red, &green, &blue, &trans, info);
829 i810_write_dac(4, red, green, blue, mmio);
833 i810fb_getcolreg(fg, &red, &green, &blue, &trans, info);
837 i810_write_dac(5, red, green, blue, mmio);
849 static void i810_init_cursor(
struct i810fb_par *par)
853 i810_enable_cursor(mmio,
OFF);
872 u32 xres, yres, vxres, vyres;
896 xres = (xres + 7) & ~7;
945 var->
green.offset = 0;
946 var->
green.length = 8;
947 var->
blue.offset = 0;
948 var->
blue.length = 8;
953 var->
green.length = (var->
green.length == 5) ? 5 : 6;
955 var->
blue.length = 5;
957 var->
blue.offset = 0;
958 var->
green.offset = 5;
959 var->
red.offset = 5 + var->
green.length;
960 var->
transp.offset = (5 + var->
red.offset) & 15;
964 var->
red.offset = 16;
966 var->
green.offset = 8;
967 var->
green.length = 8;
968 var->
blue.offset = 0;
969 var->
blue.length = 8;
974 var->
red.msb_right = 0;
975 var->
green.msb_right = 0;
976 var->
blue.msb_right = 0;
977 var->
transp.msb_right = 0;
994 int line_length, vidmem, mode_valid = 0,
retval = 0;
1001 vidmem = line_length*vyres;
1003 if (vidmem > par->
fb.size) {
1004 vyres = par->
fb.size/line_length;
1005 if (vyres < var->yres) {
1006 vyres = info->
var.yres;
1007 vxres = par->
fb.size/vyres;
1009 line_length = get_line_length(par, vxres,
1011 vidmem = line_length * info->
var.yres;
1012 if (vxres < var->xres) {
1013 printk(
"i810fb: required video memory, "
1014 "%d bytes, for %dx%d-%d (virtual) "
1015 "is out of range\n",
1016 vidmem, vxres, vyres,
1031 info->
monspecs.dclkmax = 234000000;
1034 info->
monspecs.dclkmax = 229000000;
1038 info->
monspecs.dclkmax = 204000000;
1047 #ifdef CONFIG_FB_I810_I2C
1048 if (!mode_valid && info->
monspecs.gtf &&
1052 if (!mode_valid && info->
monspecs.modedb_len) {
1062 if (!mode_valid && info->
monspecs.modedb_len == 0) {
1068 printk(
"i810fb: invalid video mode%s\n",
1069 default_sync ?
"" :
". Specifying "
1070 "vsyncN/hsyncN parameters may help");
1102 switch (info->
var.bits_per_pixel) {
1109 if (info->
var.nonstd)
1138 u32 xres, yres, vxres, vyres;
1153 if (var->
green.length == 5)
1206 if ((info->
var.green.length == 5 && regno > 31) ||
1207 (info->
var.green.length == 6 && regno > 63))
1215 info->
var.green.length == 5)
1216 i810_read_dac(regno * 8, red, green, blue, mmio);
1219 info->
var.green.length == 6) {
1222 i810_read_dac(regno * 8, red, &tmp, blue, mmio);
1223 i810_read_dac(regno * 4, &tmp, green, &tmp, mmio);
1226 i810_read_dac(regno, red, green, blue, mmio);
1238 static int i810fb_open(
struct fb_info *info,
int user)
1249 i810_save_vga_state(par);
1258 static int i810fb_release(
struct fb_info *info,
int user)
1269 i810_restore_vga_state(par);
1280 static int i810fb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
1281 unsigned blue,
unsigned transp,
1289 if (regno > 255)
return 1;
1292 if ((info->
var.green.length == 5 && regno > 31) ||
1293 (info->
var.green.length == 6 && regno > 63))
1297 if (info->
var.grayscale)
1298 red = green = blue = (19595 * red + 38470 * green +
1305 info->
var.green.length == 5) {
1306 for (i = 0; i < 8; i++)
1307 i810_write_dac((
u8) (regno * 8) + i, (
u8) red,
1308 (
u8) green, (
u8) blue, mmio);
1310 info->
var.green.length == 6) {
1314 for (i = 0; i < 8; i++)
1315 i810_write_dac((
u8) (regno * 8) + i,
1316 (
u8) red, (
u8) green,
1319 i810_read_dac((
u8) (regno*4), &r, &g, &b, mmio);
1320 for (i = 0; i < 4; i++)
1321 i810_write_dac((
u8) (regno*4) + i, r, (
u8) green,
1324 i810_write_dac((
u8) regno, (
u8) red, (
u8) green,
1331 switch (info->
var.bits_per_pixel) {
1334 if (info->
var.green.length == 5)
1336 (regno << 10) | (regno << 5) |
1340 (regno << 11) | (regno << 5) |
1343 if (info->
var.green.length == 5) {
1346 ((red & 0xf800) >> 1) |
1347 ((green & 0xf800) >> 6) |
1348 ((blue & 0xf800) >> 11);
1353 ((green & 0xf800) >> 5) |
1354 ((blue & 0xf800) >> 11);
1362 (regno << 16) | (regno << 8) |
1366 ((red & 0xff00) << 8) |
1368 ((blue & 0xff00) >> 8);
1388 static int i810fb_blank (
int blank_mode,
struct fb_info *info)
1392 int mode = 0, pwr, scr_off = 0;
1396 switch (blank_mode) {
1426 i810_screen_off(mmio, scr_off);
1433 static int i810fb_set_par(
struct fb_info *info)
1437 decode_var(&info->
var, par);
1438 i810_load_regs(par);
1439 i810_init_cursor(par);
1440 encode_fix(&info->
fix, info);
1446 info->
pixmap.scan_align = 2;
1448 info->
pixmap.scan_align = 1;
1468 i810_round_off(var);
1469 if ((err = i810_check_params(var, info)))
1473 set_color_bitfields(var);
1485 if (cursor->
image.width > 64 || cursor->
image.height > 64)
1489 i810_init_cursor(par);
1493 i810_enable_cursor(mmio,
OFF);
1498 tmp = (cursor->
image.dx - info->
var.xoffset) & 0xffff;
1499 tmp |= (cursor->
image.dy - info->
var.yoffset) << 16;
1504 i810_reset_cursor_image(par);
1507 i810_load_cursor_colors(cursor->
image.fg_color,
1508 cursor->
image.bg_color,
1512 int size = ((cursor->
image.width + 7) >> 3) *
1513 cursor->
image.height;
1520 switch (cursor->
rop) {
1522 for (i = 0; i <
size; i++)
1523 data[i] = cursor->
image.data[i] ^ cursor->
mask[i];
1528 data[i] = cursor->
image.data[i] & cursor->
mask[i];
1532 i810_load_cursor_image(cursor->
image.width,
1533 cursor->
image.height, data,
1539 i810_enable_cursor(mmio,
ON);
1546 .fb_open = i810fb_open,
1547 .fb_release = i810fb_release,
1548 .fb_check_var = i810fb_check_var,
1549 .fb_set_par = i810fb_set_par,
1550 .fb_setcolreg = i810fb_setcolreg,
1551 .fb_blank = i810fb_blank,
1552 .fb_pan_display = i810fb_pan_display,
1556 .fb_cursor = i810fb_cursor,
1565 struct fb_info *info = pci_get_drvdata(dev);
1570 switch (mesg.
event) {
1573 dev->
dev.power.power_state = mesg;
1580 if (info->
fbops->fb_sync)
1581 info->
fbops->fb_sync(info);
1595 static int i810fb_resume(
struct pci_dev *dev)
1597 struct fb_info *info = pci_get_drvdata(dev);
1620 i810fb_set_par(info);
1633 par->
fb.physical = par->
aperture.physical+(par->
fb.offset << 12);
1634 par->
fb.virtual = par->
aperture.virtual+(par->
fb.offset << 12);
1636 (par->
iring.offset << 12);
1638 (par->
iring.offset << 12);
1645 if (vram + 1 > par->
aperture.size >> 20)
1646 vram = (par->
aperture.size >> 20) - 1;
1647 if (v_offset_default > (par->
aperture.size >> 20))
1648 v_offset_default = (par->
aperture.size >> 20);
1649 if (vram + v_offset_default + 1 > par->
aperture.size >> 20)
1650 v_offset_default = (par->
aperture.size >> 20) - (vram + 1);
1652 par->
fb.size = vram << 20;
1653 par->
fb.offset = v_offset_default << 20;
1654 par->
fb.offset >>= 12;
1656 par->
iring.offset = par->
fb.offset + (par->
fb.size >> 12);
1669 i810_fix_offsets(par);
1670 size = par->
fb.size + par->
iring.size;
1673 printk(
"i810fb_alloc_fbmem: cannot acquire agpgart\n");
1676 if (!(par->
i810_gtt.i810_fb_memory =
1678 printk(
"i810fb_alloc_fbmem: can't allocate framebuffer "
1685 printk(
"i810fb_alloc_fbmem: can't bind framebuffer memory\n");
1690 if (!(par->
i810_gtt.i810_cursor_memory =
1693 printk(
"i810fb_alloc_cursormem: can't allocate"
1700 printk(
"i810fb_alloc_cursormem: cannot bind cursor memory\n");
1707 i810_fix_pointers(par);
1736 if (hsync2 < hsync1)
1743 if (
IS_DVT && vsync1 < 60)
1749 if (vsync2 < vsync1)
1764 v_offset_default = voffset;
1765 else if (par->
aperture.size > 32 * 1024 * 1024)
1766 v_offset_default = 16;
1768 v_offset_default = 8;
1779 par->
ddc_num = (ddc3 ? 3 : 2);
1787 info->
var.xres = xres;
1789 info->
var.xres = 640;
1792 info->
var.yres = yres;
1794 info->
var.yres = 480;
1797 vyres = (vram << 20)/(info->
var.xres*
bpp >> 3);
1799 info->
var.yres_virtual = vyres;
1800 info->
var.bits_per_pixel =
bpp;
1803 info->
var.nonstd = 1;
1806 info->
var.accel_flags = 1;
1808 i810_init_monspecs(info);
1822 i810_init_cursor(par);
1830 pci_read_config_byte(par->
dev, 0x50, ®);
1837 i810_allocate_pci_resource(
struct i810fb_par *par,
1843 printk(
"i810fb_init: cannot enable device\n");
1858 printk(
"i810fb_init: device is disabled\n");
1865 printk(
"i810fb_init: cannot request framebuffer region\n");
1873 printk(
"i810fb_init: cannot remap framebuffer region\n");
1880 printk(
"i810fb_init: cannot request mmio region\n");
1888 printk(
"i810fb_init: cannot remap mmio region\n");
1901 #ifdef CONFIG_FB_I810_I2C
1910 #ifdef CONFIG_FB_I810_I2C
1913 for (i = 0; i < par->
ddc_num + 1; i++) {
1920 printk(
"i810fb_init_pci: DDC probe successful\n");
1925 printk(
"i810fb_init_pci: Unable to get Mode Database\n");
1951 info->
var.bits_per_pixel);
1961 char *this_opt, *suffix =
NULL;
1963 if (!options || !*options)
1966 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
1967 if (!
strncmp(this_opt,
"mtrr", 4))
1969 else if (!
strncmp(this_opt,
"accel", 5))
1971 else if (!
strncmp(this_opt,
"extvga", 6))
1973 else if (!
strncmp(this_opt,
"sync", 4))
1975 else if (!
strncmp(this_opt,
"vram:", 5))
1977 else if (!
strncmp(this_opt,
"voffset:", 8))
1979 else if (!
strncmp(this_opt,
"xres:", 5))
1981 else if (!
strncmp(this_opt,
"yres:", 5))
1983 else if (!
strncmp(this_opt,
"vyres:", 6))
1985 else if (!
strncmp(this_opt,
"bpp:", 4))
1987 else if (!
strncmp(this_opt,
"hsync1:", 7)) {
1991 }
else if (!
strncmp(this_opt,
"hsync2:", 7)) {
1995 }
else if (!
strncmp(this_opt,
"vsync1:", 7))
1997 else if (!
strncmp(this_opt,
"vsync2:", 7))
1999 else if (!
strncmp(this_opt,
"dcolor", 6))
2001 else if (!
strncmp(this_opt,
"ddc3", 4))
2004 mode_option = this_opt;
2028 i810fb_release_resource(info, par);
2031 info->
pixmap.size = 8*1024;
2032 info->
pixmap.buf_align = 8;
2033 info->
pixmap.access_align = 32;
2036 if ((err = i810_allocate_pci_resource(par, entry))) {
2037 i810fb_release_resource(info, par);
2041 i810_init_defaults(par, info);
2043 if ((err = i810_alloc_agp_mem(info))) {
2044 i810fb_release_resource(info, par);
2048 i810_init_device(par);
2054 i810fb_find_init_mode(info);
2056 if ((err = info->
fbops->fb_check_var(&info->
var, info))) {
2057 i810fb_release_resource(info, par);
2068 i810fb_release_resource(info, par);
2069 printk(
"i810fb_init: cannot register framebuffer device\n");
2073 pci_set_drvdata(dev, info);
2074 pixclock = 1000000000/(info->
var.pixclock);
2076 hfreq = pixclock/(info->
var.xres + info->
var.left_margin +
2077 info->
var.hsync_len + info->
var.right_margin);
2078 vfreq = hfreq/(info->
var.yres + info->
var.upper_margin +
2079 info->
var.vsync_len + info->
var.lower_margin);
2081 printk(
"I810FB: fb%d : %s v%d.%d.%d%s\n"
2082 "I810FB: Video RAM : %dK\n"
2083 "I810FB: Monitor : H: %d-%d KHz V: %d-%d Hz\n"
2084 "I810FB: Mode : %dx%d-%dbpp@%dHz\n",
2088 (
int) par->
fb.size>>10, info->
monspecs.hfmin/1000,
2099 static void i810fb_release_resource(
struct fb_info *info,
2107 if (par->
i810_gtt.i810_cursor_memory)
2129 struct fb_info *info = pci_get_drvdata(dev);
2133 i810fb_release_resource(info, par);
2134 pci_set_drvdata(dev,
NULL);
2135 printk(
"cleanup_module: unloaded i810 framebuffer device\n");
2145 i810fb_setup(option);
2147 return pci_register_driver(&i810fb_driver);
2162 return pci_register_driver(&i810fb_driver);
2170 "memory (0 to maximum aperture size), in MiB (default = 48)");
2177 MODULE_PARM_DESC(yres,
"Vertical resolution in scanlines (default = 480)");
2180 " (default = 480)");
2204 " (default = 0 = TrueColor)");
2212 " compatible cards");
2215 static void __exit i810fb_exit(
void)