forked from mirrors/linux
		
	Merge branch 'intelfb-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/intelfb-2.6
* 'intelfb-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/intelfb-2.6: intelfbhw.c: intelfbhw_get_p1p2 defined but not used intelfb: fix mtrr_reg signedness intelfb: update doc and Kconfig (supported devices) intelfb: add preliminary i2c support intelfb: add preliminary i2c support intelfb: add preliminary i2c support intelfb: add preliminary i2c support intelfb: add preliminary i2c support intelfb: add preliminary i2c support intelfb: add preliminary i2c support intelfb: add preliminary i2c support intelfb: add vsync interrupt support intelfb: add vsync interrupt support intelfb: add vsync interrupt support intelfb: add vsync interrupt support intelfb: add vsync interrupt support
This commit is contained in:
		
						commit
						db1a19b38f
					
				
					 9 changed files with 535 additions and 11 deletions
				
			
		| 
						 | 
					@ -1,16 +1,19 @@
 | 
				
			||||||
Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver
 | 
					Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver
 | 
				
			||||||
================================================================
 | 
					================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
A. Introduction
 | 
					A. Introduction
 | 
				
			||||||
	This is a framebuffer driver for various Intel 810/815 compatible
 | 
						This is a framebuffer driver for various Intel 8xx/9xx compatible
 | 
				
			||||||
graphics devices.  These would include:
 | 
					graphics devices.  These would include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Intel 830M
 | 
						Intel 830M
 | 
				
			||||||
	Intel 810E845G
 | 
						Intel 845G
 | 
				
			||||||
	Intel 852GM
 | 
						Intel 852GM
 | 
				
			||||||
	Intel 855GM
 | 
						Intel 855GM
 | 
				
			||||||
	Intel 865G
 | 
						Intel 865G
 | 
				
			||||||
	Intel 915G
 | 
						Intel 915G
 | 
				
			||||||
 | 
						Intel 915GM
 | 
				
			||||||
 | 
						Intel 945G
 | 
				
			||||||
 | 
						Intel 945GM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
B.  List of available options
 | 
					B.  List of available options
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +81,7 @@ C. Kernel booting
 | 
				
			||||||
Separate each option/option-pair by commas (,) and the option from its value
 | 
					Separate each option/option-pair by commas (,) and the option from its value
 | 
				
			||||||
with an equals sign (=) as in the following:
 | 
					with an equals sign (=) as in the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
video=i810fb:option1,option2=value2
 | 
					video=intelfb:option1,option2=value2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Sample Usage
 | 
					Sample Usage
 | 
				
			||||||
------------
 | 
					------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -825,30 +825,48 @@ config FB_I810_I2C
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config FB_INTEL
 | 
					config FB_INTEL
 | 
				
			||||||
	tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
 | 
						tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)"
 | 
				
			||||||
	depends on FB && EXPERIMENTAL && PCI && X86
 | 
						depends on FB && EXPERIMENTAL && PCI && X86
 | 
				
			||||||
	select AGP
 | 
						select AGP
 | 
				
			||||||
	select AGP_INTEL
 | 
						select AGP_INTEL
 | 
				
			||||||
 | 
						select I2C_ALGOBIT if FB_INTEL_I2C
 | 
				
			||||||
 | 
						select I2C if FB_INTEL_I2C
 | 
				
			||||||
	select FB_MODE_HELPERS
 | 
						select FB_MODE_HELPERS
 | 
				
			||||||
	select FB_CFB_FILLRECT
 | 
						select FB_CFB_FILLRECT
 | 
				
			||||||
	select FB_CFB_COPYAREA
 | 
						select FB_CFB_COPYAREA
 | 
				
			||||||
	select FB_CFB_IMAGEBLIT
 | 
						select FB_CFB_IMAGEBLIT
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  This driver supports the on-board graphics built in to the Intel
 | 
						  This driver supports the on-board graphics built in to the Intel
 | 
				
			||||||
          830M/845G/852GM/855GM/865G chipsets.
 | 
					          830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM chipsets.
 | 
				
			||||||
          Say Y if you have and plan to use such a board.
 | 
					          Say Y if you have and plan to use such a board.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          To compile this driver as a module, choose M here: the
 | 
						  If you say Y here and want DDC/I2C support you must first say Y to
 | 
				
			||||||
 | 
						  "I2C support" and "I2C bit-banging support" in the character devices
 | 
				
			||||||
 | 
						  section.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  If you say M here then "I2C support" and "I2C bit-banging support"
 | 
				
			||||||
 | 
						  can be build either as modules or built-in.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  To compile this driver as a module, choose M here: the
 | 
				
			||||||
	  module will be called intelfb.
 | 
						  module will be called intelfb.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  For more information, please read <file:Documentation/fb/intelfb.txt>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config FB_INTEL_DEBUG
 | 
					config FB_INTEL_DEBUG
 | 
				
			||||||
        bool "Intel driver Debug Messages"
 | 
						bool "Intel driver Debug Messages"
 | 
				
			||||||
	depends on FB_INTEL
 | 
						depends on FB_INTEL
 | 
				
			||||||
	---help---
 | 
						---help---
 | 
				
			||||||
	  Say Y here if you want the Intel driver to output all sorts
 | 
						  Say Y here if you want the Intel driver to output all sorts
 | 
				
			||||||
	  of debugging informations to provide to the maintainer when
 | 
						  of debugging informations to provide to the maintainer when
 | 
				
			||||||
	  something goes wrong.
 | 
						  something goes wrong.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config FB_INTEL_I2C
 | 
				
			||||||
 | 
						bool "DDC/I2C for Intel framebuffer support"
 | 
				
			||||||
 | 
						depends on FB_INTEL
 | 
				
			||||||
 | 
						default y
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Say Y here if you want DDC/I2C support for your on-board Intel graphics.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config FB_MATROX
 | 
					config FB_MATROX
 | 
				
			||||||
	tristate "Matrox acceleration"
 | 
						tristate "Matrox acceleration"
 | 
				
			||||||
	depends on FB && PCI
 | 
						depends on FB && PCI
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
obj-$(CONFIG_FB_INTEL) += intelfb.o
 | 
					obj-$(CONFIG_FB_INTEL) += intelfb.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
