/* * 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/aperture.h>#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 const struct pci_device_id rivafb_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440) }, // NF2/IGP version, GeForce 4 MX, NV18 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x01f0) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200) }, { } /* 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;static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT); 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 = backlight_get_brightness(bd); 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->device, 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 = BACKLIGHT_POWER_ON; 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 * @data8: 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); for (j = 0; j < w/2; j++) { tmp = 0;#if defined (__BIG_ENDIAN) tmp = (b & (1 << 31)) ? fg << 16 : bg << 16; b <<= 1; tmp |= (b & (1 << 31)) ? fg : bg; b <<= 1;#else tmp = (b & 1) ? fg : bg; b >>= 1; tmp |= (b & 1) ? fg << 16 : bg << 16; b >>= 1;#endif writel(tmp, &par->riva.CURSOR[k++]); } k += (MAX_CURS - w)/2; }} /* ------------------------------------------------------------------------- * * * general utility functions * * ------------------------------------------------------------------------- */ /** * riva_wclut - set CLUT entry * @chip: pointer to RIVA_HW_INST object * @regnum: register number * @red: red component * @green: green component * @blue: blue component * * DESCRIPTION: * Sets color register @regnum. * * CALLED FROM: * rivafb_setcolreg() */static void riva_wclut(RIVA_HW_INST *chip, unsigned char regnum, unsigned char red, unsigned char green, unsigned char blue){ VGA_WR08(chip->PDIO, 0x3c8, regnum); VGA_WR08(chip->PDIO, 0x3c9, red); VGA_WR08(chip->PDIO, 0x3c9, green); VGA_WR08(chip->PDIO, 0x3c9, blue);} /**Lines 1–500 of 2157. 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/aperture.h> #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 const struct pci_device_id rivafb_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440) }, // NF2/IGP version, GeForce 4 MX, NV18 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x01f0) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200) }, { } /* 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; static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT); 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 = backlight_get_brightness(bd); 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->device, 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 = BACKLIGHT_POWER_ON; 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 * @data8: 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); for (j = 0; j < w/2; j++) { tmp = 0; #if defined (__BIG_ENDIAN) tmp = (b & (1 << 31)) ? fg << 16 : bg << 16; b <<= 1; tmp |= (b & (1 << 31)) ? fg : bg; b <<= 1; #else tmp = (b & 1) ? fg : bg; b >>= 1; tmp |= (b & 1) ? fg << 16 : bg << 16; b >>= 1; #endif writel(tmp, &par->riva.CURSOR[k++]); } k += (MAX_CURS - w)/2; } } /* ------------------------------------------------------------------------- * * * general utility functions * * ------------------------------------------------------------------------- */ /** * riva_wclut - set CLUT entry * @chip: pointer to RIVA_HW_INST object * @regnum: register number * @red: red component * @green: green component * @blue: blue component * * DESCRIPTION: * Sets color register @regnum. * * CALLED FROM: * rivafb_setcolreg() */ static void riva_wclut(RIVA_HW_INST *chip, unsigned char regnum, unsigned char red, unsigned char green, unsigned char blue) { VGA_WR08(chip->PDIO, 0x3c8, regnum); VGA_WR08(chip->PDIO, 0x3c9, red); VGA_WR08(chip->PDIO, 0x3c9, green); VGA_WR08(chip->PDIO, 0x3c9, blue); } /**