/* * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver * * Maintained by Ani Joshi <ajoshi@shell.unixbox.com> * * Copyright 1999-2000 Jeff Garzik * * Contributors: * * Ani Joshi: Lots of debugging and cleanup work, really helped * get the driver going * * Ferenc Bakonyi: Bug fixes, cleanup, modularization * * Jindrich Makovicka: Accel code help, hw cursor, mtrr * * Paul Richards: Bug fixes, updates * * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven * Includes riva_hw.c from nVidia, see copyright below. * KGI code provided the basis for state storage, init, and mode switching. * * 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. * * Known bugs and issues: * restoring text mode fails * doublescan modes are broken */ #include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/backlight.h>#include <linux/bitrev.h>#ifdef CONFIG_PMAC_BACKLIGHT#include <asm/machdep.h>#include <asm/backlight.h>#endif #include "rivafb.h"#include "nvreg.h" /* version number of this driver */#define RIVAFB_VERSION "0.9.5b" /* ------------------------------------------------------------------------- * * * various helpful macros and constants * * ------------------------------------------------------------------------- */#ifdef CONFIG_FB_RIVA_DEBUG#define NVTRACE printk#else#define NVTRACE if(0) printk#endif #define NVTRACE_ENTER(...) NVTRACE("%s START\n", __func__)#define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __func__) #ifdef CONFIG_FB_RIVA_DEBUG#define assert(expr) \ if(!(expr)) { \ printk( "Assertion failed! %s,%s,%s,line=%d\n",\ #expr,__FILE__,__func__,__LINE__); \ BUG(); \ }#else#define assert(expr)#endif #define PFX "rivafb: " /* macro that allows you to set overflow bits */#define SetBitField(value,from,to) SetBF(to,GetBF(value,from))#define SetBit(n) (1<<(n))#define Set8Bits(value) ((value)&0xff) /* HW cursor parameters */#define MAX_CURS 32 /* ------------------------------------------------------------------------- * * * prototypes * * ------------------------------------------------------------------------- */ static int rivafb_blank(int blank, struct fb_info *info); /* ------------------------------------------------------------------------- * * * card identification * * ------------------------------------------------------------------------- */ static struct pci_device_id rivafb_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, // NF2/IGP version, GeForce 4 MX, NV18 { PCI_VENDOR_ID_NVIDIA, 0x01f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } /* terminate list */};MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl); /* ------------------------------------------------------------------------- * * * global variables * * ------------------------------------------------------------------------- */ /* command line data, set in rivafb_setup() */static int flatpanel = -1; /* Autodetect later */static int forceCRTC = -1;static bool noaccel = 0;static bool nomtrr = 0;#ifdef CONFIG_PMAC_BACKLIGHTstatic int backlight = 1;#elsestatic int backlight = 0;#endif static char *mode_option = NULL;static bool strictmode = 0; static struct fb_fix_screeninfo rivafb_fix = { .type = FB_TYPE_PACKED_PIXELS, .xpanstep = 1, .ypanstep = 1,}; static struct fb_var_screeninfo rivafb_default_var = { .xres = 640, .yres = 480, .xres_virtual = 640, .yres_virtual = 480, .bits_per_pixel = 8, .red = {0, 8, 0}, .green = {0, 8, 0}, .blue = {0, 8, 0}, .transp = {0, 0, 0}, .activate = FB_ACTIVATE_NOW, .height = -1, .width = -1, .pixclock = 39721, .left_margin = 40, .right_margin = 24, .upper_margin = 32, .lower_margin = 11, .hsync_len = 96, .vsync_len = 2, .vmode = FB_VMODE_NONINTERLACED}; /* from GGI */static const struct riva_regs reg_template = { {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ATTR */ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x01, 0x0F, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CRT */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, /* 0x10 */ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 */ }, {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA */ 0xFF}, {0x03, 0x01, 0x0F, 0x00, 0x0E}, /* SEQ */ 0xEB /* MISC */}; /* * Backlight control */#ifdef CONFIG_FB_RIVA_BACKLIGHT/* We do not have any information about which values are allowed, thus * we used safe values. */#define MIN_LEVEL 0x158#define MAX_LEVEL 0x534#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX) static int riva_bl_get_level_brightness(struct riva_par *par, int level){ struct fb_info *info = pci_get_drvdata(par->pdev); int nlevel; /* Get and convert the value */ /* No locking on bl_curve since accessing a single value */ nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; if (nlevel < 0) nlevel = 0; else if (nlevel < MIN_LEVEL) nlevel = MIN_LEVEL; else if (nlevel > MAX_LEVEL) nlevel = MAX_LEVEL; return nlevel;} static int riva_bl_update_status(struct backlight_device *bd){ struct riva_par *par = bl_get_data(bd); U032 tmp_pcrt, tmp_pmc; int level; if (bd->props.power != FB_BLANK_UNBLANK || bd->props.fb_blank != FB_BLANK_UNBLANK) level = 0; else level = bd->props.brightness; tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF; tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC; if(level > 0) { tmp_pcrt |= 0x1; tmp_pmc |= (1 << 31); /* backlight bit */ tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */ } NV_WR32(par->riva.PCRTC0, 0x081C, tmp_pcrt); NV_WR32(par->riva.PMC, 0x10F0, tmp_pmc); return 0;} static const struct backlight_ops riva_bl_ops = { .update_status = riva_bl_update_status,}; static void riva_bl_init(struct riva_par *par){ struct backlight_properties props; struct fb_info *info = pci_get_drvdata(par->pdev); struct backlight_device *bd; char name[12]; if (!par->FlatPanel) return; #ifdef CONFIG_PMAC_BACKLIGHT if (!machine_is(powermac) || !pmac_has_backlight_type("mnca")) return;#endif snprintf(name, sizeof(name), "rivabl%d", info->node); memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd = backlight_device_register(name, info->dev, par, &riva_bl_ops, &props); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "riva: Backlight registration failed\n"); goto error; } info->bl_dev = bd; fb_bl_default_curve(info, 0, MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, FB_BACKLIGHT_MAX); bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); printk("riva: Backlight initialized (%s)\n", name); return; error: return;} static void riva_bl_exit(struct fb_info *info){ struct backlight_device *bd = info->bl_dev; backlight_device_unregister(bd); printk("riva: Backlight unloaded\n");}#elsestatic inline void riva_bl_init(struct riva_par *par) {}static inline void riva_bl_exit(struct fb_info *info) {}#endif /* CONFIG_FB_RIVA_BACKLIGHT */ /* ------------------------------------------------------------------------- * * * MMIO access macros * * ------------------------------------------------------------------------- */ static inline void CRTCout(struct riva_par *par, unsigned char index, unsigned char val){ VGA_WR08(par->riva.PCIO, 0x3d4, index); VGA_WR08(par->riva.PCIO, 0x3d5, val);} static inline unsigned char CRTCin(struct riva_par *par, unsigned char index){ VGA_WR08(par->riva.PCIO, 0x3d4, index); return (VGA_RD08(par->riva.PCIO, 0x3d5));} static inline void GRAout(struct riva_par *par, unsigned char index, unsigned char val){ VGA_WR08(par->riva.PVIO, 0x3ce, index); VGA_WR08(par->riva.PVIO, 0x3cf, val);} static inline unsigned char GRAin(struct riva_par *par, unsigned char index){ VGA_WR08(par->riva.PVIO, 0x3ce, index); return (VGA_RD08(par->riva.PVIO, 0x3cf));} static inline void SEQout(struct riva_par *par, unsigned char index, unsigned char val){ VGA_WR08(par->riva.PVIO, 0x3c4, index); VGA_WR08(par->riva.PVIO, 0x3c5, val);} static inline unsigned char SEQin(struct riva_par *par, unsigned char index){ VGA_WR08(par->riva.PVIO, 0x3c4, index); return (VGA_RD08(par->riva.PVIO, 0x3c5));} static inline void ATTRout(struct riva_par *par, unsigned char index, unsigned char val){ VGA_WR08(par->riva.PCIO, 0x3c0, index); VGA_WR08(par->riva.PCIO, 0x3c0, val);} static inline unsigned char ATTRin(struct riva_par *par, unsigned char index){ VGA_WR08(par->riva.PCIO, 0x3c0, index); return (VGA_RD08(par->riva.PCIO, 0x3c1));} static inline void MISCout(struct riva_par *par, unsigned char val){ VGA_WR08(par->riva.PVIO, 0x3c2, val);} static inline unsigned char MISCin(struct riva_par *par){ return (VGA_RD08(par->riva.PVIO, 0x3cc));} static inline void reverse_order(u32 *l){ u8 *a = (u8 *)l; a[0] = bitrev8(a[0]); a[1] = bitrev8(a[1]); a[2] = bitrev8(a[2]); a[3] = bitrev8(a[3]);} /* ------------------------------------------------------------------------- * * * cursor stuff * * ------------------------------------------------------------------------- */ /** * rivafb_load_cursor_image - load cursor image to hardware * @data: address to monochrome bitmap (1 = foreground color, 0 = background) * @par: pointer to private data * @w: width of cursor image in pixels * @h: height of cursor image in scanlines * @bg: background color (ARGB1555) - alpha bit determines opacity * @fg: foreground color (ARGB1555) * * DESCRIPTiON: * Loads cursor image based on a monochrome source and mask bitmap. The * image bits determines the color of the pixel, 0 for background, 1 for * foreground. Only the affected region (as determined by @w and @h * parameters) will be updated. * * CALLED FROM: * rivafb_cursor() */static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8, u16 bg, u16 fg, u32 w, u32 h){ int i, j, k = 0; u32 b, tmp; u32 *data = (u32 *)data8; bg = le16_to_cpu(bg); fg = le16_to_cpu(fg); w = (w + 1) & ~1; for (i = 0; i < h; i++) { b = *data++; reverse_order(&b);Lines 1–500 of 2196. Load more
/* * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver * * Maintained by Ani Joshi <ajoshi@shell.unixbox.com> * * Copyright 1999-2000 Jeff Garzik * * Contributors: * * Ani Joshi: Lots of debugging and cleanup work, really helped * get the driver going * * Ferenc Bakonyi: Bug fixes, cleanup, modularization * * Jindrich Makovicka: Accel code help, hw cursor, mtrr * * Paul Richards: Bug fixes, updates * * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven * Includes riva_hw.c from nVidia, see copyright below. * KGI code provided the basis for state storage, init, and mode switching. * * 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. * * Known bugs and issues: * restoring text mode fails * doublescan modes are broken */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/delay.h> #include <linux/fb.h> #include <linux/init.h> #include <linux/pci.h> #include <linux/backlight.h> #include <linux/bitrev.h> #ifdef CONFIG_PMAC_BACKLIGHT #include <asm/machdep.h> #include <asm/backlight.h> #endif #include "rivafb.h" #include "nvreg.h" /* version number of this driver */ #define RIVAFB_VERSION "0.9.5b" /* ------------------------------------------------------------------------- * * * various helpful macros and constants * * ------------------------------------------------------------------------- */ #ifdef CONFIG_FB_RIVA_DEBUG #define NVTRACE printk #else #define NVTRACE if(0) printk #endif #define NVTRACE_ENTER(...) NVTRACE("%s START\n", __func__) #define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __func__) #ifdef CONFIG_FB_RIVA_DEBUG #define assert(expr) \ if(!(expr)) { \ printk( "Assertion failed! %s,%s,%s,line=%d\n",\ #expr,__FILE__,__func__,__LINE__); \ BUG(); \ } #else #define assert(expr) #endif #define PFX "rivafb: " /* macro that allows you to set overflow bits */ #define SetBitField(value,from,to) SetBF(to,GetBF(value,from)) #define SetBit(n) (1<<(n)) #define Set8Bits(value) ((value)&0xff) /* HW cursor parameters */ #define MAX_CURS 32 /* ------------------------------------------------------------------------- * * * prototypes * * ------------------------------------------------------------------------- */ static int rivafb_blank(int blank, struct fb_info *info); /* ------------------------------------------------------------------------- * * * card identification * * ------------------------------------------------------------------------- */ static struct pci_device_id rivafb_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, // NF2/IGP version, GeForce 4 MX, NV18 { PCI_VENDOR_ID_NVIDIA, 0x01f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl); /* ------------------------------------------------------------------------- * * * global variables * * ------------------------------------------------------------------------- */ /* command line data, set in rivafb_setup() */ static int flatpanel = -1; /* Autodetect later */ static int forceCRTC = -1; static bool noaccel = 0; static bool nomtrr = 0; #ifdef CONFIG_PMAC_BACKLIGHT static int backlight = 1; #else static int backlight = 0; #endif static char *mode_option = NULL; static bool strictmode = 0; static struct fb_fix_screeninfo rivafb_fix = { .type = FB_TYPE_PACKED_PIXELS, .xpanstep = 1, .ypanstep = 1, }; static struct fb_var_screeninfo rivafb_default_var = { .xres = 640, .yres = 480, .xres_virtual = 640, .yres_virtual = 480, .bits_per_pixel = 8, .red = {0, 8, 0}, .green = {0, 8, 0}, .blue = {0, 8, 0}, .transp = {0, 0, 0}, .activate = FB_ACTIVATE_NOW, .height = -1, .width = -1, .pixclock = 39721, .left_margin = 40, .right_margin = 24, .upper_margin = 32, .lower_margin = 11, .hsync_len = 96, .vsync_len = 2, .vmode = FB_VMODE_NONINTERLACED }; /* from GGI */ static const struct riva_regs reg_template = { {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ATTR */ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x01, 0x0F, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CRT */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, /* 0x10 */ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 */ }, {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA */ 0xFF}, {0x03, 0x01, 0x0F, 0x00, 0x0E}, /* SEQ */ 0xEB /* MISC */ }; /* * Backlight control */ #ifdef CONFIG_FB_RIVA_BACKLIGHT /* We do not have any information about which values are allowed, thus * we used safe values. */ #define MIN_LEVEL 0x158 #define MAX_LEVEL 0x534 #define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX) static int riva_bl_get_level_brightness(struct riva_par *par, int level) { struct fb_info *info = pci_get_drvdata(par->pdev); int nlevel; /* Get and convert the value */ /* No locking on bl_curve since accessing a single value */ nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; if (nlevel < 0) nlevel = 0; else if (nlevel < MIN_LEVEL) nlevel = MIN_LEVEL; else if (nlevel > MAX_LEVEL) nlevel = MAX_LEVEL; return nlevel; } static int riva_bl_update_status(struct backlight_device *bd) { struct riva_par *par = bl_get_data(bd); U032 tmp_pcrt, tmp_pmc; int level; if (bd->props.power != FB_BLANK_UNBLANK || bd->props.fb_blank != FB_BLANK_UNBLANK) level = 0; else level = bd->props.brightness; tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF; tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC; if(level > 0) { tmp_pcrt |= 0x1; tmp_pmc |= (1 << 31); /* backlight bit */ tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */ } NV_WR32(par->riva.PCRTC0, 0x081C, tmp_pcrt); NV_WR32(par->riva.PMC, 0x10F0, tmp_pmc); return 0; } static const struct backlight_ops riva_bl_ops = { .update_status = riva_bl_update_status, }; static void riva_bl_init(struct riva_par *par) { struct backlight_properties props; struct fb_info *info = pci_get_drvdata(par->pdev); struct backlight_device *bd; char name[12]; if (!par->FlatPanel) return; #ifdef CONFIG_PMAC_BACKLIGHT if (!machine_is(powermac) || !pmac_has_backlight_type("mnca")) return; #endif snprintf(name, sizeof(name), "rivabl%d", info->node); memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd = backlight_device_register(name, info->dev, par, &riva_bl_ops, &props); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "riva: Backlight registration failed\n"); goto error; } info->bl_dev = bd; fb_bl_default_curve(info, 0, MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, FB_BACKLIGHT_MAX); bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); printk("riva: Backlight initialized (%s)\n", name); return; error: return; } static void riva_bl_exit(struct fb_info *info) { struct backlight_device *bd = info->bl_dev; backlight_device_unregister(bd); printk("riva: Backlight unloaded\n"); } #else static inline void riva_bl_init(struct riva_par *par) {} static inline void riva_bl_exit(struct fb_info *info) {} #endif /* CONFIG_FB_RIVA_BACKLIGHT */ /* ------------------------------------------------------------------------- * * * MMIO access macros * * ------------------------------------------------------------------------- */ static inline void CRTCout(struct riva_par *par, unsigned char index, unsigned char val) { VGA_WR08(par->riva.PCIO, 0x3d4, index); VGA_WR08(par->riva.PCIO, 0x3d5, val); } static inline unsigned char CRTCin(struct riva_par *par, unsigned char index) { VGA_WR08(par->riva.PCIO, 0x3d4, index); return (VGA_RD08(par->riva.PCIO, 0x3d5)); } static inline void GRAout(struct riva_par *par, unsigned char index, unsigned char val) { VGA_WR08(par->riva.PVIO, 0x3ce, index); VGA_WR08(par->riva.PVIO, 0x3cf, val); } static inline unsigned char GRAin(struct riva_par *par, unsigned char index) { VGA_WR08(par->riva.PVIO, 0x3ce, index); return (VGA_RD08(par->riva.PVIO, 0x3cf)); } static inline void SEQout(struct riva_par *par, unsigned char index, unsigned char val) { VGA_WR08(par->riva.PVIO, 0x3c4, index); VGA_WR08(par->riva.PVIO, 0x3c5, val); } static inline unsigned char SEQin(struct riva_par *par, unsigned char index) { VGA_WR08(par->riva.PVIO, 0x3c4, index); return (VGA_RD08(par->riva.PVIO, 0x3c5)); } static inline void ATTRout(struct riva_par *par, unsigned char index, unsigned char val) { VGA_WR08(par->riva.PCIO, 0x3c0, index); VGA_WR08(par->riva.PCIO, 0x3c0, val); } static inline unsigned char ATTRin(struct riva_par *par, unsigned char index) { VGA_WR08(par->riva.PCIO, 0x3c0, index); return (VGA_RD08(par->riva.PCIO, 0x3c1)); } static inline void MISCout(struct riva_par *par, unsigned char val) { VGA_WR08(par->riva.PVIO, 0x3c2, val); } static inline unsigned char MISCin(struct riva_par *par) { return (VGA_RD08(par->riva.PVIO, 0x3cc)); } static inline void reverse_order(u32 *l) { u8 *a = (u8 *)l; a[0] = bitrev8(a[0]); a[1] = bitrev8(a[1]); a[2] = bitrev8(a[2]); a[3] = bitrev8(a[3]); } /* ------------------------------------------------------------------------- * * * cursor stuff * * ------------------------------------------------------------------------- */ /** * rivafb_load_cursor_image - load cursor image to hardware * @data: address to monochrome bitmap (1 = foreground color, 0 = background) * @par: pointer to private data * @w: width of cursor image in pixels * @h: height of cursor image in scanlines * @bg: background color (ARGB1555) - alpha bit determines opacity * @fg: foreground color (ARGB1555) * * DESCRIPTiON: * Loads cursor image based on a monochrome source and mask bitmap. The * image bits determines the color of the pixel, 0 for background, 1 for * foreground. Only the affected region (as determined by @w and @h * parameters) will be updated. * * CALLED FROM: * rivafb_cursor() */ static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8, u16 bg, u16 fg, u32 w, u32 h) { int i, j, k = 0; u32 b, tmp; u32 *data = (u32 *)data8; bg = le16_to_cpu(bg); fg = le16_to_cpu(fg); w = (w + 1) & ~1; for (i = 0; i < h; i++) { b = *data++; reverse_order(&b);