diff options
Diffstat (limited to 'drivers/video')
42 files changed, 914 insertions, 813 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 702eb933cf8..a1c8923b0bf 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -53,6 +53,11 @@ config FB (e.g. an accelerated X server) and that are not frame buffer device-aware may cause unexpected results. If unsure, say N. +config FB_DDC + tristate + depends on FB && I2C && I2C_ALGOBIT + default n + config FB_CFB_FILLRECT tristate depends on FB @@ -696,6 +701,7 @@ config FB_NVIDIA depends on FB && PCI select I2C_ALGOBIT if FB_NVIDIA_I2C select I2C if FB_NVIDIA_I2C + select FB_DDC if FB_NVIDIA_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -734,6 +740,7 @@ config FB_RIVA depends on FB && PCI select I2C_ALGOBIT if FB_RIVA_I2C select I2C if FB_RIVA_I2C + select FB_DDC if FB_RIVA_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -822,33 +829,52 @@ config FB_I810_I2C depends on FB_I810 && FB_I810_GTF select I2C select I2C_ALGOBIT + select FB_DDC help config FB_INTEL - tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)" + tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)" depends on FB && EXPERIMENTAL && PCI && X86 select AGP select AGP_INTEL + select I2C_ALGOBIT if FB_INTEL_I2C + select I2C if FB_INTEL_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT help This driver supports the on-board graphics built in to the Intel - 830M/845G/852GM/855GM/865G chipsets. + 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM chipsets. Say Y if you have and plan to use such a board. - To compile this driver as a module, choose M here: the + If you say Y here and want DDC/I2C support you must first say Y to + "I2C support" and "I2C bit-banging support" in the character devices + section. + + If you say M here then "I2C support" and "I2C bit-banging support" + can be build either as modules or built-in. + + To compile this driver as a module, choose M here: the module will be called intelfb. + For more information, please read <file:Documentation/fb/intelfb.txt> + config FB_INTEL_DEBUG - bool "Intel driver Debug Messages" + bool "Intel driver Debug Messages" depends on FB_INTEL ---help--- Say Y here if you want the Intel driver to output all sorts of debugging informations to provide to the maintainer when something goes wrong. +config FB_INTEL_I2C + bool "DDC/I2C for Intel framebuffer support" + depends on FB_INTEL + default y + help + Say Y here if you want DDC/I2C support for your on-board Intel graphics. + config FB_MATROX tristate "Matrox acceleration" depends on FB && PCI @@ -994,6 +1020,7 @@ config FB_RADEON depends on FB && PCI select I2C_ALGOBIT if FB_RADEON_I2C select I2C if FB_RADEON_I2C + select FB_DDC if FB_RADEON_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -1122,6 +1149,7 @@ config FB_SAVAGE depends on FB && PCI && EXPERIMENTAL select I2C_ALGOBIT if FB_SAVAGE_I2C select I2C if FB_SAVAGE_I2C + select FB_DDC if FB_SAVAGE_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -1601,7 +1629,8 @@ config FB_VIRTUAL kernel option `video=vfb:'. To compile this driver as a module, choose M here: the - module will be called vfb. + module will be called vfb. In order to load it, you must use + the vfb_enable=1 option. If unsure, say N. if VT diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 481c6c9695f..a6980e9a248 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o obj-$(CONFIG_FB_MACMODES) += macmodes.o +obj-$(CONFIG_FB_DDC) += fb_ddc.o # Hardware specific drivers go first obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index 55fb8b04489..b04f49fb976 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h @@ -355,5 +355,9 @@ static inline void wait_for_idle(struct atyfb_par *par) extern void aty_reset_engine(const struct atyfb_par *par); extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); -extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par); extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); + +void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); +void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); +void atyfb_imageblit(struct fb_info *info, const struct fb_image *image); + diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 19a71f04578..b45c9fd1b33 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -240,9 +240,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); static int atyfb_blank(int blank, struct fb_info *info); static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); -extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); -extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image); #ifdef __sparc__ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma); #endif @@ -3863,6 +3860,7 @@ static int __devinit atyfb_setup(char *options) static int __devinit atyfb_init(void) { + int err1 = 1, err2 = 1; #ifndef MODULE char *option = NULL; @@ -3872,12 +3870,13 @@ static int __devinit atyfb_init(void) #endif #ifdef CONFIG_PCI - pci_register_driver(&atyfb_driver); + err1 = pci_register_driver(&atyfb_driver); #endif #ifdef CONFIG_ATARI - atyfb_atari_probe(); + err2 = atyfb_atari_probe(); #endif - return 0; + + return (err1 && err2) ? -ENODEV : 0; } static void __exit atyfb_exit(void) diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c index e7056934c6a..5080816be65 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/aty/mach64_ct.c @@ -27,7 +27,7 @@ u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par) return res; } -void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par) +static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par) { /* write addr byte */ aty_st_8(CLOCK_CNTL_ADDR, ((offset << 2) & PLL_ADDR) | PLL_WR_EN, par); diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 9aaca58c074..67675452009 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c @@ -16,8 +16,6 @@ #include "radeonfb.h" #include "../edid.h" -#define RADEON_DDC 0x50 - static void radeon_gpio_setscl(void* data, int state) { struct radeon_i2c_chan *chan = data; @@ -138,108 +136,10 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) rinfo->i2c[3].rinfo = NULL; } - -static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan) -{ - u8 start = 0x0; - struct i2c_msg msgs[] = { - { - .addr = RADEON_DDC, - .len = 1, - .buf = &start, - }, { - .addr = RADEON_DDC, - .flags = I2C_M_RD, - .len = EDID_LENGTH, - }, - }; - u8 *buf; - - buf = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (!buf) { - dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n"); - return NULL; - } - msgs[1].buf = buf; - - if (i2c_transfer(&chan->adapter, msgs, 2) == 2) - return buf; - dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n"); - kfree(buf); - return NULL; -} - - -int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid) +int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, + u8 **out_edid) { - u32 reg = rinfo->i2c[conn-1].ddc_reg; - u8 *edid = NULL; - int i, j; - - OUTREG(reg, INREG(reg) & - ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); - - OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); - - for (i = 0; i < 3; i++) { - /* For some old monitors we need the - * following process to initialize/stop DDC - */ - OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); - (void)INREG(reg); - msleep(13); - - OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); - for (j = 0; j < 5; j++) { - msleep(10); - if (INREG(reg) & VGA_DDC_CLK_INPUT) - break; - } - if (j == 5) - continue; - - OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN); - (void)INREG(reg); - msleep(15); - OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN); - (void)INREG(reg); - msleep(15); - OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); - (void)INREG(reg); - msleep(15); - - /* Do the real work */ - edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]); - - OUTREG(reg, INREG(reg) | - (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); - msleep(15); - - OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); - for (j = 0; j < 10; j++) { - msleep(10); - if (INREG(reg) & VGA_DDC_CLK_INPUT) - break; - } - - OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); - (void)INREG(reg); - msleep(15); - OUTREG(reg, INREG(reg) | - (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); - if (edid) - break; - } - /* Release the DDC lines when done or the Apple Cinema HD display - * will switch off - */ - OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN)); - (void)INREG(reg); + u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); if (out_edid) *out_edid = edid; diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 365de5dcc88..9a2b0d69b0a 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c @@ -86,6 +86,9 @@ static struct radeon_device_id radeon_workaround_list[] = { BUGFIX("Samsung P35", PCI_VENDOR_ID_SAMSUNG, 0xc00c, radeon_pm_off, radeon_reinitialize_M10), + BUGFIX("Acer Aspire 2010", + PCI_VENDOR_ID_AI, 0x0061, + radeon_pm_off, radeon_reinitialize_M10), { .ident = NULL } }; diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index f25d5d64833..ef5c16f7f5a 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -8,6 +8,7 @@ * <c.pellegrin@exadron.com> * * PM support added by Rodolfo Giometti <giometti@linux.it> + * Cursor enable/disable by Rodolfo Giometti <giometti@linux.it> * * Copyright 2002 MontaVista Software * Author: MontaVista Software, Inc. @@ -110,6 +111,10 @@ static struct fb_var_screeninfo au1100fb_var __initdata = { static struct au1100fb_drv_info drv_info; +static int nocursor = 0; +module_param(nocursor, int, 0644); +MODULE_PARM_DESC(nocursor, "cursor enable/disable"); + /* * Set hardware with var settings. This will enable the controller with a specific * mode, normally validated with the fb_check_var method @@ -422,6 +427,17 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) return 0; } +/* fb_cursor + * Used to disable cursor drawing... + */ +int au1100fb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) +{ + if (nocursor) + return 0; + else + return -EINVAL; /* just to force soft_cursor() call */ +} + static struct fb_ops au1100fb_ops = { .owner = THIS_MODULE, @@ -433,6 +449,7 @@ static struct fb_ops au1100fb_ops = .fb_imageblit = cfb_imageblit, .fb_rotate = au1100fb_fb_rotate, .fb_mmap = au1100fb_fb_mmap, + .fb_cursor = au1100fb_fb_cursor, }; @@ -677,7 +694,7 @@ int au1100fb_setup(char *options) if (options) { while ((this_opt = strsep(&options,",")) != NULL) { /* Panel option */ - if (!strncmp(this_opt, "panel:", 6)) { + if (!strncmp(this_opt, "panel:", 6)) { int i; this_opt += 6; for (i = 0; i < num_panels; i++) { @@ -685,13 +702,18 @@ int au1100fb_setup(char *options) known_lcd_panels[i].name, strlen(this_opt))) { panel_idx = i; - break; + break; + } } - } if (i >= num_panels) { print_warn("Panel %s not supported!", this_opt); } } + if (!strncmp(this_opt, "nocursor", 8)) { + this_opt += 8; + nocursor = 1; + print_info("Cursor disabled"); + } /* Mode option (only option that start with digit) */ else if (isdigit(this_opt[0])) { mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL); @@ -700,7 +722,7 @@ int au1100fb_setup(char *options) /* Unsupported option */ else { print_warn("Unsupported option \"%s\"", this_opt); - } + } } } diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 1b4f75d1f8a..8c041daa3a1 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -133,6 +133,7 @@ static int info_idx = -1; /* console rotation */ static int rotate; +static int fbcon_has_sysfs; static const struct consw fb_con; @@ -396,9 +397,8 @@ static void fb_flashcursor(void *private) vc = vc_cons[ops->currcon].d; if (!vc || !CON_IS_VISIBLE(vc) || - fbcon_is_inactive(vc, info) || registered_fb[con2fb_map[vc->vc_num]] != info || - vc_cons[ops->currcon].d->vc_deccm != 1) { + vc->vc_deccm != 1) { release_console_sem(); return; } @@ -2166,7 +2166,12 @@ static int fbcon_switch(struct vc_data *vc) fbcon_del_cursor_timer(old_info); } - fbcon_add_cursor_timer(info); + if (fbcon_is_inactive(vc, info) || + ops->blank_state != FB_BLANK_UNBLANK) + fbcon_del_cursor_timer(info); + else + fbcon_add_cursor_timer(info); + set_blitting_type(vc, info); ops->cursor_reset = 1; @@ -2276,10 +2281,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) update_screen(vc); } - if (!blank) - fbcon_add_cursor_timer(info); - else + if (fbcon_is_inactive(vc, info) || + ops->blank_state != FB_BLANK_UNBLANK) fbcon_del_cursor_timer(info); + else + fbcon_add_cursor_timer(info); return 0; } @@ -3161,11 +3167,26 @@ static struct class_device_attribute class_device_attrs[] = { static int fbcon_init_class_device(void) { - int i; + int i, error = 0; + + fbcon_has_sysfs = 1; + + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { + error = class_device_create_file(fbcon_class_device, + &class_device_attrs[i]); + + if (error) + break; + } + + if (error) { + while (--i >= 0) + class_device_remove_file(fbcon_class_device, + &class_device_attrs[i]); + + fbcon_has_sysfs = 0; + } - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(fbcon_class_device, - &class_device_attrs[i]); return 0; } @@ -3225,7 +3246,10 @@ static void fbcon_exit(void) module_put(info->fbops->owner); if (info->fbcon_par) { + struct fbcon_ops *ops = info->fbcon_par; + fbcon_del_cursor_timer(info); + kfree(ops->cursor_src); kfree(info->fbcon_par); info->fbcon_par = NULL; } @@ -3271,9 +3295,13 @@ static void __exit fbcon_deinit_class_device(void) { int i; - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(fbcon_class_device, - &class_device_attrs[i]); + if (fbcon_has_sysfs) { + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_remove_file(fbcon_class_device, + &class_device_attrs[i]); + + fbcon_has_sysfs = 0; + } } static void __exit fb_console_exit(void) diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index f244ad066d6..b9386d168c0 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -80,6 +80,8 @@ struct fbcon_ops { char *cursor_data; u8 *fontbuffer; u8 *fontdata; + u8 *cursor_src; + u32 cursor_size; u32 fd_size; }; /* diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 4481c80b8b2..825e6d6972a 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c @@ -391,7 +391,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, ops->cursor_reset = 0; } -int ccw_update_start(struct fb_info *info) +static int ccw_update_start(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; u32 yoffset; diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index 7f92c06afea..c637e631880 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c @@ -375,7 +375,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, ops->cursor_reset = 0; } -int cw_update_start(struct fb_info *info) +static int cw_update_start(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; u32 vxres = GETVXRES(ops->p->scrollmode, info); diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index ab91005e64d..1473506df5d 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c @@ -415,7 +415,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, ops->cursor_reset = 0; } -int ud_update_start(struct fb_info *info) +static int ud_update_start(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; int xoffset, yoffset; diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 557c563e4ae..7d07d838356 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c @@ -20,11 +20,12 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) { + struct fbcon_ops *ops = info->fbcon_par; unsigned int scan_align = info->pixmap.scan_align - 1; unsigned int buf_align = info->pixmap.buf_align - 1; unsigned int i, size, dsize, s_pitch, d_pitch; struct fb_image *image; - u8 *dst, *src; + u8 *dst; if (info->state != FBINFO_STATE_RUNNING) return 0; @@ -32,11 +33,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) s_pitch = (cursor->image.width + 7) >> 3; dsize = s_pitch * cursor->image.height; - src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC); - if (!src) - return -ENOMEM; + if (dsize + sizeof(struct fb_image) != ops->cursor_size) { + if (ops->cursor_src != NULL) + kfree(ops->cursor_src); + ops->cursor_size = dsize + sizeof(struct fb_image); - image = (struct fb_image *) (src + dsize); + ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); + if (!ops->cursor_src) { + ops->cursor_size = 0; + return -ENOMEM; + } + } + + image = (struct fb_image *) (ops->cursor_src + dsize); *image = cursor->image; d_pitch = (s_pitch + scan_align) & ~scan_align; @@ -48,21 +57,23 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) switch (cursor->rop) { case ROP_XOR: for (i = 0; i < dsize; i++) - src[i] = image->data[i] ^ cursor->mask[i]; + ops->cursor_src[i] = image->data[i] ^ + cursor->mask[i]; break; case ROP_COPY: default: for (i = 0; i < dsize; i++) - src[i] = image->data[i] & cursor->mask[i]; + ops->cursor_src[i] = image->data[i] & + cursor->mask[i]; break; } } else - memcpy(src, image->data, dsize); + memcpy(ops->cursor_src, image->data, dsize); - fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); + fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch, + image->height); image->data = dst; info->fbops->fb_imageblit(info, image); - kfree(src); return 0; } diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c new file mode 100644 index 00000000000..3aa6ebf68f1 --- /dev/null +++ b/drivers/video/fb_ddc.c @@ -0,0 +1,116 @@ +/* + * driver/vide/fb_ddc.c - DDC/EDID read support. + * + * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/fb.h> +#include <linux/i2c-algo-bit.h> + +#include "edid.h" + +#define DDC_ADDR 0x50 + +static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) +{ + unsigned char start = 0x0; + struct i2c_msg msgs[] = { + { + .addr = DDC_ADDR, + .len = 1, + .buf = &start, + }, { + .addr = DDC_ADDR, + .flags = I2C_M_RD, + .len = EDID_LENGTH, + } + }; + unsigned char *buf; + + buf = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (!buf) { + dev_warn(&adapter->dev, "unable to allocate memory for EDID " + "block.\n"); + return NULL; + } + msgs[1].buf = buf; + + if (i2c_transfer(adapter, msgs, 2) == 2) + return buf; + + dev_warn(&adapter->dev, "unable to read EDID block.\n"); + kfree(buf); + return NULL; +} + +unsigned char *fb_ddc_read(struct i2c_adapter *adapter) +{ + struct i2c_algo_bit_data *algo_data = adapter->algo_data; + unsigned char *edid = NULL; + int i, j; + + algo_data->setscl(algo_data->data, 1); + algo_data->setscl(algo_data->data, 0); + + for (i = 0; i < 3; i++) { + /* For some old monitors we need the + * following process to initialize/stop DDC + */ + algo_data->setsda(algo_data->data, 0); + msleep(13); + + algo_data->setscl(algo_data->data, 1); + for (j = 0; j < 5; j++) { + msleep(10); + if (algo_data->getscl(algo_data->data)) + break; + } + if (j == 5) + continue; + + algo_data->setsda(algo_data->data, 0); + msleep(15); + algo_data->setscl(algo_data->data, 0); + msleep(15); + algo_data->setsda(algo_data->data, 1); + msleep(15); + + /* Do the real work */ + edid = fb_do_probe_ddc_edid(adapter); + algo_data->setsda(algo_data->data, 0); + algo_data->setscl(algo_data->data, 0); + msleep(15); + + algo_data->setscl(algo_data->data, 1); + for (j = 0; j < 10; j++) { + msleep(10); + if (algo_data->getscl(algo_data->data)) + break; + } + + algo_data->setsda(algo_data->data, 1); + msleep(15); + algo_data->setscl(algo_data->data, 0); + if (edid) + break; + } + /* Release the DDC lines when done or the Apple Cinema HD display + * will switch off + */ + algo_data->setsda(algo_data->data, 0); + algo_data->setscl(algo_data->data, 0); + + return edid; +} + +EXPORT_SYMBOL_GPL(fb_ddc_read); + +MODULE_AUTHOR("Dennis Munsie <dmunsie@cecropia.com>"); +MODULE_DESCRIPTION("DDC/EDID reading support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 17961e3ecaa..93ffcdd95f5 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -554,7 +554,8 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset, int clen; clen = 0; - for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && len < 4000; fi++) + for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && clen < 4000; + fi++) if (*fi) clen += sprintf(buf + clen, "%d %s\n", (*fi)->node, diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index c151dcf6878..d3a50417ed9 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -20,6 +20,8 @@ #include <linux/console.h> #include <linux/module.h> +#define FB_SYSFS_FLAG_ATTR 1 + /** * framebuffer_alloc - creates a new frame buffer info structure * @@ -483,12 +485,27 @@ static struct class_device_attribute class_device_attrs[] = { int fb_init_class_device(struct fb_info *fb_info) { - unsigned int i; + int i, error = 0; + class_set_devdata(fb_info->class_device, fb_info); - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(fb_info->class_device, - &class_device_attrs[i]); + fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; + + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { + error = class_device_create_file(fb_info->class_device, + &class_device_attrs[i]); + + if (error) + break; + } + + if (error) { + while (--i >= 0) + class_device_remove_file(fb_info->class_device, + &class_device_attrs[i]); + fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; + } + return 0; } @@ -496,9 +513,13 @@ void fb_cleanup_class_device(struct fb_info *fb_info) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(fb_info->class_device, - &class_device_attrs[i]); + if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) { + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_remove_file(fb_info->class_device, + &class_device_attrs[i]); + + fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; + } } #ifdef CONFIG_FB_BACKLIGHT diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index 7d06b38e80a..b38d805db31 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c @@ -19,7 +19,6 @@ #include "i810_main.h" #include "../edid.h" -#define I810_DDC 0x50 /* bit locations in the registers */ #define SCL_DIR_MASK 0x0001 #define SCL_DIR 0x0002 @@ -150,53 +149,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par) par->chan[2].par = NULL; } -static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan) -{ - u8 start = 0x0; - struct i2c_msg msgs[] = { - { - .addr = I810_DDC, - .len = 1, - .buf = &start, - }, { - .addr = I810_DDC, - .flags = I2C_M_RD, - .len = EDID_LENGTH, - }, - }; - u8 *buf; - - buf = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (!buf) { - DPRINTK("i810-i2c: Failed to allocate memory\n"); - return NULL; - } - msgs[1].buf = buf; - - if (i2c_transfer(&chan->adapter, msgs, 2) == 2) { - DPRINTK("i810-i2c: I2C Transfer successful\n"); - return buf; - } - - DPRINTK("i810-i2c: Unable to read EDID block.\n"); - kfree(buf); - return NULL; -} - int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn) { struct i810fb_par *par = info->par; u8 *edid = NULL; - int i; DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn+1); if (conn < par->ddc_num) { - for (i = 0; i < 3; i++) { - /* Do the real work */ - edid = i810_do_probe_i2c_edid(&par->chan[conn]); - if (edid) - break; - } + edid = fb_ddc_read(&par->chan[conn].adapter); } else { const u8 *e = fb_firmware_edid(info->device); diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index d42edaccb84..b55a12d95eb 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -1602,7 +1602,10 @@ static int i810fb_resume(struct pci_dev *dev) acquire_console_sem(); pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); - pci_enable_device(dev); + + if (pci_enable_device(dev)) + goto fail; + pci_set_master(dev); agp_bind_memory(par->i810_gtt.i810_fb_memory, par->fb.offset); @@ -1611,6 +1614,7 @@ static int i810fb_resume(struct pci_dev *dev) i810fb_set_par(info); fb_set_suspend (info, 0); info->fbops->fb_blank(VESA_NO_BLANKING, info); +fail: release_console_sem(); return 0; } diff --git a/drivers/video/intelfb/Makefile b/drivers/video/intelfb/Makefile index 722d21d6e5c..6c782d3ae1b 100644 --- a/drivers/video/intelfb/Makefile +++ b/drivers/video/intelfb/Makefile @@ -1,6 +1,8 @@ obj-$(CONFIG_FB_INTEL) += intelfb.o -intelfb-objs := intelfbdrv.o intelfbhw.o +intelfb-y := intelfbdrv.o intelfbhw.o +intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o +intelfb-objs := $(intelfb-y) ifdef CONFIG_FB_INTEL_DEBUG #EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index e290d7460e1..80b94c19a9f 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h @@ -6,6 +6,10 @@ #include <linux/agp_backend.h> #include <linux/fb.h> +#ifdef CONFIG_FB_INTEL_I2C +#include <linux/i2c.h> +#include <linux/i2c-algo-bit.h> +#endif /*** Version/name ***/ #define INTELFB_VERSION "0.9.4" @@ -115,6 +119,29 @@ /* Intel agpgart driver */ #define AGP_PHYSICAL_MEMORY 2 +/* store information about an Ixxx DVO */ +/* The i830->i865 use multiple DVOs with multiple i2cs */ +/* the i915, i945 have a single sDVO i2c bus - which is different */ +#define MAX_OUTPUTS 6 + +/* these are outputs from the chip - integrated only + external chips are via DVO or SDVO output */ +#define INTELFB_OUTPUT_UNUSED 0 +#define INTELFB_OUTPUT_ANALOG 1 +#define INTELFB_OUTPUT_DVO 2 +#define INTELFB_OUTPUT_SDVO 3 +#define INTELFB_OUTPUT_LVDS 4 +#define INTELFB_OUTPUT_TVOUT 5 + +#define INTELFB_DVO_CHIP_NONE 0 +#define INTELFB_DVO_CHIP_LVDS 1 +#define INTELFB_DVO_CHIP_TMDS 2 +#define INTELFB_DVO_CHIP_TVOUT 4 + +#define INTELFB_OUTPUT_PIPE_NC 0 +#define INTELFB_OUTPUT_PIPE_A 1 +#define INTELFB_OUTPUT_PIPE_B 2 + /*** Data Types ***/ /* supported chipsets */ @@ -195,6 +222,10 @@ struct intelfb_hwstate { u32 mem_mode; u32 fw_blc_0; u32 fw_blc_1; + u16 hwstam; + u16 ier; + u16 iir; + u16 imr; }; struct intelfb_heap_data { @@ -204,6 +235,33 @@ struct intelfb_heap_data { u32 size; // in bytes }; +#ifdef CONFIG_FB_INTEL_I2C +struct intelfb_i2c_chan { + struct intelfb_info *dinfo; + u32 reg; + struct i2c_adapter adapter; + struct i2c_algo_bit_data algo; +}; +#endif + +struct intelfb_output_rec { + int type; + int pipe; + int flags; + +#ifdef CONFIG_FB_INTEL_I2C + struct intelfb_i2c_chan i2c_bus; + struct intelfb_i2c_chan ddc_bus; +#endif +}; + +struct intelfb_vsync { + wait_queue_head_t wait; + unsigned int count; + int pan_display; + u32 pan_offset; +}; + struct intelfb_info { struct fb_info *info; struct fb_ops *fbops; @@ -220,7 +278,7 @@ struct intelfb_info { u8 fbmem_gart; /* mtrr support */ - u32 mtrr_reg; + int mtrr_reg; u32 has_mtrr; /* heap data */ @@ -267,6 +325,12 @@ struct intelfb_info { int fixed_mode; int ring_active; int flag; + unsigned long irq_flags; + int open; + + /* vsync */ + struct intelfb_vsync vsync; + spinlock_t int_lock; /* hw cursor */ int cursor_on; @@ -285,12 +349,25 @@ struct intelfb_info { /* index into plls */ int pll_index; + + /* outputs */ + int num_outputs; + struct intelfb_output_rec output[MAX_OUTPUTS]; }; #define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) +#ifndef FBIO_WAITFORVSYNC +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) +#endif + /*** function prototypes ***/ extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); +#ifdef CONFIG_FB_INTEL_I2C +extern void intelfb_create_i2c_busses(struct intelfb_info *dinfo); +extern void intelfb_delete_i2c_busses(struct intelfb_info *dinfo); +#endif + #endif /* _INTELFB_H */ diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c new file mode 100644 index 00000000000..c1113d6e941 --- /dev/null +++ b/drivers/video/intelfb/intelfb_i2c.c @@ -0,0 +1,200 @@ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/pci.h> +#include <linux/fb.h> + +#include <linux/i2c.h> +#include <linux/i2c-id.h> +#include <linux/i2c-algo-bit.h> + +#include <asm/io.h> + +#include "intelfb.h" +#include "intelfbhw.h" + +/* bit locations in the registers */ +#define SCL_DIR_MASK 0x0001 +#define SCL_DIR 0x0002 +#define SCL_VAL_MASK 0x0004 +#define SCL_VAL_OUT 0x0008 +#define SCL_VAL_IN 0x0010 +#define SDA_DIR_MASK 0x0100 +#define SDA_DIR 0x0200 +#define SDA_VAL_MASK 0x0400 +#define SDA_VAL_OUT 0x0800 +#define SDA_VAL_IN 0x1000 + +static void intelfb_gpio_setscl(void *data, int state) +{ + struct intelfb_i2c_chan *chan = data; + struct intelfb_info *dinfo = chan->dinfo; + u32 val; + + OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); + val = INREG(chan->reg); +} + +static void intelfb_gpio_setsda(void *data, int state) +{ + struct intelfb_i2c_chan *chan = data; + struct intelfb_info *dinfo = chan->dinfo; + u32 val; + + OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); + val = INREG(chan->reg); +} + +static int intelfb_gpio_getscl(void *data) +{ + struct intelfb_i2c_chan *chan = data; + struct intelfb_info *dinfo = chan->dinfo; + u32 val; + + OUTREG(chan->reg, SCL_DIR_MASK); + OUTREG(chan->reg, 0); + val = INREG(chan->reg); + return ((val & SCL_VAL_IN) != 0); +} + +static int intelfb_gpio_getsda(void *data) +{ + struct intelfb_i2c_chan *chan = data; + struct intelfb_info *dinfo = chan->dinfo; + u32 val; + + OUTREG(chan->reg, SDA_DIR_MASK); + OUTREG(chan->reg, 0); + val = INREG(chan->reg); + return ((val & SDA_VAL_IN) != 0); +} + +static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, + struct intelfb_i2c_chan *chan, + const u32 reg, const char *name) +{ + int rc; + + chan->dinfo = dinfo; + chan->reg = reg; + snprintf(chan->adapter.name, I2C_NAME_SIZE, "intelfb %s", name); + chan->adapter.owner = THIS_MODULE; + chan->adapter.id = I2C_HW_B_INTELFB; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &chan->dinfo->pdev->dev; + chan->algo.setsda = intelfb_gpio_setsda; + chan->algo.setscl = intelfb_gpio_setscl; + chan->algo.getsda = intelfb_gpio_getsda; + chan->algo.getscl = intelfb_gpio_getscl; + chan->algo.udelay = 40; + chan->algo.timeout = 20; + chan->algo.data = chan; + + i2c_set_adapdata(&chan->adapter, chan); + + /* Raise SCL and SDA */ + intelfb_gpio_setsda(chan, 1); + intelfb_gpio_setscl(chan, 1); + udelay(20); + + rc = i2c_bit_add_bus(&chan->adapter); + if (rc == 0) + DBG_MSG("I2C bus %s registered.\n", name); + else + WRN_MSG("Failed to register I2C bus %s.\n", name); + return rc; +} + +void intelfb_create_i2c_busses(struct intelfb_info *dinfo) +{ + int i = 0; + + /* everyone has at least a single analog output */ + dinfo->num_outputs = 1; + dinfo->output[i].type = INTELFB_OUTPUT_ANALOG; + + /* setup the DDC bus for analog output */ + intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, "CRTDDC_A"); + i++; + + /* need to add the output busses for each device + - this function is very incomplete + - i915GM has LVDS and TVOUT for example + */ + switch(dinfo->chipset) { + case INTEL_830M: + case INTEL_845G: + case INTEL_855GM: + case INTEL_865G: + dinfo->output[i].type = INTELFB_OUTPUT_DVO; + intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOD, "DVODDC_D"); + intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "DVOI2C_E"); + i++; + break; + case INTEL_915G: + case INTEL_915GM: + /* has some LVDS + tv-out */ + case INTEL_945G: + case INTEL_945GM: + /* SDVO ports have a single control bus - 2 devices */ + dinfo->output[i].type = INTELFB_OUTPUT_SDVO; + intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "SDVOCTRL_E"); + /* TODO: initialize the SDVO */ +// I830SDVOInit(pScrn, i, DVOB); + i++; + + /* set up SDVOC */ + dinfo->output[i].type = INTELFB_OUTPUT_SDVO; + dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus; + /* TODO: initialize the SDVO */ +// I830SDVOInit(pScrn, i, DVOC); + i++; + break; + } + dinfo->num_outputs = i; +} + +void intelfb_delete_i2c_busses(struct intelfb_info *dinfo) +{ + int i; + + for (i = 0; i < MAX_OUTPUTS; i++) { + if (dinfo->output[i].i2c_bus.dinfo) { + i2c_bit_del_bus(&dinfo->output[i].i2c_bus.adapter); + dinfo->output[i].i2c_bus.dinfo = NULL; + } + if (dinfo->output[i].ddc_bus.dinfo) { + i2c_bit_del_bus(&dinfo->output[i].ddc_bus.adapter); + dinfo->output[i].ddc_bus.dinfo = NULL; + } + } +} diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 06af89d44a0..6f9de04193d 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -136,6 +136,8 @@ static void __devinit get_initial_mode(struct intelfb_info *dinfo); static void update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var); +static int intelfb_open(struct fb_info *info, int user); +static int intelfb_release(struct fb_info *info, int user); static int intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); static int intelfb_set_par(struct fb_info *info); @@ -194,6 +196,8 @@ static int num_registered = 0; /* fb ops */ static struct fb_ops intel_fb_ops = { .owner = THIS_MODULE, + .fb_open = intelfb_open, + .fb_release = intelfb_release, .fb_check_var = intelfb_check_var, .fb_set_par = intelfb_set_par, .fb_setcolreg = intelfb_setcolreg, @@ -446,6 +450,8 @@ cleanup(struct intelfb_info *dinfo) if (!dinfo) return; + intelfbhw_disable_irq(dinfo); + fb_dealloc_cmap(&dinfo->info->cmap); kfree(dinfo->info->pixmap.addr); @@ -467,6 +473,11 @@ cleanup(struct intelfb_info *dinfo) agp_free_memory(dinfo->gtt_ring_mem); } +#ifdef CONFIG_FB_INTEL_I2C + /* un-register I2C bus */ + intelfb_delete_i2c_busses(dinfo); +#endif + if (dinfo->mmio_base) iounmap((void __iomem *)dinfo->mmio_base); if (dinfo->aperture.virtual) @@ -844,6 +855,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) if (bailearly == 5) bailout(dinfo); +#ifdef CONFIG_FB_INTEL_I2C + /* register I2C bus */ + intelfb_create_i2c_busses(dinfo); +#endif + if (bailearly == 6) bailout(dinfo); @@ -888,6 +904,13 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) } dinfo->registered = 1; + dinfo->open = 0; + + init_waitqueue_head(&dinfo->vsync.wait); + spin_lock_init(&dinfo->int_lock); + dinfo->irq_flags = 0; + dinfo->vsync.pan_display = 0; + dinfo->vsync.pan_offset = 0; return 0; @@ -1188,6 +1211,34 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) ***************************************************************/ static int +intelfb_open(struct fb_info *info, int user) +{ + struct intelfb_info *dinfo = GET_DINFO(info); + + if (user) { + dinfo->open++; + } + + return 0; +} + +static int +intelfb_release(struct fb_info *info, int user) +{ + struct intelfb_info *dinfo = GET_DINFO(info); + + if (user) { + dinfo->open--; + msleep(1); + if (!dinfo->open) { + intelfbhw_disable_irq(dinfo); + } + } + + return 0; +} + +static int intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { int change_var = 0; @@ -1433,6 +1484,19 @@ static int intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { int retval = 0; + struct intelfb_info *dinfo = GET_DINFO(info); + u32 pipe = 0; + + switch (cmd) { + case FBIO_WAITFORVSYNC: + if (get_user(pipe, (__u32 __user *)arg)) + return -EFAULT; + + retval = intelfbhw_wait_for_vsync(dinfo, pipe); + break; + default: + break; + } return retval; } diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 2a9322f9cfd..f887f1efd3f 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -32,6 +32,7 @@ #include <linux/pci.h> #include <linux/vmalloc.h> #include <linux/pagemap.h> +#include <linux/interrupt.h> #include <asm/io.h> @@ -368,7 +369,13 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) offset += dinfo->fb.offset << 12; - OUTREG(DSPABASE, offset); + dinfo->vsync.pan_offset = offset; + if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) { + dinfo->vsync.pan_display = 1; + } else { + dinfo->vsync.pan_display = 0; + OUTREG(DSPABASE, offset); + } return 0; } @@ -585,6 +592,11 @@ intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, hw->fw_blc_0 = INREG(FW_BLC_0); hw->fw_blc_1 = INREG(FW_BLC_1); + hw->hwstam = INREG16(HWSTAM); + hw->ier = INREG16(IER); + hw->iir = INREG16(IIR); + hw->imr = INREG16(IMR); + return 0; } @@ -613,6 +625,7 @@ static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvd return vco / p; } +#if REGDUMP static void intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) { @@ -638,6 +651,7 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) *o_p1 = p1; *o_p2 = p2; } +#endif void @@ -794,6 +808,10 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0); printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1); + printk(" HWSTAM 0x%04x\n", hw->hwstam); + printk(" IER 0x%04x\n", hw->ier); + printk(" IIR 0x%04x\n", hw->iir); + printk(" IMR 0x%04x\n", hw->imr); printk("hw state dump end\n"); #endif } @@ -1932,3 +1950,119 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) { addr += 16; } } + +static irqreturn_t +intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) { + int handled = 0; + u16 tmp; + struct intelfb_info *dinfo = (struct intelfb_info *)dev_id; + + spin_lock(&dinfo->int_lock); + + tmp = INREG16(IIR); + tmp &= VSYNC_PIPE_A_INTERRUPT; + + if (tmp == 0) { + spin_unlock(&dinfo->int_lock); + return IRQ_RETVAL(handled); + } + + OUTREG16(IIR, tmp); + + if (tmp & VSYNC_PIPE_A_INTERRUPT) { + dinfo->vsync.count++; + if (dinfo->vsync.pan_display) { + dinfo->vsync.pan_display = 0; + OUTREG(DSPABASE, dinfo->vsync.pan_offset); + } + wake_up_interruptible(&dinfo->vsync.wait); + handled = 1; + } + + spin_unlock(&dinfo->int_lock); + + return IRQ_RETVAL(handled); +} + +int +intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) { + + if (!test_and_set_bit(0, &dinfo->irq_flags)) { + if (request_irq(dinfo->pdev->irq, intelfbhw_irq, SA_SHIRQ, "intelfb", dinfo)) { + clear_bit(0, &dinfo->irq_flags); + return -EINVAL; + } + + spin_lock_irq(&dinfo->int_lock); + OUTREG16(HWSTAM, 0xfffe); + OUTREG16(IMR, 0x0); + OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT); + spin_unlock_irq(&dinfo->int_lock); + } else if (reenable) { + u16 ier; + + spin_lock_irq(&dinfo->int_lock); + ier = INREG16(IER); + if ((ier & VSYNC_PIPE_A_INTERRUPT)) { + DBG_MSG("someone disabled the IRQ [%08X]\n", ier); + OUTREG(IER, VSYNC_PIPE_A_INTERRUPT); + } + spin_unlock_irq(&dinfo->int_lock); + } + return 0; +} + +void +intelfbhw_disable_irq(struct intelfb_info *dinfo) { + u16 tmp; + + if (test_and_clear_bit(0, &dinfo->irq_flags)) { + if (dinfo->vsync.pan_display) { + dinfo->vsync.pan_display = 0; + OUTREG(DSPABASE, dinfo->vsync.pan_offset); + } + spin_lock_irq(&dinfo->int_lock); + OUTREG16(HWSTAM, 0xffff); + OUTREG16(IMR, 0xffff); + OUTREG16(IER, 0x0); + + tmp = INREG16(IIR); + OUTREG16(IIR, tmp); + spin_unlock_irq(&dinfo->int_lock); + + free_irq(dinfo->pdev->irq, dinfo); + } +} + +int +intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) { + struct intelfb_vsync *vsync; + unsigned int count; + int ret; + + switch (pipe) { + case 0: + vsync = &dinfo->vsync; + break; + default: + return -ENODEV; + } + + ret = intelfbhw_enable_irq(dinfo, 0); + if (ret) { + return ret; + } + + count = vsync->count; + ret = wait_event_interruptible_timeout(vsync->wait, count != vsync->count, HZ/10); + if (ret < 0) { + return ret; + } + if (ret == 0) { + intelfbhw_enable_irq(dinfo, 1); + DBG_MSG("wait_for_vsync timed out!\n"); + return -ETIMEDOUT; + } + + return 0; +} diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h index 10acda098b7..8c54ba8fbdd 100644 --- a/drivers/video/intelfb/intelfbhw.h +++ b/drivers/video/intelfb/intelfbhw.h @@ -88,6 +88,19 @@ #define INSTDONE 0x2090 #define PRI_RING_EMPTY 1 +#define HWSTAM 0x2098 +#define IER 0x20A0 +#define IIR 0x20A4 +#define IMR 0x20A8 +#define VSYNC_PIPE_A_INTERRUPT (1 << 7) +#define PIPE_A_EVENT_INTERRUPT (1 << 4) +#define VSYNC_PIPE_B_INTERRUPT (1 << 5) +#define PIPE_B_EVENT_INTERRUPT (1 << 4) +#define HOST_PORT_EVENT_INTERRUPT (1 << 3) +#define CAPTURE_EVENT_INTERRUPT (1 << 2) +#define USER_DEFINED_INTERRUPT (1 << 1) +#define BREAKPOINT_INTERRUPT 1 + #define INSTPM 0x20c0 #define SYNC_FLUSH_ENABLE (1 << 5) @@ -113,6 +126,12 @@ #define FW_DISPC_BL_SHIFT 8 #define FW_DISPC_BL_MASK 0x7 +#define GPIOA 0x5010 +#define GPIOB 0x5014 +#define GPIOC 0x5018 // this may be external DDC on i830 +#define GPIOD 0x501C // this is DVO DDC +#define GPIOE 0x5020 // this is DVO i2C +#define GPIOF 0x5024 /* PLL registers */ #define VGA0_DIVISOR 0x06000 @@ -468,9 +487,12 @@ /* I/O macros */ #define INREG8(addr) readb((u8 __iomem *)(dinfo->mmio_base + (addr))) +#define INREG16(addr) readw((u16 __iomem *)(dinfo->mmio_base + (addr))) #define INREG(addr) readl((u32 __iomem *)(dinfo->mmio_base + (addr))) #define OUTREG8(addr, val) writeb((val),(u8 __iomem *)(dinfo->mmio_base + \ (addr))) +#define OUTREG16(addr, val) writew((val),(u16 __iomem *)(dinfo->mmio_base + \ + (addr))) #define OUTREG(addr, val) writel((val),(u32 __iomem *)(dinfo->mmio_base + \ (addr))) @@ -545,5 +567,8 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height, u8 *data); extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo); +extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable); +extern void intelfbhw_disable_irq(struct intelfb_info *dinfo); +extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe); #endif /* _INTELFBHW_H */ diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 4a57dabb77d..7acf01c181e 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -2277,10 +2277,13 @@ static void __init matroxfb_init_params(void) { } } -static void __init matrox_init(void) { +static int __init matrox_init(void) { + int err; + matroxfb_init_params(); - pci_register_driver(&matroxfb_driver); + err = pci_register_driver(&matroxfb_driver); dev = -1; /* accept all new devices... */ + return err; } /* **************************** exit-time only **************************** */ @@ -2437,6 +2440,7 @@ static int __initdata initialized = 0; static int __init matroxfb_init(void) { char *option = NULL; + int err = 0; DBG(__FUNCTION__) @@ -2448,11 +2452,11 @@ static int __init matroxfb_init(void) return -ENXIO; if (!initialized) { initialized = 1; - matrox_init(); + err = matrox_init(); } hotplug = 1; /* never return failure, user can hotplug matrox later... */ - return 0; + return err; } module_init(matroxfb_init); diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index 6849ab75d40..a32d1af79e0 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c @@ -118,8 +118,19 @@ static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps, /* convert pixclock to KHz */ pixclock = PICOS2KHZ(pixclock_ps); + /* PLL output freq = (ref_clk * M) / (N * 2^P) + * + * M: 1 to 63 + * N: 1 to 7 + * P: 0 to 7 + */ + + /* RAPH: When N==1, the resulting pixel clock appears to + * get divided by 2. Preventing N=1 by starting the following + * loop at 2 prevents this. Is this a bug with my chip + * revision or something I dont understand? */ for (m = 1; m < 64; m++) { - for (n = 1; n < 8; n++) { + for (n = 2; n < 8; n++) { for (p = 0; p < 8; p++) { clk = (ref_clk * m) / (n * (1 << p)); err = (clk > pixclock) ? (clk - pixclock) : @@ -244,8 +255,8 @@ static int mbxfb_set_par(struct fb_info *info) /* setup resolution */ gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT)); - gsctrl |= Gsctrl_Width(info->var.xres - 1) | - Gsctrl_Height(info->var.yres - 1); + gsctrl |= Gsctrl_Width(info->var.xres) | + Gsctrl_Height(info->var.yres); writel(gsctrl, GSCTRL); udelay(1000); @@ -402,8 +413,8 @@ static void __devinit setup_graphics(struct fb_info *fbi) { unsigned long gsctrl; - gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) | - Gsctrl_Height(fbi->var.yres - 1); + gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) | + Gsctrl_Height(fbi->var.yres); switch (fbi->var.bits_per_pixel) { case 16: if (fbi->var.green.length == 5) diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 19eef3a0902..e48de3c9fd1 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c @@ -160,51 +160,12 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par) } -static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan) -{ - u8 start = 0x0; - struct i2c_msg msgs[] = { - { - .addr = 0x50, - .len = 1, - .buf = &start, - }, { - .addr = 0x50, - .flags = I2C_M_RD, - .len = EDID_LENGTH, - }, - }; - u8 *buf; - - if (!chan->par) - return NULL; - - buf = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (!buf) { - dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n"); - return NULL; - } - msgs[1].buf = buf; - - if (i2c_transfer(&chan->adapter, msgs, 2) == 2) - return buf; - dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n"); - kfree(buf); - return NULL; -} - int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) { struct nvidia_par *par = info->par; - u8 *edid = NULL; - int i; - - for (i = 0; i < 3; i++) { - /* Do the real work */ - edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]); - if (edid) - break; - } + u8 *edid; + + edid = fb_ddc_read(&par->chan[conn - 1].adapter); if (!edid && conn == 1) { /* try to get from firmware */ diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index f8cd4c519ae..eb24107bcc8 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -28,6 +28,9 @@ #include <asm/prom.h> #include <asm/pci-bridge.h> #endif +#ifdef CONFIG_BOOTX_TEXT +#include <asm/btext.h> +#endif #include "nv_local.h" #include "nv_type.h" @@ -681,6 +684,13 @@ static int nvidiafb_set_par(struct fb_info *info) nvidia_vga_protect(par, 0); +#ifdef CONFIG_BOOTX_TEXT + /* Update debug text engine */ + btext_update_display(info->fix.smem_start, + info->var.xres, info->var.yres, + info->var.bits_per_pixel, info->fix.line_length); +#endif + NVTRACE_LEAVE(); return 0; } @@ -984,7 +994,10 @@ static int nvidiafb_resume(struct pci_dev *dev) if (par->pm_state != PM_EVENT_FREEZE) { pci_restore_state(dev); - pci_enable_device(dev); + + if (pci_enable_device(dev)) + goto fail; + pci_set_master(dev); } @@ -993,6 +1006,7 @@ static int nvidiafb_resume(struct pci_dev *dev) fb_set_suspend (info, 0); nvidiafb_blank(FB_BLANK_UNBLANK, info); +fail: release_console_sem(); return 0; } diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 4acde4f7dbf..b120896c8ab 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -393,8 +393,8 @@ static void riva_bl_init(struct riva_par *par) mutex_lock(&info->bl_mutex); info->bl_dev = bd; fb_bl_default_curve(info, 0, - 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, - 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); + MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, + FB_BACKLIGHT_MAX); mutex_unlock(&info->bl_mutex); down(&bd->sem); @@ -784,7 +784,7 @@ static void riva_load_video_mode(struct fb_info *info) NVTRACE_ENTER(); /* time to calculate */ - rivafb_blank(1, info); + rivafb_blank(FB_BLANK_NORMAL, info); bpp = info->var.bits_per_pixel; if (bpp == 16 && info->var.green.length == 5) @@ -917,7 +917,7 @@ static void riva_load_video_mode(struct fb_info *info) par->current_state = newmode; riva_load_state(par, &par->current_state); par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */ - rivafb_blank(0, info); + rivafb_blank(FB_BLANK_UNBLANK, info); NVTRACE_LEAVE(); } diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index 9751c37c0bf..c15b259af64 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c @@ -25,8 +25,6 @@ #include "rivafb.h" #include "../edid.h" -#define RIVA_DDC 0x50 - static void riva_gpio_setscl(void* data, int state) { struct riva_i2c_chan *chan = data; @@ -158,50 +156,12 @@ void riva_delete_i2c_busses(struct riva_par *par) par->chan[2].par = NULL; } -static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan) -{ - u8 start = 0x0; - struct i2c_msg msgs[] = { - { - .addr = RIVA_DDC, - .len = 1, - .buf = &start, - }, { - .addr = RIVA_DDC, - .flags = I2C_M_RD, - .len = EDID_LENGTH, - }, - }; - u8 *buf; - - if (!chan->par) - return NULL; - - buf = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (!buf) { - dev_warn(&chan->par->pdev->dev, "Out of memory!\n"); - return NULL; - } - msgs[1].buf = buf; - - if (i2c_transfer(&chan->adapter, msgs, 2) == 2) - return buf; - dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n"); - kfree(buf); - return NULL; -} - int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid) { u8 *edid = NULL; - int i; - for (i = 0; i < 3; i++) { - /* Do the real work */ - edid = riva_do_probe_i2c_edid(&par->chan[conn-1]); - if (edid) - break; - } + edid = fb_ddc_read(&par->chan[conn-1].adapter); + if (out_edid) *out_edid = edid; if (!edid) diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index d7d810dbf0b..3f94223b7f0 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c @@ -213,52 +213,15 @@ void savagefb_delete_i2c_busses(struct fb_info *info) par->chan.par = NULL; } -static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan) -{ - u8 start = 0x0; - struct i2c_msg msgs[] = { - { - .addr = SAVAGE_DDC, - .len = 1, - .buf = &start, - }, { - .addr = SAVAGE_DDC, - .flags = I2C_M_RD, - .len = EDID_LENGTH, - }, - }; - u8 *buf = NULL; - - if (chan->par) { - buf = kmalloc(EDID_LENGTH, GFP_KERNEL); - - if (buf) { - msgs[1].buf = buf; - - if (i2c_transfer(&chan->adapter, msgs, 2) != 2) { - dev_dbg(&chan->par->pcidev->dev, - "Unable to read EDID block.\n"); - kfree(buf); - buf = NULL; - } - } - } - - return buf; -} - int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid) { struct savagefb_par *par = info->par; - u8 *edid = NULL; - int i; - - for (i = 0; i < 3; i++) { - /* Do the real work */ - edid = savage_do_probe_i2c_edid(&par->chan); - if (edid) - break; - } + u8 *edid; + + if (par->chan.par) + edid = fb_ddc_read(&par->chan.adapter); + else + edid = NULL; if (!edid) { /* try to get from firmware */ diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index 7ecab87cef0..59d12844b4d 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h @@ -77,16 +77,9 @@ #include <linux/types.h> #include <asm/io.h> #include <linux/fb.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <video/fbcon.h> -#endif #include "sis.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <linux/sisfb.h> -#else #include <video/sisfb.h> #endif -#endif /* Mode numbers */ static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h index bc321dc57e9..4f3a28699d3 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/sis/init301.h @@ -71,16 +71,9 @@ #include <linux/types.h> #include <asm/io.h> #include <linux/fb.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <video/fbcon.h> -#endif #include "sis.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <linux/sisfb.h> -#else #include <video/sisfb.h> #endif -#endif static const unsigned char SiS_YPbPrTable[3][64] = { { diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c index 09f5d758b6c..c3884a29f4c 100644 --- a/drivers/video/sis/initextlfb.c +++ b/drivers/video/sis/initextlfb.c @@ -34,12 +34,10 @@ #include <linux/types.h> #include <linux/fb.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno, unsigned char rateindex); int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, unsigned char rateindex, struct fb_var_screeninfo *var); -#endif BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex); @@ -49,7 +47,6 @@ extern BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *Mode extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno, unsigned char rateindex) @@ -177,7 +174,6 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, return 1; } -#endif /* Linux >= 2.5 */ BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal, diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h index f59568020eb..d048bd39961 100644 --- a/drivers/video/sis/osdef.h +++ b/drivers/video/sis/osdef.h @@ -100,11 +100,7 @@ #define SIS315H #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #define SIS_LINUX_KERNEL_26 -#else -#define SIS_LINUX_KERNEL_24 -#endif #if !defined(SIS300) && !defined(SIS315H) #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c index 3b7ce032e2e..7addf91d2fe 100644 --- a/drivers/video/sis/sis_accel.c +++ b/drivers/video/sis/sis_accel.c @@ -32,22 +32,10 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/fb.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <linux/console.h> -#endif #include <linux/ioport.h> #include <linux/types.h> - #include <asm/io.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <video/fbcon.h> -#include <video/fbcon-cfb8.h> -#include <video/fbcon-cfb16.h> -#include <video/fbcon-cfb24.h> -#include <video/fbcon-cfb32.h> -#endif - #include "sis.h" #include "sis_accel.h" @@ -91,11 +79,9 @@ static const u8 sisPatALUConv[] = 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ }; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) static const int myrops[] = { 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; -#endif /* 300 series ----------------------------------------------------- */ #ifdef CONFIG_FB_SIS_300 @@ -315,8 +301,6 @@ void sisfb_syncaccel(struct sis_video_info *ivideo) } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */ - int fbcon_sis_sync(struct fb_info *info) { struct sis_video_info *ivideo = (struct sis_video_info *)info->par; @@ -438,13 +422,3 @@ void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area) sisfb_syncaccel(ivideo); } - -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */ - -#include "sisfb_accel_2_4.h" - -#endif /* KERNEL VERSION */ - - diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h index 046e2c4a8e0..30e03cdf6b8 100644 --- a/drivers/video/sis/sis_accel.h +++ b/drivers/video/sis/sis_accel.h @@ -390,25 +390,11 @@ MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \ CmdQueLen -= 2; - int sisfb_initaccel(struct sis_video_info *ivideo); void sisfb_syncaccel(struct sis_video_info *ivideo); -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33) -void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty, - int dstx, int height, int width); -void fbcon_sis_revc(struct display *p, int srcy, int srcx); -void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy, - int srcx, int height, int width); -void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy, - int srcx, int height, int width); -void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy, - int srcx, int height, int width); -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) int fbcon_sis_sync(struct fb_info *info); void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect); void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area); -#endif #endif diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 895ebda7d9e..baaf495a0a6 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -35,9 +35,7 @@ #include <linux/version.h> #include <linux/module.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #include <linux/moduleparam.h> -#endif #include <linux/kernel.h> #include <linux/smp_lock.h> #include <linux/spinlock.h> @@ -58,9 +56,6 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/vmalloc.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <linux/vt_kern.h> -#endif #include <linux/capability.h> #include <linux/fs.h> #include <linux/types.h> @@ -70,35 +65,9 @@ #include <asm/mtrr.h> #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <video/fbcon.h> -#include <video/fbcon-cfb8.h> -#include <video/fbcon-cfb16.h> -#include <video/fbcon-cfb24.h> -#include <video/fbcon-cfb32.h> -#endif - #include "sis.h" #include "sis_main.h" -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) -#error "This version of sisfb requires at least 2.6.3" -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#ifdef FBCON_HAS_CFB8 -extern struct display_switch fbcon_sis8; -#endif -#ifdef FBCON_HAS_CFB16 -extern struct display_switch fbcon_sis16; -#endif -#ifdef FBCON_HAS_CFB32 -extern struct display_switch fbcon_sis32; -#endif -#endif - static void sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_command); @@ -114,17 +83,7 @@ sisfb_setdefaultparms(void) sisfb_max = -1; sisfb_userom = -1; sisfb_useoem = -1; -#ifdef MODULE - /* Module: "None" for 2.4, default mode for 2.5+ */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - sisfb_mode_idx = -1; -#else - sisfb_mode_idx = MODE_INDEX_NONE; -#endif -#else - /* Static: Default mode */ sisfb_mode_idx = -1; -#endif sisfb_parm_rate = -1; sisfb_crt1off = 0; sisfb_forcecrt1 = -1; @@ -142,10 +101,6 @@ sisfb_setdefaultparms(void) sisfb_tvxposoffset = 0; sisfb_tvyposoffset = 0; sisfb_nocrt2rate = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - sisfb_inverse = 0; - sisfb_fontname[0] = 0; -#endif #if !defined(__i386__) && !defined(__x86_64__) sisfb_resetcard = 0; sisfb_videoram = 0; @@ -162,14 +117,11 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet) /* We don't know the hardware specs yet and there is no ivideo */ if(vesamode == 0) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - sisfb_mode_idx = MODE_INDEX_NONE; -#else if(!quiet) printk(KERN_ERR "sisfb: Invalid mode. Using default.\n"); sisfb_mode_idx = DEFAULT_MODE; -#endif + return; } @@ -215,7 +167,6 @@ sisfb_search_mode(char *name, BOOLEAN quiet) return; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { if(!quiet) printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); @@ -223,7 +174,7 @@ sisfb_search_mode(char *name, BOOLEAN quiet) sisfb_mode_idx = DEFAULT_MODE; return; } -#endif + if(strlen(name) <= 19) { strcpy(strbuf1, name); for(i = 0; i < strlen(strbuf1); i++) { @@ -1315,20 +1266,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in ivideo->refresh_rate = 60; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - if(ivideo->sisfb_thismonitor.datavalid) { - if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx, - ivideo->rate_idx, ivideo->refresh_rate)) { - printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n"); - } - } -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) { -#else if(isactive) { -#endif /* If acceleration to be used? Need to know * before pre/post_set_mode() */ @@ -1367,9 +1305,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in ivideo->current_linelength = ivideo->video_linelength; ivideo->current_pixclock = var->pixclock; ivideo->current_refresh_rate = ivideo->refresh_rate; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate; -#endif } return 0; @@ -1435,18 +1371,6 @@ sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) return 0; } -/* ------------ FBDev related routines for 2.4 series ----------- */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - -#include "sisfb_fbdev_2_4.h" - -#endif - -/* ------------ FBDev related routines for 2.6 series ----------- */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - static int sisfb_open(struct fb_info *info, int user) { @@ -1744,8 +1668,6 @@ sisfb_blank(int blank, struct fb_info *info) return sisfb_myblank(ivideo, blank); } -#endif - /* ----------- FBDev related routines for all series ---------- */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) @@ -1969,20 +1891,6 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) /* ---------------- fb_ops structures ----------------- */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -static struct fb_ops sisfb_ops = { - .owner = THIS_MODULE, - .fb_get_fix = sisfb_get_fix, - .fb_get_var = sisfb_get_var, - .fb_set_var = sisfb_set_var, - .fb_get_cmap = sisfb_get_cmap, - .fb_set_cmap = sisfb_set_cmap, - .fb_pan_display = sisfb_pan_display, - .fb_ioctl = sisfb_ioctl -}; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static struct fb_ops sisfb_ops = { .owner = THIS_MODULE, .fb_open = sisfb_open, @@ -2004,7 +1912,6 @@ static struct fb_ops sisfb_ops = { #endif .fb_ioctl = sisfb_ioctl }; -#endif /* ---------------- Chip generation dependent routines ---------------- */ @@ -4100,16 +4007,6 @@ sisfb_setup(char *options) sisfb_search_mode(this_opt + 5, FALSE); } else if(!strnicmp(this_opt, "vesa:", 5)) { sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - } else if(!strnicmp(this_opt, "inverse", 7)) { - sisfb_inverse = 1; - /* fb_invert_cmaps(); */ - } else if(!strnicmp(this_opt, "font:", 5)) { - if(strlen(this_opt + 5) < 40) { - strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1); - sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0'; - } -#endif } else if(!strnicmp(this_opt, "rate:", 5)) { sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { @@ -5870,17 +5767,9 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if(sisfb_off) return -ENXIO; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3)) sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev); if(!sis_fb_info) return -ENOMEM; -#else - sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL); - if(!sis_fb_info) - return -ENOMEM; - memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo)); - sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info)); -#endif ivideo = (struct sis_video_info *)sis_fb_info->par; ivideo->memyselfandi = sis_fb_info; @@ -5970,10 +5859,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ivideo->tvxpos = sisfb_tvxposoffset; ivideo->tvypos = sisfb_tvyposoffset; ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate; -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) - ivideo->sisfb_inverse = sisfb_inverse; -#endif - ivideo->refresh_rate = 0; if(ivideo->sisfb_parm_rate != -1) { ivideo->refresh_rate = ivideo->sisfb_parm_rate; @@ -6049,10 +5934,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - strcpy(sis_fb_info->modename, ivideo->myid); -#endif - ivideo->SiS_Pr.ChipType = ivideo->chip; ivideo->SiS_Pr.ivideo = (void *)ivideo; @@ -6134,20 +6015,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #endif } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#ifdef MODULE - if((reg & 0x80) && (reg != 0xff)) { - if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) - != 0xFF) { - printk(KERN_INFO "sisfb: Cannot initialize display mode, " - "X server is active\n"); - ret = -EBUSY; - goto error_4; - } - } -#endif -#endif - /* Search and copy ROM image */ ivideo->bios_abase = NULL; ivideo->SiS_Pr.VirtualRomBase = NULL; @@ -6281,9 +6148,6 @@ error_0: iounmap(ivideo->video_vbase); error_1: release_mem_region(ivideo->video_base, ivideo->video_size); error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); error_3: vfree(ivideo->bios_abase); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -error_4: -#endif if(ivideo->lpcdev) SIS_PCI_PUT_DEVICE(ivideo->lpcdev); if(ivideo->nbridge) @@ -6586,7 +6450,6 @@ error_4: sis_fb_info->fix = ivideo->sisfb_fix; sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; sis_fb_info->fbops = &sisfb_ops; - sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info); sis_fb_info->pseudo_palette = ivideo->pseudo_palette; @@ -6603,10 +6466,6 @@ error_4: } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - vc_resize_con(1, 1, 0); -#endif - if(register_framebuffer(sis_fb_info) < 0) { printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n"); ret = -EINVAL; @@ -6653,12 +6512,7 @@ error_4: printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n", -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - GET_FB_IDX(sis_fb_info->node), -#else - sis_fb_info->node, -#endif - ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); + sis_fb_info->node, ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n"); @@ -6732,11 +6586,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev) /* Unregister the framebuffer */ if(ivideo->registered) { unregister_framebuffer(sis_fb_info); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3)) framebuffer_release(sis_fb_info); -#else - kfree(sis_fb_info); -#endif } /* OK, our ivideo is gone for good from here. */ @@ -6762,7 +6612,6 @@ static struct pci_driver sisfb_driver = { SISINITSTATIC int __init sisfb_init(void) { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) #ifndef MODULE char *options = NULL; @@ -6771,15 +6620,12 @@ SISINITSTATIC int __init sisfb_init(void) sisfb_setup(options); #endif -#endif return pci_register_driver(&sisfb_driver); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) #ifndef MODULE module_init(sisfb_init); #endif -#endif /*****************************************************/ /* MODULE */ @@ -6799,9 +6645,6 @@ static int pdc1 = -1; static int noaccel = -1; static int noypan = -1; static int nomax = -1; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -static int inverse = 0; -#endif static int userom = -1; static int useoem = -1; static char *tvstandard = NULL; @@ -6861,10 +6704,6 @@ static int __init sisfb_init_module(void) else if(nomax == 0) sisfb_max = 1; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - if(inverse) sisfb_inverse = 1; -#endif - if(mem) sisfb_parm_mem = mem; @@ -6913,35 +6752,6 @@ MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3X MODULE_LICENSE("GPL"); MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(mem, "i"); -MODULE_PARM(noaccel, "i"); -MODULE_PARM(noypan, "i"); -MODULE_PARM(nomax, "i"); -MODULE_PARM(userom, "i"); -MODULE_PARM(useoem, "i"); -MODULE_PARM(mode, "s"); -MODULE_PARM(vesa, "i"); -MODULE_PARM(rate, "i"); -MODULE_PARM(forcecrt1, "i"); -MODULE_PARM(forcecrt2type, "s"); -MODULE_PARM(scalelcd, "i"); -MODULE_PARM(pdc, "i"); -MODULE_PARM(pdc1, "i"); -MODULE_PARM(specialtiming, "s"); -MODULE_PARM(lvdshl, "i"); -MODULE_PARM(tvstandard, "s"); -MODULE_PARM(tvxposoffset, "i"); -MODULE_PARM(tvyposoffset, "i"); -MODULE_PARM(nocrt2rate, "i"); -MODULE_PARM(inverse, "i"); -#if !defined(__i386__) && !defined(__x86_64__) -MODULE_PARM(resetcard, "i"); -MODULE_PARM(videoram, "i"); -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) module_param(mem, int, 0); module_param(noaccel, int, 0); module_param(noypan, int, 0); @@ -6966,18 +6776,7 @@ module_param(nocrt2rate, int, 0); module_param(resetcard, int, 0); module_param(videoram, int, 0); #endif -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM_DESC(mem, - "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" - "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" - "on the amount of video RAM available. If 8MB of video RAM or less is available,\n" - "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" - "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n" - "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n" - "for XFree86 4.x/X.org 6.7 and later.\n"); -#else MODULE_PARM_DESC(mem, "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" @@ -6985,7 +6784,6 @@ MODULE_PARM_DESC(mem, "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n" "The value is to be specified without 'KB'.\n"); -#endif MODULE_PARM_DESC(noaccel, "\nIf set to anything other than 0, 2D acceleration will be disabled.\n" @@ -7002,23 +6800,6 @@ MODULE_PARM_DESC(nomax, "enable the user to positively specify a virtual Y size of the screen using\n" "fbset. (default: 0)\n"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM_DESC(mode, - "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n" - "1024x768x16. Other formats supported include XxY-Depth and\n" - "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n" - "number, it will be interpreted as a VESA mode number. (default: none if\n" - "sisfb is a module; this leaves the console untouched and the driver will\n" - "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n" - "is in the kernel)\n"); -MODULE_PARM_DESC(vesa, - "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n" - "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n" - "and the driver will only do the video memory management for eg. DRM/DRI;\n" - "0x0103 if sisfb is in the kernel)\n"); -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) MODULE_PARM_DESC(mode, "\nSelects the desired default display mode in the format XxYxDepth,\n" "eg. 1024x768x16. Other formats supported include XxY-Depth and\n" @@ -7028,7 +6809,6 @@ MODULE_PARM_DESC(mode, MODULE_PARM_DESC(vesa, "\nSelects the desired default display mode by VESA defined mode number, eg.\n" "0x117 (default: 0x0103)\n"); -#endif MODULE_PARM_DESC(rate, "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n" @@ -7094,12 +6874,6 @@ MODULE_PARM_DESC(nocrt2rate, "\nSetting this to 1 will force the driver to use the default refresh rate for\n" "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM_DESC(inverse, - "\nSetting this to anything but 0 should invert the display colors, but this\n" - "does not seem to work. (default: 0)\n"); -#endif - #if !defined(__i386__) && !defined(__x86_64__) #ifdef CONFIG_FB_SIS_300 MODULE_PARM_DESC(resetcard, diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h index 70b6df371b8..88e4f1e4147 100644 --- a/drivers/video/sis/sis_main.h +++ b/drivers/video/sis/sis_main.h @@ -67,15 +67,7 @@ static int sisfb_ypan = -1; static int sisfb_max = -1; static int sisfb_userom = 1; static int sisfb_useoem = -1; -#ifdef MODULE -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -static int sisfb_mode_idx = -1; -#else -static int sisfb_mode_idx = MODE_INDEX_NONE; /* Don't use a mode by default if we are a module */ -#endif -#else static int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */ -#endif static int sisfb_parm_rate = -1; static int sisfb_crt1off = 0; static int sisfb_forcecrt1 = -1; @@ -93,10 +85,6 @@ static int sisfb_tvstd = -1; static int sisfb_tvxposoffset = 0; static int sisfb_tvyposoffset = 0; static int sisfb_nocrt2rate = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -static int sisfb_inverse = 0; -static char sisfb_fontname[40]; -#endif #if !defined(__i386__) && !defined(__x86_64__) static int sisfb_resetcard = 0; static int sisfb_videoram = 0; @@ -687,54 +675,8 @@ SISINITSTATIC int sisfb_init(void); static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -static int sisfb_get_fix(struct fb_fix_screeninfo *fix, - int con, - struct fb_info *info); -static int sisfb_get_var(struct fb_var_screeninfo *var, - int con, - struct fb_info *info); -static int sisfb_set_var(struct fb_var_screeninfo *var, - int con, - struct fb_info *info); -static void sisfb_crtc_to_var(struct sis_video_info *ivideo, - struct fb_var_screeninfo *var); -static int sisfb_get_cmap(struct fb_cmap *cmap, - int kspc, - int con, - struct fb_info *info); -static int sisfb_set_cmap(struct fb_cmap *cmap, - int kspc, - int con, - struct fb_info *info); -static int sisfb_update_var(int con, - struct fb_info *info); -static int sisfb_switch(int con, - struct fb_info *info); -static void sisfb_blank(int blank, - struct fb_info *info); -static void sisfb_set_disp(int con, - struct fb_var_screeninfo *var, - struct fb_info *info); -static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, - unsigned *blue, unsigned *transp, - struct fb_info *fb_info); -static void sisfb_do_install_cmap(int con, - struct fb_info *info); -static int sisfb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, int con, - struct fb_info *info); -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg); -#else -static int sisfb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - struct fb_info *info); -#endif static int sisfb_set_par(struct fb_info *info); static int sisfb_blank(int blank, struct fb_info *info); @@ -743,7 +685,6 @@ extern void fbcon_sis_fillrect(struct fb_info *info, extern void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area); extern int fbcon_sis_sync(struct fb_info *info); -#endif /* Internal 2D accelerator functions */ extern int sisfb_initaccel(struct sis_video_info *ivideo); @@ -811,16 +752,10 @@ extern BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr); extern BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno, unsigned char rateindex); extern int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, unsigned char rateindex, struct fb_var_screeninfo *var); -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, - int yres, struct fb_var_screeninfo *var, BOOLEAN writeres); -#endif /* Chrontel TV, DDC and DPMS functions */ extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg); diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h index 831b9f42264..05d08b7889a 100644 --- a/drivers/video/sis/vgatypes.h +++ b/drivers/video/sis/vgatypes.h @@ -73,12 +73,10 @@ typedef unsigned int BOOLEAN; #ifdef SIS_LINUX_KERNEL typedef unsigned long SISIOADDRESS; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) #include <linux/types.h> /* Need __iomem */ #undef SISIOMEMTYPE #define SISIOMEMTYPE __iomem #endif -#endif #ifdef SIS_XORG_XF86 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0) diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index dad54e73147..711cb11d6eb 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -17,7 +17,10 @@ * (port driver to new frambuffer infrastructure) * 01/2003 Helge Deller <deller@gmx.de> * (initial work on fb hardware acceleration for voodoo2) - * + * 08/2006 Alan Cox <alan@redhat.com> + * Remove never finished and bogus 24/32bit support + * Clean up macro abuse + * Minor tidying for format. */ /* @@ -40,6 +43,7 @@ through the fifo. warning: issuing a nop command seems to need pci_fifo -FIXME: in case of failure in the init sequence, be sure we return to a safe state. +- FIXME: Use accelerator for 2D scroll -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20) */ @@ -67,9 +71,6 @@ #undef SST_DEBUG -/* enable 24/32 bpp functions ? (completely untested!) */ -#undef EN_24_32_BPP - /* Default video mode . 0 800x600@60 took from glide @@ -377,7 +378,11 @@ static void sstfb_clear_screen(struct fb_info *info) * sstfb_check_var - Optional function. Validates a var passed in. * @var: frame buffer variable screen structure * @info: frame buffer structure that represents a single frame buffer + * + * Limit to the abilities of a single chip as SLI is not supported + * by this driver. */ + static int sstfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { @@ -390,7 +395,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, unsigned int freq; if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) { - eprintk("Pixclock at %ld KHZ out of range\n", + printk(KERN_ERR "sstfb: Pixclock at %ld KHZ out of range\n", PICOS2KHZ(var->pixclock)); return -EINVAL; } @@ -409,27 +414,15 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, case 0 ... 16 : var->bits_per_pixel = 16; break; -#ifdef EN_24_32_BPP - case 17 ... 24 : - var->bits_per_pixel = 24; - break; - case 25 ... 32 : - var->bits_per_pixel = 32; - break; -#endif default : - eprintk("Unsupported bpp %d\n", var->bits_per_pixel); + printk(KERN_ERR "sstfb: Unsupported bpp %d\n", var->bits_per_pixel); return -EINVAL; } /* validity tests */ - if ((var->xres <= 1) || (yDim <= 0 ) - || (var->hsync_len <= 1) - || (hSyncOff <= 1) - || (var->left_margin <= 2) - || (vSyncOn <= 0) - || (vSyncOff <= 0) - || (vBackPorch <= 0)) { + if (var->xres <= 1 || yDim <= 0 || var->hsync_len <= 1 || + hSyncOff <= 1 || var->left_margin <= 2 || vSyncOn <= 0 || + vSyncOff <= 0 || vBackPorch <= 0) { return -EINVAL; } @@ -437,21 +430,17 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, /* Voodoo 2 limits */ tiles_in_X = (var->xres + 63 ) / 64 * 2; - if (((var->xres - 1) >= POW2(11)) || (yDim >= POW2(11))) { - eprintk("Unsupported resolution %dx%d\n", + if (var->xres > POW2(11) || yDim >= POW2(11)) { + printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n", var->xres, var->yres); return -EINVAL; } - if (((var->hsync_len-1) >= POW2(9)) - || ((hSyncOff-1) >= POW2(11)) - || ((var->left_margin - 2) >= POW2(9)) - || (vSyncOn >= POW2(13)) - || (vSyncOff >= POW2(13)) - || (vBackPorch >= POW2(9)) - || (tiles_in_X >= POW2(6)) - || (tiles_in_X <= 0)) { - eprintk("Unsupported Timings\n"); + if (var->hsync_len > POW2(9) || hSyncOff > POW2(11) || + var->left_margin - 2 >= POW2(9) || vSyncOn >= POW2(13) || + vSyncOff >= POW2(13) || vBackPorch >= POW2(9) || + tiles_in_X >= POW2(6) || tiles_in_X <= 0) { + printk(KERN_ERR "sstfb: Unsupported timings\n"); return -EINVAL; } } else { @@ -459,24 +448,20 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, tiles_in_X = (var->xres + 63 ) / 64; if (var->vmode) { - eprintk("Interlace/Doublescan not supported %#x\n", + printk(KERN_ERR "sstfb: Interlace/doublescan not supported %#x\n", var->vmode); return -EINVAL; } - if (((var->xres - 1) >= POW2(10)) || (var->yres >= POW2(10))) { - eprintk("Unsupported resolution %dx%d\n", + if (var->xres > POW2(10) || var->yres >= POW2(10)) { + printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n", var->xres, var->yres); return -EINVAL; } - if (((var->hsync_len - 1) >= POW2(8)) - || ((hSyncOff-1) >= POW2(10)) - || ((var->left_margin - 2) >= POW2(8)) - || (vSyncOn >= POW2(12)) - || (vSyncOff >= POW2(12)) - || (vBackPorch >= POW2(8)) - || (tiles_in_X >= POW2(4)) - || (tiles_in_X <= 0)) { - eprintk("Unsupported Timings\n"); + if (var->hsync_len > POW2(8) || hSyncOff - 1 > POW2(10) || + var->left_margin - 2 >= POW2(8) || vSyncOn >= POW2(12) || + vSyncOff >= POW2(12) || vBackPorch >= POW2(8) || + tiles_in_X >= POW2(4) || tiles_in_X <= 0) { + printk(KERN_ERR "sstfb: Unsupported timings\n"); return -EINVAL; } } @@ -486,8 +471,8 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, real_length = tiles_in_X * (IS_VOODOO2(par) ? 32 : 64 ) * ((var->bits_per_pixel == 16) ? 2 : 4); - if ((real_length * yDim) > info->fix.smem_len) { - eprintk("Not enough video memory\n"); + if (real_length * yDim > info->fix.smem_len) { + printk(KERN_ERR "sstfb: Not enough video memory\n"); return -ENOMEM; } @@ -515,20 +500,6 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, var->blue.offset = 0; var->transp.offset = 0; break; -#ifdef EN_24_32_BPP - case 24: /* RGB 888 LfbMode 4 */ - case 32: /* ARGB 8888 LfbMode 5 */ - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - var->transp.length = 0; - - var->red.offset = 16; - var->green.offset = 8; - var->blue.offset = 0; - var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */ - break; -#endif default: return -EINVAL; } @@ -653,13 +624,6 @@ static int sstfb_set_par(struct fb_info *info) case 16: fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL; break; -#ifdef EN_24_32_BPP - case 24: - case 32: - /* sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP);*/ - fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP; - break; -#endif default: return -EINVAL; } @@ -690,14 +654,6 @@ static int sstfb_set_par(struct fb_info *info) case 16: lfbmode = LFB_565; break; -#ifdef EN_24_32_BPP - case 24: - lfbmode = LFB_888; - break; - case 32: - lfbmode = LFB_8888; - break; -#endif default: return -EINVAL; } @@ -789,8 +745,7 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) return -EFAULT; if (val > info->fix.smem_len) val = info->fix.smem_len; - printk("filling %#x \n", val); - for (p=0 ; p<val; p+=2) + for (p = 0 ; p < val; p += 2) writew(p >> 6, info->screen_base + p); return 0; @@ -802,13 +757,10 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp | PCI_EN_INIT_WR ); fbiinit0 = sst_read (FBIINIT0); - if (val) { + if (val) sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH); - iprintk("Disabling VGA pass-through\n"); - } else { + else sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH); - iprintk("Enabling VGA pass-through\n"); - } pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp); return 0; @@ -884,9 +836,9 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize) u8 __iomem *fbbase_virt = info->screen_base; /* force memsize */ - if ((mem >= 1 ) && (mem <= 4)) { + if (mem >= 1 && mem <= 4) { *memsize = (mem * 0x100000); - iprintk("supplied memsize: %#x\n", *memsize); + printk(KERN_INFO "supplied memsize: %#x\n", *memsize); return 1; } @@ -927,7 +879,7 @@ static int __devinit sst_detect_att(struct fb_info *info) struct sstfb_par *par = info->par; int i, mir, dir; - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) { sst_dac_write(DACREG_WMA, 0); /* backdoor */ sst_dac_read(DACREG_RMR); /* read 4 times RMR */ sst_dac_read(DACREG_RMR); @@ -940,7 +892,7 @@ static int __devinit sst_detect_att(struct fb_info *info) /*the 7th, device ID register */ dir = sst_dac_read(DACREG_RMR); f_ddprintk("mir: %#x, dir: %#x\n", mir, dir); - if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) { + if (mir == DACREG_MIR_ATT && dir == DACREG_DIR_ATT) { return 1; } } @@ -1134,12 +1086,6 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp) case 16: sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP); break; -#ifdef EN_24_32_BPP - case 24: - case 32: - sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP); - break; -#endif default: dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp); break; @@ -1154,12 +1100,6 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp) case 16: sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP); break; -#ifdef EN_24_32_BPP - case 24: - case 32: - sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP); - break; -#endif default: dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp); break; @@ -1250,7 +1190,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par) PCI_EN_INIT_WR | PCI_REMAP_DAC ); /* detect dac type */ if (!sst_detect_dactype(info, par)) { - eprintk("Unknown dac type\n"); + printk(KERN_ERR "sstfb: unknown dac type.\n"); //FIXME watch it: we are not in a safe state, bad bad bad. return 0; } @@ -1258,10 +1198,10 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par) /* set graphic clock */ par->gfx_clock = spec->default_gfx_clock; if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) { - iprintk("Using supplied graphic freq : %dMHz\n", gfxclk); + printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk); par->gfx_clock = gfxclk *1000; } else if (gfxclk) { - wprintk ("%dMhz is way out of spec! Using default\n", gfxclk); + printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk); } sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings); @@ -1396,7 +1336,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, /* Enable device in PCI config. */ if ((err=pci_enable_device(pdev))) { - eprintk("cannot enable device\n"); + printk(KERN_ERR "cannot enable device\n"); return err; } @@ -1422,39 +1362,39 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, fix->smem_start = fix->mmio_start + 0x400000; if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) { - eprintk("cannot reserve mmio memory\n"); + printk(KERN_ERR "sstfb: cannot reserve mmio memory\n"); goto fail_mmio_mem; } if (!request_mem_region(fix->smem_start, 0x400000,"sstfb FB")) { - eprintk("cannot reserve fb memory\n"); + printk(KERN_ERR "sstfb: cannot reserve fb memory\n"); goto fail_fb_mem; } par->mmio_vbase = ioremap_nocache(fix->mmio_start, fix->mmio_len); if (!par->mmio_vbase) { - eprintk("cannot remap register area %#lx\n", + printk(KERN_ERR "sstfb: cannot remap register area %#lx\n", fix->mmio_start); goto fail_mmio_remap; } info->screen_base = ioremap_nocache(fix->smem_start, 0x400000); if (!info->screen_base) { - eprintk("cannot remap framebuffer %#lx\n", + printk(KERN_ERR "sstfb: cannot remap framebuffer %#lx\n", fix->smem_start); goto fail_fb_remap; } if (!sst_init(info, par)) { - eprintk("Init failed\n"); + printk(KERN_ERR "sstfb: Init failed\n"); goto fail; } sst_get_memsize(info, &fix->smem_len); strlcpy(fix->id, spec->name, sizeof(fix->id)); - iprintk("%s (revision %d) with %s dac\n", + printk(KERN_INFO "%s (revision %d) with %s dac\n", fix->id, par->revision, par->dac_sw.name); - iprintk("framebuffer at %#lx, mapped to 0x%p, size %dMB\n", + printk(KERN_INFO "framebuffer at %#lx, mapped to 0x%p, size %dMB\n", fix->smem_start, info->screen_base, fix->smem_len >> 20); @@ -1471,24 +1411,25 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, fix->accel = FB_ACCEL_NONE; /* FIXME */ /* * According to the specs, the linelength must be of 1024 *pixels* - * and the 24bpp mode is in fact a 32 bpp mode. + * and the 24bpp mode is in fact a 32 bpp mode (and both are in + * fact dithered to 16bit). */ fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */ if ( mode_option && fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) { - eprintk("can't set supplied video mode. Using default\n"); + printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n"); info->var = sstfb_default; } else info->var = sstfb_default; if (sstfb_check_var(&info->var, info)) { - eprintk("invalid default video mode.\n"); + printk(KERN_ERR "sstfb: invalid default video mode.\n"); goto fail; } if (sstfb_set_par(info)) { - eprintk("can't set default video mode.\n"); + printk(KERN_ERR "sstfb: can't set default video mode.\n"); goto fail; } @@ -1497,7 +1438,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, /* register fb */ info->device = &pdev->dev; if (register_framebuffer(info) < 0) { - eprintk("can't register framebuffer.\n"); + printk(KERN_ERR "sstfb: can't register framebuffer.\n"); goto fail; } @@ -1711,4 +1652,3 @@ module_param(gfxclk, int, 0); MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)"); module_param(slowpci, bool, 0); MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)"); - |