--- /dev/null
+/*
+ * linux/drivers/video/i830/i830.c
+ * -- Intel 830 framebuffer device
+ *
+ * Copyright (C) 2004 Frank Zirkelbach <hackbard@hackdaworld.dyndns.org>
+ * All Rights Reserved
+ *
+ * Code based on vfb.c (Geert Uytterhoeven), i810fb (Tony Daplas),
+ * xorg i830 drivers and intelfb (David Dawes).
+ *
+ * This driver is subject to the terms of the GNU General Public License.
+ * See file COPYING in the main directory for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/resource.h>
+#include <linux/unistd.h>
+#include <asm/io.h>
+#include <asm/div64.h>
+#include <asm/page.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "i830_regs.h"
+#include "i830.h"
+
+static const char *i830_pci_list[] __devinitdata = {
+ "Intel(R) 830 Chipset Graphics Controller Framebuffer Device"
+};
+static struct pci_device_id i830fb_pci_table[] = {
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82830_CGC,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0 }
+};
+satic struct pci_driver i830fb_driver = {
+ .name = "i830fb",
+ .id_table = i830fb_pci_table,
+ .probe = i830fb_init_pci,
+ .remove = __exit_p(i830fb_remove_pci),
+ .suspend = i830fb_suspend,
+ .resume = i830fb_resume
+};
+static struct fb_ops i830fb_ops __devinitdata = {
+ .owner = THIS_MODULE,
+ .fb_open = i830fb_open,
+ .fb_release = i830fb_release,
+ .fb_check_var = i830fb_check_var,
+ .fb_set_par = i830fb_set_par,
+ .fb_setcolreg = i830fb_setcolreg,
+ .fb_blank = i830fb_blank,
+ .fb_pan_display = i830fb_pan_display,
+ .fb_fillrect = i830fb_fillrect,
+ .fb_copyarea = i830fb_copyarea,
+ .fb_imageblit = i830fb_imageblit,
+ .fb_cursor = i830fb_cursor,
+ .fb_sync = i830fb_sync,
+ .fb_ioctl = i830fb_ioctl
+};
+
+/* drivers default values */
+static int vram __initdata = 4;
+static int bpp __initdata = 8;
+static int mtrr __initdata = 0;
+static int accel __initdata = 0;
+static int hsync1 __initdata = 0;
+static int hsync2 __initdata = 0;
+static int vsync1 __initdata = 0;
+static int vsync2 __initdata = 0;
+static int xres __initdata = 640;
+static int yres __initdata = 480;
+static int sync __initdata = 0;
+static int ext_vga __initdata = 0;
+
+
+
+
+int __init i830fb_init(void) {
+
+#ifdef MODULE
+
+ hsync1 *= 1000;
+ hsync2 *= 1000;
+
+#endif
+
+#ifndef MODULE
+
+ if(agp_intel_init()) {
+ printk("i830fb_init: unable to initialize intel agpgart\n");
+ return -ENODEV;
+ }
+
+#endif
+
+ if(pci_register_driver(&i830fb_driver) > 0) return 0;
+
+ pci_unregister_driver(&i830fb_driver);
+
+ return -ENODEV;
+}
+
+#ifdef MODULE
+
+MODULE_PARAM(vram, "i");
+MODULE_PARAM_DESC(vram, "Allocated system RAM in MB (default=4));
+MODULE_PARAM(bpp, "i");
+MODULE_PARAM_DESC(bpp, "Display depth in bits per pixel (default=8));
+MODULE_PARAM(mtrr, "i");
+MODULE_PARAM_DESC(mtrr, "Use MTRR (default=0));
+MODULE_PARAM(accel, "i");
+MODULE_PARAM_DESC(accel, "Use acceleration (default=0));
+MODULE_PARAM(hsync1, "i");
+MODULE_PARAM_DESC(hsync1, "Minimum horizontal frequency in kHz (default=29));
+MODULE_PARAM(hsync2, "i");
+MODULE_PARAM_DESC(hsync2, "Maximum horizontal frequency in kHz (default=30));
+MODULE_PARAM(vsync1, "i");
+MODULE_PARAM_DESC(vsync1, "Minimum vertical frequency in Hz (default=60));
+MODULE_PARAM(vsync2, "i");
+MODULE_PARAM_DESC(vsync2, "Maximum vertical frequency in Hz (default=60));
+MODULE_PARAM(xres, "i");
+MODULE_PARAM_DESC(xres, "Horizontal resolution in pixels (default=640));
+MODULE_PARAM(yres, "i");
+MODULE_PARAM_DESC(yres, "Vertical resolution in pixels (default=480));
+MODULE_PARAM(sync);
+MODULE_PARAM_DESC(sync, "Wait for hardware blit (default=0));
+MODULE_PARAM(ext_vga);
+MODULE_PARAM_DESC(ext_vga, "Enable external vga port (default=0));
+
+MODULE_LICENSE("GPL");
+
+static void __exit i830fb_exit(void) {
+ pci_unregister_driver(&i830fb_driver);
+}
+module_init(i830fb_init);
+module_exit(i830fb_exit);
+
+#endif
+
+static int i830fb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ struct fb_info *info) {
+
+ printk("i830fb_ioctl: no specific ioctl (yet)\n")
+ return -EINVAL;
+
+}
+
+static int __devinit i830fb_init_pci(struct pci_dev *dev,
+ const struct pci_device_id *entry) {
+
+ struct fb_info *info;
+ struct i830fb_par *par;
+ int err, vfreq, hfreq, pixclock, size;
+
+ par = NULL;
+
+ if(!(info = kmalloc(sizeof(struct fb_info), GFP_KERNEL))) {
+ i830fb_release_resource(info, par);
+ return -ENOMEM;
+ }
+ memset(info, 0, sizeof(struct fb_info));
+
+ if(!(par = kmalloc(sizeof(struct i830fb_par), GFP_KERNEL))) {
+ i830fb_release_resource(info, par);
+ return -ENOMEM;
+ }
+ memset(par, 0, sizeof(struct i830fb_par));
+
+ par->dev = dev;
+ info->par = par;
+
+ if(!(info->pixmap.addr = kmalloc(64*1024, FGP_KERNEL))) {
+ i830fb_release_resource(info, par);
+ return -ENOMEM;
+ }
+ memset(info->pixmap.addr, 0, 64*1024));
+ info->pixmap.size = 64*1024;
+ info->pixmap.buf_align = 8;
+ info->pixmap.flags = FB_PIXMAP_SYSTEM;
+
+ /* allocate pci resource */
+ if((err = pci_enable_device(dev))) {
+ printk("i830fb_init_pci: unable to enable device\n");
+ i830fb_release_resource(info, par);
+ return err;
+ }
+ par->res_flags |= PCI_DEVICE_ENABLED;
+ if(pci_resource_len(dev, 0) > 512 * 1024) {
+ par->aperture.physical = pci_resource_start(dev, 0);
+ par->aperture.size = pci_resource_len(dev, 0);
+ par->mmio.physical = pci_resource_start(dev, 1);
+ par->mmio.size = pci_resource_len(dev, 1);
+ }
+ else {
+ par->aperture.physical = pci_resource_start(dev, 1);
+ par->aperture.size = pci_resource_len(dev, 1);
+ par->mmio.physical = pci_resource_start(dev, 0);
+ par->mmio.size = pci_resource_len(dev, 0);
+ }
+ if(par->mmio.size != MMIO_SIZE)
+ printk("i830fb_init_pci: warning - mmio size not 512 kB !\n");
+ if(!par->aperture.size) {
+ printk("i830fb_init_pci: unable to get resource start/len\n");
+ i830fb_release_resource(info, par);
+ return -ENOMEM;
+ }
+ if(!request_mem_region(par->aperture.physical, par->aperture.size,
+ i830_pci_list[entry->driver_data])) {
+ printk("i830fb_init_pci: unable to request fb region\n");
+ i830fb_release_resource(info, par);
+ return -ENODEV;
+ }
+ par->res_flags |= FB_MEM_REGION_REQ;
+ if(!request_mem_region(par->mmio.physical, MMIO_SIZE,
+ i830_pci_list[entry->driver_data])) {
+ printk("i830fb_init_pci: unable to request mmio region\n");
+ i830fb_release_resource(info, par);
+ return -ENODEV;
+ }
+ par->res_flags |= MMIO_MEM_REGION_REQ;
+ par->aperture.virtual = ioremap_nocache(par->aperture.physical,
+ par->aperture.size);
+ if(!par->aperture.virtual) {
+ printk("i830fb_init_pci: unable to remap fb region\n");
+ i830fb_release_resource(info, par);
+ return -ENODEV;
+ }
+ par->mmio.virtual = ioremap_nocache(par->mmio.physical, MMIO_SIZE);
+ if(!par->mmio.virtual) {
+ printk("i830fb_init_pci: unable to remap mmio region\n");
+ i830fb_release_resource(info, par);
+ return -ENODEV;
+ }
+
+ /* initialize values to use */
+ // TODO: check with voffset!
+ if(!vram) vram=1;
+ if(accel) {
+ par->dev_flags |= ACCEL;
+ info->var.accel_flags = 1;
+ }
+ if(sync) par->dev_flags |= SYNC;
+ if(bpp < 8) bpp = 8;
+ if(bpp > 32) bpp = 32;
+ par->i830fb_ops = i830fb_ops;
+ info->var.xres = xres;
+ info->var.yres = yres;
+ info->var.bits_per_pixel = bpp;
+ if(!hsync1) hsync1 = 29000
+ if(!hsync2) hsync2 = 30000
+ if(!vsync1) vsync1 = 60
+ if(!vsync2) vsync2 = 60
+ info->monospecs.hfmax = hsync2;
+ info->monospecs.hfmin = hsync1;
+ info->monospecs.vfmax = vsync2;
+ info->monospecs.vfmin = vsync1;
+ if(hsync2 < hsync1) info->monospecs.hfmin = hsync2;
+ if(vsync2 < vsync1) info->monospecs.vfmin = vsync2;
+
+ /* fix offsets and allocate agp memory */
+ if(vram > ((par->aperture.size >> 20) - 1)
+ vram = (par->aperture.size >> 20) - 1;
+ // v_offset_default ? (0 here)
+ par->fb.size = vram << 20;
+ par->fb.offset = 0;
+ par->fb.offset >>= 12; /* what is all this devision by 4kB for? */
+ par->ring.offset = par->fb.offset + (par->fb.size >> 12);
+ par->ring.size = RINGBUF_SIZE;
+ par->cursor.offset = par->ring.offset + (RINGBUF_SIZE >> 12);
+ par->cursor.size = CURSOR_SIZE;
+ size=par->fb.size + par->ring.size;
+ if(!(par->drm_agp = (drm_agp_t *) inter_module_get("drm_agp"))) {
+ printk("i830fb_init_pci: unable to acquire agp\n");
+ i830fb_release_resource(info, par);
+ return -ENODEV;
+ }
+ par->drm_agp->acquire();
+ if(!(par->i830_gtt.i830_fb_mem =
+ par->drm_agp->allocate_memory(size >> 12, AGP_NORMAL_MEMORY))) {
+ printk("i830fb_init_pci: unable to allocate fb memory (agp)\n");
+ par->drm_agp->release();
+ i830fb_release_resource(info, par);
+ return -ENOMEM;
+ }
+ if(par->drm_agp->bind_memory(par->i830_gtt.i830_fb_mem,
+ par->fb.offset)) {
+ printk("i830fb_init_pci: unable to bind fb memory (agp)\n");
+ par->drm_agp->release();
+ i830fb_release_resource(info, par);
+ return -EBUSY;
+ }
+ if(!(par->i830_gtt.i830_cursor_mem =
+ par->drm_agp->allocate_memory(par->cursor.size >> 12,
+ AGP_NORMAL_MEMORY))) {
+ printk("i830fb_init_pci: unable to allocate cursor mem(agp)\n");
+ par->drm_agp->release();
+ i830fb_release_resource(info, par);
+ return -ENOMEM;
+ }
+ if(par->drm_agp->bind_memory(par->i830_gtt.i830_cursor_mem,
+ par->cursor.offset)) {
+ printk("i830fb_init_pci: unable to bind cursor mem (agp)\n");
+ par->drm_agp->release();
+ i830fb_release_resource(info, par);
+ return -EBUSY;
+ }
+ par->cursor.physical = par->i830_gtt.i830_cursor_mem->physical;
+ par->fb.physical = par->aperture.physical + (par->fb.offset << 12);
+
+
+
+
--- /dev/null
+/*
+ * linux/drivers/video/i830/i830.h
+ * -- Intel 830 framebuffer device header file
+ *
+ * Copyright (C) 2004 Frank Zirkelbach <hackbard@hackdaworld.dyndns.org>
+ * All Rights Reserved
+ *
+ * This driver is subject to the terms of the GNU General Public License.
+ * See file COPYING in the main directory for more details.
+ *
+ */
+
+#ifndef __I830_H__
+#define __I830_H__
+
+/* variable types
+struct mode_registers {
+ u32 pixclock, M, N, P;
+ u8 cr00, cr01, cr02, cr03;
+ u8 cr04, cr05, cr06, cr07;
+ u8 cr09, cr10, cr11, cr12;
+ u8 cr13, cr15, cr16, cr30;
+ u8 cr31, cr32, cr33, cr35, cr39;
+ u32 bpp8_100, bpp16_100, bpp24_100;
+ u32 bpp8_133, bpp16_133, bpp24_133;
+ u8 msr;
+};
+struct state_registers {
+ u32 dclk_1d, dclk_2d, dclk_0ds;
+ u32 pixconf, fw_blc, pgtbl_ctl;
+ u32 fence0, hws_pga, dplystas;
+ u16 bltcntl, hwstam, ier, iir, imr;
+ u8 cr00, cr01, cr02, cr03, cr04;
+ u8 cr05, cr06, cr07, cr08, cro9;
+ u8 cr10, cr11, cr12, cr13, cr14;
+ u8 cr15, cr16, cr17, cr80, gr10;
+ u8 cr30, cr31, cr32, cr33, cr35;
+ u8 cr39, cr41, cr70, sr01, msr;
+};
+struct gtt_data {
+ struct agp_memory *i830_fb_mem;
+ struct agp_memory *i830_cursor_mem;
+};
+struct mem_region {
+ unsigned long physical;
+ __u8 *virtual;
+ u32 offset;
+ u32 size;
+};
+struct i830fb_par {
+ struct mode_registers regs;
+ struct state_registers hw_state;
+ struct gtt_data i830_gtt;
+ struct fb_ops i830fb_ops;
+ struct pci_dev *dev; /* pci device */
+ struct mem_region aperture; /* aperture memory region */
+ struct mem_region mmio; /* memory mapped region */
+ struct mem_region fb; /* framebuffer memory region */
+ struct mem_region ring; /* ringbuffer memory region */
+ struct mem_region cursor;
+ struct vga_state state;
+ drm_agp_t *drm_agp;
+ atomic_t use_count;
+ u32 pseudo_palette[17];
+ u32 pci_state[16];
+ u32 pitch;
+ u32 pixconf;
+ u32 watermark;
+ u32 mem_freq;
+ u32 res_flags; /* resource flags */
+#define FB_MEM_REGION_REQ 1
+#define MMIO_MEM_REGION_REQ 2
+#define PCI_DEVICE_ENABLED 4
+ u32 dev_flags;
+ u32 cur_tail;
+ u32 depth;
+ u32 blit_bpp;
+ u32 ovract;
+ u32 cur_state;
+ int mtrr_reg;
+ u16 bltcntl;
+ u8 interlace;
+};
+
+/* general defines */
+#define MMIO_SIZE (512 * 1024)
+#define RINGBUF_SIZE (64 * 1024)
+#define CURSOR_SIZE (4 * 1024)
+
+/* function prototypes */
+i830fb_init_pci();
+i830fb_remove_pci();
+i830fb_suspend();
+i830fb_resume();
+i830fb_open();
+i830fb_release();
+i830fb_check_var();
+i830fb_set_par();
+i830fb_setcolreg();
+i830fb_blank();
+i830fb_pan_display();
+i830fb_fillrect();
+i830fb_copyarea();
+i830fb_imageblit();
+i830fb_cursor();
+i830fb_sync();
+i830fb_ioctl();
+i830fb_release_resource();
+
+
+
+#endif /* __I830_H__ */