/* * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver * * Maintained by Ani Joshi <[email protected]> * * 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 … /* ------------------------------------------------------------------------- * * * various helpful macros and constants * * ------------------------------------------------------------------------- */ #ifdef CONFIG_FB_RIVA_DEBUG #define NVTRACE … #else #define NVTRACE … #endif #define NVTRACE_ENTER(...) … #define NVTRACE_LEAVE(...) … #ifdef CONFIG_FB_RIVA_DEBUG #define assert(expr) … #else #define assert … #endif #define PFX … /* macro that allows you to set overflow bits */ #define SetBitField(value,from,to) … #define SetBit(n) … #define Set8Bits(value) … /* HW cursor parameters */ #define MAX_CURS … /* ------------------------------------------------------------------------- * * * prototypes * * ------------------------------------------------------------------------- */ static int rivafb_blank(int blank, struct fb_info *info); /* ------------------------------------------------------------------------- * * * card identification * * ------------------------------------------------------------------------- */ static const struct pci_device_id rivafb_pci_tbl[] = …; MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl); /* ------------------------------------------------------------------------- * * * global variables * * ------------------------------------------------------------------------- */ /* command line data, set in rivafb_setup() */ static int flatpanel = …; /* Autodetect later */ static int forceCRTC = …; static bool noaccel = …; static bool nomtrr = …; static int backlight = … IS_BUILTIN(…); static char *mode_option = …; static bool strictmode = …; static struct fb_fix_screeninfo rivafb_fix = …; static struct fb_var_screeninfo rivafb_default_var = …; /* from GGI */ static const struct riva_regs reg_template = …; /* * 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 … #define MAX_LEVEL … #define LEVEL_STEP … static int riva_bl_get_level_brightness(struct riva_par *par, int level) { … } static int riva_bl_update_status(struct backlight_device *bd) { … } static const struct backlight_ops riva_bl_ops = …; static void riva_bl_init(struct riva_par *par) { … } static void riva_bl_exit(struct fb_info *info) { … } #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) { … } static inline unsigned char CRTCin(struct riva_par *par, unsigned char index) { … } static inline void GRAout(struct riva_par *par, unsigned char index, unsigned char val) { … } static inline unsigned char GRAin(struct riva_par *par, unsigned char index) { … } static inline void SEQout(struct riva_par *par, unsigned char index, unsigned char val) { … } static inline unsigned char SEQin(struct riva_par *par, unsigned char index) { … } static inline void ATTRout(struct riva_par *par, unsigned char index, unsigned char val) { … } static inline unsigned char ATTRin(struct riva_par *par, unsigned char index) { … } static inline void MISCout(struct riva_par *par, unsigned char val) { … } static inline unsigned char MISCin(struct riva_par *par) { … } static inline void reverse_order(u32 *l) { … } /* ------------------------------------------------------------------------- * * * 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) { … } /* ------------------------------------------------------------------------- * * * 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) { … } /** * riva_rclut - read fromCLUT register * @chip: pointer to RIVA_HW_INST object * @regnum: register number * @red: red component * @green: green component * @blue: blue component * * DESCRIPTION: * Reads red, green, and blue from color register @regnum. * * CALLED FROM: * rivafb_setcolreg() */ static void riva_rclut(RIVA_HW_INST *chip, unsigned char regnum, unsigned char *red, unsigned char *green, unsigned char *blue) { … } /** * riva_save_state - saves current chip state * @par: pointer to riva_par object containing info for current riva board * @regs: pointer to riva_regs object * * DESCRIPTION: * Saves current chip state to @regs. * * CALLED FROM: * rivafb_probe() */ /* from GGI */ static void riva_save_state(struct riva_par *par, struct riva_regs *regs) { … } /** * riva_load_state - loads current chip state * @par: pointer to riva_par object containing info for current riva board * @regs: pointer to riva_regs object * * DESCRIPTION: * Loads chip state from @regs. * * CALLED FROM: * riva_load_video_mode() * rivafb_probe() * rivafb_remove() */ /* from GGI */ static void riva_load_state(struct riva_par *par, struct riva_regs *regs) { … } /** * riva_load_video_mode - calculate timings * @info: pointer to fb_info object containing info for current riva board * * DESCRIPTION: * Calculate some timings and then send em off to riva_load_state(). * * CALLED FROM: * rivafb_set_par() */ static int riva_load_video_mode(struct fb_info *info) { … } static void riva_update_var(struct fb_var_screeninfo *var, const struct fb_videomode *modedb) { … } /** * rivafb_do_maximize - * @info: pointer to fb_info object containing info for current riva board * @var: standard kernel fb changeable data * @nom: nom * @den: den * * DESCRIPTION: * . * * RETURNS: * -EINVAL on failure, 0 on success * * * CALLED FROM: * rivafb_check_var() */ static int rivafb_do_maximize(struct fb_info *info, struct fb_var_screeninfo *var, int nom, int den) { … } static void riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1) { … } /* acceleration routines */ static inline void wait_for_idle(struct riva_par *par) { … } /* * Set ROP. Translate X rop into ROP3. Internal routine. */ static void riva_set_rop_solid(struct riva_par *par, int rop) { … } static void riva_setup_accel(struct fb_info *info) { … } /** * riva_get_cmap_len - query current color map length * @var: standard kernel fb changeable data * * DESCRIPTION: * Get current color map length. * * RETURNS: * Length of color map * * CALLED FROM: * rivafb_setcolreg() */ static int riva_get_cmap_len(const struct fb_var_screeninfo *var) { … } /* ------------------------------------------------------------------------- * * * framebuffer operations * * ------------------------------------------------------------------------- */ static int rivafb_open(struct fb_info *info, int user) { … } static int rivafb_release(struct fb_info *info, int user) { … } static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { … } static int rivafb_set_par(struct fb_info *info) { … } /** * rivafb_pan_display * @var: standard kernel fb changeable data * @info: pointer to fb_info object containing info for current riva board * * DESCRIPTION: * Pan (or wrap, depending on the `vmode' field) the display using the * `xoffset' and `yoffset' fields of the `var' structure. * If the values don't fit, return -EINVAL. * * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag */ static int rivafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { … } static int rivafb_blank(int blank, struct fb_info *info) { … } /** * rivafb_setcolreg * @regno: register index * @red: red component * @green: green component * @blue: blue component * @transp: transparency * @info: pointer to fb_info object containing info for current riva board * * DESCRIPTION: * Set a single color register. The values supplied have a 16 bit * magnitude. * * RETURNS: * Return != 0 for invalid regno. * * CALLED FROM: * fbcmap.c:fb_set_cmap() */ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { … } /** * rivafb_fillrect - hardware accelerated color fill function * @info: pointer to fb_info structure * @rect: pointer to fb_fillrect structure * * DESCRIPTION: * This function fills up a region of framebuffer memory with a solid * color with a choice of two different ROP's, copy or invert. * * CALLED FROM: * framebuffer hook */ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { … } /** * rivafb_copyarea - hardware accelerated blit function * @info: pointer to fb_info structure * @region: pointer to fb_copyarea structure * * DESCRIPTION: * This copies an area of pixels from one location to another * * CALLED FROM: * framebuffer hook */ static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region) { … } static inline void convert_bgcolor_16(u32 *col) { … } /** * rivafb_imageblit: hardware accelerated color expand function * @info: pointer to fb_info structure * @image: pointer to fb_image structure * * DESCRIPTION: * If the source is a monochrome bitmap, the function fills up a a region * of framebuffer memory with pixels whose color is determined by the bit * setting of the bitmap, 1 - foreground, 0 - background. * * If the source is not a monochrome bitmap, color expansion is not done. * In this case, it is channeled to a software function. * * CALLED FROM: * framebuffer hook */ static void rivafb_imageblit(struct fb_info *info, const struct fb_image *image) { … } /** * rivafb_cursor - hardware cursor function * @info: pointer to info structure * @cursor: pointer to fbcursor structure * * DESCRIPTION: * A cursor function that supports displaying a cursor image via hardware. * Within the kernel, copy and invert rops are supported. If exported * to user space, only the copy rop will be supported. * * CALLED FROM * framebuffer hook */ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) { … } static int rivafb_sync(struct fb_info *info) { … } /* ------------------------------------------------------------------------- * * * initialization helper functions * * ------------------------------------------------------------------------- */ /* kernel interface */ static const struct fb_ops riva_fb_ops = …; static int riva_set_fbinfo(struct fb_info *info) { … } static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) { … } #if defined(CONFIG_FB_RIVA_I2C) static int riva_get_EDID_i2c(struct fb_info *info) { … } #endif /* CONFIG_FB_RIVA_I2C */ static void riva_update_default_var(struct fb_var_screeninfo *var, struct fb_info *info) { … } static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev) { … } static void riva_get_edidinfo(struct fb_info *info) { … } /* ------------------------------------------------------------------------- * * * PCI bus * * ------------------------------------------------------------------------- */ static u32 riva_get_arch(struct pci_dev *pd) { … } static int rivafb_probe(struct pci_dev *pd, const struct pci_device_id *ent) { … } static void rivafb_remove(struct pci_dev *pd) { … } /* ------------------------------------------------------------------------- * * * initialization * * ------------------------------------------------------------------------- */ #ifndef MODULE static int rivafb_setup(char *options) { … } #endif /* !MODULE */ static struct pci_driver rivafb_driver = …; /* ------------------------------------------------------------------------- * * * modularization * * ------------------------------------------------------------------------- */ static int rivafb_init(void) { … } module_init(…) …; static void __exit rivafb_exit(void) { … } module_exit(rivafb_exit); module_param(noaccel, bool, 0); MODULE_PARM_DESC(…) …; module_param(flatpanel, int, 0); MODULE_PARM_DESC(…) …; module_param(forceCRTC, int, 0); MODULE_PARM_DESC(…) …; module_param(nomtrr, bool, 0); MODULE_PARM_DESC(…) …; module_param(strictmode, bool, 0); MODULE_PARM_DESC(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;