intelfb-objs := intelfbdrv.o intelfbhw.o
 | 
					intelfb-y := intelfbdrv.o intelfbhw.o
 | 
				
			||||||
 | 
					intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o
 | 
				
			||||||
 | 
					intelfb-objs := $(intelfb-y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifdef CONFIG_FB_INTEL_DEBUG
 | 
					ifdef CONFIG_FB_INTEL_DEBUG
 | 
				
			||||||
#EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP
 | 
					#EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,10 @@
 | 
				
			||||||
#include <linux/agp_backend.h>
 | 
					#include <linux/agp_backend.h>
 | 
				
			||||||
#include <linux/fb.h>
 | 
					#include <linux/fb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_FB_INTEL_I2C
 | 
				
			||||||
 | 
					#include <linux/i2c.h>
 | 
				
			||||||
 | 
					#include <linux/i2c-algo-bit.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*** Version/name ***/
 | 
					/*** Version/name ***/
 | 
				
			||||||
#define INTELFB_VERSION			"0.9.4"
 | 
					#define INTELFB_VERSION			"0.9.4"
 | 
				
			||||||
| 
						 | 
					@ -115,6 +119,29 @@
 | 
				
			||||||
/* Intel agpgart driver */
 | 
					/* Intel agpgart driver */
 | 
				
			||||||
#define AGP_PHYSICAL_MEMORY     2
 | 
					#define AGP_PHYSICAL_MEMORY     2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* store information about an Ixxx DVO */
 | 
				
			||||||
 | 
					/* The i830->i865 use multiple DVOs with multiple i2cs */
 | 
				
			||||||
 | 
					/* the i915, i945 have a single sDVO i2c bus - which is different */
 | 
				
			||||||
 | 
					#define MAX_OUTPUTS 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* these are outputs from the chip - integrated only
 | 
				
			||||||
 | 
					   external chips are via DVO or SDVO output */
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_UNUSED 0
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_ANALOG 1
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_DVO 2
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_SDVO 3
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_LVDS 4
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_TVOUT 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define INTELFB_DVO_CHIP_NONE 0
 | 
				
			||||||
 | 
					#define INTELFB_DVO_CHIP_LVDS 1
 | 
				
			||||||
 | 
					#define INTELFB_DVO_CHIP_TMDS 2
 | 
				
			||||||
 | 
					#define INTELFB_DVO_CHIP_TVOUT 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_PIPE_NC  0
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_PIPE_A   1
 | 
				
			||||||
 | 
					#define INTELFB_OUTPUT_PIPE_B   2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*** Data Types ***/
 | 
					/*** Data Types ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* supported chipsets */
 | 
					/* supported chipsets */
 | 
				
			||||||
| 
						 | 
					@ -195,6 +222,10 @@ struct intelfb_hwstate {
 | 
				
			||||||
	u32 mem_mode;
 | 
						u32 mem_mode;
 | 
				
			||||||
	u32 fw_blc_0;
 | 
						u32 fw_blc_0;
 | 
				
			||||||
	u32 fw_blc_1;
 | 
						u32 fw_blc_1;
 | 
				
			||||||
 | 
						u16 hwstam;
 | 
				
			||||||
 | 
						u16 ier;
 | 
				
			||||||
 | 
						u16 iir;
 | 
				
			||||||
 | 
						u16 imr;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct intelfb_heap_data {
 | 
					struct intelfb_heap_data {
 | 
				
			||||||
| 
						 | 
					@ -204,6 +235,33 @@ struct intelfb_heap_data {
 | 
				
			||||||
	u32 size;    // in bytes
 | 
						u32 size;    // in bytes
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_FB_INTEL_I2C
 | 
				
			||||||
 | 
					struct intelfb_i2c_chan {
 | 
				
			||||||
 | 
					    struct intelfb_info *dinfo;
 | 
				
			||||||
 | 
					    u32 reg;
 | 
				
			||||||
 | 
					    struct i2c_adapter adapter;
 | 
				
			||||||
 | 
					    struct i2c_algo_bit_data algo;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct intelfb_output_rec {
 | 
				
			||||||
 | 
					    int type;
 | 
				
			||||||
 | 
					    int pipe;
 | 
				
			||||||
 | 
					    int flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_FB_INTEL_I2C
 | 
				
			||||||
 | 
					    struct intelfb_i2c_chan i2c_bus;
 | 
				
			||||||
 | 
					    struct intelfb_i2c_chan ddc_bus;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct intelfb_vsync {
 | 
				
			||||||
 | 
						wait_queue_head_t wait;
 | 
				
			||||||
 | 
						unsigned int count;
 | 
				
			||||||
 | 
						int pan_display;
 | 
				
			||||||
 | 
						u32 pan_offset;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct intelfb_info {
 | 
					struct intelfb_info {
 | 
				
			||||||
	struct fb_info *info;
 | 
						struct fb_info *info;
 | 
				
			||||||
	struct fb_ops  *fbops;
 | 
						struct fb_ops  *fbops;
 | 
				
			||||||
| 
						 | 
					@ -220,7 +278,7 @@ struct intelfb_info {
 | 
				
			||||||
	u8 fbmem_gart;
 | 
						u8 fbmem_gart;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* mtrr support */
 | 
						/* mtrr support */
 | 
				
			||||||
	u32 mtrr_reg;
 | 
						int mtrr_reg;
 | 
				
			||||||
	u32 has_mtrr;
 | 
						u32 has_mtrr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* heap data */
 | 
						/* heap data */
 | 
				
			||||||
| 
						 | 
					@ -267,6 +325,12 @@ struct intelfb_info {
 | 
				
			||||||
	int fixed_mode;
 | 
						int fixed_mode;
 | 
				
			||||||
	int ring_active;
 | 
						int ring_active;
 | 
				
			||||||
	int flag;
 | 
						int flag;
 | 
				
			||||||
 | 
						unsigned long irq_flags;
 | 
				
			||||||
 | 
						int open;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* vsync */
 | 
				
			||||||
 | 
						struct intelfb_vsync vsync;
 | 
				
			||||||
 | 
						spinlock_t int_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* hw cursor */
 | 
						/* hw cursor */
 | 
				
			||||||
	int cursor_on;
 | 
						int cursor_on;
 | 
				
			||||||
| 
						 | 
					@ -285,12 +349,25 @@ struct intelfb_info {
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* index into plls */
 | 
						/* index into plls */
 | 
				
			||||||
	int pll_index;
 | 
						int pll_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* outputs */
 | 
				
			||||||
 | 
						int num_outputs;
 | 
				
			||||||
 | 
						struct intelfb_output_rec output[MAX_OUTPUTS];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM))
 | 
					#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef FBIO_WAITFORVSYNC
 | 
				
			||||||
 | 
					#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*** function prototypes ***/
 | 
					/*** function prototypes ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var);
 | 
					extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_FB_INTEL_I2C
 | 
				
			||||||
 | 
					extern void intelfb_create_i2c_busses(struct intelfb_info *dinfo);
 | 
				
			||||||
 | 
					extern void intelfb_delete_i2c_busses(struct intelfb_info *dinfo);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _INTELFB_H */
 | 
					#endif /* _INTELFB_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										200
									
								
								drivers/video/intelfb/intelfb_i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								drivers/video/intelfb/intelfb_i2c.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,200 @@
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 Copyright 2006 Dave Airlie <airlied@linux.ie>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All Rights Reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					on the rights to use, copy, modify, merge, publish, distribute, sub
 | 
				
			||||||
 | 
					license, and/or sell copies of the Software, and to permit persons to whom
 | 
				
			||||||
 | 
					the Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice (including the next
 | 
				
			||||||
 | 
					paragraph) shall be included in all copies or substantial portions of the
 | 
				
			||||||
 | 
					Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 | 
				
			||||||
 | 
					THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 | 
				
			||||||
 | 
					DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 | 
				
			||||||
 | 
					OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 | 
				
			||||||
 | 
					USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/config.h>
 | 
				
			||||||
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					#include <linux/sched.h>
 | 
				
			||||||
 | 
					#include <linux/delay.h>
 | 
				
			||||||
 | 
					#include <linux/pci.h>
 | 
				
			||||||
 | 
					#include <linux/fb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/i2c.h>
 | 
				
			||||||
 | 
					#include <linux/i2c-id.h>
 | 
				
			||||||
 | 
					#include <linux/i2c-algo-bit.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <asm/io.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "intelfb.h"
 | 
				
			||||||
 | 
					#include "intelfbhw.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* bit locations in the registers */
 | 
				
			||||||
 | 
					#define SCL_DIR_MASK		0x0001
 | 
				
			||||||
 | 
					#define SCL_DIR			0x0002
 | 
				
			||||||
 | 
					#define SCL_VAL_MASK		0x0004
 | 
				
			||||||
 | 
					#define SCL_VAL_OUT		0x0008
 | 
				
			||||||
 | 
					#define SCL_VAL_IN		0x0010
 | 
				
			||||||
 | 
					#define SDA_DIR_MASK		0x0100
 | 
				
			||||||
 | 
					#define SDA_DIR			0x0200
 | 
				
			||||||
 | 
					#define SDA_VAL_MASK		0x0400
 | 
				
			||||||
 | 
					#define SDA_VAL_OUT		0x0800
 | 
				
			||||||
 | 
					#define SDA_VAL_IN		0x1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void intelfb_gpio_setscl(void *data, int state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct intelfb_i2c_chan *chan = data;
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = chan->dinfo;
 | 
				
			||||||
 | 
						u32 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
 | 
				
			||||||
 | 
						val = INREG(chan->reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void intelfb_gpio_setsda(void *data, int state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct intelfb_i2c_chan *chan = data;
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = chan->dinfo;
 | 
				
			||||||
 | 
						u32 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
 | 
				
			||||||
 | 
						val = INREG(chan->reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int intelfb_gpio_getscl(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct intelfb_i2c_chan *chan = data;
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = chan->dinfo;
 | 
				
			||||||
 | 
						u32 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OUTREG(chan->reg, SCL_DIR_MASK);
 | 
				
			||||||
 | 
						OUTREG(chan->reg, 0);
 | 
				
			||||||
 | 
						val = INREG(chan->reg);
 | 
				
			||||||
 | 
						return ((val & SCL_VAL_IN) != 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int intelfb_gpio_getsda(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct intelfb_i2c_chan *chan = data;
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = chan->dinfo;
 | 
				
			||||||
 | 
						u32 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OUTREG(chan->reg, SDA_DIR_MASK);
 | 
				
			||||||
 | 
						OUTREG(chan->reg, 0);
 | 
				
			||||||
 | 
						val = INREG(chan->reg);
 | 
				
			||||||
 | 
						return ((val & SDA_VAL_IN) != 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
 | 
				
			||||||
 | 
													 struct intelfb_i2c_chan *chan,
 | 
				
			||||||
 | 
													 const u32 reg, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chan->dinfo					= dinfo;
 | 
				
			||||||
 | 
						chan->reg					= reg;
 | 
				
			||||||
 | 
						snprintf(chan->adapter.name, I2C_NAME_SIZE, "intelfb %s", name);
 | 
				
			||||||
 | 
						chan->adapter.owner			= THIS_MODULE;
 | 
				
			||||||
 | 
						chan->adapter.id			= I2C_HW_B_INTELFB;
 | 
				
			||||||
 | 
						chan->adapter.algo_data		= &chan->algo;
 | 
				
			||||||
 | 
						chan->adapter.dev.parent	= &chan->dinfo->pdev->dev;
 | 
				
			||||||
 | 
						chan->algo.setsda			= intelfb_gpio_setsda;
 | 
				
			||||||
 | 
						chan->algo.setscl			= intelfb_gpio_setscl;
 | 
				
			||||||
 | 
						chan->algo.getsda			= intelfb_gpio_getsda;
 | 
				
			||||||
 | 
						chan->algo.getscl			= intelfb_gpio_getscl;
 | 
				
			||||||
 | 
						chan->algo.udelay			= 40;
 | 
				
			||||||
 | 
						chan->algo.timeout			= 20;
 | 
				
			||||||
 | 
						chan->algo.data				= chan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						i2c_set_adapdata(&chan->adapter, chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Raise SCL and SDA */
 | 
				
			||||||
 | 
						intelfb_gpio_setsda(chan, 1);
 | 
				
			||||||
 | 
						intelfb_gpio_setscl(chan, 1);
 | 
				
			||||||
 | 
						udelay(20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = i2c_bit_add_bus(&chan->adapter);
 | 
				
			||||||
 | 
						if (rc == 0)
 | 
				
			||||||
 | 
							DBG_MSG("I2C bus %s registered.\n", name);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							WRN_MSG("Failed to register I2C bus %s.\n", name);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* everyone has at least a single analog output */
 | 
				
			||||||
 | 
						dinfo->num_outputs = 1;
 | 
				
			||||||
 | 
						dinfo->output[i].type = INTELFB_OUTPUT_ANALOG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* setup the DDC bus for analog output */
 | 
				
			||||||
 | 
						intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, "CRTDDC_A");
 | 
				
			||||||
 | 
						i++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* need to add the output busses for each device
 | 
				
			||||||
 | 
					       - this function is very incomplete
 | 
				
			||||||
 | 
					       - i915GM has LVDS and TVOUT for example
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    switch(dinfo->chipset) {
 | 
				
			||||||
 | 
						case INTEL_830M:
 | 
				
			||||||
 | 
						case INTEL_845G:
 | 
				
			||||||
 | 
						case INTEL_855GM:
 | 
				
			||||||
 | 
						case INTEL_865G:
 | 
				
			||||||
 | 
							dinfo->output[i].type = INTELFB_OUTPUT_DVO;
 | 
				
			||||||
 | 
							intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOD, "DVODDC_D");
 | 
				
			||||||
 | 
							intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "DVOI2C_E");
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case INTEL_915G:
 | 
				
			||||||
 | 
						case INTEL_915GM:
 | 
				
			||||||
 | 
							/* has  some LVDS + tv-out */
 | 
				
			||||||
 | 
						case INTEL_945G:
 | 
				
			||||||
 | 
						case INTEL_945GM:
 | 
				
			||||||
 | 
							/* SDVO ports have a single control bus - 2 devices */
 | 
				
			||||||
 | 
							dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
 | 
				
			||||||
 | 
							intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "SDVOCTRL_E");
 | 
				
			||||||
 | 
							/* TODO: initialize the SDVO */
 | 
				
			||||||
 | 
					//		I830SDVOInit(pScrn, i, DVOB);
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* set up SDVOC */
 | 
				
			||||||
 | 
							dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
 | 
				
			||||||
 | 
							dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus;
 | 
				
			||||||
 | 
							/* TODO: initialize the SDVO */
 | 
				
			||||||
 | 
					//		I830SDVOInit(pScrn, i, DVOC);
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dinfo->num_outputs = i;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void intelfb_delete_i2c_busses(struct intelfb_info *dinfo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < MAX_OUTPUTS; i++) {
 | 
				
			||||||
 | 
							if (dinfo->output[i].i2c_bus.dinfo) {
 | 
				
			||||||
 | 
								i2c_bit_del_bus(&dinfo->output[i].i2c_bus.adapter);
 | 
				
			||||||
 | 
								dinfo->output[i].i2c_bus.dinfo = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (dinfo->output[i].ddc_bus.dinfo) {
 | 
				
			||||||
 | 
								i2c_bit_del_bus(&dinfo->output[i].ddc_bus.adapter);
 | 
				
			||||||
 | 
								dinfo->output[i].ddc_bus.dinfo = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -136,6 +136,8 @@
 | 
				
			||||||
static void __devinit get_initial_mode(struct intelfb_info *dinfo);
 | 
					static void __devinit get_initial_mode(struct intelfb_info *dinfo);
 | 
				
			||||||
static void update_dinfo(struct intelfb_info *dinfo,
 | 
					static void update_dinfo(struct intelfb_info *dinfo,
 | 
				
			||||||
			 struct fb_var_screeninfo *var);
 | 
								 struct fb_var_screeninfo *var);
 | 
				
			||||||
 | 
					static int intelfb_open(struct fb_info *info, int user);
 | 
				
			||||||
 | 
					static int intelfb_release(struct fb_info *info, int user);
 | 
				
			||||||
static int intelfb_check_var(struct fb_var_screeninfo *var,
 | 
					static int intelfb_check_var(struct fb_var_screeninfo *var,
 | 
				
			||||||
			     struct fb_info *info);
 | 
								     struct fb_info *info);
 | 
				
			||||||
static int intelfb_set_par(struct fb_info *info);
 | 
					static int intelfb_set_par(struct fb_info *info);
 | 
				
			||||||
| 
						 | 
					@ -194,6 +196,8 @@ static int num_registered = 0;
 | 
				
			||||||
/* fb ops */
 | 
					/* fb ops */
 | 
				
			||||||
static struct fb_ops intel_fb_ops = {
 | 
					static struct fb_ops intel_fb_ops = {
 | 
				
			||||||
	.owner =		THIS_MODULE,
 | 
						.owner =		THIS_MODULE,
 | 
				
			||||||
 | 
						.fb_open =              intelfb_open,
 | 
				
			||||||
 | 
						.fb_release =           intelfb_release,
 | 
				
			||||||
	.fb_check_var =         intelfb_check_var,
 | 
						.fb_check_var =         intelfb_check_var,
 | 
				
			||||||
	.fb_set_par =           intelfb_set_par,
 | 
						.fb_set_par =           intelfb_set_par,
 | 
				
			||||||
	.fb_setcolreg =		intelfb_setcolreg,
 | 
						.fb_setcolreg =		intelfb_setcolreg,
 | 
				
			||||||
| 
						 | 
					@ -446,6 +450,8 @@ cleanup(struct intelfb_info *dinfo)
 | 
				
			||||||
	if (!dinfo)
 | 
						if (!dinfo)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						intelfbhw_disable_irq(dinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fb_dealloc_cmap(&dinfo->info->cmap);
 | 
						fb_dealloc_cmap(&dinfo->info->cmap);
 | 
				
			||||||
	kfree(dinfo->info->pixmap.addr);
 | 
						kfree(dinfo->info->pixmap.addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -467,6 +473,11 @@ cleanup(struct intelfb_info *dinfo)
 | 
				
			||||||
		agp_free_memory(dinfo->gtt_ring_mem);
 | 
							agp_free_memory(dinfo->gtt_ring_mem);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_FB_INTEL_I2C
 | 
				
			||||||
 | 
						/* un-register I2C bus */
 | 
				
			||||||
 | 
						intelfb_delete_i2c_busses(dinfo);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dinfo->mmio_base)
 | 
						if (dinfo->mmio_base)
 | 
				
			||||||
		iounmap((void __iomem *)dinfo->mmio_base);
 | 
							iounmap((void __iomem *)dinfo->mmio_base);
 | 
				
			||||||
	if (dinfo->aperture.virtual)
 | 
						if (dinfo->aperture.virtual)
 | 
				
			||||||
| 
						 | 
					@ -844,6 +855,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
 | 
				
			||||||
	if (bailearly == 5)
 | 
						if (bailearly == 5)
 | 
				
			||||||
		bailout(dinfo);
 | 
							bailout(dinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_FB_INTEL_I2C
 | 
				
			||||||
 | 
						/* register I2C bus */
 | 
				
			||||||
 | 
						intelfb_create_i2c_busses(dinfo);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bailearly == 6)
 | 
						if (bailearly == 6)
 | 
				
			||||||
		bailout(dinfo);
 | 
							bailout(dinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -888,6 +904,13 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dinfo->registered = 1;
 | 
						dinfo->registered = 1;
 | 
				
			||||||
 | 
						dinfo->open = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						init_waitqueue_head(&dinfo->vsync.wait);
 | 
				
			||||||
 | 
						spin_lock_init(&dinfo->int_lock);
 | 
				
			||||||
 | 
						dinfo->irq_flags = 0;
 | 
				
			||||||
 | 
						dinfo->vsync.pan_display = 0;
 | 
				
			||||||
 | 
						dinfo->vsync.pan_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1187,6 +1210,34 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
 | 
				
			||||||
 *                       fbdev interface                       *
 | 
					 *                       fbdev interface                       *
 | 
				
			||||||
 ***************************************************************/
 | 
					 ***************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					intelfb_open(struct fb_info *info, int user)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = GET_DINFO(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (user) {
 | 
				
			||||||
 | 
							dinfo->open++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					intelfb_release(struct fb_info *info, int user)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = GET_DINFO(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (user) {
 | 
				
			||||||
 | 
							dinfo->open--;
 | 
				
			||||||
 | 
							msleep(1);
 | 
				
			||||||
 | 
							if (!dinfo->open) {
 | 
				
			||||||
 | 
								intelfbhw_disable_irq(dinfo);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 | 
					intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1433,6 +1484,19 @@ static int
 | 
				
			||||||
intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 | 
					intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int retval = 0;
 | 
						int retval = 0;
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = GET_DINFO(info);
 | 
				
			||||||
 | 
						u32 pipe = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (cmd) {
 | 
				
			||||||
 | 
							case FBIO_WAITFORVSYNC:
 | 
				
			||||||
 | 
								if (get_user(pipe, (__u32 __user *)arg))
 | 
				
			||||||
 | 
									return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								retval = intelfbhw_wait_for_vsync(dinfo, pipe);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@
 | 
				
			||||||
#include <linux/pci.h>
 | 
					#include <linux/pci.h>
 | 
				
			||||||
#include <linux/vmalloc.h>
 | 
					#include <linux/vmalloc.h>
 | 
				
			||||||
#include <linux/pagemap.h>
 | 
					#include <linux/pagemap.h>
 | 
				
			||||||
 | 
					#include <linux/interrupt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/io.h>
 | 
					#include <asm/io.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -368,7 +369,13 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	offset += dinfo->fb.offset << 12;
 | 
						offset += dinfo->fb.offset << 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	OUTREG(DSPABASE, offset);
 | 
						dinfo->vsync.pan_offset = offset;
 | 
				
			||||||
 | 
						if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) {
 | 
				
			||||||
 | 
							dinfo->vsync.pan_display = 1;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							dinfo->vsync.pan_display = 0;
 | 
				
			||||||
 | 
							OUTREG(DSPABASE, offset);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -585,6 +592,11 @@ intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
 | 
				
			||||||
	hw->fw_blc_0 = INREG(FW_BLC_0);
 | 
						hw->fw_blc_0 = INREG(FW_BLC_0);
 | 
				
			||||||
	hw->fw_blc_1 = INREG(FW_BLC_1);
 | 
						hw->fw_blc_1 = INREG(FW_BLC_1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hw->hwstam = INREG16(HWSTAM);
 | 
				
			||||||
 | 
						hw->ier = INREG16(IER);
 | 
				
			||||||
 | 
						hw->iir = INREG16(IIR);
 | 
				
			||||||
 | 
						hw->imr = INREG16(IMR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -613,6 +625,7 @@ static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvd
 | 
				
			||||||
	return vco / p;
 | 
						return vco / p;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if REGDUMP
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
 | 
					intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -638,6 +651,7 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
 | 
				
			||||||
	*o_p1 = p1;
 | 
						*o_p1 = p1;
 | 
				
			||||||
	*o_p2 = p2;
 | 
						*o_p2 = p2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -794,6 +808,10 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
 | 
				
			||||||
	printk("	FW_BLC_0		0x%08x\n", hw->fw_blc_0);
 | 
						printk("	FW_BLC_0		0x%08x\n", hw->fw_blc_0);
 | 
				
			||||||
	printk("	FW_BLC_1		0x%08x\n", hw->fw_blc_1);
 | 
						printk("	FW_BLC_1		0x%08x\n", hw->fw_blc_1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk("	HWSTAM			0x%04x\n", hw->hwstam);
 | 
				
			||||||
 | 
						printk("	IER			0x%04x\n", hw->ier);
 | 
				
			||||||
 | 
						printk("	IIR			0x%04x\n", hw->iir);
 | 
				
			||||||
 | 
						printk("	IMR			0x%04x\n", hw->imr);
 | 
				
			||||||
	printk("hw state dump end\n");
 | 
						printk("hw state dump end\n");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1932,3 +1950,119 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
 | 
				
			||||||
		addr += 16;
 | 
							addr += 16;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static irqreturn_t
 | 
				
			||||||
 | 
					intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) {
 | 
				
			||||||
 | 
						int handled = 0;
 | 
				
			||||||
 | 
						u16 tmp;
 | 
				
			||||||
 | 
						struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock(&dinfo->int_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = INREG16(IIR);
 | 
				
			||||||
 | 
						tmp &= VSYNC_PIPE_A_INTERRUPT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tmp == 0) {
 | 
				
			||||||
 | 
							spin_unlock(&dinfo->int_lock);
 | 
				
			||||||
 | 
							return IRQ_RETVAL(handled);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OUTREG16(IIR, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tmp & VSYNC_PIPE_A_INTERRUPT) {
 | 
				
			||||||
 | 
							dinfo->vsync.count++;
 | 
				
			||||||
 | 
							if (dinfo->vsync.pan_display) {
 | 
				
			||||||
 | 
								dinfo->vsync.pan_display = 0;
 | 
				
			||||||
 | 
								OUTREG(DSPABASE, dinfo->vsync.pan_offset);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wake_up_interruptible(&dinfo->vsync.wait);
 | 
				
			||||||
 | 
							handled = 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_unlock(&dinfo->int_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return IRQ_RETVAL(handled);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!test_and_set_bit(0, &dinfo->irq_flags)) {
 | 
				
			||||||
 | 
							if (request_irq(dinfo->pdev->irq, intelfbhw_irq, SA_SHIRQ, "intelfb", dinfo)) {
 | 
				
			||||||
 | 
								clear_bit(0, &dinfo->irq_flags);
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							spin_lock_irq(&dinfo->int_lock);
 | 
				
			||||||
 | 
							OUTREG16(HWSTAM, 0xfffe);
 | 
				
			||||||
 | 
							OUTREG16(IMR, 0x0);
 | 
				
			||||||
 | 
							OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT);
 | 
				
			||||||
 | 
							spin_unlock_irq(&dinfo->int_lock);
 | 
				
			||||||
 | 
						} else if (reenable) {
 | 
				
			||||||
 | 
							u16 ier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							spin_lock_irq(&dinfo->int_lock);
 | 
				
			||||||
 | 
							ier = INREG16(IER);
 | 
				
			||||||
 | 
							if ((ier & VSYNC_PIPE_A_INTERRUPT)) {
 | 
				
			||||||
 | 
								DBG_MSG("someone disabled the IRQ [%08X]\n", ier);
 | 
				
			||||||
 | 
								OUTREG(IER, VSYNC_PIPE_A_INTERRUPT);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							spin_unlock_irq(&dinfo->int_lock);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					intelfbhw_disable_irq(struct intelfb_info *dinfo) {
 | 
				
			||||||
 | 
						u16 tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (test_and_clear_bit(0, &dinfo->irq_flags)) {
 | 
				
			||||||
 | 
							if (dinfo->vsync.pan_display) {
 | 
				
			||||||
 | 
								dinfo->vsync.pan_display = 0;
 | 
				
			||||||
 | 
								OUTREG(DSPABASE, dinfo->vsync.pan_offset);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							spin_lock_irq(&dinfo->int_lock);
 | 
				
			||||||
 | 
							OUTREG16(HWSTAM, 0xffff);
 | 
				
			||||||
 | 
							OUTREG16(IMR, 0xffff);
 | 
				
			||||||
 | 
							OUTREG16(IER, 0x0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tmp = INREG16(IIR);
 | 
				
			||||||
 | 
							OUTREG16(IIR, tmp);
 | 
				
			||||||
 | 
							spin_unlock_irq(&dinfo->int_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							free_irq(dinfo->pdev->irq, dinfo);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) {
 | 
				
			||||||
 | 
						struct intelfb_vsync *vsync;
 | 
				
			||||||
 | 
						unsigned int count;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (pipe) {
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								vsync = &dinfo->vsync;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return -ENODEV;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = intelfbhw_enable_irq(dinfo, 0);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						count = vsync->count;
 | 
				
			||||||
 | 
						ret = wait_event_interruptible_timeout(vsync->wait, count != vsync->count, HZ/10);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (ret == 0) {
 | 
				
			||||||
 | 
							intelfbhw_enable_irq(dinfo, 1);
 | 
				
			||||||
 | 
							DBG_MSG("wait_for_vsync timed out!\n");
 | 
				
			||||||
 | 
							return -ETIMEDOUT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,6 +88,19 @@
 | 
				
			||||||
#define INSTDONE		0x2090
 | 
					#define INSTDONE		0x2090
 | 
				
			||||||
#define PRI_RING_EMPTY			1
 | 
					#define PRI_RING_EMPTY			1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSTAM			0x2098
 | 
				
			||||||
 | 
					#define IER			0x20A0
 | 
				
			||||||
 | 
					#define IIR			0x20A4
 | 
				
			||||||
 | 
					#define IMR			0x20A8
 | 
				
			||||||
 | 
					#define VSYNC_PIPE_A_INTERRUPT		(1 << 7)
 | 
				
			||||||
 | 
					#define PIPE_A_EVENT_INTERRUPT		(1 << 4)
 | 
				
			||||||
 | 
					#define VSYNC_PIPE_B_INTERRUPT		(1 << 5)
 | 
				
			||||||
 | 
					#define PIPE_B_EVENT_INTERRUPT		(1 << 4)
 | 
				
			||||||
 | 
					#define HOST_PORT_EVENT_INTERRUPT	(1 << 3)
 | 
				
			||||||
 | 
					#define CAPTURE_EVENT_INTERRUPT		(1 << 2)
 | 
				
			||||||
 | 
					#define USER_DEFINED_INTERRUPT		(1 << 1)
 | 
				
			||||||
 | 
					#define BREAKPOINT_INTERRUPT		1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define INSTPM			0x20c0
 | 
					#define INSTPM			0x20c0
 | 
				
			||||||
#define SYNC_FLUSH_ENABLE		(1 << 5)
 | 
					#define SYNC_FLUSH_ENABLE		(1 << 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,6 +126,12 @@
 | 
				
			||||||
#define FW_DISPC_BL_SHIFT		8
 | 
					#define FW_DISPC_BL_SHIFT		8
 | 
				
			||||||
#define FW_DISPC_BL_MASK		0x7
 | 
					#define FW_DISPC_BL_MASK		0x7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GPIOA             0x5010
 | 
				
			||||||
 | 
					#define GPIOB             0x5014
 | 
				
			||||||
 | 
					#define GPIOC             0x5018 // this may be external DDC on i830
 | 
				
			||||||
 | 
					#define GPIOD             0x501C // this is DVO DDC
 | 
				
			||||||
 | 
					#define GPIOE             0x5020 // this is DVO i2C
 | 
				
			||||||
 | 
					#define GPIOF             0x5024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* PLL registers */
 | 
					/* PLL registers */
 | 
				
			||||||
#define VGA0_DIVISOR		0x06000
 | 
					#define VGA0_DIVISOR		0x06000
 | 
				
			||||||
| 
						 | 
					@ -468,9 +487,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* I/O macros */
 | 
					/* I/O macros */
 | 
				
			||||||
#define INREG8(addr)	      readb((u8 __iomem *)(dinfo->mmio_base + (addr)))
 | 
					#define INREG8(addr)	      readb((u8 __iomem *)(dinfo->mmio_base + (addr)))
 | 
				
			||||||
 | 
					#define INREG16(addr)	      readw((u16 __iomem *)(dinfo->mmio_base + (addr)))
 | 
				
			||||||
#define INREG(addr)	      readl((u32 __iomem *)(dinfo->mmio_base + (addr)))
 | 
					#define INREG(addr)	      readl((u32 __iomem *)(dinfo->mmio_base + (addr)))
 | 
				
			||||||
#define OUTREG8(addr, val)    writeb((val),(u8 __iomem *)(dinfo->mmio_base + \
 | 
					#define OUTREG8(addr, val)    writeb((val),(u8 __iomem *)(dinfo->mmio_base + \
 | 
				
			||||||
							   (addr)))
 | 
												   (addr)))
 | 
				
			||||||
 | 
					#define OUTREG16(addr, val)    writew((val),(u16 __iomem *)(dinfo->mmio_base + \
 | 
				
			||||||
 | 
												   (addr)))
 | 
				
			||||||
#define OUTREG(addr, val)     writel((val),(u32 __iomem *)(dinfo->mmio_base + \
 | 
					#define OUTREG(addr, val)     writel((val),(u32 __iomem *)(dinfo->mmio_base + \
 | 
				
			||||||
                                     (addr)))
 | 
					                                     (addr)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -545,5 +567,8 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg,
 | 
				
			||||||
extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
 | 
					extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
 | 
				
			||||||
				  int height, u8 *data);
 | 
									  int height, u8 *data);
 | 
				
			||||||
extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
 | 
					extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
 | 
				
			||||||
 | 
					extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable);
 | 
				
			||||||
 | 
					extern void intelfbhw_disable_irq(struct intelfb_info *dinfo);
 | 
				
			||||||
 | 
					extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _INTELFBHW_H */
 | 
					#endif /* _INTELFBHW_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -193,6 +193,7 @@
 | 
				
			||||||
#define I2C_HW_B_RADEON		0x01001e /* radeon framebuffer driver */
 | 
					#define I2C_HW_B_RADEON		0x01001e /* radeon framebuffer driver */
 | 
				
			||||||
#define I2C_HW_B_EM28XX		0x01001f /* em28xx video capture cards */
 | 
					#define I2C_HW_B_EM28XX		0x01001f /* em28xx video capture cards */
 | 
				
			||||||
#define I2C_HW_B_CX2341X	0x010020 /* Conexant CX2341X MPEG encoder cards */
 | 
					#define I2C_HW_B_CX2341X	0x010020 /* Conexant CX2341X MPEG encoder cards */
 | 
				
			||||||
 | 
					#define I2C_HW_B_INTELFB	0x010021 /* intel framebuffer driver */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* --- PCF 8584 based algorithms					*/
 | 
					/* --- PCF 8584 based algorithms					*/
 | 
				
			||||||
#define I2C_HW_P_LP		0x020000 /* Parallel port interface */
 | 
					#define I2C_HW_P_LP		0x020000 /* Parallel port interface */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue