diff options
| -rw-r--r-- | Documentation/fb/intelfb.txt | 11 | ||||
| -rw-r--r-- | drivers/video/Kconfig | 26 | ||||
| -rw-r--r-- | drivers/video/intelfb/Makefile | 4 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfb.h | 79 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfb_i2c.c | 200 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfbdrv.c | 64 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfbhw.c | 136 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfbhw.h | 25 | ||||
| -rw-r--r-- | include/linux/i2c-id.h | 1 |
9 files changed, 535 insertions, 11 deletions
diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt index c12d39a23c3d..aa0d322db171 100644 --- a/Documentation/fb/intelfb.txt +++ b/Documentation/fb/intelfb.txt | |||
| @@ -1,16 +1,19 @@ | |||
| 1 | Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver | 1 | Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver |
| 2 | ================================================================ | 2 | ================================================================ |
| 3 | 3 | ||
| 4 | A. Introduction | 4 | A. Introduction |
| 5 | This is a framebuffer driver for various Intel 810/815 compatible | 5 | This is a framebuffer driver for various Intel 8xx/9xx compatible |
| 6 | graphics devices. These would include: | 6 | graphics devices. These would include: |
| 7 | 7 | ||
| 8 | Intel 830M | 8 | Intel 830M |
| 9 | Intel 810E845G | 9 | Intel 845G |
| 10 | Intel 852GM | 10 | Intel 852GM |
| 11 | Intel 855GM | 11 | Intel 855GM |
| 12 | Intel 865G | 12 | Intel 865G |
| 13 | Intel 915G | 13 | Intel 915G |
| 14 | Intel 915GM | ||
| 15 | Intel 945G | ||
| 16 | Intel 945GM | ||
| 14 | 17 | ||
| 15 | B. List of available options | 18 | B. List of available options |
| 16 | 19 | ||
| @@ -78,7 +81,7 @@ C. Kernel booting | |||
| 78 | Separate each option/option-pair by commas (,) and the option from its value | 81 | Separate each option/option-pair by commas (,) and the option from its value |
| 79 | with an equals sign (=) as in the following: | 82 | with an equals sign (=) as in the following: |
| 80 | 83 | ||
| 81 | video=i810fb:option1,option2=value2 | 84 | video=intelfb:option1,option2=value2 |
| 82 | 85 | ||
| 83 | Sample Usage | 86 | Sample Usage |
| 84 | ------------ | 87 | ------------ |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 702eb933cf88..e0ef3328942c 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
| @@ -825,30 +825,48 @@ config FB_I810_I2C | |||
| 825 | help | 825 | help |
| 826 | 826 | ||
| 827 | config FB_INTEL | 827 | config FB_INTEL |
| 828 | tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)" | 828 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)" |
| 829 | depends on FB && EXPERIMENTAL && PCI && X86 | 829 | depends on FB && EXPERIMENTAL && PCI && X86 |
| 830 | select AGP | 830 | select AGP |
| 831 | select AGP_INTEL | 831 | select AGP_INTEL |
| 832 | select I2C_ALGOBIT if FB_INTEL_I2C | ||
| 833 | select I2C if FB_INTEL_I2C | ||
| 832 | select FB_MODE_HELPERS | 834 | select FB_MODE_HELPERS |
| 833 | select FB_CFB_FILLRECT | 835 | select FB_CFB_FILLRECT |
| 834 | select FB_CFB_COPYAREA | 836 | select FB_CFB_COPYAREA |
| 835 | select FB_CFB_IMAGEBLIT | 837 | select FB_CFB_IMAGEBLIT |
| 836 | help | 838 | help |
| 837 | This driver supports the on-board graphics built in to the Intel | 839 | This driver supports the on-board graphics built in to the Intel |
| 838 | 830M/845G/852GM/855GM/865G chipsets. | 840 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM chipsets. |
| 839 | Say Y if you have and plan to use such a board. | 841 | Say Y if you have and plan to use such a board. |
| 840 | 842 | ||
| 841 | To compile this driver as a module, choose M here: the | 843 | If you say Y here and want DDC/I2C support you must first say Y to |
| 844 | "I2C support" and "I2C bit-banging support" in the character devices | ||
| 845 | section. | ||
| 846 | |||
| 847 | If you say M here then "I2C support" and "I2C bit-banging support" | ||
| 848 | can be build either as modules or built-in. | ||
| 849 | |||
| 850 | To compile this driver as a module, choose M here: the | ||
| 842 | module will be called intelfb. | 851 | module will be called intelfb. |
| 843 | 852 | ||
| 853 | For more information, please read <file:Documentation/fb/intelfb.txt> | ||
| 854 | |||
| 844 | config FB_INTEL_DEBUG | 855 | config FB_INTEL_DEBUG |
| 845 | bool "Intel driver Debug Messages" | 856 | bool "Intel driver Debug Messages" |
| 846 | depends on FB_INTEL | 857 | depends on FB_INTEL |
| 847 | ---help--- | 858 | ---help--- |
| 848 | Say Y here if you want the Intel driver to output all sorts | 859 | Say Y here if you want the Intel driver to output all sorts |
| 849 | of debugging informations to provide to the maintainer when | 860 | of debugging informations to provide to the maintainer when |
| 850 | something goes wrong. | 861 | something goes wrong. |
| 851 | 862 | ||
| 863 | config FB_INTEL_I2C | ||
| 864 | bool "DDC/I2C for Intel framebuffer support" | ||
| 865 | depends on FB_INTEL | ||
| 866 | default y | ||
| 867 | help | ||
| 868 | Say Y here if you want DDC/I2C support for your on-board Intel graphics. | ||
| 869 | |||
| 852 | config FB_MATROX | 870 | config FB_MATROX |
| 853 | tristate "Matrox acceleration" | 871 | tristate "Matrox acceleration" |
| 854 | depends on FB && PCI | 872 | depends on FB && PCI |
diff --git a/drivers/video/intelfb/Makefile b/drivers/video/intelfb/Makefile index 722d21d6e5cd..6c782d3ae1be 100644 --- a/drivers/video/intelfb/Makefile +++ b/drivers/video/intelfb/Makefile | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | obj-$(CONFIG_FB_INTEL) += intelfb.o | 1 | obj-$(CONFIG_FB_INTEL) += intelfb.o |
| 2 | 2 | ||
| 3 | intelfb-objs := intelfbdrv.o intelfbhw.o | 3 | intelfb-y := intelfbdrv.o intelfbhw.o |
| 4 | intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o | ||
| 5 | intelfb-objs := $(intelfb-y) | ||
| 4 | 6 | ||
| 5 | ifdef CONFIG_FB_INTEL_DEBUG | 7 | ifdef CONFIG_FB_INTEL_DEBUG |
| 6 | #EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP | 8 | #EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP |
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index e290d7460e1b..80b94c19a9fa 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h | |||
| @@ -6,6 +6,10 @@ | |||
| 6 | #include <linux/agp_backend.h> | 6 | #include <linux/agp_backend.h> |
| 7 | #include <linux/fb.h> | 7 | #include <linux/fb.h> |
| 8 | 8 | ||
| 9 | #ifdef CONFIG_FB_INTEL_I2C | ||
| 10 | #include <linux/i2c.h> | ||
| 11 | #include <linux/i2c-algo-bit.h> | ||
| 12 | #endif | ||
| 9 | 13 | ||
| 10 | /*** Version/name ***/ | 14 | /*** Version/name ***/ |
| 11 | #define INTELFB_VERSION "0.9.4" | 15 | #define INTELFB_VERSION "0.9.4" |
| @@ -115,6 +119,29 @@ | |||
| 115 | /* Intel agpgart driver */ | 119 | /* Intel agpgart driver */ |
| 116 | #define AGP_PHYSICAL_MEMORY 2 | 120 | #define AGP_PHYSICAL_MEMORY 2 |
| 117 | 121 | ||
| 122 | /* store information about an Ixxx DVO */ | ||
| 123 | /* The i830->i865 use multiple DVOs with multiple i2cs */ | ||
| 124 | /* the i915, i945 have a single sDVO i2c bus - which is different */ | ||
| 125 | #define MAX_OUTPUTS 6 | ||
| 126 | |||
| 127 | /* these are outputs from the chip - integrated only | ||
| 128 | external chips are via DVO or SDVO output */ | ||
| 129 | #define INTELFB_OUTPUT_UNUSED 0 | ||
| 130 | #define INTELFB_OUTPUT_ANALOG 1 | ||
| 131 | #define INTELFB_OUTPUT_DVO 2 | ||
| 132 | #define INTELFB_OUTPUT_SDVO 3 | ||
| 133 | #define INTELFB_OUTPUT_LVDS 4 | ||
| 134 | #define INTELFB_OUTPUT_TVOUT 5 | ||
| 135 | |||
| 136 | #define INTELFB_DVO_CHIP_NONE 0 | ||
| 137 | #define INTELFB_DVO_CHIP_LVDS 1 | ||
| 138 | #define INTELFB_DVO_CHIP_TMDS 2 | ||
| 139 | #define INTELFB_DVO_CHIP_TVOUT 4 | ||
| 140 | |||
| 141 | #define INTELFB_OUTPUT_PIPE_NC 0 | ||
| 142 | #define INTELFB_OUTPUT_PIPE_A 1 | ||
| 143 | #define INTELFB_OUTPUT_PIPE_B 2 | ||
| 144 | |||
| 118 | /*** Data Types ***/ | 145 | /*** Data Types ***/ |
| 119 | 146 | ||
| 120 | /* supported chipsets */ | 147 | /* supported chipsets */ |
| @@ -195,6 +222,10 @@ struct intelfb_hwstate { | |||
| 195 | u32 mem_mode; | 222 | u32 mem_mode; |
| 196 | u32 fw_blc_0; | 223 | u32 fw_blc_0; |
| 197 | u32 fw_blc_1; | 224 | u32 fw_blc_1; |
| 225 | u16 hwstam; | ||
| 226 | u16 ier; | ||
| 227 | u16 iir; | ||
| 228 | u16 imr; | ||
| 198 | }; | 229 | }; |
| 199 | 230 | ||
| 200 | struct intelfb_heap_data { | 231 | struct intelfb_heap_data { |
| @@ -204,6 +235,33 @@ struct intelfb_heap_data { | |||
| 204 | u32 size; // in bytes | 235 | u32 size; // in bytes |
| 205 | }; | 236 | }; |
| 206 | 237 | ||
| 238 | #ifdef CONFIG_FB_INTEL_I2C | ||
| 239 | struct intelfb_i2c_chan { | ||
| 240 | struct intelfb_info *dinfo; | ||
| 241 | u32 reg; | ||
| 242 | struct i2c_adapter adapter; | ||
| 243 | struct i2c_algo_bit_data algo; | ||
| 244 | }; | ||
| 245 | #endif | ||
| 246 | |||
| 247 | struct intelfb_output_rec { | ||
| 248 | int type; | ||
| 249 | int pipe; | ||
| 250 | int flags; | ||
| 251 | |||
| 252 | #ifdef CONFIG_FB_INTEL_I2C | ||
| 253 | struct intelfb_i2c_chan i2c_bus; | ||
| 254 | struct intelfb_i2c_chan ddc_bus; | ||
| 255 | #endif | ||
| 256 | }; | ||
| 257 | |||
| 258 | struct intelfb_vsync { | ||
| 259 | wait_queue_head_t wait; | ||
| 260 | unsigned int count; | ||
| 261 | int pan_display; | ||
| 262 | u32 pan_offset; | ||
| 263 | }; | ||
| 264 | |||
| 207 | struct intelfb_info { | 265 | struct intelfb_info { |
| 208 | struct fb_info *info; | 266 | struct fb_info *info; |
| 209 | struct fb_ops *fbops; | 267 | struct fb_ops *fbops; |
| @@ -220,7 +278,7 @@ struct intelfb_info { | |||
| 220 | u8 fbmem_gart; | 278 | u8 fbmem_gart; |
| 221 | 279 | ||
| 222 | /* mtrr support */ | 280 | /* mtrr support */ |
| 223 | u32 mtrr_reg; | 281 | int mtrr_reg; |
| 224 | u32 has_mtrr; | 282 | u32 has_mtrr; |
| 225 | 283 | ||
| 226 | /* heap data */ | 284 | /* heap data */ |
| @@ -267,6 +325,12 @@ struct intelfb_info { | |||
| 267 | int fixed_mode; | 325 | int fixed_mode; |
| 268 | int ring_active; | 326 | int ring_active; |
| 269 | int flag; | 327 | int flag; |
| 328 | unsigned long irq_flags; | ||
| 329 | int open; | ||
| 330 | |||
| 331 | /* vsync */ | ||
| 332 | struct intelfb_vsync vsync; | ||
| 333 | spinlock_t int_lock; | ||
| 270 | 334 | ||
| 271 | /* hw cursor */ | 335 | /* hw cursor */ |
| 272 | int cursor_on; | 336 | int cursor_on; |
| @@ -285,12 +349,25 @@ struct intelfb_info { | |||
| 285 | 349 | ||
| 286 | /* index into plls */ | 350 | /* index into plls */ |
| 287 | int pll_index; | 351 | int pll_index; |
| 352 | |||
| 353 | /* outputs */ | ||
| 354 | int num_outputs; | ||
| 355 | struct intelfb_output_rec output[MAX_OUTPUTS]; | ||
| 288 | }; | 356 | }; |
| 289 | 357 | ||
| 290 | #define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) | 358 | #define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) |
| 291 | 359 | ||
| 360 | #ifndef FBIO_WAITFORVSYNC | ||
| 361 | #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) | ||
| 362 | #endif | ||
| 363 | |||
| 292 | /*** function prototypes ***/ | 364 | /*** function prototypes ***/ |
| 293 | 365 | ||
| 294 | extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); | 366 | extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); |
| 295 | 367 | ||
| 368 | #ifdef CONFIG_FB_INTEL_I2C | ||
| 369 | extern void intelfb_create_i2c_busses(struct intelfb_info *dinfo); | ||
| 370 | extern void intelfb_delete_i2c_busses(struct intelfb_info *dinfo); | ||
| 371 | #endif | ||
| 372 | |||
| 296 | #endif /* _INTELFB_H */ | 373 | #endif /* _INTELFB_H */ |
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c new file mode 100644 index 000000000000..c1113d6e941d --- /dev/null +++ b/drivers/video/intelfb/intelfb_i2c.c | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | /************************************************************************** | ||
| 2 | |||
| 3 | Copyright 2006 Dave Airlie <airlied@linux.ie> | ||
| 4 | |||
| 5 | All Rights Reserved. | ||
| 6 | |||
| 7 | Permission is hereby granted, free of charge, to any person obtaining a | ||
| 8 | copy of this software and associated documentation files (the "Software"), | ||
| 9 | to deal in the Software without restriction, including without limitation | ||
| 10 | on the rights to use, copy, modify, merge, publish, distribute, sub | ||
| 11 | license, and/or sell copies of the Software, and to permit persons to whom | ||
| 12 | the Software is furnished to do so, subject to the following conditions: | ||
| 13 | |||
| 14 | The above copyright notice and this permission notice (including the next | ||
| 15 | paragraph) shall be included in all copies or substantial portions of the | ||
| 16 | Software. | ||
| 17 | |||
| 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 20 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
| 21 | THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
| 22 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| 23 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| 24 | USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 25 | |||
| 26 | **************************************************************************/ | ||
| 27 | |||
| 28 | #include <linux/config.h> | ||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/sched.h> | ||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/pci.h> | ||
| 34 | #include <linux/fb.h> | ||
| 35 | |||
| 36 | #include <linux/i2c.h> | ||
| 37 | #include <linux/i2c-id.h> | ||
| 38 | #include <linux/i2c-algo-bit.h> | ||
| 39 | |||
| 40 | #include <asm/io.h> | ||
| 41 | |||
| 42 | #include "intelfb.h" | ||
| 43 | #include "intelfbhw.h" | ||
| 44 | |||
| 45 | /* bit locations in the registers */ | ||
| 46 | #define SCL_DIR_MASK 0x0001 | ||
| 47 | #define SCL_DIR 0x0002 | ||
| 48 | #define SCL_VAL_MASK 0x0004 | ||
| 49 | #define SCL_VAL_OUT 0x0008 | ||
| 50 | #define SCL_VAL_IN 0x0010 | ||
| 51 | #define SDA_DIR_MASK 0x0100 | ||
| 52 | #define SDA_DIR 0x0200 | ||
| 53 | #define SDA_VAL_MASK 0x0400 | ||
| 54 | #define SDA_VAL_OUT 0x0800 | ||
| 55 | #define SDA_VAL_IN 0x1000 | ||
| 56 | |||
| 57 | static void intelfb_gpio_setscl(void *data, int state) | ||
| 58 | { | ||
| 59 | struct intelfb_i2c_chan *chan = data; | ||
| 60 | struct intelfb_info *dinfo = chan->dinfo; | ||
| 61 | u32 val; | ||
| 62 | |||
| 63 | OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); | ||
| 64 | val = INREG(chan->reg); | ||
| 65 | } | ||
| 66 | |||
| 67 | static void intelfb_gpio_setsda(void *data, int state) | ||
| 68 | { | ||
| 69 | struct intelfb_i2c_chan *chan = data; | ||
| 70 | struct intelfb_info *dinfo = chan->dinfo; | ||
| 71 | u32 val; | ||
| 72 | |||
| 73 | OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); | ||
| 74 | val = INREG(chan->reg); | ||
| 75 | } | ||
| 76 | |||
| 77 | static int intelfb_gpio_getscl(void *data) | ||
| 78 | { | ||
| 79 | struct intelfb_i2c_chan *chan = data; | ||
| 80 | struct intelfb_info *dinfo = chan->dinfo; | ||
| 81 | u32 val; | ||
| 82 | |||
| 83 | OUTREG(chan->reg, SCL_DIR_MASK); | ||
| 84 | OUTREG(chan->reg, 0); | ||
| 85 | val = INREG(chan->reg); | ||
| 86 | return ((val & SCL_VAL_IN) != 0); | ||
| 87 | } | ||
| 88 | |||
| 89 | static int intelfb_gpio_getsda(void *data) | ||
| 90 | { | ||
| 91 | struct intelfb_i2c_chan *chan = data; | ||
| 92 | struct intelfb_info *dinfo = chan->dinfo; | ||
| 93 | u32 val; | ||
| 94 | |||
| 95 | OUTREG(chan->reg, SDA_DIR_MASK); | ||
| 96 | OUTREG(chan->reg, 0); | ||
| 97 | val = INREG(chan->reg); | ||
| 98 | return ((val & SDA_VAL_IN) != 0); | ||
| 99 | } | ||
| 100 | |||
| 101 | static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, | ||
| 102 | struct intelfb_i2c_chan *chan, | ||
| 103 | const u32 reg, const char *name) | ||
| 104 | { | ||
| 105 | int rc; | ||
| 106 | |||
| 107 | chan->dinfo = dinfo; | ||
| 108 | chan->reg = reg; | ||
| 109 | snprintf(chan->adapter.name, I2C_NAME_SIZE, "intelfb %s", name); | ||
| 110 | chan->adapter.owner = THIS_MODULE; | ||
| 111 | chan->adapter.id = I2C_HW_B_INTELFB; | ||
| 112 | chan->adapter.algo_data = &chan->algo; | ||
| 113 | chan->adapter.dev.parent = &chan->dinfo->pdev->dev; | ||
| 114 | chan->algo.setsda = intelfb_gpio_setsda; | ||
| 115 | chan->algo.setscl = intelfb_gpio_setscl; | ||
| 116 | chan->algo.getsda = intelfb_gpio_getsda; | ||
| 117 | chan->algo.getscl = intelfb_gpio_getscl; | ||
| 118 | chan->algo.udelay = 40; | ||
| 119 | chan->algo.timeout = 20; | ||
| 120 | chan->algo.data = chan; | ||
| 121 | |||
| 122 | i2c_set_adapdata(&chan->adapter, chan); | ||
| 123 | |||
| 124 | /* Raise SCL and SDA */ | ||
| 125 | intelfb_gpio_setsda(chan, 1); | ||
| 126 | intelfb_gpio_setscl(chan, 1); | ||
| 127 | udelay(20); | ||
| 128 | |||
| 129 | rc = i2c_bit_add_bus(&chan->adapter); | ||
| 130 | if (rc == 0) | ||
| 131 | DBG_MSG("I2C bus %s registered.\n", name); | ||
| 132 | else | ||
| 133 | WRN_MSG("Failed to register I2C bus %s.\n", name); | ||
| 134 | return rc; | ||
| 135 | } | ||
| 136 | |||
| 137 | void intelfb_create_i2c_busses(struct intelfb_info *dinfo) | ||
| 138 | { | ||
| 139 | int i = 0; | ||
| 140 | |||
| 141 | /* everyone has at least a single analog output */ | ||
| 142 | dinfo->num_outputs = 1; | ||
| 143 | dinfo->output[i].type = INTELFB_OUTPUT_ANALOG; | ||
| 144 | |||
| 145 | /* setup the DDC bus for analog output */ | ||
| 146 | intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, "CRTDDC_A"); | ||
| 147 | i++; | ||
| 148 | |||
| 149 | /* need to add the output busses for each device | ||
| 150 | - this function is very incomplete | ||
| 151 | - i915GM has LVDS and TVOUT for example | ||
| 152 | */ | ||
| 153 | switch(dinfo->chipset) { | ||
| 154 | case INTEL_830M: | ||
| 155 | case INTEL_845G: | ||
| 156 | case INTEL_855GM: | ||
| 157 | case INTEL_865G: | ||
| 158 | dinfo->output[i].type = INTELFB_OUTPUT_DVO; | ||
| 159 | intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOD, "DVODDC_D"); | ||
| 160 | intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "DVOI2C_E"); | ||
| 161 | i++; | ||
| 162 | break; | ||
| 163 | case INTEL_915G: | ||
| 164 | case INTEL_915GM: | ||
| 165 | /* has some LVDS + tv-out */ | ||
| 166 | case INTEL_945G: | ||
| 167 | case INTEL_945GM: | ||
| 168 | /* SDVO ports have a single control bus - 2 devices */ | ||
| 169 | dinfo->output[i].type = INTELFB_OUTPUT_SDVO; | ||
| 170 | intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "SDVOCTRL_E"); | ||
| 171 | /* TODO: initialize the SDVO */ | ||
| 172 | // I830SDVOInit(pScrn, i, DVOB); | ||
| 173 | i++; | ||
| 174 | |||
| 175 | /* set up SDVOC */ | ||
| 176 | dinfo->output[i].type = INTELFB_OUTPUT_SDVO; | ||
| 177 | dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus; | ||
| 178 | /* TODO: initialize the SDVO */ | ||
| 179 | // I830SDVOInit(pScrn, i, DVOC); | ||
| 180 | i++; | ||
| 181 | break; | ||
| 182 | } | ||
| 183 | dinfo->num_outputs = i; | ||
| 184 | } | ||
| 185 | |||
| 186 | void intelfb_delete_i2c_busses(struct intelfb_info *dinfo) | ||
| 187 | { | ||
| 188 | int i; | ||
| 189 | |||
| 190 | for (i = 0; i < MAX_OUTPUTS; i++) { | ||
| 191 | if (dinfo->output[i].i2c_bus.dinfo) { | ||
| 192 | i2c_bit_del_bus(&dinfo->output[i].i2c_bus.adapter); | ||
| 193 | dinfo->output[i].i2c_bus.dinfo = NULL; | ||
| 194 | } | ||
| 195 | if (dinfo->output[i].ddc_bus.dinfo) { | ||
| 196 | i2c_bit_del_bus(&dinfo->output[i].ddc_bus.adapter); | ||
| 197 | dinfo->output[i].ddc_bus.dinfo = NULL; | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 06af89d44a0d..6f9de04193d2 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
| @@ -136,6 +136,8 @@ | |||
| 136 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); | 136 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); |
| 137 | static void update_dinfo(struct intelfb_info *dinfo, | 137 | static void update_dinfo(struct intelfb_info *dinfo, |
| 138 | struct fb_var_screeninfo *var); | 138 | struct fb_var_screeninfo *var); |
| 139 | static int intelfb_open(struct fb_info *info, int user); | ||
| 140 | static int intelfb_release(struct fb_info *info, int user); | ||
| 139 | static int intelfb_check_var(struct fb_var_screeninfo *var, | 141 | static int intelfb_check_var(struct fb_var_screeninfo *var, |
| 140 | struct fb_info *info); | 142 | struct fb_info *info); |
| 141 | static int intelfb_set_par(struct fb_info *info); | 143 | static int intelfb_set_par(struct fb_info *info); |
| @@ -194,6 +196,8 @@ static int num_registered = 0; | |||
| 194 | /* fb ops */ | 196 | /* fb ops */ |
| 195 | static struct fb_ops intel_fb_ops = { | 197 | static struct fb_ops intel_fb_ops = { |
| 196 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
| 199 | .fb_open = intelfb_open, | ||
| 200 | .fb_release = intelfb_release, | ||
| 197 | .fb_check_var = intelfb_check_var, | 201 | .fb_check_var = intelfb_check_var, |
| 198 | .fb_set_par = intelfb_set_par, | 202 | .fb_set_par = intelfb_set_par, |
| 199 | .fb_setcolreg = intelfb_setcolreg, | 203 | .fb_setcolreg = intelfb_setcolreg, |
| @@ -446,6 +450,8 @@ cleanup(struct intelfb_info *dinfo) | |||
| 446 | if (!dinfo) | 450 | if (!dinfo) |
| 447 | return; | 451 | return; |
| 448 | 452 | ||
| 453 | intelfbhw_disable_irq(dinfo); | ||
| 454 | |||
| 449 | fb_dealloc_cmap(&dinfo->info->cmap); | 455 | fb_dealloc_cmap(&dinfo->info->cmap); |
| 450 | kfree(dinfo->info->pixmap.addr); | 456 | kfree(dinfo->info->pixmap.addr); |
| 451 | 457 | ||
| @@ -467,6 +473,11 @@ cleanup(struct intelfb_info *dinfo) | |||
| 467 | agp_free_memory(dinfo->gtt_ring_mem); | 473 | agp_free_memory(dinfo->gtt_ring_mem); |
| 468 | } | 474 | } |
| 469 | 475 | ||
| 476 | #ifdef CONFIG_FB_INTEL_I2C | ||
| 477 | /* un-register I2C bus */ | ||
| 478 | intelfb_delete_i2c_busses(dinfo); | ||
| 479 | #endif | ||
| 480 | |||
| 470 | if (dinfo->mmio_base) | 481 | if (dinfo->mmio_base) |
| 471 | iounmap((void __iomem *)dinfo->mmio_base); | 482 | iounmap((void __iomem *)dinfo->mmio_base); |
| 472 | if (dinfo->aperture.virtual) | 483 | if (dinfo->aperture.virtual) |
| @@ -844,6 +855,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 844 | if (bailearly == 5) | 855 | if (bailearly == 5) |
| 845 | bailout(dinfo); | 856 | bailout(dinfo); |
| 846 | 857 | ||
| 858 | #ifdef CONFIG_FB_INTEL_I2C | ||
| 859 | /* register I2C bus */ | ||
| 860 | intelfb_create_i2c_busses(dinfo); | ||
| 861 | #endif | ||
| 862 | |||
| 847 | if (bailearly == 6) | 863 | if (bailearly == 6) |
| 848 | bailout(dinfo); | 864 | bailout(dinfo); |
| 849 | 865 | ||
| @@ -888,6 +904,13 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 888 | } | 904 | } |
| 889 | 905 | ||
| 890 | dinfo->registered = 1; | 906 | dinfo->registered = 1; |
| 907 | dinfo->open = 0; | ||
| 908 | |||
| 909 | init_waitqueue_head(&dinfo->vsync.wait); | ||
| 910 | spin_lock_init(&dinfo->int_lock); | ||
| 911 | dinfo->irq_flags = 0; | ||
| 912 | dinfo->vsync.pan_display = 0; | ||
| 913 | dinfo->vsync.pan_offset = 0; | ||
| 891 | 914 | ||
| 892 | return 0; | 915 | return 0; |
| 893 | 916 | ||
| @@ -1188,6 +1211,34 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) | |||
| 1188 | ***************************************************************/ | 1211 | ***************************************************************/ |
| 1189 | 1212 | ||
| 1190 | static int | 1213 | static int |
| 1214 | intelfb_open(struct fb_info *info, int user) | ||
| 1215 | { | ||
| 1216 | struct intelfb_info *dinfo = GET_DINFO(info); | ||
| 1217 | |||
| 1218 | if (user) { | ||
| 1219 | dinfo->open++; | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | return 0; | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | static int | ||
| 1226 | intelfb_release(struct fb_info *info, int user) | ||
| 1227 | { | ||
| 1228 | struct intelfb_info *dinfo = GET_DINFO(info); | ||
| 1229 | |||
| 1230 | if (user) { | ||
| 1231 | dinfo->open--; | ||
| 1232 | msleep(1); | ||
| 1233 | if (!dinfo->open) { | ||
| 1234 | intelfbhw_disable_irq(dinfo); | ||
| 1235 | } | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | return 0; | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | static int | ||
| 1191 | intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 1242 | intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
| 1192 | { | 1243 | { |
| 1193 | int change_var = 0; | 1244 | int change_var = 0; |
| @@ -1433,6 +1484,19 @@ static int | |||
| 1433 | intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) | 1484 | intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) |
| 1434 | { | 1485 | { |
| 1435 | int retval = 0; | 1486 | int retval = 0; |
| 1487 | struct intelfb_info *dinfo = GET_DINFO(info); | ||
| 1488 | u32 pipe = 0; | ||
| 1489 | |||
| 1490 | switch (cmd) { | ||
| 1491 | case FBIO_WAITFORVSYNC: | ||
| 1492 | if (get_user(pipe, (__u32 __user *)arg)) | ||
| 1493 | return -EFAULT; | ||
| 1494 | |||
| 1495 | retval = intelfbhw_wait_for_vsync(dinfo, pipe); | ||
| 1496 | break; | ||
| 1497 | default: | ||
| 1498 | break; | ||
| 1499 | } | ||
| 1436 | 1500 | ||
| 1437 | return retval; | 1501 | return retval; |
| 1438 | } | 1502 | } |
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 2a9322f9cfdc..f887f1efd3fe 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
| 33 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
| 34 | #include <linux/pagemap.h> | 34 | #include <linux/pagemap.h> |
| 35 | #include <linux/interrupt.h> | ||
| 35 | 36 | ||
| 36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
| 37 | 38 | ||
| @@ -368,7 +369,13 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
| 368 | 369 | ||
| 369 | offset += dinfo->fb.offset << 12; | 370 | offset += dinfo->fb.offset << 12; |
| 370 | 371 | ||
| 371 | OUTREG(DSPABASE, offset); | 372 | dinfo->vsync.pan_offset = offset; |
| 373 | if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) { | ||
| 374 | dinfo->vsync.pan_display = 1; | ||
| 375 | } else { | ||
| 376 | dinfo->vsync.pan_display = 0; | ||
| 377 | OUTREG(DSPABASE, offset); | ||
| 378 | } | ||
| 372 | 379 | ||
| 373 | return 0; | 380 | return 0; |
| 374 | } | 381 | } |
| @@ -585,6 +592,11 @@ intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, | |||
| 585 | hw->fw_blc_0 = INREG(FW_BLC_0); | 592 | hw->fw_blc_0 = INREG(FW_BLC_0); |
| 586 | hw->fw_blc_1 = INREG(FW_BLC_1); | 593 | hw->fw_blc_1 = INREG(FW_BLC_1); |
| 587 | 594 | ||
| 595 | hw->hwstam = INREG16(HWSTAM); | ||
| 596 | hw->ier = INREG16(IER); | ||
| 597 | hw->iir = INREG16(IIR); | ||
| 598 | hw->imr = INREG16(IMR); | ||
| 599 | |||
| 588 | return 0; | 600 | return 0; |
| 589 | } | 601 | } |
| 590 | 602 | ||
| @@ -613,6 +625,7 @@ static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvd | |||
| 613 | return vco / p; | 625 | return vco / p; |
| 614 | } | 626 | } |
| 615 | 627 | ||
| 628 | #if REGDUMP | ||
| 616 | static void | 629 | static void |
| 617 | intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) | 630 | intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) |
| 618 | { | 631 | { |
| @@ -638,6 +651,7 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) | |||
| 638 | *o_p1 = p1; | 651 | *o_p1 = p1; |
| 639 | *o_p2 = p2; | 652 | *o_p2 = p2; |
| 640 | } | 653 | } |
| 654 | #endif | ||
| 641 | 655 | ||
| 642 | 656 | ||
| 643 | void | 657 | void |
| @@ -794,6 +808,10 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) | |||
| 794 | printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0); | 808 | printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0); |
| 795 | printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1); | 809 | printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1); |
| 796 | 810 | ||
| 811 | printk(" HWSTAM 0x%04x\n", hw->hwstam); | ||
| 812 | printk(" IER 0x%04x\n", hw->ier); | ||
| 813 | printk(" IIR 0x%04x\n", hw->iir); | ||
| 814 | printk(" IMR 0x%04x\n", hw->imr); | ||
| 797 | printk("hw state dump end\n"); | 815 | printk("hw state dump end\n"); |
| 798 | #endif | 816 | #endif |
| 799 | } | 817 | } |
| @@ -1932,3 +1950,119 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) { | |||
| 1932 | addr += 16; | 1950 | addr += 16; |
| 1933 | } | 1951 | } |
| 1934 | } | 1952 | } |
| 1953 | |||
| 1954 | static irqreturn_t | ||
| 1955 | intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) { | ||
| 1956 | int handled = 0; | ||
| 1957 | u16 tmp; | ||
| 1958 | struct intelfb_info *dinfo = (struct intelfb_info *)dev_id; | ||
| 1959 | |||
| 1960 | spin_lock(&dinfo->int_lock); | ||
| 1961 | |||
| 1962 | tmp = INREG16(IIR); | ||
| 1963 | tmp &= VSYNC_PIPE_A_INTERRUPT; | ||
| 1964 | |||
| 1965 | if (tmp == 0) { | ||
| 1966 | spin_unlock(&dinfo->int_lock); | ||
| 1967 | return IRQ_RETVAL(handled); | ||
| 1968 | } | ||
| 1969 | |||
| 1970 | OUTREG16(IIR, tmp); | ||
| 1971 | |||
| 1972 | if (tmp & VSYNC_PIPE_A_INTERRUPT) { | ||
| 1973 | dinfo->vsync.count++; | ||
| 1974 | if (dinfo->vsync.pan_display) { | ||
| 1975 | dinfo->vsync.pan_display = 0; | ||
| 1976 | OUTREG(DSPABASE, dinfo->vsync.pan_offset); | ||
| 1977 | } | ||
| 1978 | wake_up_interruptible(&dinfo->vsync.wait); | ||
| 1979 | handled = 1; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | spin_unlock(&dinfo->int_lock); | ||
| 1983 | |||
| 1984 | return IRQ_RETVAL(handled); | ||
| 1985 | } | ||
| 1986 | |||
| 1987 | int | ||
| 1988 | intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) { | ||
| 1989 | |||
| 1990 | if (!test_and_set_bit(0, &dinfo->irq_flags)) { | ||
| 1991 | if (request_irq(dinfo->pdev->irq, intelfbhw_irq, SA_SHIRQ, "intelfb", dinfo)) { | ||
| 1992 | clear_bit(0, &dinfo->irq_flags); | ||
| 1993 | return -EINVAL; | ||
| 1994 | } | ||
| 1995 | |||
| 1996 | spin_lock_irq(&dinfo->int_lock); | ||
| 1997 | OUTREG16(HWSTAM, 0xfffe); | ||
| 1998 | OUTREG16(IMR, 0x0); | ||
| 1999 | OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT); | ||
| 2000 | spin_unlock_irq(&dinfo->int_lock); | ||
| 2001 | } else if (reenable) { | ||
| 2002 | u16 ier; | ||
| 2003 | |||
| 2004 | spin_lock_irq(&dinfo->int_lock); | ||
| 2005 | ier = INREG16(IER); | ||
| 2006 | if ((ier & VSYNC_PIPE_A_INTERRUPT)) { | ||
| 2007 | DBG_MSG("someone disabled the IRQ [%08X]\n", ier); | ||
| 2008 | OUTREG(IER, VSYNC_PIPE_A_INTERRUPT); | ||
| 2009 | } | ||
| 2010 | spin_unlock_irq(&dinfo->int_lock); | ||
| 2011 | } | ||
| 2012 | return 0; | ||
| 2013 | } | ||
| 2014 | |||
| 2015 | void | ||
| 2016 | intelfbhw_disable_irq(struct intelfb_info *dinfo) { | ||
| 2017 | u16 tmp; | ||
| 2018 | |||
| 2019 | if (test_and_clear_bit(0, &dinfo->irq_flags)) { | ||
| 2020 | if (dinfo->vsync.pan_display) { | ||
| 2021 | dinfo->vsync.pan_display = 0; | ||
| 2022 | OUTREG(DSPABASE, dinfo->vsync.pan_offset); | ||
| 2023 | } | ||
| 2024 | spin_lock_irq(&dinfo->int_lock); | ||
| 2025 | OUTREG16(HWSTAM, 0xffff); | ||
| 2026 | OUTREG16(IMR, 0xffff); | ||
| 2027 | OUTREG16(IER, 0x0); | ||
| 2028 | |||
| 2029 | tmp = INREG16(IIR); | ||
| 2030 | OUTREG16(IIR, tmp); | ||
| 2031 | spin_unlock_irq(&dinfo->int_lock); | ||
| 2032 | |||
| 2033 | free_irq(dinfo->pdev->irq, dinfo); | ||
| 2034 | } | ||
| 2035 | } | ||
| 2036 | |||
| 2037 | int | ||
| 2038 | intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) { | ||
| 2039 | struct intelfb_vsync *vsync; | ||
| 2040 | unsigned int count; | ||
| 2041 | int ret; | ||
| 2042 | |||
| 2043 | switch (pipe) { | ||
| 2044 | case 0: | ||
| 2045 | vsync = &dinfo->vsync; | ||
| 2046 | break; | ||
| 2047 | default: | ||
| 2048 | return -ENODEV; | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | ret = intelfbhw_enable_irq(dinfo, 0); | ||
| 2052 | if (ret) { | ||
| 2053 | return ret; | ||
| 2054 | } | ||
| 2055 | |||
| 2056 | count = vsync->count; | ||
| 2057 | ret = wait_event_interruptible_timeout(vsync->wait, count != vsync->count, HZ/10); | ||
| 2058 | if (ret < 0) { | ||
| 2059 | return ret; | ||
| 2060 | } | ||
| 2061 | if (ret == 0) { | ||
| 2062 | intelfbhw_enable_irq(dinfo, 1); | ||
| 2063 | DBG_MSG("wait_for_vsync timed out!\n"); | ||
| 2064 | return -ETIMEDOUT; | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | return 0; | ||
| 2068 | } | ||
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h index 10acda098b71..8c54ba8fbdda 100644 --- a/drivers/video/intelfb/intelfbhw.h +++ b/drivers/video/intelfb/intelfbhw.h | |||
| @@ -88,6 +88,19 @@ | |||
| 88 | #define INSTDONE 0x2090 | 88 | #define INSTDONE 0x2090 |
| 89 | #define PRI_RING_EMPTY 1 | 89 | #define PRI_RING_EMPTY 1 |
| 90 | 90 | ||
| 91 | #define HWSTAM 0x2098 | ||
| 92 | #define IER 0x20A0 | ||
| 93 | #define IIR 0x20A4 | ||
| 94 | #define IMR 0x20A8 | ||
| 95 | #define VSYNC_PIPE_A_INTERRUPT (1 << 7) | ||
| 96 | #define PIPE_A_EVENT_INTERRUPT (1 << 4) | ||
| 97 | #define VSYNC_PIPE_B_INTERRUPT (1 << 5) | ||
| 98 | #define PIPE_B_EVENT_INTERRUPT (1 << 4) | ||
| 99 | #define HOST_PORT_EVENT_INTERRUPT (1 << 3) | ||
| 100 | #define CAPTURE_EVENT_INTERRUPT (1 << 2) | ||
| 101 | #define USER_DEFINED_INTERRUPT (1 << 1) | ||
| 102 | #define BREAKPOINT_INTERRUPT 1 | ||
| 103 | |||
| 91 | #define INSTPM 0x20c0 | 104 | #define INSTPM 0x20c0 |
| 92 | #define SYNC_FLUSH_ENABLE (1 << 5) | 105 | #define SYNC_FLUSH_ENABLE (1 << 5) |
| 93 | 106 | ||
| @@ -113,6 +126,12 @@ | |||
| 113 | #define FW_DISPC_BL_SHIFT 8 | 126 | #define FW_DISPC_BL_SHIFT 8 |
| 114 | #define FW_DISPC_BL_MASK 0x7 | 127 | #define FW_DISPC_BL_MASK 0x7 |
| 115 | 128 | ||
| 129 | #define GPIOA 0x5010 | ||
| 130 | #define GPIOB 0x5014 | ||
| 131 | #define GPIOC 0x5018 // this may be external DDC on i830 | ||
| 132 | #define GPIOD 0x501C // this is DVO DDC | ||
| 133 | #define GPIOE 0x5020 // this is DVO i2C | ||
| 134 | #define GPIOF 0x5024 | ||
| 116 | 135 | ||
| 117 | /* PLL registers */ | 136 | /* PLL registers */ |
| 118 | #define VGA0_DIVISOR 0x06000 | 137 | #define VGA0_DIVISOR 0x06000 |
| @@ -468,9 +487,12 @@ | |||
| 468 | 487 | ||
| 469 | /* I/O macros */ | 488 | /* I/O macros */ |
| 470 | #define INREG8(addr) readb((u8 __iomem *)(dinfo->mmio_base + (addr))) | 489 | #define INREG8(addr) readb((u8 __iomem *)(dinfo->mmio_base + (addr))) |
| 490 | #define INREG16(addr) readw((u16 __iomem *)(dinfo->mmio_base + (addr))) | ||
| 471 | #define INREG(addr) readl((u32 __iomem *)(dinfo->mmio_base + (addr))) | 491 | #define INREG(addr) readl((u32 __iomem *)(dinfo->mmio_base + (addr))) |
| 472 | #define OUTREG8(addr, val) writeb((val),(u8 __iomem *)(dinfo->mmio_base + \ | 492 | #define OUTREG8(addr, val) writeb((val),(u8 __iomem *)(dinfo->mmio_base + \ |
| 473 | (addr))) | 493 | (addr))) |
| 494 | #define OUTREG16(addr, val) writew((val),(u16 __iomem *)(dinfo->mmio_base + \ | ||
| 495 | (addr))) | ||
| 474 | #define OUTREG(addr, val) writel((val),(u32 __iomem *)(dinfo->mmio_base + \ | 496 | #define OUTREG(addr, val) writel((val),(u32 __iomem *)(dinfo->mmio_base + \ |
| 475 | (addr))) | 497 | (addr))) |
| 476 | 498 | ||
| @@ -545,5 +567,8 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, | |||
| 545 | extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, | 567 | extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, |
| 546 | int height, u8 *data); | 568 | int height, u8 *data); |
| 547 | extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo); | 569 | extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo); |
| 570 | extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable); | ||
| 571 | extern void intelfbhw_disable_irq(struct intelfb_info *dinfo); | ||
| 572 | extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe); | ||
| 548 | 573 | ||
| 549 | #endif /* _INTELFBHW_H */ | 574 | #endif /* _INTELFBHW_H */ |
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 9418519a55d1..0a8f750cbede 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h | |||
| @@ -193,6 +193,7 @@ | |||
| 193 | #define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */ | 193 | #define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */ |
| 194 | #define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */ | 194 | #define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */ |
| 195 | #define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */ | 195 | #define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */ |
| 196 | #define I2C_HW_B_INTELFB 0x010021 /* intel framebuffer driver */ | ||
| 196 | 197 | ||
| 197 | /* --- PCF 8584 based algorithms */ | 198 | /* --- PCF 8584 based algorithms */ |
| 198 | #define I2C_HW_P_LP 0x020000 /* Parallel port interface */ | 199 | #define I2C_HW_P_LP 0x020000 /* Parallel port interface */ |
