From d5c2e404ed69bdf2379e89418878f6e56b12fd96 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Mon, 9 Dec 2002 01:38:40 -0800 Subject: Added in Radeon PCI ids into pci_ids.h from radeon.h. IGA fbdev uses C99 now. --- include/linux/pci_ids.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7c0e1de47668..2bcd41cd751f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -263,6 +263,43 @@ /* Radeon NV-100 */ #define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159 #define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a +/* Radeon R100 */ +#define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144 +#define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145 +#define PCI_DEVICE_ID_ATI_RADEON_QF 0x5146 +#define PCI_DEVICE_ID_ATI_RADEON_QG 0x5147 +/* Radeon RV100 (VE) */ +#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159 +#define PCI_DEVICE_ID_ATI_RADEON_QZ 0x515a +/* Radeon R200 (8500) */ +#define PCI_DEVICE_ID_ATI_RADEON_QL 0x514c +#define PCI_DEVICE_ID_ATI_RADEON_QN 0x514e +#define PCI_DEVICE_ID_ATI_RADEON_QO 0x514f +#define PCI_DEVICE_ID_ATI_RADEON_Ql 0x516c +#define PCI_DEVICE_ID_ATI_RADEON_BB 0x4242 +/* Radeon RV200 (7500) */ +#define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157 +#define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158 +/* Radeon RV250 (9000) */ +#define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964 +#define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965 +#define PCI_DEVICE_ID_ATI_RADEON_If 0x4966 +#define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967 +/* Radeon R300 (9700) */ +#define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44 +#define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45 +#define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46 +#define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47 +/* Radeon M6 */ +#define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59 +#define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a +/* Radeon M7 */ +#define PCI_DEVICE_ID_ATI_RADEON_LW 0x4c57 +#define PCI_DEVICE_ID_ATI_RADEON_LX 0x4c58 +#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4964 +#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4965 +#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4966 +#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4967 /* Radeon */ #define PCI_DEVICE_ID_ATI_RADEON_RA 0x5144 #define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145 -- cgit v1.2.3 From 0e2e212c853772767dfdcba6fa191314d1082d47 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Wed, 11 Dec 2002 19:53:49 -0800 Subject: Anothe rattempt at commting. --- Documentation/fb/intel810.txt | 272 +++++ drivers/video/Kconfig | 38 + drivers/video/Makefile | 7 +- drivers/video/aty/atyfb_base.c | 2 +- drivers/video/cfbimgblt.c | 11 +- drivers/video/console/fbcon.c | 6 +- drivers/video/fbmem.c | 5 + drivers/video/fbmon.c | 323 +++++- drivers/video/i810/i810.h | 300 ++++++ drivers/video/i810/i810_accel.c | 513 +++++++++ drivers/video/i810/i810_dvt.c | 308 ++++++ drivers/video/i810/i810_gtf.c | 275 +++++ drivers/video/i810/i810_main.c | 2248 +++++++++++++++++++++++++++++++++++++++ drivers/video/i810/i810_main.h | 205 ++++ drivers/video/i810/i810_regs.h | 274 +++++ drivers/video/offb.c | 5 +- drivers/video/riva/fbdev.c.new | 2036 +++++++++++++++++++++++++++++++++++ include/linux/fb.h | 3 + 18 files changed, 6758 insertions(+), 73 deletions(-) create mode 100644 Documentation/fb/intel810.txt create mode 100644 drivers/video/i810/i810.h create mode 100644 drivers/video/i810/i810_accel.c create mode 100644 drivers/video/i810/i810_dvt.c create mode 100644 drivers/video/i810/i810_gtf.c create mode 100644 drivers/video/i810/i810_main.c create mode 100644 drivers/video/i810/i810_main.h create mode 100644 drivers/video/i810/i810_regs.h create mode 100644 drivers/video/riva/fbdev.c.new (limited to 'include/linux') diff --git a/Documentation/fb/intel810.txt b/Documentation/fb/intel810.txt new file mode 100644 index 000000000000..a5312cfc63da --- /dev/null +++ b/Documentation/fb/intel810.txt @@ -0,0 +1,272 @@ +Intel 810/815 Framebuffer driver + Tony Daplas + http://i810fb.sourceforge.net + + March 17, 2002 + + First Released: July 2001 +================================================================ + +A. Introduction + This is a framebuffer driver for various Intel 810/815 compatible +graphics devices. These would include: + + Intel 810 + Intel 810E + Intel 810-DC100 + Intel 815 Internal graphics only, 100Mhz FSB + Intel 815 Internal graphics only + Intel 815 Internal graphics and AGP + +B. Features + + - Choice of using Discrete Video Timings, VESA Generalized Timing + Formula, or a framebuffer specific database to set the video mode + + - Supports a variable range of horizontal and vertical resolution, and + vertical refresh rates if the VESA Generalized Timing Formula is + enabled. + + - Supports color depths of 8, 16, 24 and 32 bits per pixel + + - Supports pseudocolor, directcolor, or truecolor visuals + + - Full and optimized hardware acceleration at 8, 16 and 24 bpp + + - Robust video state save and restore + + - MTRR support + + - Utilizes user-entered monitor specifications to automatically + calculate required video mode parameters. + + - Can concurrently run with xfree86 running with native i810 drivers + + - Hardware Cursor Support + +C. List of available options + + a. "video=i810fb" + enables the i810 driver + + Recommendation: required + + b. "xres:" + select horizontal resolution in pixels + + Recommendation: user preference + (default = 640) + + c. "yres:" + select vertical resolution in scanlines. If Discrete Video Timings + is enabled, this will be ignored and computed as 3*xres/4. + + Recommendation: user preference + (default = 480) + + d. "vyres:" + select virtual vertical resolution in scanlines. If (0) or none + is specified, this will be computed against maximum available memory. + + Recommendation: do not set + (default = 480) + + e. "vram:" + select amount of system RAM in MB to allocate for the video memory + + Recommendation: 1 - 4 MB. + (default = 4) + + f. "bpp:" + select desired pixel depth + + Recommendation: 8 + (default = 8) + + g. "hsync1/hsync2:" + select the minimum and maximum Horizontal Sync Frequency of the + monitor in KHz. If a using a fixed frequency monitor, hsync1 must + be equal to hsync2. + + Recommendation: check monitor manual for correct values + default (29/30) + + h. "vsync1/vsync2:" + select the minimum and maximum Vertical Sync Frequency of the monitor + in Hz. You can also use this option to lock your monitor's refresh + rate. + + Recommendation: check monitor manual for correct values + (default = 60/60) + + IMPORTANT: If you need to clamp your timings, try to give some + leeway for computational errors (over/underflows). Example: if + using vsync1/vsync2 = 60/60, make sure hsync1/hsync2 has at least + a 1 unit difference, and vice versa. + + i. "voffset:" + select at what offset in MB of the logical memory to allocate the + framebuffer memory. The intent is to avoid the memory blocks + used by standard graphics applications (XFree86). The default + offset (16 MB for a 64MB aperture, 8 MB for a 32MB aperture) will + avoid XFree86's usage and allows up to 7MB/15MB of framebuffer + memory. Depending on your usage, adjust the value up or down, + (0 for maximum usage, 31/63 MB for the least amount). Note, an + arbitrary setting may conflict with XFree86. + + Recommendation: do not set + (default = 8 or 16 MB) + + j. "accel" + enable text acceleration. This can be enabled/reenabled anytime + by using 'fbset -accel true/false'. + + Recommendation: enable + (default = not set) + + k. "mtrr" + enable MTRR. This allows data transfers to the framebuffer memory + to occur in bursts which can significantly increase performance. + Not very helpful with the i810/i815 because of 'shared memory'. + + Recommendation: do not set + (default = not set) + + l. "extvga" + if specified, secondary/external VGA output will always be enabled. + Useful if the BIOS turns off the VGA port when no monitor is attached. + The external VGA monitor can then be attached without rebooting. + + Recommendation: do not set + (default = not set) + + m. "sync" + Forces the hardware engine to do a "sync" or wait for the hardware + to finish before starting another instruction. This will produce a + more stable setup, but will be slower. + + Recommendation: do not set + (default = not set) + + n. "dcolor" + Use directcolor visual instead of truecolor for pixel depths greater + than 8 bpp. Useful for color tuning, such as gamma control. + + Recommendation: do not set + (default = not set) + +D. Kernel booting + +Separate each option/option-pair by commas (,) and the option from its value +with a colon (:) as in the following: + +video=i810fb:option1,option2:value2 + +Sample Usage +------------ + +In /etc/lilo.conf, add the line: + +append="video=i810fb:vram:2,xres:1024,yres:768,bpp:8,hsync1:30,hsync2:55, \ + vsync1:50,vsync2:85,accel,mtrr" + +This will initialize the framebuffer to 1024x768 at 8bpp. The framebuffer +will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate +will be computed based on the hsync1/hsync2 and vsync1/vsync2 values. + +IMPORTANT: +You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes +better than 640x480 at 60Hz. + +E. Module options + + The module parameters are essentially similar to the kernel +parameters. The main difference is that you need to include a Boolean value +(1 for TRUE, and 0 for FALSE) for those options which don't need a value. + +Example, to enable MTRR, include "mtrr=1". + +Sample Usage +------------ + +Using the same setup as described above, load the module like this: + + modprobe i810fb vram=2 xres=1024 bpp=8 hsync1=30 hsync2=55 vsync1=50 \ + vsync2=85 accel=1 mtrr=1 + +Or just add the following to /etc/modules.conf + + options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \ + vsync2=85 accel=1 mtrr=1 + +and just do a + + modprobe i810fb + + +F. Setup + + a. Do your usual method of configuring the kernel. + + make menuconfig/xconfig/config + + b. Under "Code Maturity Options", enable "Prompt for experimental/ + incomplete code/drivers". + + c. Enable agpgart support for the Intel 810/815 on-board graphics. + This is required. The option is under "Character Devices" + + d. Under "Graphics Support", select "Intel 810/815" either statically + or as a module. Choose "use VESA GTF for video timings" if you + need to maximize the capability of your display. To be on the + safe side, you can leave this unselected. + + e. If you want a framebuffer console, enable it under "Console + Drivers" + + f. Compile your kernel. + + g. Load the driver as described in section D and E. + + Optional: + h. If you are going to run XFree86 with its native drivers, the + standard XFree86 4.1.0 and 4.2.0 drivers should work as is. + However, there's a bug in the XFree86 i810 drivers. It attempts + to use XAA even when switched to the console. This will crash + your server. I have a fix at this site: + + http://i810fb.sourceforge.net. + + You can either use the patch, or just replace + + /usr/X11R6/lib/modules/drivers/i810_drv.o + + with the one provided at the website. + + i. Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver + patch to see the chipset in action (or inaction :-). + +G. Acknowledgment: + + 1. Geert Uytterhoeven - his excellent howto and the virtual + framebuffer driver code made this possible. + + 2. Jeff Hartmann for his agpgart code. + + 3. The X developers. Insights were provided just by reading the + XFree86 source code. + + 4. Intel(c). For this value-oriented chipset driver and for + providing documentation. + + 5. Matt Sottek. His inputs and ideas helped in making some + optimizations possible. + +H. Home Page: + + A more complete, and probably updated information is provided at +http://i810fb.sourceforge.net. + +########################### +Tony + diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 5770cd817030..fe439b36e801 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -471,6 +471,44 @@ config FB_RIVA module will be called rivafb.o. If you want to compile it as a module, say M here and read . +config FB_I810 + tristate "Intel 810/815 support (EXPERIMENTAL)" + depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI + help + This driver supports the on-board graphics built in to the Intel 810 + and 815 chipsets. Say Y if you have and plan to use such a board. + + The driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). + The module will be called i810fb.o. If you want to compile it as a + module, say M here and read . + + For more information, please read + + +config FB_I810_GTF + bool "use VESA Generalized Timing Formula" + depends on FB_I810 + help + If you say Y, then the VESA standard, Generalized Timing Formula + or GTF, will be used to calculate the required video timing values + per video mode. Since the GTF allows nondiscrete timings + (nondiscrete being a range of values as opposed to discrete being a + set of values), you'll be able to use any combination of horizontal + and vertical resolutions, and vertical refresh rates without having + to specify your own timing parameters. This is especially useful + to maximize the performance of an aging display, or if you just + have a display with nonstandard dimensions. A VESA compliant + monitor is recommended, but can still work with non-compliant ones. + If you need or want this, then select this option. The timings may + not be compliant with Intel's recommended values. Use at your own + risk. + + If you say N, the driver will revert to discrete video timings + using a set recommended by Intel in their documentation. + + If unsure, say N. + config FB_MATROX tristate "Matrox acceleration" depends on FB && PCI diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 21d7f402a86c..2efca73de407 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -12,8 +12,7 @@ export-objs := fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o obj-$(CONFIG_VT) += console/ -# Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x -obj-$(CONFIG_FB) += fbmem.o fbcmap.o modedb.o softcursor.o +obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o modedb.o softcursor.o # Only include macmodes.o if we have FB support and are PPC ifeq ($(CONFIG_FB),y) obj-$(CONFIG_PPC) += macmodes.o @@ -42,7 +41,7 @@ obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbim obj-$(CONFIG_FB_3DFX) += tdfxfb.o obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_HP300) += hpfb.o cfbfillrect.o cfbimgblt.o -obj-$(CONFIG_FB_OF) += offb.o cfbfillrect.o cfbimgblit.o cfbcopyarea.o +obj-$(CONFIG_FB_OF) += offb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_IMSTT) += imsttfb.o obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o obj-$(CONFIG_FB_CLGEN) += clgenfb.o @@ -74,6 +73,8 @@ obj-$(CONFIG_FB_RIVA) += riva/ cfbfillrect.o cfbcopyarea.o \ cfbimgblt.o vgastate.o obj-$(CONFIG_FB_SIS) += sis/ obj-$(CONFIG_FB_ATY) += aty/ cfbimgblt.o +obj-$(CONFIG_FB_I810) += i810/ cfbfillrect.o cfbcopyarea.o \ + cfbimgblt.o vgastate.o obj-$(CONFIG_FB_SUN3) += sun3fb.o obj-$(CONFIG_FB_BWTWO) += bwtwofb.o diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 10a9cf58402a..b59ab3d9af04 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -976,7 +976,7 @@ static int atyfb_release(struct fb_info *info, int user) var.yres_virtual = var.yres; } - gen_set_var(&var, -1, info); + fb_set_var(&var, -1, info); } } } diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c index 11a87a694a85..5cdab4d58663 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/cfbimgblt.c @@ -103,10 +103,10 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8 { /* Draw the penguin */ int i, n; - unsigned long bitmask = SHIFT_LOW(~0UL, BITS_PER_LONG - p->var.bits_per_pixel); + int bpp = p->var.bits_per_pixel; unsigned long *palette = (unsigned long *) p->pseudo_palette; unsigned long *dst, *dst2, color = 0, val, shift; - unsigned long null_bits = BITS_PER_LONG - p->var.bits_per_pixel; + unsigned long null_bits = BITS_PER_LONG - bpp; u8 *src = image->data; dst2 = (unsigned long *) dst1; @@ -125,9 +125,10 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8 while (n--) { if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR ) - color = palette[*src] & bitmask; + color = palette[*src]; else - color = *src & bitmask; + color = *src; + color <<= LEFT_POS(bpp); val |= SHIFT_HIGH(color, shift); if (shift >= null_bits) { FB_WRITEL(val, dst++); @@ -136,7 +137,7 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8 else val = SHIFT_LOW(color, BITS_PER_LONG - shift); } - shift += p->var.bits_per_pixel; + shift += bpp; shift &= (BITS_PER_LONG - 1); src++; } diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 68a6c45c0b24..83bcdae0a36e 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -929,11 +929,11 @@ static void fbcon_set_display(int con, int init, int logo) struct display *q = &fb_display[i]; struct vc_data *tmp = vc_cons[i].d; - if (fontwidthvalid(p, vc->vc_font.width)) { + if (!fontwidthvalid(p, vc->vc_font.width)) { /* If we are not the first console on this fb, copy the font from that console */ - tmp->vc_font.width = vc->vc_font.width; - tmp->vc_font.height = vc->vc_font.height; + vc->vc_font.width = tmp->vc_font.width; + vc->vc_font.height = tmp->vc_font.height; p->fontdata = q->fontdata; p->userfont = q->userfont; if (p->userfont) { diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 1f943d14954a..fdd9b5ee6e4c 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -141,6 +141,8 @@ extern int pvr2fb_init(void); extern int pvr2fb_setup(char*); extern int sstfb_init(void); extern int sstfb_setup(char*); +extern int i810fb_init(void); +extern int i810fb_setup(char*); static struct { const char *name; @@ -235,6 +237,9 @@ static struct { #ifdef CONFIG_FB_TRIDENT { "trident", tridentfb_init, tridentfb_setup }, #endif +#ifdef CONFIG_FB_I810 + { "i810fb", i810fb_init, i810fb_setup }, +#endif /* * Generic drivers that are used as fallbacks diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 77a796109a99..4693961f899b 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -1,77 +1,284 @@ /* * linux/drivers/video/fbmon.c * - * Copyright (C) 1999 James Simmons + * Copyright (C) 2002 James Simmons * * 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. * - * Notes: - * This code handles the different types of monitors that are out their. - * Most video cards for example can support a mode like 800x600 but fix - * frequency monitors can't. So the code here checks if the monitor can - * support the mode as well as the card can. Fbmonospecs takes on - * different meaning with different types of monitors. For multifrequency - * monitors fbmonospecs represents the range of frequencies the monitor - * can support. Only one fbmonospec needs to be allocated. The fbmonospecs - * pointer in fb_info points to this one. If you specific a mode that has - * timing greater than the allowed range then setting the video mode will - * fail. With multifrequency monitors you can set any mode you like as long - * as you have a programmable clock on the video card. - * With fixed frequency monitors you have only a SET of very narrow - * allowed frequency ranges. So for a fixed fequency monitor you have a - * array of fbmonospecs. The fbmonospecs in fb_info represents the - * monitor frequency for the CURRENT mode. If you change the mode and ask - * for fbmonospecs you will NOT get the same values as before. Note this - * is not true for multifrequency monitors where you do get the same - * fbmonospecs each time. Also the values in each fbmonospecs represent the - * very narrow frequency band for range. Well you can't have exactly the - * same frequencies from fixed monitor. So some tolerance is excepted. - * By DEFAULT all monitors are assumed fixed frequency since they are so - * easy to fry or screw up a mode with. Just try setting a 800x600 mode on - * one. After you boot you can run a simple program the tells what kind of - * monitor you have. If you have a multifrequency monitor then you can set - * any mode size you like as long as your video card has a programmable clock. - * By default also besides assuming you have a fixed frequency monitor it - * assumes the monitor only supports lower modes. This way for example you - * can't set a 1280x1024 mode on a fixed frequency monitor that can only - * support up to 1024x768. - * */ #include #include #include -int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal, - const struct fb_info *fb_info) +/* + * EDID parser + * + * portions of this file were based on the EDID parser by + * John Fremlin and Ani Joshi + */ + +#define EDID_LENGTH 0x80 +#define EDID_HEADER 0x00 +#define EDID_HEADER_END 0x07 + +#define ID_MANUFACTURER_NAME 0x08 +#define ID_MANUFACTURER_NAME_END 0x09 +#define ID_MODEL 0x0a + +#define ID_SERIAL_NUMBER 0x0c + +#define MANUFACTURE_WEEK 0x10 +#define MANUFACTURE_YEAR 0x11 + +#define EDID_STRUCT_VERSION 0x12 +#define EDID_STRUCT_REVISION 0x13 + +#define DPMS_FLAGS 0x18 +#define ESTABLISHED_TIMING_1 0x23 +#define ESTABLISHED_TIMING_2 0x24 +#define MANUFACTURERS_TIMINGS 0x25 + +#define DETAILED_TIMING_DESCRIPTIONS_START 0x36 +#define DETAILED_TIMING_DESCRIPTION_SIZE 18 +#define NO_DETAILED_TIMING_DESCRIPTIONS 4 + +#define DETAILED_TIMING_DESCRIPTION_1 0x36 +#define DETAILED_TIMING_DESCRIPTION_2 0x48 +#define DETAILED_TIMING_DESCRIPTION_3 0x5a +#define DETAILED_TIMING_DESCRIPTION_4 0x6c + +#define DESCRIPTOR_DATA 5 + +#define UPPER_NIBBLE( x ) \ + (((128|64|32|16) & (x)) >> 4) + +#define LOWER_NIBBLE( x ) \ + ((1|2|4|8) & (x)) + +#define COMBINE_HI_8LO( hi, lo ) \ + ( (((unsigned)hi) << 8) | (unsigned)lo ) + +#define COMBINE_HI_4LO( hi, lo ) \ + ( (((unsigned)hi) << 4) | (unsigned)lo ) + +#define PIXEL_CLOCK_LO (unsigned)block[ 0 ] +#define PIXEL_CLOCK_HI (unsigned)block[ 1 ] +#define PIXEL_CLOCK (COMBINE_HI_8LO( PIXEL_CLOCK_HI,PIXEL_CLOCK_LO )*1000 +#define H_ACTIVE_LO (unsigned)block[ 2 ] +#define H_BLANKING_LO (unsigned)block[ 3 ] +#define H_ACTIVE_HI UPPER_NIBBLE( (unsigned)block[ 4 ] ) +#define H_ACTIVE COMBINE_HI_8LO( H_ACTIVE_HI, H_ACTIVE_LO ) +#define H_BLANKING_HI LOWER_NIBBLE( (unsigned)block[ 4 ] ) +#define H_BLANKING COMBINE_HI_8LO( H_BLANKING_HI, H_BLANKING_LO ) + +#define V_ACTIVE_LO (unsigned)block[ 5 ] +#define V_BLANKING_LO (unsigned)block[ 6 ] +#define V_ACTIVE_HI UPPER_NIBBLE( (unsigned)block[ 7 ] ) +#define V_ACTIVE COMBINE_HI_8LO( V_ACTIVE_HI, V_ACTIVE_LO ) +#define V_BLANKING_HI LOWER_NIBBLE( (unsigned)block[ 7 ] ) +#define V_BLANKING COMBINE_HI_8LO( V_BLANKING_HI, V_BLANKING_LO ) + +#define H_SYNC_OFFSET_LO (unsigned)block[ 8 ] +#define H_SYNC_WIDTH_LO (unsigned)block[ 9 ] + +#define V_SYNC_OFFSET_LO UPPER_NIBBLE( (unsigned)block[ 10 ] ) +#define V_SYNC_WIDTH_LO LOWER_NIBBLE( (unsigned)block[ 10 ] ) + +#define V_SYNC_WIDTH_HI ((unsigned)block[ 11 ] & (1|2)) +#define V_SYNC_OFFSET_HI (((unsigned)block[ 11 ] & (4|8)) >> 2) + +#define H_SYNC_WIDTH_HI (((unsigned)block[ 11 ] & (16|32)) >> 4) +#define H_SYNC_OFFSET_HI (((unsigned)block[ 11 ] & (64|128)) >> 6) + +#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO ) +#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO ) + +#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO ) +#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO ) + +#define H_SIZE_LO (unsigned)block[ 12 ] +#define V_SIZE_LO (unsigned)block[ 13 ] + +#define H_SIZE_HI UPPER_NIBBLE( (unsigned)block[ 14 ] ) +#define V_SIZE_HI LOWER_NIBBLE( (unsigned)block[ 14 ] ) + +#define H_SIZE COMBINE_HI_8LO( H_SIZE_HI, H_SIZE_LO ) +#define V_SIZE COMBINE_HI_8LO( V_SIZE_HI, V_SIZE_LO ) + +#define H_BORDER (unsigned)block[ 15 ] +#define V_BORDER (unsigned)block[ 16 ] + +#define FLAGS (unsigned)block[ 17 ] + +#define INTERLACED (FLAGS&128) +#define SYNC_TYPE (FLAGS&3<<3) /* bits 4,3 */ +#define SYNC_SEPARATE (3<<3) +#define HSYNC_POSITIVE (FLAGS & 4) +#define VSYNC_POSITIVE (FLAGS & 2) + +const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00 +}; +const unsigned char edid_v1_descriptor_flag[] = { 0x00, 0x00 }; + +static int edid_checksum(unsigned char *edid) { -#if 0 - /* - * long long divisions .... $#%%#$ - */ - unsigned long long hpicos, vpicos; - const unsigned long long _1e12 = 1000000000000ULL; - const struct fb_monspecs *monspecs = &fb_info->monspecs; - - hpicos = (unsigned long long)htotal*(unsigned long long)pixclock; - vpicos = (unsigned long long)vtotal*(unsigned long long)hpicos; - if (!vpicos) - return 0; - - if (monspecs->hfmin == 0) - return 1; - - if (hpicos*monspecs->hfmin > _1e12 || hpicos*monspecs->hfmax < _1e12 || - vpicos*monspecs->vfmin > _1e12 || vpicos*monspecs->vfmax < _1e12) - return 0; -#endif - return 1; + unsigned char i, csum = 0; + + for (i = 0; i < EDID_LENGTH; i++) + csum += edid[i]; + + if (csum == 0x00) { + /* checksum passed, everything's good */ + return 1; + } else { + printk("EDID checksum failed, aborting\n"); + return 0; + } } -int fbmon_dpms(const struct fb_info *fb_info) +static int edid_check_header(unsigned char *edid) { - return fb_info->monspecs.dpms; + if ((edid[0] != 0x00) || (edid[1] != 0xff) || (edid[2] != 0xff) || + (edid[3] != 0xff) || (edid[4] != 0xff) || (edid[5] != 0xff) || + (edid[6] != 0xff)) { + printk + ("EDID header doesn't match EDID v1 header, aborting\n"); + return 0; + } + return 1; } -EXPORT_SYMBOL(fbmon_valid_timings); + +static char *edid_get_vendor(unsigned char *block) +{ + static char sign[4]; + unsigned short h; + + h = COMBINE_HI_8LO(block[0], block[1]); + sign[0] = ((h >> 10) & 0x1f) + 'A' - 1; + sign[1] = ((h >> 5) & 0x1f) + 'A' - 1; + sign[2] = (h & 0x1f) + 'A' - 1; + sign[3] = 0; + + return sign; +} + +static char *edid_get_monitor(unsigned char *block) +{ + static char name[13]; + unsigned i; + const unsigned char *ptr = block + DESCRIPTOR_DATA; + + for (i = 0; i < 13; i++, ptr++) { + if (*ptr == 0xa) { + name[i] = 0x00; + return name; + } + name[i] = *ptr; + } + return name; +} + +static int edid_is_timing_block(unsigned char *block) +{ + if ((block[0] == 0x00) && (block[1] == 0x00)) + return 0; + else + return 1; +} + +static int edid_is_monitor_block(unsigned char *block) +{ + if ((block[0] == 0x00) && (block[1] == 0x00) && (block[3] == 0xfc)) + return 1; + else + return 0; +} + +static void parse_timing_block(unsigned char *block, + struct fb_var_screeninfo *var) +{ + var->xres = var->xres_virtual = H_ACTIVE; + var->yres = var->yres_virtual = V_ACTIVE; + var->height = var->width = -1; + var->right_margin = H_SYNC_OFFSET; + var->left_margin = (H_ACTIVE + H_BLANKING) - + (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); + var->upper_margin = V_BLANKING - V_SYNC_OFFSET - V_SYNC_WIDTH; + var->lower_margin = V_SYNC_OFFSET; + var->hsync_len = H_SYNC_WIDTH; + var->vsync_len = V_SYNC_WIDTH; + var->pixclock = PIXEL_CLOCK; + var->pixclock /= 1000; + var->pixclock = KHZ2PICOS(var->pixclock); + + if (HSYNC_POSITIVE) + var->sync |= FB_SYNC_HOR_HIGH_ACT; + if (VSYNC_POSITIVE) + var->sync |= FB_SYNC_VERT_HIGH_ACT; +} + +int parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) +{ + int i; + unsigned char *block, *vendor, *monitor; + + if (!(edid_checksum(edid))) + return 0; + + if (!(edid_check_header(edid))) + return 0; + + printk("EDID ver %d rev %d\n", (int) edid[EDID_STRUCT_VERSION], + (int) edid[EDID_STRUCT_REVISION]); + + vendor = edid_get_vendor(edid + ID_MANUFACTURER_NAME); + + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; + + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { + if (edid_is_monitor_block(block)) { + monitor = edid_get_monitor(block); + } + } + + printk("EDID: detected %s %s\n", vendor, monitor); + + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; + + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { + if (edid_is_timing_block(block)) { + parse_timing_block(block, var); + } + } + return 1; +} + +char *get_EDID(struct pci_dev *pdev) +{ +#ifdef CONFIG_ALL_PPC + static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL }; + unsigned char *pedid = NULL; + struct device_node *dp; + int i; + + dp = pci_device_to_OF_node(pdev); + while (dp != NULL) { + for (i = 0; propnames[i] != NULL; ++i) { + pedid = (unsigned char *) get_property(dp, propnames[i], NULL); + if (pedid != NULL) + return pedid; + } + dp = dp->child; + } + return pedid; +#else + return NULL; +#endif +} + +EXPORT_SYMBOL(parse_edid); +EXPORT_SYMBOL(get_EDID); diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h new file mode 100644 index 000000000000..3a548d4fa5c6 --- /dev/null +++ b/drivers/video/i810/i810.h @@ -0,0 +1,300 @@ +/*-*- linux-c -*- + * linux/drivers/video/i810.h -- Intel 810 General Definitions/Declarations + * + * Copyright (C) 2001 Antonino Daplas + * All Rights Reserved + * + * + * 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. + */ + +#ifndef __I810_H__ +#define __I810_H__ + +#include +#include +#include +#include