Commit 3a59026ba111d85b1a86af0f1c4e5a8ef1242d82

Authored by Scott MacKenzie
Committed by Linus Torvalds
1 parent b8c49ef6ae

[PATCH] intelfb: extend partial support of i915G to include i915GM

Add partial support for GMA900 within the i915GM chipset.

Signed-off-by: Scott MacKenzie <irrational@poboxes.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 3 changed files with 14 additions and 5 deletions Inline Diff

drivers/video/intelfb/intelfb.h
1 #ifndef _INTELFB_H 1 #ifndef _INTELFB_H
2 #define _INTELFB_H 2 #define _INTELFB_H
3 3
4 /* $DHD: intelfb/intelfb.h,v 1.40 2003/06/27 15:06:25 dawes Exp $ */ 4 /* $DHD: intelfb/intelfb.h,v 1.40 2003/06/27 15:06:25 dawes Exp $ */
5 5
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 9
10 /*** Version/name ***/ 10 /*** Version/name ***/
11 #define INTELFB_VERSION "0.9.2" 11 #define INTELFB_VERSION "0.9.2"
12 #define INTELFB_MODULE_NAME "intelfb" 12 #define INTELFB_MODULE_NAME "intelfb"
13 #define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G" 13 #define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM"
14 14
15 15
16 /*** Debug/feature defines ***/ 16 /*** Debug/feature defines ***/
17 17
18 #ifndef DEBUG 18 #ifndef DEBUG
19 #define DEBUG 0 19 #define DEBUG 0
20 #endif 20 #endif
21 21
22 #ifndef VERBOSE 22 #ifndef VERBOSE
23 #define VERBOSE 0 23 #define VERBOSE 0
24 #endif 24 #endif
25 25
26 #ifndef REGDUMP 26 #ifndef REGDUMP
27 #define REGDUMP 0 27 #define REGDUMP 0
28 #endif 28 #endif
29 29
30 #ifndef DETECT_VGA_CLASS_ONLY 30 #ifndef DETECT_VGA_CLASS_ONLY
31 #define DETECT_VGA_CLASS_ONLY 1 31 #define DETECT_VGA_CLASS_ONLY 1
32 #endif 32 #endif
33 33
34 #ifndef ALLOCATE_FOR_PANNING 34 #ifndef ALLOCATE_FOR_PANNING
35 #define ALLOCATE_FOR_PANNING 1 35 #define ALLOCATE_FOR_PANNING 1
36 #endif 36 #endif
37 37
38 #ifndef PREFERRED_MODE 38 #ifndef PREFERRED_MODE
39 #define PREFERRED_MODE "1024x768-32@70" 39 #define PREFERRED_MODE "1024x768-32@70"
40 #endif 40 #endif
41 41
42 /*** hw-related values ***/ 42 /*** hw-related values ***/
43 43
44 /* PCI ids for supported devices */ 44 /* PCI ids for supported devices */
45 #define PCI_DEVICE_ID_INTEL_830M 0x3577 45 #define PCI_DEVICE_ID_INTEL_830M 0x3577
46 #define PCI_DEVICE_ID_INTEL_845G 0x2562 46 #define PCI_DEVICE_ID_INTEL_845G 0x2562
47 #define PCI_DEVICE_ID_INTEL_85XGM 0x3582 47 #define PCI_DEVICE_ID_INTEL_85XGM 0x3582
48 #define PCI_DEVICE_ID_INTEL_865G 0x2572 48 #define PCI_DEVICE_ID_INTEL_865G 0x2572
49 #define PCI_DEVICE_ID_INTEL_915G 0x2582 49 #define PCI_DEVICE_ID_INTEL_915G 0x2582
50 #define PCI_DEVICE_ID_INTEL_915GM 0x2592
50 51
51 /* Size of MMIO region */ 52 /* Size of MMIO region */
52 #define INTEL_REG_SIZE 0x80000 53 #define INTEL_REG_SIZE 0x80000
53 54
54 #define STRIDE_ALIGNMENT 16 55 #define STRIDE_ALIGNMENT 16
55 56
56 #define PALETTE_8_ENTRIES 256 57 #define PALETTE_8_ENTRIES 256
57 58
58 59
59 /*** Macros ***/ 60 /*** Macros ***/
60 61
61 /* basic arithmetic */ 62 /* basic arithmetic */
62 #define KB(x) ((x) * 1024) 63 #define KB(x) ((x) * 1024)
63 #define MB(x) ((x) * 1024 * 1024) 64 #define MB(x) ((x) * 1024 * 1024)
64 #define BtoKB(x) ((x) / 1024) 65 #define BtoKB(x) ((x) / 1024)
65 #define BtoMB(x) ((x) / 1024 / 1024) 66 #define BtoMB(x) ((x) / 1024 / 1024)
66 67
67 #define GTT_PAGE_SIZE KB(4) 68 #define GTT_PAGE_SIZE KB(4)
68 69
69 #define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y)) 70 #define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y))
70 #define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) 71 #define ROUND_DOWN_TO(x, y) ((x) / (y) * (y))
71 #define ROUND_UP_TO_PAGE(x) ROUND_UP_TO((x), GTT_PAGE_SIZE) 72 #define ROUND_UP_TO_PAGE(x) ROUND_UP_TO((x), GTT_PAGE_SIZE)
72 #define ROUND_DOWN_TO_PAGE(x) ROUND_DOWN_TO((x), GTT_PAGE_SIZE) 73 #define ROUND_DOWN_TO_PAGE(x) ROUND_DOWN_TO((x), GTT_PAGE_SIZE)
73 74
74 /* messages */ 75 /* messages */
75 #define PFX INTELFB_MODULE_NAME ": " 76 #define PFX INTELFB_MODULE_NAME ": "
76 77
77 #define ERR_MSG(fmt, args...) printk(KERN_ERR PFX fmt, ## args) 78 #define ERR_MSG(fmt, args...) printk(KERN_ERR PFX fmt, ## args)
78 #define WRN_MSG(fmt, args...) printk(KERN_WARNING PFX fmt, ## args) 79 #define WRN_MSG(fmt, args...) printk(KERN_WARNING PFX fmt, ## args)
79 #define NOT_MSG(fmt, args...) printk(KERN_NOTICE PFX fmt, ## args) 80 #define NOT_MSG(fmt, args...) printk(KERN_NOTICE PFX fmt, ## args)
80 #define INF_MSG(fmt, args...) printk(KERN_INFO PFX fmt, ## args) 81 #define INF_MSG(fmt, args...) printk(KERN_INFO PFX fmt, ## args)
81 #if DEBUG 82 #if DEBUG
82 #define DBG_MSG(fmt, args...) printk(KERN_DEBUG PFX fmt, ## args) 83 #define DBG_MSG(fmt, args...) printk(KERN_DEBUG PFX fmt, ## args)
83 #else 84 #else
84 #define DBG_MSG(fmt, args...) while (0) printk(fmt, ## args) 85 #define DBG_MSG(fmt, args...) while (0) printk(fmt, ## args)
85 #endif 86 #endif
86 87
87 /* get commonly used pointers */ 88 /* get commonly used pointers */
88 #define GET_DINFO(info) (info)->par 89 #define GET_DINFO(info) (info)->par
89 90
90 /* misc macros */ 91 /* misc macros */
91 #define ACCEL(d, i) \ 92 #define ACCEL(d, i) \
92 ((d)->accel && !(d)->ring_lockup && \ 93 ((d)->accel && !(d)->ring_lockup && \
93 ((i)->var.accel_flags & FB_ACCELF_TEXT)) 94 ((i)->var.accel_flags & FB_ACCELF_TEXT))
94 95
95 /*#define NOACCEL_CHIPSET(d) \ 96 /*#define NOACCEL_CHIPSET(d) \
96 ((d)->chipset != INTEL_865G)*/ 97 ((d)->chipset != INTEL_865G)*/
97 #define NOACCEL_CHIPSET(d) \ 98 #define NOACCEL_CHIPSET(d) \
98 (0) 99 (0)
99 100
100 #define FIXED_MODE(d) ((d)->fixed_mode) 101 #define FIXED_MODE(d) ((d)->fixed_mode)
101 102
102 /*** Driver paramters ***/ 103 /*** Driver paramters ***/
103 104
104 #define RINGBUFFER_SIZE KB(64) 105 #define RINGBUFFER_SIZE KB(64)
105 #define HW_CURSOR_SIZE KB(4) 106 #define HW_CURSOR_SIZE KB(4)
106 107
107 /* Intel agpgart driver */ 108 /* Intel agpgart driver */
108 #define AGP_PHYSICAL_MEMORY 2 109 #define AGP_PHYSICAL_MEMORY 2
109 110
110 /*** Data Types ***/ 111 /*** Data Types ***/
111 112
112 /* supported chipsets */ 113 /* supported chipsets */
113 enum intel_chips { 114 enum intel_chips {
114 INTEL_830M, 115 INTEL_830M,
115 INTEL_845G, 116 INTEL_845G,
116 INTEL_85XGM, 117 INTEL_85XGM,
117 INTEL_852GM, 118 INTEL_852GM,
118 INTEL_852GME, 119 INTEL_852GME,
119 INTEL_855GM, 120 INTEL_855GM,
120 INTEL_855GME, 121 INTEL_855GME,
121 INTEL_865G, 122 INTEL_865G,
122 INTEL_915G 123 INTEL_915G,
124 INTEL_915GM
123 }; 125 };
124 126
125 struct intelfb_hwstate { 127 struct intelfb_hwstate {
126 u32 vga0_divisor; 128 u32 vga0_divisor;
127 u32 vga1_divisor; 129 u32 vga1_divisor;
128 u32 vga_pd; 130 u32 vga_pd;
129 u32 dpll_a; 131 u32 dpll_a;
130 u32 dpll_b; 132 u32 dpll_b;
131 u32 fpa0; 133 u32 fpa0;
132 u32 fpa1; 134 u32 fpa1;
133 u32 fpb0; 135 u32 fpb0;
134 u32 fpb1; 136 u32 fpb1;
135 u32 palette_a[PALETTE_8_ENTRIES]; 137 u32 palette_a[PALETTE_8_ENTRIES];
136 u32 palette_b[PALETTE_8_ENTRIES]; 138 u32 palette_b[PALETTE_8_ENTRIES];
137 u32 htotal_a; 139 u32 htotal_a;
138 u32 hblank_a; 140 u32 hblank_a;
139 u32 hsync_a; 141 u32 hsync_a;
140 u32 vtotal_a; 142 u32 vtotal_a;
141 u32 vblank_a; 143 u32 vblank_a;
142 u32 vsync_a; 144 u32 vsync_a;
143 u32 src_size_a; 145 u32 src_size_a;
144 u32 bclrpat_a; 146 u32 bclrpat_a;
145 u32 htotal_b; 147 u32 htotal_b;
146 u32 hblank_b; 148 u32 hblank_b;
147 u32 hsync_b; 149 u32 hsync_b;
148 u32 vtotal_b; 150 u32 vtotal_b;
149 u32 vblank_b; 151 u32 vblank_b;
150 u32 vsync_b; 152 u32 vsync_b;
151 u32 src_size_b; 153 u32 src_size_b;
152 u32 bclrpat_b; 154 u32 bclrpat_b;
153 u32 adpa; 155 u32 adpa;
154 u32 dvoa; 156 u32 dvoa;
155 u32 dvob; 157 u32 dvob;
156 u32 dvoc; 158 u32 dvoc;
157 u32 dvoa_srcdim; 159 u32 dvoa_srcdim;
158 u32 dvob_srcdim; 160 u32 dvob_srcdim;
159 u32 dvoc_srcdim; 161 u32 dvoc_srcdim;
160 u32 lvds; 162 u32 lvds;
161 u32 pipe_a_conf; 163 u32 pipe_a_conf;
162 u32 pipe_b_conf; 164 u32 pipe_b_conf;
163 u32 disp_arb; 165 u32 disp_arb;
164 u32 cursor_a_control; 166 u32 cursor_a_control;
165 u32 cursor_b_control; 167 u32 cursor_b_control;
166 u32 cursor_a_base; 168 u32 cursor_a_base;
167 u32 cursor_b_base; 169 u32 cursor_b_base;
168 u32 cursor_size; 170 u32 cursor_size;
169 u32 disp_a_ctrl; 171 u32 disp_a_ctrl;
170 u32 disp_b_ctrl; 172 u32 disp_b_ctrl;
171 u32 disp_a_base; 173 u32 disp_a_base;
172 u32 disp_b_base; 174 u32 disp_b_base;
173 u32 cursor_a_palette[4]; 175 u32 cursor_a_palette[4];
174 u32 cursor_b_palette[4]; 176 u32 cursor_b_palette[4];
175 u32 disp_a_stride; 177 u32 disp_a_stride;
176 u32 disp_b_stride; 178 u32 disp_b_stride;
177 u32 vgacntrl; 179 u32 vgacntrl;
178 u32 add_id; 180 u32 add_id;
179 u32 swf0x[7]; 181 u32 swf0x[7];
180 u32 swf1x[7]; 182 u32 swf1x[7];
181 u32 swf3x[3]; 183 u32 swf3x[3];
182 u32 fence[8]; 184 u32 fence[8];
183 u32 instpm; 185 u32 instpm;
184 u32 mem_mode; 186 u32 mem_mode;
185 u32 fw_blc_0; 187 u32 fw_blc_0;
186 u32 fw_blc_1; 188 u32 fw_blc_1;
187 }; 189 };
188 190
189 struct intelfb_heap_data { 191 struct intelfb_heap_data {
190 u32 physical; 192 u32 physical;
191 u8 __iomem *virtual; 193 u8 __iomem *virtual;
192 u32 offset; // in GATT pages 194 u32 offset; // in GATT pages
193 u32 size; // in bytes 195 u32 size; // in bytes
194 }; 196 };
195 197
196 struct intelfb_info { 198 struct intelfb_info {
197 struct fb_info *info; 199 struct fb_info *info;
198 struct fb_ops *fbops; 200 struct fb_ops *fbops;
199 struct pci_dev *pdev; 201 struct pci_dev *pdev;
200 202
201 struct intelfb_hwstate save_state; 203 struct intelfb_hwstate save_state;
202 204
203 /* agpgart structs */ 205 /* agpgart structs */
204 struct agp_memory *gtt_fb_mem; // use all stolen memory or vram 206 struct agp_memory *gtt_fb_mem; // use all stolen memory or vram
205 struct agp_memory *gtt_ring_mem; // ring buffer 207 struct agp_memory *gtt_ring_mem; // ring buffer
206 struct agp_memory *gtt_cursor_mem; // hw cursor 208 struct agp_memory *gtt_cursor_mem; // hw cursor
207 209
208 /* use a gart reserved fb mem */ 210 /* use a gart reserved fb mem */
209 u8 fbmem_gart; 211 u8 fbmem_gart;
210 212
211 /* mtrr support */ 213 /* mtrr support */
212 u32 mtrr_reg; 214 u32 mtrr_reg;
213 u32 has_mtrr; 215 u32 has_mtrr;
214 216
215 /* heap data */ 217 /* heap data */
216 struct intelfb_heap_data aperture; 218 struct intelfb_heap_data aperture;
217 struct intelfb_heap_data fb; 219 struct intelfb_heap_data fb;
218 struct intelfb_heap_data ring; 220 struct intelfb_heap_data ring;
219 struct intelfb_heap_data cursor; 221 struct intelfb_heap_data cursor;
220 222
221 /* mmio regs */ 223 /* mmio regs */
222 u32 mmio_base_phys; 224 u32 mmio_base_phys;
223 u8 __iomem *mmio_base; 225 u8 __iomem *mmio_base;
224 226
225 /* fb start offset (in bytes) */ 227 /* fb start offset (in bytes) */
226 u32 fb_start; 228 u32 fb_start;
227 229
228 /* ring buffer */ 230 /* ring buffer */
229 u8 __iomem *ring_head; 231 u8 __iomem *ring_head;
230 u32 ring_tail; 232 u32 ring_tail;
231 u32 ring_tail_mask; 233 u32 ring_tail_mask;
232 u32 ring_space; 234 u32 ring_space;
233 u32 ring_lockup; 235 u32 ring_lockup;
234 236
235 /* palette */ 237 /* palette */
236 u32 pseudo_palette[17]; 238 u32 pseudo_palette[17];
237 239
238 /* chip info */ 240 /* chip info */
239 int pci_chipset; 241 int pci_chipset;
240 int chipset; 242 int chipset;
241 const char *name; 243 const char *name;
242 int mobile; 244 int mobile;
243 245
244 /* current mode */ 246 /* current mode */
245 int bpp, depth; 247 int bpp, depth;
246 u32 visual; 248 u32 visual;
247 int xres, yres, pitch; 249 int xres, yres, pitch;
248 int pixclock; 250 int pixclock;
249 251
250 /* current pipe */ 252 /* current pipe */
251 int pipe; 253 int pipe;
252 254
253 /* some flags */ 255 /* some flags */
254 int accel; 256 int accel;
255 int hwcursor; 257 int hwcursor;
256 int fixed_mode; 258 int fixed_mode;
257 int ring_active; 259 int ring_active;
258 260
259 /* hw cursor */ 261 /* hw cursor */
260 int cursor_on; 262 int cursor_on;
261 int cursor_blanked; 263 int cursor_blanked;
262 u8 cursor_src[64]; 264 u8 cursor_src[64];
263 265
264 /* initial parameters */ 266 /* initial parameters */
265 int initial_vga; 267 int initial_vga;
266 struct fb_var_screeninfo initial_var; 268 struct fb_var_screeninfo initial_var;
267 u32 initial_fb_base; 269 u32 initial_fb_base;
268 u32 initial_video_ram; 270 u32 initial_video_ram;
269 u32 initial_pitch; 271 u32 initial_pitch;
270 272
271 /* driver registered */ 273 /* driver registered */
272 int registered; 274 int registered;
273 }; 275 };
274 276
275 /*** function prototypes ***/ 277 /*** function prototypes ***/
276 278
277 extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); 279 extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var);
278 280
279 #endif /* _INTELFB_H */ 281 #endif /* _INTELFB_H */
280 282
drivers/video/intelfb/intelfbdrv.c
1 /* 1 /*
2 * intelfb 2 * intelfb
3 * 3 *
4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G 4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM
5 * integrated graphics chips. 5 * integrated graphics chips.
6 * 6 *
7 * Copyright ยฉ 2002, 2003 David Dawes <dawes@xfree86.org> 7 * Copyright ยฉ 2002, 2003 David Dawes <dawes@xfree86.org>
8 * 2004 Sylvain Meyer 8 * 2004 Sylvain Meyer
9 * 9 *
10 * This driver consists of two parts. The first part (intelfbdrv.c) provides 10 * This driver consists of two parts. The first part (intelfbdrv.c) provides
11 * the basic fbdev interfaces, is derived in part from the radeonfb and 11 * the basic fbdev interfaces, is derived in part from the radeonfb and
12 * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c) 12 * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c)
13 * provides the code to program the hardware. Most of it is derived from 13 * provides the code to program the hardware. Most of it is derived from
14 * the i810/i830 XFree86 driver. The HW-specific code is covered here 14 * the i810/i830 XFree86 driver. The HW-specific code is covered here
15 * under a dual license (GPL and MIT/XFree86 license). 15 * under a dual license (GPL and MIT/XFree86 license).
16 * 16 *
17 * Author: David Dawes 17 * Author: David Dawes
18 * 18 *
19 */ 19 */
20 20
21 /* $DHD: intelfb/intelfbdrv.c,v 1.20 2003/06/27 15:17:40 dawes Exp $ */ 21 /* $DHD: intelfb/intelfbdrv.c,v 1.20 2003/06/27 15:17:40 dawes Exp $ */
22 22
23 /* 23 /*
24 * Changes: 24 * Changes:
25 * 01/2003 - Initial driver (0.1.0), no mode switching, no acceleration. 25 * 01/2003 - Initial driver (0.1.0), no mode switching, no acceleration.
26 * This initial version is a basic core that works a lot like 26 * This initial version is a basic core that works a lot like
27 * the vesafb driver. It must be built-in to the kernel, 27 * the vesafb driver. It must be built-in to the kernel,
28 * and the initial video mode must be set with vga=XXX at 28 * and the initial video mode must be set with vga=XXX at
29 * boot time. (David Dawes) 29 * boot time. (David Dawes)
30 * 30 *
31 * 01/2003 - Version 0.2.0: Mode switching added, colormap support 31 * 01/2003 - Version 0.2.0: Mode switching added, colormap support
32 * implemented, Y panning, and soft screen blanking implemented. 32 * implemented, Y panning, and soft screen blanking implemented.
33 * No acceleration yet. (David Dawes) 33 * No acceleration yet. (David Dawes)
34 * 34 *
35 * 01/2003 - Version 0.3.0: fbcon acceleration support added. Module 35 * 01/2003 - Version 0.3.0: fbcon acceleration support added. Module
36 * option handling added. (David Dawes) 36 * option handling added. (David Dawes)
37 * 37 *
38 * 01/2003 - Version 0.4.0: fbcon HW cursor support added. (David Dawes) 38 * 01/2003 - Version 0.4.0: fbcon HW cursor support added. (David Dawes)
39 * 39 *
40 * 01/2003 - Version 0.4.1: Add auto-generation of built-in modes. 40 * 01/2003 - Version 0.4.1: Add auto-generation of built-in modes.
41 * (David Dawes) 41 * (David Dawes)
42 * 42 *
43 * 02/2003 - Version 0.4.2: Add check for active non-CRT devices, and 43 * 02/2003 - Version 0.4.2: Add check for active non-CRT devices, and
44 * mode validation checks. (David Dawes) 44 * mode validation checks. (David Dawes)
45 * 45 *
46 * 02/2003 - Version 0.4.3: Check when the VC is in graphics mode so that 46 * 02/2003 - Version 0.4.3: Check when the VC is in graphics mode so that
47 * acceleration is disabled while an XFree86 server is running. 47 * acceleration is disabled while an XFree86 server is running.
48 * (David Dawes) 48 * (David Dawes)
49 * 49 *
50 * 02/2003 - Version 0.4.4: Monitor DPMS support. (David Dawes) 50 * 02/2003 - Version 0.4.4: Monitor DPMS support. (David Dawes)
51 * 51 *
52 * 02/2003 - Version 0.4.5: Basic XFree86 + fbdev working. (David Dawes) 52 * 02/2003 - Version 0.4.5: Basic XFree86 + fbdev working. (David Dawes)
53 * 53 *
54 * 02/2003 - Version 0.5.0: Modify to work with the 2.5.32 kernel as well 54 * 02/2003 - Version 0.5.0: Modify to work with the 2.5.32 kernel as well
55 * as 2.4.x kernels. (David Dawes) 55 * as 2.4.x kernels. (David Dawes)
56 * 56 *
57 * 02/2003 - Version 0.6.0: Split out HW-specifics into a separate file. 57 * 02/2003 - Version 0.6.0: Split out HW-specifics into a separate file.
58 * (David Dawes) 58 * (David Dawes)
59 * 59 *
60 * 02/2003 - Version 0.7.0: Test on 852GM/855GM. Acceleration and HW 60 * 02/2003 - Version 0.7.0: Test on 852GM/855GM. Acceleration and HW
61 * cursor are disabled on this platform. (David Dawes) 61 * cursor are disabled on this platform. (David Dawes)
62 * 62 *
63 * 02/2003 - Version 0.7.1: Test on 845G. Acceleration is disabled 63 * 02/2003 - Version 0.7.1: Test on 845G. Acceleration is disabled
64 * on this platform. (David Dawes) 64 * on this platform. (David Dawes)
65 * 65 *
66 * 02/2003 - Version 0.7.2: Test on 830M. Acceleration and HW 66 * 02/2003 - Version 0.7.2: Test on 830M. Acceleration and HW
67 * cursor are disabled on this platform. (David Dawes) 67 * cursor are disabled on this platform. (David Dawes)
68 * 68 *
69 * 02/2003 - Version 0.7.3: Fix 8-bit modes for mobile platforms 69 * 02/2003 - Version 0.7.3: Fix 8-bit modes for mobile platforms
70 * (David Dawes) 70 * (David Dawes)
71 * 71 *
72 * 02/2003 - Version 0.7.4: Add checks for FB and FBCON_HAS_CFB* configured 72 * 02/2003 - Version 0.7.4: Add checks for FB and FBCON_HAS_CFB* configured
73 * in the kernel, and add mode bpp verification and default 73 * in the kernel, and add mode bpp verification and default
74 * bpp selection based on which FBCON_HAS_CFB* are configured. 74 * bpp selection based on which FBCON_HAS_CFB* are configured.
75 * (David Dawes) 75 * (David Dawes)
76 * 76 *
77 * 02/2003 - Version 0.7.5: Add basic package/install scripts based on the 77 * 02/2003 - Version 0.7.5: Add basic package/install scripts based on the
78 * DRI packaging scripts. (David Dawes) 78 * DRI packaging scripts. (David Dawes)
79 * 79 *
80 * 04/2003 - Version 0.7.6: Fix typo that affects builds with SMP-enabled 80 * 04/2003 - Version 0.7.6: Fix typo that affects builds with SMP-enabled
81 * kernels. (David Dawes, reported by Anupam). 81 * kernels. (David Dawes, reported by Anupam).
82 * 82 *
83 * 06/2003 - Version 0.7.7: 83 * 06/2003 - Version 0.7.7:
84 * Fix Makefile.kernel build problem (Tsutomu Yasuda). 84 * Fix Makefile.kernel build problem (Tsutomu Yasuda).
85 * Fix mis-placed #endif (2.4.21 kernel). 85 * Fix mis-placed #endif (2.4.21 kernel).
86 * 86 *
87 * 09/2004 - Version 0.9.0 - by Sylvain Meyer 87 * 09/2004 - Version 0.9.0 - by Sylvain Meyer
88 * Port to linux 2.6 kernel fbdev 88 * Port to linux 2.6 kernel fbdev
89 * Fix HW accel and HW cursor on i845G 89 * Fix HW accel and HW cursor on i845G
90 * Use of agpgart for fb memory reservation 90 * Use of agpgart for fb memory reservation
91 * Add mtrr support 91 * Add mtrr support
92 * 92 *
93 * 10/2004 - Version 0.9.1 93 * 10/2004 - Version 0.9.1
94 * Use module_param instead of old MODULE_PARM 94 * Use module_param instead of old MODULE_PARM
95 * Some cleanup 95 * Some cleanup
96 * 96 *
97 * 11/2004 - Version 0.9.2 97 * 11/2004 - Version 0.9.2
98 * Add vram option to reserve more memory than stolen by BIOS 98 * Add vram option to reserve more memory than stolen by BIOS
99 * Fix intelfbhw_pan_display typo 99 * Fix intelfbhw_pan_display typo
100 * Add __initdata annotations 100 * Add __initdata annotations
101 * 101 *
102 * TODO: 102 * TODO:
103 * 103 *
104 * 104 *
105 * Wish List: 105 * Wish List:
106 * 106 *
107 * 107 *
108 */ 108 */
109 109
110 #include <linux/config.h> 110 #include <linux/config.h>
111 #include <linux/module.h> 111 #include <linux/module.h>
112 #include <linux/kernel.h> 112 #include <linux/kernel.h>
113 #include <linux/errno.h> 113 #include <linux/errno.h>
114 #include <linux/string.h> 114 #include <linux/string.h>
115 #include <linux/mm.h> 115 #include <linux/mm.h>
116 #include <linux/tty.h> 116 #include <linux/tty.h>
117 #include <linux/slab.h> 117 #include <linux/slab.h>
118 #include <linux/delay.h> 118 #include <linux/delay.h>
119 #include <linux/fb.h> 119 #include <linux/fb.h>
120 #include <linux/ioport.h> 120 #include <linux/ioport.h>
121 #include <linux/init.h> 121 #include <linux/init.h>
122 #include <linux/pci.h> 122 #include <linux/pci.h>
123 #include <linux/vmalloc.h> 123 #include <linux/vmalloc.h>
124 #include <linux/pagemap.h> 124 #include <linux/pagemap.h>
125 #include <linux/version.h> 125 #include <linux/version.h>
126 126
127 #include <asm/io.h> 127 #include <asm/io.h>
128 128
129 #ifdef CONFIG_MTRR 129 #ifdef CONFIG_MTRR
130 #include <asm/mtrr.h> 130 #include <asm/mtrr.h>
131 #endif 131 #endif
132 132
133 #include "intelfb.h" 133 #include "intelfb.h"
134 #include "intelfbhw.h" 134 #include "intelfbhw.h"
135 135
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_get_fix(struct fb_fix_screeninfo *fix, 139 static int intelfb_get_fix(struct fb_fix_screeninfo *fix,
140 struct fb_info *info); 140 struct fb_info *info);
141 141
142 static int intelfb_check_var(struct fb_var_screeninfo *var, 142 static int intelfb_check_var(struct fb_var_screeninfo *var,
143 struct fb_info *info); 143 struct fb_info *info);
144 static int intelfb_set_par(struct fb_info *info); 144 static int intelfb_set_par(struct fb_info *info);
145 static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 145 static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
146 unsigned blue, unsigned transp, 146 unsigned blue, unsigned transp,
147 struct fb_info *info); 147 struct fb_info *info);
148 148
149 static int intelfb_blank(int blank, struct fb_info *info); 149 static int intelfb_blank(int blank, struct fb_info *info);
150 static int intelfb_pan_display(struct fb_var_screeninfo *var, 150 static int intelfb_pan_display(struct fb_var_screeninfo *var,
151 struct fb_info *info); 151 struct fb_info *info);
152 152
153 static void intelfb_fillrect(struct fb_info *info, 153 static void intelfb_fillrect(struct fb_info *info,
154 const struct fb_fillrect *rect); 154 const struct fb_fillrect *rect);
155 static void intelfb_copyarea(struct fb_info *info, 155 static void intelfb_copyarea(struct fb_info *info,
156 const struct fb_copyarea *region); 156 const struct fb_copyarea *region);
157 static void intelfb_imageblit(struct fb_info *info, 157 static void intelfb_imageblit(struct fb_info *info,
158 const struct fb_image *image); 158 const struct fb_image *image);
159 static int intelfb_cursor(struct fb_info *info, 159 static int intelfb_cursor(struct fb_info *info,
160 struct fb_cursor *cursor); 160 struct fb_cursor *cursor);
161 161
162 static int intelfb_sync(struct fb_info *info); 162 static int intelfb_sync(struct fb_info *info);
163 163
164 static int intelfb_ioctl(struct inode *inode, struct file *file, 164 static int intelfb_ioctl(struct inode *inode, struct file *file,
165 unsigned int cmd, unsigned long arg, 165 unsigned int cmd, unsigned long arg,
166 struct fb_info *info); 166 struct fb_info *info);
167 167
168 static int __devinit intelfb_pci_register(struct pci_dev *pdev, 168 static int __devinit intelfb_pci_register(struct pci_dev *pdev,
169 const struct pci_device_id *ent); 169 const struct pci_device_id *ent);
170 static void __devexit intelfb_pci_unregister(struct pci_dev *pdev); 170 static void __devexit intelfb_pci_unregister(struct pci_dev *pdev);
171 static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo); 171 static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo);
172 172
173 /* 173 /*
174 * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the 174 * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the
175 * mobile chipsets from being registered. 175 * mobile chipsets from being registered.
176 */ 176 */
177 #if DETECT_VGA_CLASS_ONLY 177 #if DETECT_VGA_CLASS_ONLY
178 #define INTELFB_CLASS_MASK ~0 << 8 178 #define INTELFB_CLASS_MASK ~0 << 8
179 #else 179 #else
180 #define INTELFB_CLASS_MASK 0 180 #define INTELFB_CLASS_MASK 0
181 #endif 181 #endif
182 182
183 static struct pci_device_id intelfb_pci_table[] __devinitdata = { 183 static struct pci_device_id intelfb_pci_table[] __devinitdata = {
184 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830M, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_830M }, 184 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830M, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_830M },
185 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G }, 185 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G },
186 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, 186 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
187 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, 187 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
188 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, 188 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
189 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
189 { 0, } 190 { 0, }
190 }; 191 };
191 192
192 /* Global data */ 193 /* Global data */
193 static int num_registered = 0; 194 static int num_registered = 0;
194 195
195 /* fb ops */ 196 /* fb ops */
196 static struct fb_ops intel_fb_ops = { 197 static struct fb_ops intel_fb_ops = {
197 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
198 .fb_check_var = intelfb_check_var, 199 .fb_check_var = intelfb_check_var,
199 .fb_set_par = intelfb_set_par, 200 .fb_set_par = intelfb_set_par,
200 .fb_setcolreg = intelfb_setcolreg, 201 .fb_setcolreg = intelfb_setcolreg,
201 .fb_blank = intelfb_blank, 202 .fb_blank = intelfb_blank,
202 .fb_pan_display = intelfb_pan_display, 203 .fb_pan_display = intelfb_pan_display,
203 .fb_fillrect = intelfb_fillrect, 204 .fb_fillrect = intelfb_fillrect,
204 .fb_copyarea = intelfb_copyarea, 205 .fb_copyarea = intelfb_copyarea,
205 .fb_imageblit = intelfb_imageblit, 206 .fb_imageblit = intelfb_imageblit,
206 .fb_cursor = intelfb_cursor, 207 .fb_cursor = intelfb_cursor,
207 .fb_sync = intelfb_sync, 208 .fb_sync = intelfb_sync,
208 .fb_ioctl = intelfb_ioctl 209 .fb_ioctl = intelfb_ioctl
209 }; 210 };
210 211
211 /* PCI driver module table */ 212 /* PCI driver module table */
212 static struct pci_driver intelfb_driver = { 213 static struct pci_driver intelfb_driver = {
213 .name = "intelfb", 214 .name = "intelfb",
214 .id_table = intelfb_pci_table, 215 .id_table = intelfb_pci_table,
215 .probe = intelfb_pci_register, 216 .probe = intelfb_pci_register,
216 .remove = __devexit_p(intelfb_pci_unregister) 217 .remove = __devexit_p(intelfb_pci_unregister)
217 }; 218 };
218 219
219 /* Module description/parameters */ 220 /* Module description/parameters */
220 MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, " 221 MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, "
221 "Sylvain Meyer <sylvain.meyer@worldonline.fr>"); 222 "Sylvain Meyer <sylvain.meyer@worldonline.fr>");
222 MODULE_DESCRIPTION( 223 MODULE_DESCRIPTION(
223 "Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS " chipsets"); 224 "Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS " chipsets");
224 MODULE_LICENSE("Dual BSD/GPL"); 225 MODULE_LICENSE("Dual BSD/GPL");
225 MODULE_DEVICE_TABLE(pci, intelfb_pci_table); 226 MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
226 227
227 static int accel = 1; 228 static int accel = 1;
228 static int vram = 4; 229 static int vram = 4;
229 static int hwcursor = 0; 230 static int hwcursor = 0;
230 static int mtrr = 1; 231 static int mtrr = 1;
231 static int fixed = 0; 232 static int fixed = 0;
232 static int noinit = 0; 233 static int noinit = 0;
233 static int noregister = 0; 234 static int noregister = 0;
234 static int probeonly = 0; 235 static int probeonly = 0;
235 static int idonly = 0; 236 static int idonly = 0;
236 static int bailearly = 0; 237 static int bailearly = 0;
237 static int voffset = 48; 238 static int voffset = 48;
238 static char *mode = NULL; 239 static char *mode = NULL;
239 240
240 module_param(accel, bool, S_IRUGO); 241 module_param(accel, bool, S_IRUGO);
241 MODULE_PARM_DESC(accel, "Enable hardware acceleration"); 242 MODULE_PARM_DESC(accel, "Enable hardware acceleration");
242 module_param(vram, int, S_IRUGO); 243 module_param(vram, int, S_IRUGO);
243 MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB"); 244 MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB");
244 module_param(voffset, int, S_IRUGO); 245 module_param(voffset, int, S_IRUGO);
245 MODULE_PARM_DESC(voffset, "Offset of framebuffer in MiB"); 246 MODULE_PARM_DESC(voffset, "Offset of framebuffer in MiB");
246 module_param(hwcursor, bool, S_IRUGO); 247 module_param(hwcursor, bool, S_IRUGO);
247 MODULE_PARM_DESC(hwcursor, "Enable HW cursor"); 248 MODULE_PARM_DESC(hwcursor, "Enable HW cursor");
248 module_param(mtrr, bool, S_IRUGO); 249 module_param(mtrr, bool, S_IRUGO);
249 MODULE_PARM_DESC(mtrr, "Enable MTRR support"); 250 MODULE_PARM_DESC(mtrr, "Enable MTRR support");
250 module_param(fixed, bool, S_IRUGO); 251 module_param(fixed, bool, S_IRUGO);
251 MODULE_PARM_DESC(fixed, "Disable mode switching"); 252 MODULE_PARM_DESC(fixed, "Disable mode switching");
252 module_param(noinit, bool, 0); 253 module_param(noinit, bool, 0);
253 MODULE_PARM_DESC(noinit, "Don't initialise graphics mode when loading"); 254 MODULE_PARM_DESC(noinit, "Don't initialise graphics mode when loading");
254 module_param(noregister, bool, 0); 255 module_param(noregister, bool, 0);
255 MODULE_PARM_DESC(noregister, "Don't register, just probe and exit (debug)"); 256 MODULE_PARM_DESC(noregister, "Don't register, just probe and exit (debug)");
256 module_param(probeonly, bool, 0); 257 module_param(probeonly, bool, 0);
257 MODULE_PARM_DESC(probeonly, "Do a minimal probe (debug)"); 258 MODULE_PARM_DESC(probeonly, "Do a minimal probe (debug)");
258 module_param(idonly, bool, 0); 259 module_param(idonly, bool, 0);
259 MODULE_PARM_DESC(idonly, "Just identify without doing anything else (debug)"); 260 MODULE_PARM_DESC(idonly, "Just identify without doing anything else (debug)");
260 module_param(bailearly, bool, 0); 261 module_param(bailearly, bool, 0);
261 MODULE_PARM_DESC(bailearly, "Bail out early, depending on value (debug)"); 262 MODULE_PARM_DESC(bailearly, "Bail out early, depending on value (debug)");
262 module_param(mode, charp, S_IRUGO); 263 module_param(mode, charp, S_IRUGO);
263 MODULE_PARM_DESC(mode, 264 MODULE_PARM_DESC(mode,
264 "Initial video mode \"<xres>x<yres>[-<depth>][@<refresh>]\""); 265 "Initial video mode \"<xres>x<yres>[-<depth>][@<refresh>]\"");
265 266
266 #ifndef MODULE 267 #ifndef MODULE
267 #define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name))) 268 #define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name)))
268 #define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name), NULL, 0) 269 #define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name), NULL, 0)
269 #define OPT_STRVAL(opt, name) (opt + strlen(name)) 270 #define OPT_STRVAL(opt, name) (opt + strlen(name))
270 271
271 static __inline__ char * 272 static __inline__ char *
272 get_opt_string(const char *this_opt, const char *name) 273 get_opt_string(const char *this_opt, const char *name)
273 { 274 {
274 const char *p; 275 const char *p;
275 int i; 276 int i;
276 char *ret; 277 char *ret;
277 278
278 p = OPT_STRVAL(this_opt, name); 279 p = OPT_STRVAL(this_opt, name);
279 i = 0; 280 i = 0;
280 while (p[i] && p[i] != ' ' && p[i] != ',') 281 while (p[i] && p[i] != ' ' && p[i] != ',')
281 i++; 282 i++;
282 ret = kmalloc(i + 1, GFP_KERNEL); 283 ret = kmalloc(i + 1, GFP_KERNEL);
283 if (ret) { 284 if (ret) {
284 strncpy(ret, p, i); 285 strncpy(ret, p, i);
285 ret[i] = '\0'; 286 ret[i] = '\0';
286 } 287 }
287 return ret; 288 return ret;
288 } 289 }
289 290
290 static __inline__ int 291 static __inline__ int
291 get_opt_int(const char *this_opt, const char *name, int *ret) 292 get_opt_int(const char *this_opt, const char *name, int *ret)
292 { 293 {
293 if (!ret) 294 if (!ret)
294 return 0; 295 return 0;
295 296
296 if (!OPT_EQUAL(this_opt, name)) 297 if (!OPT_EQUAL(this_opt, name))
297 return 0; 298 return 0;
298 299
299 *ret = OPT_INTVAL(this_opt, name); 300 *ret = OPT_INTVAL(this_opt, name);
300 return 1; 301 return 1;
301 } 302 }
302 303
303 static __inline__ int 304 static __inline__ int
304 get_opt_bool(const char *this_opt, const char *name, int *ret) 305 get_opt_bool(const char *this_opt, const char *name, int *ret)
305 { 306 {
306 if (!ret) 307 if (!ret)
307 return 0; 308 return 0;
308 309
309 if (OPT_EQUAL(this_opt, name)) { 310 if (OPT_EQUAL(this_opt, name)) {
310 if (this_opt[strlen(name)] == '=') 311 if (this_opt[strlen(name)] == '=')
311 *ret = simple_strtoul(this_opt + strlen(name) + 1, 312 *ret = simple_strtoul(this_opt + strlen(name) + 1,
312 NULL, 0); 313 NULL, 0);
313 else 314 else
314 *ret = 1; 315 *ret = 1;
315 } else { 316 } else {
316 if (OPT_EQUAL(this_opt, "no") && OPT_EQUAL(this_opt + 2, name)) 317 if (OPT_EQUAL(this_opt, "no") && OPT_EQUAL(this_opt + 2, name))
317 *ret = 0; 318 *ret = 0;
318 else 319 else
319 return 0; 320 return 0;
320 } 321 }
321 return 1; 322 return 1;
322 } 323 }
323 324
324 static int __init 325 static int __init
325 intelfb_setup(char *options) 326 intelfb_setup(char *options)
326 { 327 {
327 char *this_opt; 328 char *this_opt;
328 329
329 DBG_MSG("intelfb_setup\n"); 330 DBG_MSG("intelfb_setup\n");
330 331
331 if (!options || !*options) { 332 if (!options || !*options) {
332 DBG_MSG("no options\n"); 333 DBG_MSG("no options\n");
333 return 0; 334 return 0;
334 } else 335 } else
335 DBG_MSG("options: %s\n", options); 336 DBG_MSG("options: %s\n", options);
336 337
337 /* 338 /*
338 * These are the built-in options analogous to the module parameters 339 * These are the built-in options analogous to the module parameters
339 * defined above. 340 * defined above.
340 * 341 *
341 * The syntax is: 342 * The syntax is:
342 * 343 *
343 * video=intelfb:[mode][,<param>=<val>] ... 344 * video=intelfb:[mode][,<param>=<val>] ...
344 * 345 *
345 * e.g., 346 * e.g.,
346 * 347 *
347 * video=intelfb:1024x768-16@75,accel=0 348 * video=intelfb:1024x768-16@75,accel=0
348 */ 349 */
349 350
350 while ((this_opt = strsep(&options, ","))) { 351 while ((this_opt = strsep(&options, ","))) {
351 if (!*this_opt) 352 if (!*this_opt)
352 continue; 353 continue;
353 if (get_opt_bool(this_opt, "accel", &accel)) 354 if (get_opt_bool(this_opt, "accel", &accel))
354 ; 355 ;
355 else if (get_opt_int(this_opt, "vram", &vram)) 356 else if (get_opt_int(this_opt, "vram", &vram))
356 ; 357 ;
357 else if (get_opt_bool(this_opt, "hwcursor", &hwcursor)) 358 else if (get_opt_bool(this_opt, "hwcursor", &hwcursor))
358 ; 359 ;
359 else if (get_opt_bool(this_opt, "mtrr", &mtrr)) 360 else if (get_opt_bool(this_opt, "mtrr", &mtrr))
360 ; 361 ;
361 else if (get_opt_bool(this_opt, "fixed", &fixed)) 362 else if (get_opt_bool(this_opt, "fixed", &fixed))
362 ; 363 ;
363 else if (get_opt_bool(this_opt, "init", &noinit)) 364 else if (get_opt_bool(this_opt, "init", &noinit))
364 noinit = !noinit; 365 noinit = !noinit;
365 else if (OPT_EQUAL(this_opt, "mode=")) 366 else if (OPT_EQUAL(this_opt, "mode="))
366 mode = get_opt_string(this_opt, "mode="); 367 mode = get_opt_string(this_opt, "mode=");
367 else 368 else
368 mode = this_opt; 369 mode = this_opt;
369 } 370 }
370 371
371 return 0; 372 return 0;
372 } 373 }
373 374
374 #endif 375 #endif
375 376
376 static int __init 377 static int __init
377 intelfb_init(void) 378 intelfb_init(void)
378 { 379 {
379 #ifndef MODULE 380 #ifndef MODULE
380 char *option = NULL; 381 char *option = NULL;
381 #endif 382 #endif
382 383
383 DBG_MSG("intelfb_init\n"); 384 DBG_MSG("intelfb_init\n");
384 385
385 INF_MSG("Framebuffer driver for " 386 INF_MSG("Framebuffer driver for "
386 "Intel(R) " SUPPORTED_CHIPSETS " chipsets\n"); 387 "Intel(R) " SUPPORTED_CHIPSETS " chipsets\n");
387 INF_MSG("Version " INTELFB_VERSION "\n"); 388 INF_MSG("Version " INTELFB_VERSION "\n");
388 389
389 if (idonly) 390 if (idonly)
390 return -ENODEV; 391 return -ENODEV;
391 392
392 #ifndef MODULE 393 #ifndef MODULE
393 if (fb_get_options("intelfb", &option)) 394 if (fb_get_options("intelfb", &option))
394 return -ENODEV; 395 return -ENODEV;
395 intelfb_setup(option); 396 intelfb_setup(option);
396 #endif 397 #endif
397 398
398 return pci_register_driver(&intelfb_driver); 399 return pci_register_driver(&intelfb_driver);
399 } 400 }
400 401
401 static void __exit 402 static void __exit
402 intelfb_exit(void) 403 intelfb_exit(void)
403 { 404 {
404 DBG_MSG("intelfb_exit\n"); 405 DBG_MSG("intelfb_exit\n");
405 pci_unregister_driver(&intelfb_driver); 406 pci_unregister_driver(&intelfb_driver);
406 } 407 }
407 408
408 module_init(intelfb_init); 409 module_init(intelfb_init);
409 module_exit(intelfb_exit); 410 module_exit(intelfb_exit);
410 411
411 /*************************************************************** 412 /***************************************************************
412 * mtrr support functions * 413 * mtrr support functions *
413 ***************************************************************/ 414 ***************************************************************/
414 415
415 #ifdef CONFIG_MTRR 416 #ifdef CONFIG_MTRR
416 static inline void __devinit set_mtrr(struct intelfb_info *dinfo) 417 static inline void __devinit set_mtrr(struct intelfb_info *dinfo)
417 { 418 {
418 dinfo->mtrr_reg = mtrr_add(dinfo->aperture.physical, 419 dinfo->mtrr_reg = mtrr_add(dinfo->aperture.physical,
419 dinfo->aperture.size, MTRR_TYPE_WRCOMB, 1); 420 dinfo->aperture.size, MTRR_TYPE_WRCOMB, 1);
420 if (dinfo->mtrr_reg < 0) { 421 if (dinfo->mtrr_reg < 0) {
421 ERR_MSG("unable to set MTRR\n"); 422 ERR_MSG("unable to set MTRR\n");
422 return; 423 return;
423 } 424 }
424 dinfo->has_mtrr = 1; 425 dinfo->has_mtrr = 1;
425 } 426 }
426 static inline void unset_mtrr(struct intelfb_info *dinfo) 427 static inline void unset_mtrr(struct intelfb_info *dinfo)
427 { 428 {
428 if (dinfo->has_mtrr) 429 if (dinfo->has_mtrr)
429 mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical, 430 mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
430 dinfo->aperture.size); 431 dinfo->aperture.size);
431 } 432 }
432 #else 433 #else
433 #define set_mtrr(x) WRN_MSG("MTRR is disabled in the kernel\n") 434 #define set_mtrr(x) WRN_MSG("MTRR is disabled in the kernel\n")
434 435
435 #define unset_mtrr(x) do { } while (0) 436 #define unset_mtrr(x) do { } while (0)
436 #endif /* CONFIG_MTRR */ 437 #endif /* CONFIG_MTRR */
437 438
438 /*************************************************************** 439 /***************************************************************
439 * driver init / cleanup * 440 * driver init / cleanup *
440 ***************************************************************/ 441 ***************************************************************/
441 442
442 static void 443 static void
443 cleanup(struct intelfb_info *dinfo) 444 cleanup(struct intelfb_info *dinfo)
444 { 445 {
445 DBG_MSG("cleanup\n"); 446 DBG_MSG("cleanup\n");
446 447
447 if (!dinfo) 448 if (!dinfo)
448 return; 449 return;
449 450
450 fb_dealloc_cmap(&dinfo->info->cmap); 451 fb_dealloc_cmap(&dinfo->info->cmap);
451 kfree(dinfo->info->pixmap.addr); 452 kfree(dinfo->info->pixmap.addr);
452 453
453 if (dinfo->registered) 454 if (dinfo->registered)
454 unregister_framebuffer(dinfo->info); 455 unregister_framebuffer(dinfo->info);
455 456
456 unset_mtrr(dinfo); 457 unset_mtrr(dinfo);
457 458
458 if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) { 459 if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) {
459 agp_unbind_memory(dinfo->gtt_fb_mem); 460 agp_unbind_memory(dinfo->gtt_fb_mem);
460 agp_free_memory(dinfo->gtt_fb_mem); 461 agp_free_memory(dinfo->gtt_fb_mem);
461 } 462 }
462 if (dinfo->gtt_cursor_mem) { 463 if (dinfo->gtt_cursor_mem) {
463 agp_unbind_memory(dinfo->gtt_cursor_mem); 464 agp_unbind_memory(dinfo->gtt_cursor_mem);
464 agp_free_memory(dinfo->gtt_cursor_mem); 465 agp_free_memory(dinfo->gtt_cursor_mem);
465 } 466 }
466 if (dinfo->gtt_ring_mem) { 467 if (dinfo->gtt_ring_mem) {
467 agp_unbind_memory(dinfo->gtt_ring_mem); 468 agp_unbind_memory(dinfo->gtt_ring_mem);
468 agp_free_memory(dinfo->gtt_ring_mem); 469 agp_free_memory(dinfo->gtt_ring_mem);
469 } 470 }
470 471
471 if (dinfo->mmio_base) 472 if (dinfo->mmio_base)
472 iounmap((void __iomem *)dinfo->mmio_base); 473 iounmap((void __iomem *)dinfo->mmio_base);
473 if (dinfo->aperture.virtual) 474 if (dinfo->aperture.virtual)
474 iounmap((void __iomem *)dinfo->aperture.virtual); 475 iounmap((void __iomem *)dinfo->aperture.virtual);
475 476
476 if (dinfo->mmio_base_phys) 477 if (dinfo->mmio_base_phys)
477 release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE); 478 release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE);
478 if (dinfo->aperture.physical) 479 if (dinfo->aperture.physical)
479 release_mem_region(dinfo->aperture.physical, 480 release_mem_region(dinfo->aperture.physical,
480 dinfo->aperture.size); 481 dinfo->aperture.size);
481 framebuffer_release(dinfo->info); 482 framebuffer_release(dinfo->info);
482 } 483 }
483 484
484 #define bailout(dinfo) do { \ 485 #define bailout(dinfo) do { \
485 DBG_MSG("bailout\n"); \ 486 DBG_MSG("bailout\n"); \
486 cleanup(dinfo); \ 487 cleanup(dinfo); \
487 INF_MSG("Not going to register framebuffer, exiting...\n"); \ 488 INF_MSG("Not going to register framebuffer, exiting...\n"); \
488 return -ENODEV; \ 489 return -ENODEV; \
489 } while (0) 490 } while (0)
490 491
491 492
492 static int __devinit 493 static int __devinit
493 intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) 494 intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
494 { 495 {
495 struct fb_info *info; 496 struct fb_info *info;
496 struct intelfb_info *dinfo; 497 struct intelfb_info *dinfo;
497 int i, err, dvo; 498 int i, err, dvo;
498 int aperture_size, stolen_size; 499 int aperture_size, stolen_size;
499 struct agp_kern_info gtt_info; 500 struct agp_kern_info gtt_info;
500 int agp_memtype; 501 int agp_memtype;
501 const char *s; 502 const char *s;
502 struct agp_bridge_data *bridge; 503 struct agp_bridge_data *bridge;
503 int aperture_bar = 0; 504 int aperture_bar = 0;
504 int mmio_bar = 1; 505 int mmio_bar = 1;
505 int offset; 506 int offset;
506 507
507 DBG_MSG("intelfb_pci_register\n"); 508 DBG_MSG("intelfb_pci_register\n");
508 509
509 num_registered++; 510 num_registered++;
510 if (num_registered != 1) { 511 if (num_registered != 1) {
511 ERR_MSG("Attempted to register %d devices " 512 ERR_MSG("Attempted to register %d devices "
512 "(should be only 1).\n", num_registered); 513 "(should be only 1).\n", num_registered);
513 return -ENODEV; 514 return -ENODEV;
514 } 515 }
515 516
516 info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev); 517 info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev);
517 if (!info) { 518 if (!info) {
518 ERR_MSG("Could not allocate memory for intelfb_info.\n"); 519 ERR_MSG("Could not allocate memory for intelfb_info.\n");
519 return -ENODEV; 520 return -ENODEV;
520 } 521 }
521 if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { 522 if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
522 ERR_MSG("Could not allocate cmap for intelfb_info.\n"); 523 ERR_MSG("Could not allocate cmap for intelfb_info.\n");
523 goto err_out_cmap; 524 goto err_out_cmap;
524 return -ENODEV; 525 return -ENODEV;
525 } 526 }
526 527
527 dinfo = info->par; 528 dinfo = info->par;
528 dinfo->info = info; 529 dinfo->info = info;
529 dinfo->fbops = &intel_fb_ops; 530 dinfo->fbops = &intel_fb_ops;
530 dinfo->pdev = pdev; 531 dinfo->pdev = pdev;
531 532
532 /* Reserve pixmap space. */ 533 /* Reserve pixmap space. */
533 info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL); 534 info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
534 if (info->pixmap.addr == NULL) { 535 if (info->pixmap.addr == NULL) {
535 ERR_MSG("Cannot reserve pixmap memory.\n"); 536 ERR_MSG("Cannot reserve pixmap memory.\n");
536 goto err_out_pixmap; 537 goto err_out_pixmap;
537 } 538 }
538 memset(info->pixmap.addr, 0, 64 * 1024); 539 memset(info->pixmap.addr, 0, 64 * 1024);
539 540
540 /* set early this option because it could be changed by tv encoder 541 /* set early this option because it could be changed by tv encoder
541 driver */ 542 driver */
542 dinfo->fixed_mode = fixed; 543 dinfo->fixed_mode = fixed;
543 544
544 /* Enable device. */ 545 /* Enable device. */
545 if ((err = pci_enable_device(pdev))) { 546 if ((err = pci_enable_device(pdev))) {
546 ERR_MSG("Cannot enable device.\n"); 547 ERR_MSG("Cannot enable device.\n");
547 cleanup(dinfo); 548 cleanup(dinfo);
548 return -ENODEV; 549 return -ENODEV;
549 } 550 }
550 551
551 /* Set base addresses. */ 552 /* Set base addresses. */
552 if (ent->device == PCI_DEVICE_ID_INTEL_915G) { 553 if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
554 (ent->device == PCI_DEVICE_ID_INTEL_915GM)) {
553 aperture_bar = 2; 555 aperture_bar = 2;
554 mmio_bar = 0; 556 mmio_bar = 0;
555 /* Disable HW cursor on 915G (not implemented yet) */ 557 /* Disable HW cursor on 915G/M (not implemented yet) */
556 hwcursor = 0; 558 hwcursor = 0;
557 } 559 }
558 dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); 560 dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
559 dinfo->aperture.size = pci_resource_len(pdev, aperture_bar); 561 dinfo->aperture.size = pci_resource_len(pdev, aperture_bar);
560 dinfo->mmio_base_phys = pci_resource_start(pdev, mmio_bar); 562 dinfo->mmio_base_phys = pci_resource_start(pdev, mmio_bar);
561 DBG_MSG("fb aperture: 0x%llx/0x%llx, MMIO region: 0x%llx/0x%llx\n", 563 DBG_MSG("fb aperture: 0x%llx/0x%llx, MMIO region: 0x%llx/0x%llx\n",
562 (unsigned long long)pci_resource_start(pdev, aperture_bar), 564 (unsigned long long)pci_resource_start(pdev, aperture_bar),
563 (unsigned long long)pci_resource_len(pdev, aperture_bar), 565 (unsigned long long)pci_resource_len(pdev, aperture_bar),
564 (unsigned long long)pci_resource_start(pdev, mmio_bar), 566 (unsigned long long)pci_resource_start(pdev, mmio_bar),
565 (unsigned long long)pci_resource_len(pdev, mmio_bar)); 567 (unsigned long long)pci_resource_len(pdev, mmio_bar));
566 568
567 /* Reserve the fb and MMIO regions */ 569 /* Reserve the fb and MMIO regions */
568 if (!request_mem_region(dinfo->aperture.physical, dinfo->aperture.size, 570 if (!request_mem_region(dinfo->aperture.physical, dinfo->aperture.size,
569 INTELFB_MODULE_NAME)) { 571 INTELFB_MODULE_NAME)) {
570 ERR_MSG("Cannot reserve FB region.\n"); 572 ERR_MSG("Cannot reserve FB region.\n");
571 cleanup(dinfo); 573 cleanup(dinfo);
572 return -ENODEV; 574 return -ENODEV;
573 } 575 }
574 if (!request_mem_region(dinfo->mmio_base_phys, 576 if (!request_mem_region(dinfo->mmio_base_phys,
575 INTEL_REG_SIZE, 577 INTEL_REG_SIZE,
576 INTELFB_MODULE_NAME)) { 578 INTELFB_MODULE_NAME)) {
577 ERR_MSG("Cannot reserve MMIO region.\n"); 579 ERR_MSG("Cannot reserve MMIO region.\n");
578 cleanup(dinfo); 580 cleanup(dinfo);
579 return -ENODEV; 581 return -ENODEV;
580 } 582 }
581 583
582 /* Get the chipset info. */ 584 /* Get the chipset info. */
583 dinfo->pci_chipset = pdev->device; 585 dinfo->pci_chipset = pdev->device;
584 586
585 if (intelfbhw_get_chipset(pdev, &dinfo->name, &dinfo->chipset, 587 if (intelfbhw_get_chipset(pdev, &dinfo->name, &dinfo->chipset,
586 &dinfo->mobile)) { 588 &dinfo->mobile)) {
587 cleanup(dinfo); 589 cleanup(dinfo);
588 return -ENODEV; 590 return -ENODEV;
589 } 591 }
590 592
591 if (intelfbhw_get_memory(pdev, &aperture_size,&stolen_size)) { 593 if (intelfbhw_get_memory(pdev, &aperture_size,&stolen_size)) {
592 cleanup(dinfo); 594 cleanup(dinfo);
593 return -ENODEV; 595 return -ENODEV;
594 } 596 }
595 597
596 INF_MSG("%02x:%02x.%d: %s, aperture size %dMB, " 598 INF_MSG("%02x:%02x.%d: %s, aperture size %dMB, "
597 "stolen memory %dkB\n", 599 "stolen memory %dkB\n",
598 pdev->bus->number, PCI_SLOT(pdev->devfn), 600 pdev->bus->number, PCI_SLOT(pdev->devfn),
599 PCI_FUNC(pdev->devfn), dinfo->name, 601 PCI_FUNC(pdev->devfn), dinfo->name,
600 BtoMB(aperture_size), BtoKB(stolen_size)); 602 BtoMB(aperture_size), BtoKB(stolen_size));
601 603
602 /* Set these from the options. */ 604 /* Set these from the options. */
603 dinfo->accel = accel; 605 dinfo->accel = accel;
604 dinfo->hwcursor = hwcursor; 606 dinfo->hwcursor = hwcursor;
605 607
606 if (NOACCEL_CHIPSET(dinfo) && dinfo->accel == 1) { 608 if (NOACCEL_CHIPSET(dinfo) && dinfo->accel == 1) {
607 INF_MSG("Acceleration is not supported for the %s chipset.\n", 609 INF_MSG("Acceleration is not supported for the %s chipset.\n",
608 dinfo->name); 610 dinfo->name);
609 dinfo->accel = 0; 611 dinfo->accel = 0;
610 } 612 }
611 613
612 /* Framebuffer parameters - Use all the stolen memory if >= vram */ 614 /* Framebuffer parameters - Use all the stolen memory if >= vram */
613 if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) { 615 if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) {
614 dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size); 616 dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size);
615 dinfo->fbmem_gart = 0; 617 dinfo->fbmem_gart = 0;
616 } else { 618 } else {
617 dinfo->fb.size = MB(vram); 619 dinfo->fb.size = MB(vram);
618 dinfo->fbmem_gart = 1; 620 dinfo->fbmem_gart = 1;
619 } 621 }
620 622
621 /* Allocate space for the ring buffer and HW cursor if enabled. */ 623 /* Allocate space for the ring buffer and HW cursor if enabled. */
622 if (dinfo->accel) { 624 if (dinfo->accel) {
623 dinfo->ring.size = RINGBUFFER_SIZE; 625 dinfo->ring.size = RINGBUFFER_SIZE;
624 dinfo->ring_tail_mask = dinfo->ring.size - 1; 626 dinfo->ring_tail_mask = dinfo->ring.size - 1;
625 } 627 }
626 if (dinfo->hwcursor) { 628 if (dinfo->hwcursor) {
627 dinfo->cursor.size = HW_CURSOR_SIZE; 629 dinfo->cursor.size = HW_CURSOR_SIZE;
628 } 630 }
629 631
630 /* Use agpgart to manage the GATT */ 632 /* Use agpgart to manage the GATT */
631 if (!(bridge = agp_backend_acquire(pdev))) { 633 if (!(bridge = agp_backend_acquire(pdev))) {
632 ERR_MSG("cannot acquire agp\n"); 634 ERR_MSG("cannot acquire agp\n");
633 cleanup(dinfo); 635 cleanup(dinfo);
634 return -ENODEV; 636 return -ENODEV;
635 } 637 }
636 638
637 /* get the current gatt info */ 639 /* get the current gatt info */
638 if (agp_copy_info(bridge, &gtt_info)) { 640 if (agp_copy_info(bridge, &gtt_info)) {
639 ERR_MSG("cannot get agp info\n"); 641 ERR_MSG("cannot get agp info\n");
640 agp_backend_release(bridge); 642 agp_backend_release(bridge);
641 cleanup(dinfo); 643 cleanup(dinfo);
642 return -ENODEV; 644 return -ENODEV;
643 } 645 }
644 646
645 if (MB(voffset) < stolen_size) 647 if (MB(voffset) < stolen_size)
646 offset = (stolen_size >> 12); 648 offset = (stolen_size >> 12);
647 else 649 else
648 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE; 650 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
649 651
650 /* set the mem offsets - set them after the already used pages */ 652 /* set the mem offsets - set them after the already used pages */
651 if (dinfo->accel) { 653 if (dinfo->accel) {
652 dinfo->ring.offset = offset + gtt_info.current_memory; 654 dinfo->ring.offset = offset + gtt_info.current_memory;
653 } 655 }
654 if (dinfo->hwcursor) { 656 if (dinfo->hwcursor) {
655 dinfo->cursor.offset = offset + 657 dinfo->cursor.offset = offset +
656 + gtt_info.current_memory + (dinfo->ring.size >> 12); 658 + gtt_info.current_memory + (dinfo->ring.size >> 12);
657 } 659 }
658 if (dinfo->fbmem_gart) { 660 if (dinfo->fbmem_gart) {
659 dinfo->fb.offset = offset + 661 dinfo->fb.offset = offset +
660 + gtt_info.current_memory + (dinfo->ring.size >> 12) 662 + gtt_info.current_memory + (dinfo->ring.size >> 12)
661 + (dinfo->cursor.size >> 12); 663 + (dinfo->cursor.size >> 12);
662 } 664 }
663 665
664 /* Allocate memories (which aren't stolen) */ 666 /* Allocate memories (which aren't stolen) */
665 /* Map the fb and MMIO regions */ 667 /* Map the fb and MMIO regions */
666 /* ioremap only up to the end of used aperture */ 668 /* ioremap only up to the end of used aperture */
667 dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache 669 dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
668 (dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12) 670 (dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12)
669 + dinfo->fb.size); 671 + dinfo->fb.size);
670 if (!dinfo->aperture.virtual) { 672 if (!dinfo->aperture.virtual) {
671 ERR_MSG("Cannot remap FB region.\n"); 673 ERR_MSG("Cannot remap FB region.\n");
672 cleanup(dinfo); 674 cleanup(dinfo);
673 return -ENODEV; 675 return -ENODEV;
674 } 676 }
675 677
676 dinfo->mmio_base = 678 dinfo->mmio_base =
677 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys, 679 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
678 INTEL_REG_SIZE); 680 INTEL_REG_SIZE);
679 if (!dinfo->mmio_base) { 681 if (!dinfo->mmio_base) {
680 ERR_MSG("Cannot remap MMIO region.\n"); 682 ERR_MSG("Cannot remap MMIO region.\n");
681 cleanup(dinfo); 683 cleanup(dinfo);
682 return -ENODEV; 684 return -ENODEV;
683 } 685 }
684 686
685 if (dinfo->accel) { 687 if (dinfo->accel) {
686 if (!(dinfo->gtt_ring_mem = 688 if (!(dinfo->gtt_ring_mem =
687 agp_allocate_memory(bridge, dinfo->ring.size >> 12, 689 agp_allocate_memory(bridge, dinfo->ring.size >> 12,
688 AGP_NORMAL_MEMORY))) { 690 AGP_NORMAL_MEMORY))) {
689 ERR_MSG("cannot allocate ring buffer memory\n"); 691 ERR_MSG("cannot allocate ring buffer memory\n");
690 agp_backend_release(bridge); 692 agp_backend_release(bridge);
691 cleanup(dinfo); 693 cleanup(dinfo);
692 return -ENOMEM; 694 return -ENOMEM;
693 } 695 }
694 if (agp_bind_memory(dinfo->gtt_ring_mem, 696 if (agp_bind_memory(dinfo->gtt_ring_mem,
695 dinfo->ring.offset)) { 697 dinfo->ring.offset)) {
696 ERR_MSG("cannot bind ring buffer memory\n"); 698 ERR_MSG("cannot bind ring buffer memory\n");
697 agp_backend_release(bridge); 699 agp_backend_release(bridge);
698 cleanup(dinfo); 700 cleanup(dinfo);
699 return -EBUSY; 701 return -EBUSY;
700 } 702 }
701 dinfo->ring.physical = dinfo->aperture.physical 703 dinfo->ring.physical = dinfo->aperture.physical
702 + (dinfo->ring.offset << 12); 704 + (dinfo->ring.offset << 12);
703 dinfo->ring.virtual = dinfo->aperture.virtual 705 dinfo->ring.virtual = dinfo->aperture.virtual
704 + (dinfo->ring.offset << 12); 706 + (dinfo->ring.offset << 12);
705 dinfo->ring_head = dinfo->ring.virtual; 707 dinfo->ring_head = dinfo->ring.virtual;
706 } 708 }
707 if (dinfo->hwcursor) { 709 if (dinfo->hwcursor) {
708 agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY 710 agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY
709 : AGP_NORMAL_MEMORY; 711 : AGP_NORMAL_MEMORY;
710 if (!(dinfo->gtt_cursor_mem = 712 if (!(dinfo->gtt_cursor_mem =
711 agp_allocate_memory(bridge, dinfo->cursor.size >> 12, 713 agp_allocate_memory(bridge, dinfo->cursor.size >> 12,
712 agp_memtype))) { 714 agp_memtype))) {
713 ERR_MSG("cannot allocate cursor memory\n"); 715 ERR_MSG("cannot allocate cursor memory\n");
714 agp_backend_release(bridge); 716 agp_backend_release(bridge);
715 cleanup(dinfo); 717 cleanup(dinfo);
716 return -ENOMEM; 718 return -ENOMEM;
717 } 719 }
718 if (agp_bind_memory(dinfo->gtt_cursor_mem, 720 if (agp_bind_memory(dinfo->gtt_cursor_mem,
719 dinfo->cursor.offset)) { 721 dinfo->cursor.offset)) {
720 ERR_MSG("cannot bind cursor memory\n"); 722 ERR_MSG("cannot bind cursor memory\n");
721 agp_backend_release(bridge); 723 agp_backend_release(bridge);
722 cleanup(dinfo); 724 cleanup(dinfo);
723 return -EBUSY; 725 return -EBUSY;
724 } 726 }
725 if (dinfo->mobile) 727 if (dinfo->mobile)
726 dinfo->cursor.physical 728 dinfo->cursor.physical
727 = dinfo->gtt_cursor_mem->physical; 729 = dinfo->gtt_cursor_mem->physical;
728 else 730 else
729 dinfo->cursor.physical = dinfo->aperture.physical 731 dinfo->cursor.physical = dinfo->aperture.physical
730 + (dinfo->cursor.offset << 12); 732 + (dinfo->cursor.offset << 12);
731 dinfo->cursor.virtual = dinfo->aperture.virtual 733 dinfo->cursor.virtual = dinfo->aperture.virtual
732 + (dinfo->cursor.offset << 12); 734 + (dinfo->cursor.offset << 12);
733 } 735 }
734 if (dinfo->fbmem_gart) { 736 if (dinfo->fbmem_gart) {
735 if (!(dinfo->gtt_fb_mem = 737 if (!(dinfo->gtt_fb_mem =
736 agp_allocate_memory(bridge, dinfo->fb.size >> 12, 738 agp_allocate_memory(bridge, dinfo->fb.size >> 12,
737 AGP_NORMAL_MEMORY))) { 739 AGP_NORMAL_MEMORY))) {
738 WRN_MSG("cannot allocate framebuffer memory - use " 740 WRN_MSG("cannot allocate framebuffer memory - use "
739 "the stolen one\n"); 741 "the stolen one\n");
740 dinfo->fbmem_gart = 0; 742 dinfo->fbmem_gart = 0;
741 } 743 }
742 if (agp_bind_memory(dinfo->gtt_fb_mem, 744 if (agp_bind_memory(dinfo->gtt_fb_mem,
743 dinfo->fb.offset)) { 745 dinfo->fb.offset)) {
744 WRN_MSG("cannot bind framebuffer memory - use " 746 WRN_MSG("cannot bind framebuffer memory - use "
745 "the stolen one\n"); 747 "the stolen one\n");
746 dinfo->fbmem_gart = 0; 748 dinfo->fbmem_gart = 0;
747 } 749 }
748 } 750 }
749 751
750 /* update framebuffer memory parameters */ 752 /* update framebuffer memory parameters */
751 if (!dinfo->fbmem_gart) 753 if (!dinfo->fbmem_gart)
752 dinfo->fb.offset = 0; /* starts at offset 0 */ 754 dinfo->fb.offset = 0; /* starts at offset 0 */
753 dinfo->fb.physical = dinfo->aperture.physical 755 dinfo->fb.physical = dinfo->aperture.physical
754 + (dinfo->fb.offset << 12); 756 + (dinfo->fb.offset << 12);
755 dinfo->fb.virtual = dinfo->aperture.virtual + (dinfo->fb.offset << 12); 757 dinfo->fb.virtual = dinfo->aperture.virtual + (dinfo->fb.offset << 12);
756 dinfo->fb_start = dinfo->fb.offset << 12; 758 dinfo->fb_start = dinfo->fb.offset << 12;
757 759
758 /* release agpgart */ 760 /* release agpgart */
759 agp_backend_release(bridge); 761 agp_backend_release(bridge);
760 762
761 if (mtrr) 763 if (mtrr)
762 set_mtrr(dinfo); 764 set_mtrr(dinfo);
763 765
764 DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%x)\n", 766 DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%x)\n",
765 dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size, 767 dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size,
766 (u32 __iomem ) dinfo->fb.virtual); 768 (u32 __iomem ) dinfo->fb.virtual);
767 DBG_MSG("MMIO: 0x%x/0x%x (0x%x)\n", 769 DBG_MSG("MMIO: 0x%x/0x%x (0x%x)\n",
768 dinfo->mmio_base_phys, INTEL_REG_SIZE, 770 dinfo->mmio_base_phys, INTEL_REG_SIZE,
769 (u32 __iomem) dinfo->mmio_base); 771 (u32 __iomem) dinfo->mmio_base);
770 DBG_MSG("ring buffer: 0x%x/0x%x (0x%x)\n", 772 DBG_MSG("ring buffer: 0x%x/0x%x (0x%x)\n",
771 dinfo->ring.physical, dinfo->ring.size, 773 dinfo->ring.physical, dinfo->ring.size,
772 (u32 __iomem ) dinfo->ring.virtual); 774 (u32 __iomem ) dinfo->ring.virtual);
773 DBG_MSG("HW cursor: 0x%x/0x%x (0x%x) (offset 0x%x) (phys 0x%x)\n", 775 DBG_MSG("HW cursor: 0x%x/0x%x (0x%x) (offset 0x%x) (phys 0x%x)\n",
774 dinfo->cursor.physical, dinfo->cursor.size, 776 dinfo->cursor.physical, dinfo->cursor.size,
775 (u32 __iomem ) dinfo->cursor.virtual, dinfo->cursor.offset, 777 (u32 __iomem ) dinfo->cursor.virtual, dinfo->cursor.offset,
776 dinfo->cursor.physical); 778 dinfo->cursor.physical);
777 779
778 DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d, " 780 DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d, "
779 "noinit = %d\n", vram, accel, hwcursor, fixed, noinit); 781 "noinit = %d\n", vram, accel, hwcursor, fixed, noinit);
780 DBG_MSG("options: mode = \"%s\"\n", mode ? mode : ""); 782 DBG_MSG("options: mode = \"%s\"\n", mode ? mode : "");
781 783
782 if (probeonly) 784 if (probeonly)
783 bailout(dinfo); 785 bailout(dinfo);
784 786
785 /* 787 /*
786 * Check if the LVDS port or any DVO ports are enabled. If so, 788 * Check if the LVDS port or any DVO ports are enabled. If so,
787 * don't allow mode switching 789 * don't allow mode switching
788 */ 790 */
789 dvo = intelfbhw_check_non_crt(dinfo); 791 dvo = intelfbhw_check_non_crt(dinfo);
790 if (dvo) { 792 if (dvo) {
791 dinfo->fixed_mode = 1; 793 dinfo->fixed_mode = 1;
792 WRN_MSG("Non-CRT device is enabled ( "); 794 WRN_MSG("Non-CRT device is enabled ( ");
793 i = 0; 795 i = 0;
794 while (dvo) { 796 while (dvo) {
795 if (dvo & 1) { 797 if (dvo & 1) {
796 s = intelfbhw_dvo_to_string(1 << i); 798 s = intelfbhw_dvo_to_string(1 << i);
797 if (s) 799 if (s)
798 printk("%s ", s); 800 printk("%s ", s);
799 } 801 }
800 dvo >>= 1; 802 dvo >>= 1;
801 ++i; 803 ++i;
802 } 804 }
803 printk("). Disabling mode switching.\n"); 805 printk("). Disabling mode switching.\n");
804 } 806 }
805 807
806 if (bailearly == 1) 808 if (bailearly == 1)
807 bailout(dinfo); 809 bailout(dinfo);
808 810
809 if (FIXED_MODE(dinfo) && ORIG_VIDEO_ISVGA != VIDEO_TYPE_VLFB) { 811 if (FIXED_MODE(dinfo) && ORIG_VIDEO_ISVGA != VIDEO_TYPE_VLFB) {
810 ERR_MSG("Video mode must be programmed at boot time.\n"); 812 ERR_MSG("Video mode must be programmed at boot time.\n");
811 cleanup(dinfo); 813 cleanup(dinfo);
812 return -ENODEV; 814 return -ENODEV;
813 } 815 }
814 816
815 if (bailearly == 2) 817 if (bailearly == 2)
816 bailout(dinfo); 818 bailout(dinfo);
817 819
818 /* Initialise dinfo and related data. */ 820 /* Initialise dinfo and related data. */
819 /* If an initial mode was programmed at boot time, get its details. */ 821 /* If an initial mode was programmed at boot time, get its details. */
820 if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) 822 if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB)
821 get_initial_mode(dinfo); 823 get_initial_mode(dinfo);
822 824
823 if (bailearly == 3) 825 if (bailearly == 3)
824 bailout(dinfo); 826 bailout(dinfo);
825 827
826 if (FIXED_MODE(dinfo)) { 828 if (FIXED_MODE(dinfo)) {
827 /* remap fb address */ 829 /* remap fb address */
828 update_dinfo(dinfo, &dinfo->initial_var); 830 update_dinfo(dinfo, &dinfo->initial_var);
829 } 831 }
830 832
831 if (bailearly == 4) 833 if (bailearly == 4)
832 bailout(dinfo); 834 bailout(dinfo);
833 835
834 836
835 if (intelfb_set_fbinfo(dinfo)) { 837 if (intelfb_set_fbinfo(dinfo)) {
836 cleanup(dinfo); 838 cleanup(dinfo);
837 return -ENODEV; 839 return -ENODEV;
838 } 840 }
839 841
840 if (bailearly == 5) 842 if (bailearly == 5)
841 bailout(dinfo); 843 bailout(dinfo);
842 844
843 if (bailearly == 6) 845 if (bailearly == 6)
844 bailout(dinfo); 846 bailout(dinfo);
845 847
846 pci_set_drvdata(pdev, dinfo); 848 pci_set_drvdata(pdev, dinfo);
847 849
848 /* Save the initial register state. */ 850 /* Save the initial register state. */
849 i = intelfbhw_read_hw_state(dinfo, &dinfo->save_state, 851 i = intelfbhw_read_hw_state(dinfo, &dinfo->save_state,
850 bailearly > 6 ? bailearly - 6 : 0); 852 bailearly > 6 ? bailearly - 6 : 0);
851 if (i != 0) { 853 if (i != 0) {
852 DBG_MSG("intelfbhw_read_hw_state returned %d\n", i); 854 DBG_MSG("intelfbhw_read_hw_state returned %d\n", i);
853 bailout(dinfo); 855 bailout(dinfo);
854 } 856 }
855 857
856 intelfbhw_print_hw_state(dinfo, &dinfo->save_state); 858 intelfbhw_print_hw_state(dinfo, &dinfo->save_state);
857 859
858 if (bailearly == 18) 860 if (bailearly == 18)
859 bailout(dinfo); 861 bailout(dinfo);
860 862
861 /* Cursor initialisation */ 863 /* Cursor initialisation */
862 if (dinfo->hwcursor) { 864 if (dinfo->hwcursor) {
863 intelfbhw_cursor_init(dinfo); 865 intelfbhw_cursor_init(dinfo);
864 intelfbhw_cursor_reset(dinfo); 866 intelfbhw_cursor_reset(dinfo);
865 } 867 }
866 868
867 if (bailearly == 19) 869 if (bailearly == 19)
868 bailout(dinfo); 870 bailout(dinfo);
869 871
870 /* 2d acceleration init */ 872 /* 2d acceleration init */
871 if (dinfo->accel) 873 if (dinfo->accel)
872 intelfbhw_2d_start(dinfo); 874 intelfbhw_2d_start(dinfo);
873 875
874 if (bailearly == 20) 876 if (bailearly == 20)
875 bailout(dinfo); 877 bailout(dinfo);
876 878
877 if (noregister) 879 if (noregister)
878 bailout(dinfo); 880 bailout(dinfo);
879 881
880 if (register_framebuffer(dinfo->info) < 0) { 882 if (register_framebuffer(dinfo->info) < 0) {
881 ERR_MSG("Cannot register framebuffer.\n"); 883 ERR_MSG("Cannot register framebuffer.\n");
882 cleanup(dinfo); 884 cleanup(dinfo);
883 return -ENODEV; 885 return -ENODEV;
884 } 886 }
885 887
886 dinfo->registered = 1; 888 dinfo->registered = 1;
887 889
888 return 0; 890 return 0;
889 891
890 err_out_pixmap: 892 err_out_pixmap:
891 fb_dealloc_cmap(&info->cmap); 893 fb_dealloc_cmap(&info->cmap);
892 err_out_cmap: 894 err_out_cmap:
893 framebuffer_release(info); 895 framebuffer_release(info);
894 return -ENODEV; 896 return -ENODEV;
895 } 897 }
896 898
897 static void __devexit 899 static void __devexit
898 intelfb_pci_unregister(struct pci_dev *pdev) 900 intelfb_pci_unregister(struct pci_dev *pdev)
899 { 901 {
900 struct intelfb_info *dinfo = pci_get_drvdata(pdev); 902 struct intelfb_info *dinfo = pci_get_drvdata(pdev);
901 903
902 DBG_MSG("intelfb_pci_unregister\n"); 904 DBG_MSG("intelfb_pci_unregister\n");
903 905
904 if (!dinfo) 906 if (!dinfo)
905 return; 907 return;
906 908
907 cleanup(dinfo); 909 cleanup(dinfo);
908 910
909 pci_set_drvdata(pdev, NULL); 911 pci_set_drvdata(pdev, NULL);
910 } 912 }
911 913
912 /*************************************************************** 914 /***************************************************************
913 * helper functions * 915 * helper functions *
914 ***************************************************************/ 916 ***************************************************************/
915 917
916 int __inline__ 918 int __inline__
917 intelfb_var_to_depth(const struct fb_var_screeninfo *var) 919 intelfb_var_to_depth(const struct fb_var_screeninfo *var)
918 { 920 {
919 DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n", 921 DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n",
920 var->bits_per_pixel, var->green.length); 922 var->bits_per_pixel, var->green.length);
921 923
922 switch (var->bits_per_pixel) { 924 switch (var->bits_per_pixel) {
923 case 16: 925 case 16:
924 return (var->green.length == 6) ? 16 : 15; 926 return (var->green.length == 6) ? 16 : 15;
925 case 32: 927 case 32:
926 return 24; 928 return 24;
927 default: 929 default:
928 return var->bits_per_pixel; 930 return var->bits_per_pixel;
929 } 931 }
930 } 932 }
931 933
932 934
933 static __inline__ int 935 static __inline__ int
934 var_to_refresh(const struct fb_var_screeninfo *var) 936 var_to_refresh(const struct fb_var_screeninfo *var)
935 { 937 {
936 int xtot = var->xres + var->left_margin + var->right_margin + 938 int xtot = var->xres + var->left_margin + var->right_margin +
937 var->hsync_len; 939 var->hsync_len;
938 int ytot = var->yres + var->upper_margin + var->lower_margin + 940 int ytot = var->yres + var->upper_margin + var->lower_margin +
939 var->vsync_len; 941 var->vsync_len;
940 942
941 return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; 943 return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot;
942 } 944 }
943 945
944 /*************************************************************** 946 /***************************************************************
945 * Various intialisation functions * 947 * Various intialisation functions *
946 ***************************************************************/ 948 ***************************************************************/
947 949
948 static void __devinit 950 static void __devinit
949 get_initial_mode(struct intelfb_info *dinfo) 951 get_initial_mode(struct intelfb_info *dinfo)
950 { 952 {
951 struct fb_var_screeninfo *var; 953 struct fb_var_screeninfo *var;
952 int xtot, ytot; 954 int xtot, ytot;
953 955
954 DBG_MSG("get_initial_mode\n"); 956 DBG_MSG("get_initial_mode\n");
955 957
956 dinfo->initial_vga = 1; 958 dinfo->initial_vga = 1;
957 dinfo->initial_fb_base = screen_info.lfb_base; 959 dinfo->initial_fb_base = screen_info.lfb_base;
958 dinfo->initial_video_ram = screen_info.lfb_size * KB(64); 960 dinfo->initial_video_ram = screen_info.lfb_size * KB(64);
959 dinfo->initial_pitch = screen_info.lfb_linelength; 961 dinfo->initial_pitch = screen_info.lfb_linelength;
960 962
961 var = &dinfo->initial_var; 963 var = &dinfo->initial_var;
962 memset(var, 0, sizeof(*var)); 964 memset(var, 0, sizeof(*var));
963 var->xres = screen_info.lfb_width; 965 var->xres = screen_info.lfb_width;
964 var->yres = screen_info.lfb_height; 966 var->yres = screen_info.lfb_height;
965 var->bits_per_pixel = screen_info.lfb_depth; 967 var->bits_per_pixel = screen_info.lfb_depth;
966 switch (screen_info.lfb_depth) { 968 switch (screen_info.lfb_depth) {
967 case 15: 969 case 15:
968 var->bits_per_pixel = 16; 970 var->bits_per_pixel = 16;
969 break; 971 break;
970 case 24: 972 case 24:
971 var->bits_per_pixel = 32; 973 var->bits_per_pixel = 32;
972 break; 974 break;
973 } 975 }
974 976
975 DBG_MSG("Initial info: FB is 0x%x/0x%x (%d kByte)\n", 977 DBG_MSG("Initial info: FB is 0x%x/0x%x (%d kByte)\n",
976 dinfo->initial_fb_base, dinfo->initial_video_ram, 978 dinfo->initial_fb_base, dinfo->initial_video_ram,
977 BtoKB(dinfo->initial_video_ram)); 979 BtoKB(dinfo->initial_video_ram));
978 980
979 DBG_MSG("Initial info: mode is %dx%d-%d (%d)\n", 981 DBG_MSG("Initial info: mode is %dx%d-%d (%d)\n",
980 var->xres, var->yres, var->bits_per_pixel, 982 var->xres, var->yres, var->bits_per_pixel,
981 dinfo->initial_pitch); 983 dinfo->initial_pitch);
982 984
983 /* Dummy timing values (assume 60Hz) */ 985 /* Dummy timing values (assume 60Hz) */
984 var->left_margin = (var->xres / 8) & 0xf8; 986 var->left_margin = (var->xres / 8) & 0xf8;
985 var->right_margin = 32; 987 var->right_margin = 32;
986 var->upper_margin = 16; 988 var->upper_margin = 16;
987 var->lower_margin = 4; 989 var->lower_margin = 4;
988 var->hsync_len = (var->xres / 8) & 0xf8; 990 var->hsync_len = (var->xres / 8) & 0xf8;
989 var->vsync_len = 4; 991 var->vsync_len = 4;
990 992
991 xtot = var->xres + var->left_margin + 993 xtot = var->xres + var->left_margin +
992 var->right_margin + var->hsync_len; 994 var->right_margin + var->hsync_len;
993 ytot = var->yres + var->upper_margin + 995 ytot = var->yres + var->upper_margin +
994 var->lower_margin + var->vsync_len; 996 var->lower_margin + var->vsync_len;
995 var->pixclock = 10000000 / xtot * 1000 / ytot * 100 / 60; 997 var->pixclock = 10000000 / xtot * 1000 / ytot * 100 / 60;
996 998
997 var->height = -1; 999 var->height = -1;
998 var->width = -1; 1000 var->width = -1;
999 1001
1000 if (var->bits_per_pixel > 8) { 1002 if (var->bits_per_pixel > 8) {
1001 var->red.offset = screen_info.red_pos; 1003 var->red.offset = screen_info.red_pos;
1002 var->red.length = screen_info.red_size; 1004 var->red.length = screen_info.red_size;
1003 var->green.offset = screen_info.green_pos; 1005 var->green.offset = screen_info.green_pos;
1004 var->green.length = screen_info.green_size; 1006 var->green.length = screen_info.green_size;
1005 var->blue.offset = screen_info.blue_pos; 1007 var->blue.offset = screen_info.blue_pos;
1006 var->blue.length = screen_info.blue_size; 1008 var->blue.length = screen_info.blue_size;
1007 var->transp.offset = screen_info.rsvd_pos; 1009 var->transp.offset = screen_info.rsvd_pos;
1008 var->transp.length = screen_info.rsvd_size; 1010 var->transp.length = screen_info.rsvd_size;
1009 } else { 1011 } else {
1010 var->red.length = 8; 1012 var->red.length = 8;
1011 var->green.length = 8; 1013 var->green.length = 8;
1012 var->blue.length = 8; 1014 var->blue.length = 8;
1013 } 1015 }
1014 } 1016 }
1015 1017
1016 static int __devinit 1018 static int __devinit
1017 intelfb_init_var(struct intelfb_info *dinfo) 1019 intelfb_init_var(struct intelfb_info *dinfo)
1018 { 1020 {
1019 struct fb_var_screeninfo *var; 1021 struct fb_var_screeninfo *var;
1020 int msrc = 0; 1022 int msrc = 0;
1021 1023
1022 DBG_MSG("intelfb_init_var\n"); 1024 DBG_MSG("intelfb_init_var\n");
1023 1025
1024 var = &dinfo->info->var; 1026 var = &dinfo->info->var;
1025 if (FIXED_MODE(dinfo)) { 1027 if (FIXED_MODE(dinfo)) {
1026 memcpy(var, &dinfo->initial_var, 1028 memcpy(var, &dinfo->initial_var,
1027 sizeof(struct fb_var_screeninfo)); 1029 sizeof(struct fb_var_screeninfo));
1028 msrc = 5; 1030 msrc = 5;
1029 } else { 1031 } else {
1030 if (mode) { 1032 if (mode) {
1031 msrc = fb_find_mode(var, dinfo->info, mode, 1033 msrc = fb_find_mode(var, dinfo->info, mode,
1032 vesa_modes, VESA_MODEDB_SIZE, 1034 vesa_modes, VESA_MODEDB_SIZE,
1033 NULL, 0); 1035 NULL, 0);
1034 if (msrc) 1036 if (msrc)
1035 msrc |= 8; 1037 msrc |= 8;
1036 } 1038 }
1037 if (!msrc) { 1039 if (!msrc) {
1038 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, 1040 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE,
1039 vesa_modes, VESA_MODEDB_SIZE, 1041 vesa_modes, VESA_MODEDB_SIZE,
1040 NULL, 0); 1042 NULL, 0);
1041 } 1043 }
1042 } 1044 }
1043 1045
1044 if (!msrc) { 1046 if (!msrc) {
1045 ERR_MSG("Cannot find a suitable video mode.\n"); 1047 ERR_MSG("Cannot find a suitable video mode.\n");
1046 return 1; 1048 return 1;
1047 } 1049 }
1048 1050
1049 INF_MSG("Initial video mode is %dx%d-%d@%d.\n", var->xres, var->yres, 1051 INF_MSG("Initial video mode is %dx%d-%d@%d.\n", var->xres, var->yres,
1050 var->bits_per_pixel, var_to_refresh(var)); 1052 var->bits_per_pixel, var_to_refresh(var));
1051 1053
1052 DBG_MSG("Initial video mode is from %d.\n", msrc); 1054 DBG_MSG("Initial video mode is from %d.\n", msrc);
1053 1055
1054 #if ALLOCATE_FOR_PANNING 1056 #if ALLOCATE_FOR_PANNING
1055 /* Allow use of half of the video ram for panning */ 1057 /* Allow use of half of the video ram for panning */
1056 var->xres_virtual = var->xres; 1058 var->xres_virtual = var->xres;
1057 var->yres_virtual = 1059 var->yres_virtual =
1058 dinfo->fb.size / 2 / (var->bits_per_pixel * var->xres); 1060 dinfo->fb.size / 2 / (var->bits_per_pixel * var->xres);
1059 if (var->yres_virtual < var->yres) 1061 if (var->yres_virtual < var->yres)
1060 var->yres_virtual = var->yres; 1062 var->yres_virtual = var->yres;
1061 #else 1063 #else
1062 var->yres_virtual = var->yres; 1064 var->yres_virtual = var->yres;
1063 #endif 1065 #endif
1064 1066
1065 if (dinfo->accel) 1067 if (dinfo->accel)
1066 var->accel_flags |= FB_ACCELF_TEXT; 1068 var->accel_flags |= FB_ACCELF_TEXT;
1067 else 1069 else
1068 var->accel_flags &= ~FB_ACCELF_TEXT; 1070 var->accel_flags &= ~FB_ACCELF_TEXT;
1069 1071
1070 return 0; 1072 return 0;
1071 } 1073 }
1072 1074
1073 static int __devinit 1075 static int __devinit
1074 intelfb_set_fbinfo(struct intelfb_info *dinfo) 1076 intelfb_set_fbinfo(struct intelfb_info *dinfo)
1075 { 1077 {
1076 struct fb_info *info = dinfo->info; 1078 struct fb_info *info = dinfo->info;
1077 1079
1078 DBG_MSG("intelfb_set_fbinfo\n"); 1080 DBG_MSG("intelfb_set_fbinfo\n");
1079 1081
1080 info->flags = FBINFO_FLAG_DEFAULT; 1082 info->flags = FBINFO_FLAG_DEFAULT;
1081 info->fbops = &intel_fb_ops; 1083 info->fbops = &intel_fb_ops;
1082 info->pseudo_palette = dinfo->pseudo_palette; 1084 info->pseudo_palette = dinfo->pseudo_palette;
1083 1085
1084 info->pixmap.size = 64*1024; 1086 info->pixmap.size = 64*1024;
1085 info->pixmap.buf_align = 8; 1087 info->pixmap.buf_align = 8;
1086 info->pixmap.access_align = 32; 1088 info->pixmap.access_align = 32;
1087 info->pixmap.flags = FB_PIXMAP_SYSTEM; 1089 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1088 1090
1089 if (intelfb_init_var(dinfo)) 1091 if (intelfb_init_var(dinfo))
1090 return 1; 1092 return 1;
1091 1093
1092 info->pixmap.scan_align = 1; 1094 info->pixmap.scan_align = 1;
1093 1095
1094 update_dinfo(dinfo, &info->var); 1096 update_dinfo(dinfo, &info->var);
1095 1097
1096 return 0; 1098 return 0;
1097 } 1099 }
1098 1100
1099 /* Update dinfo to match the active video mode. */ 1101 /* Update dinfo to match the active video mode. */
1100 static void 1102 static void
1101 update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) 1103 update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
1102 { 1104 {
1103 DBG_MSG("update_dinfo\n"); 1105 DBG_MSG("update_dinfo\n");
1104 1106
1105 dinfo->bpp = var->bits_per_pixel; 1107 dinfo->bpp = var->bits_per_pixel;
1106 dinfo->depth = intelfb_var_to_depth(var); 1108 dinfo->depth = intelfb_var_to_depth(var);
1107 dinfo->xres = var->xres; 1109 dinfo->xres = var->xres;
1108 dinfo->yres = var->xres; 1110 dinfo->yres = var->xres;
1109 dinfo->pixclock = var->pixclock; 1111 dinfo->pixclock = var->pixclock;
1110 1112
1111 intelfb_get_fix(&dinfo->info->fix, dinfo->info); 1113 intelfb_get_fix(&dinfo->info->fix, dinfo->info);
1112 1114
1113 switch (dinfo->bpp) { 1115 switch (dinfo->bpp) {
1114 case 8: 1116 case 8:
1115 dinfo->visual = FB_VISUAL_PSEUDOCOLOR; 1117 dinfo->visual = FB_VISUAL_PSEUDOCOLOR;
1116 dinfo->pitch = var->xres_virtual; 1118 dinfo->pitch = var->xres_virtual;
1117 break; 1119 break;
1118 case 16: 1120 case 16:
1119 dinfo->visual = FB_VISUAL_TRUECOLOR; 1121 dinfo->visual = FB_VISUAL_TRUECOLOR;
1120 dinfo->pitch = var->xres_virtual * 2; 1122 dinfo->pitch = var->xres_virtual * 2;
1121 break; 1123 break;
1122 case 32: 1124 case 32:
1123 dinfo->visual = FB_VISUAL_TRUECOLOR; 1125 dinfo->visual = FB_VISUAL_TRUECOLOR;
1124 dinfo->pitch = var->xres_virtual * 4; 1126 dinfo->pitch = var->xres_virtual * 4;
1125 break; 1127 break;
1126 } 1128 }
1127 1129
1128 /* Make sure the line length is a aligned correctly. */ 1130 /* Make sure the line length is a aligned correctly. */
1129 dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); 1131 dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT);
1130 1132
1131 if (FIXED_MODE(dinfo)) 1133 if (FIXED_MODE(dinfo))
1132 dinfo->pitch = dinfo->initial_pitch; 1134 dinfo->pitch = dinfo->initial_pitch;
1133 1135
1134 dinfo->info->screen_base = (char __iomem *)dinfo->fb.virtual; 1136 dinfo->info->screen_base = (char __iomem *)dinfo->fb.virtual;
1135 dinfo->info->fix.line_length = dinfo->pitch; 1137 dinfo->info->fix.line_length = dinfo->pitch;
1136 dinfo->info->fix.visual = dinfo->visual; 1138 dinfo->info->fix.visual = dinfo->visual;
1137 } 1139 }
1138 1140
1139 /* fbops functions */ 1141 /* fbops functions */
1140 1142
1141 static int 1143 static int
1142 intelfb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) 1144 intelfb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
1143 { 1145 {
1144 struct intelfb_info *dinfo = GET_DINFO(info); 1146 struct intelfb_info *dinfo = GET_DINFO(info);
1145 1147
1146 DBG_MSG("intelfb_get_fix\n"); 1148 DBG_MSG("intelfb_get_fix\n");
1147 1149
1148 memset(fix, 0, sizeof(*fix)); 1150 memset(fix, 0, sizeof(*fix));
1149 strcpy(fix->id, dinfo->name); 1151 strcpy(fix->id, dinfo->name);
1150 fix->smem_start = dinfo->fb.physical; 1152 fix->smem_start = dinfo->fb.physical;
1151 fix->smem_len = dinfo->fb.size; 1153 fix->smem_len = dinfo->fb.size;
1152 fix->type = FB_TYPE_PACKED_PIXELS; 1154 fix->type = FB_TYPE_PACKED_PIXELS;
1153 fix->type_aux = 0; 1155 fix->type_aux = 0;
1154 fix->visual = dinfo->visual; 1156 fix->visual = dinfo->visual;
1155 fix->xpanstep = 8; 1157 fix->xpanstep = 8;
1156 fix->ypanstep = 1; 1158 fix->ypanstep = 1;
1157 fix->ywrapstep = 0; 1159 fix->ywrapstep = 0;
1158 fix->line_length = dinfo->pitch; 1160 fix->line_length = dinfo->pitch;
1159 fix->mmio_start = dinfo->mmio_base_phys; 1161 fix->mmio_start = dinfo->mmio_base_phys;
1160 fix->mmio_len = INTEL_REG_SIZE; 1162 fix->mmio_len = INTEL_REG_SIZE;
1161 fix->accel = FB_ACCEL_I830; 1163 fix->accel = FB_ACCEL_I830;
1162 return 0; 1164 return 0;
1163 } 1165 }
1164 1166
1165 /*************************************************************** 1167 /***************************************************************
1166 * fbdev interface * 1168 * fbdev interface *
1167 ***************************************************************/ 1169 ***************************************************************/
1168 1170
1169 static int 1171 static int
1170 intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1172 intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1171 { 1173 {
1172 int change_var = 0; 1174 int change_var = 0;
1173 struct fb_var_screeninfo v; 1175 struct fb_var_screeninfo v;
1174 struct intelfb_info *dinfo; 1176 struct intelfb_info *dinfo;
1175 static int first = 1; 1177 static int first = 1;
1176 1178
1177 DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags); 1179 DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags);
1178 1180
1179 dinfo = GET_DINFO(info); 1181 dinfo = GET_DINFO(info);
1180 1182
1181 if (intelfbhw_validate_mode(dinfo, var) != 0) 1183 if (intelfbhw_validate_mode(dinfo, var) != 0)
1182 return -EINVAL; 1184 return -EINVAL;
1183 1185
1184 v = *var; 1186 v = *var;
1185 1187
1186 /* Check for a supported bpp. */ 1188 /* Check for a supported bpp. */
1187 if (v.bits_per_pixel <= 8) { 1189 if (v.bits_per_pixel <= 8) {
1188 v.bits_per_pixel = 8; 1190 v.bits_per_pixel = 8;
1189 } else if (v.bits_per_pixel <= 16) { 1191 } else if (v.bits_per_pixel <= 16) {
1190 if (v.bits_per_pixel == 16) 1192 if (v.bits_per_pixel == 16)
1191 v.green.length = 6; 1193 v.green.length = 6;
1192 v.bits_per_pixel = 16; 1194 v.bits_per_pixel = 16;
1193 } else if (v.bits_per_pixel <= 32) { 1195 } else if (v.bits_per_pixel <= 32) {
1194 v.bits_per_pixel = 32; 1196 v.bits_per_pixel = 32;
1195 } else 1197 } else
1196 return -EINVAL; 1198 return -EINVAL;
1197 1199
1198 change_var = ((info->var.xres != var->xres) || 1200 change_var = ((info->var.xres != var->xres) ||
1199 (info->var.yres != var->yres) || 1201 (info->var.yres != var->yres) ||
1200 (info->var.xres_virtual != var->xres_virtual) || 1202 (info->var.xres_virtual != var->xres_virtual) ||
1201 (info->var.yres_virtual != var->yres_virtual) || 1203 (info->var.yres_virtual != var->yres_virtual) ||
1202 (info->var.bits_per_pixel != var->bits_per_pixel) || 1204 (info->var.bits_per_pixel != var->bits_per_pixel) ||
1203 memcmp(&info->var.red, &var->red, sizeof(var->red)) || 1205 memcmp(&info->var.red, &var->red, sizeof(var->red)) ||
1204 memcmp(&info->var.green, &var->green, 1206 memcmp(&info->var.green, &var->green,
1205 sizeof(var->green)) || 1207 sizeof(var->green)) ||
1206 memcmp(&info->var.blue, &var->blue, sizeof(var->blue))); 1208 memcmp(&info->var.blue, &var->blue, sizeof(var->blue)));
1207 1209
1208 if (FIXED_MODE(dinfo) && 1210 if (FIXED_MODE(dinfo) &&
1209 (change_var || 1211 (change_var ||
1210 var->yres_virtual > dinfo->initial_var.yres_virtual || 1212 var->yres_virtual > dinfo->initial_var.yres_virtual ||
1211 var->yres_virtual < dinfo->initial_var.yres || 1213 var->yres_virtual < dinfo->initial_var.yres ||
1212 var->xoffset || var->nonstd)) { 1214 var->xoffset || var->nonstd)) {
1213 if (first) { 1215 if (first) {
1214 ERR_MSG("Changing the video mode is not supported.\n"); 1216 ERR_MSG("Changing the video mode is not supported.\n");
1215 first = 0; 1217 first = 0;
1216 } 1218 }
1217 return -EINVAL; 1219 return -EINVAL;
1218 } 1220 }
1219 1221
1220 switch (intelfb_var_to_depth(&v)) { 1222 switch (intelfb_var_to_depth(&v)) {
1221 case 8: 1223 case 8:
1222 v.red.offset = v.green.offset = v.blue.offset = 0; 1224 v.red.offset = v.green.offset = v.blue.offset = 0;
1223 v.red.length = v.green.length = v.blue.length = 8; 1225 v.red.length = v.green.length = v.blue.length = 8;
1224 v.transp.offset = v.transp.length = 0; 1226 v.transp.offset = v.transp.length = 0;
1225 break; 1227 break;
1226 case 15: 1228 case 15:
1227 v.red.offset = 10; 1229 v.red.offset = 10;
1228 v.green.offset = 5; 1230 v.green.offset = 5;
1229 v.blue.offset = 0; 1231 v.blue.offset = 0;
1230 v.red.length = v.green.length = v.blue.length = 5; 1232 v.red.length = v.green.length = v.blue.length = 5;
1231 v.transp.offset = v.transp.length = 0; 1233 v.transp.offset = v.transp.length = 0;
1232 break; 1234 break;
1233 case 16: 1235 case 16:
1234 v.red.offset = 11; 1236 v.red.offset = 11;
1235 v.green.offset = 5; 1237 v.green.offset = 5;
1236 v.blue.offset = 0; 1238 v.blue.offset = 0;
1237 v.red.length = 5; 1239 v.red.length = 5;
1238 v.green.length = 6; 1240 v.green.length = 6;
1239 v.blue.length = 5; 1241 v.blue.length = 5;
1240 v.transp.offset = v.transp.length = 0; 1242 v.transp.offset = v.transp.length = 0;
1241 break; 1243 break;
1242 case 24: 1244 case 24:
1243 v.red.offset = 16; 1245 v.red.offset = 16;
1244 v.green.offset = 8; 1246 v.green.offset = 8;
1245 v.blue.offset = 0; 1247 v.blue.offset = 0;
1246 v.red.length = v.green.length = v.blue.length = 8; 1248 v.red.length = v.green.length = v.blue.length = 8;
1247 v.transp.offset = v.transp.length = 0; 1249 v.transp.offset = v.transp.length = 0;
1248 break; 1250 break;
1249 case 32: 1251 case 32:
1250 v.red.offset = 16; 1252 v.red.offset = 16;
1251 v.green.offset = 8; 1253 v.green.offset = 8;
1252 v.blue.offset = 0; 1254 v.blue.offset = 0;
1253 v.red.length = v.green.length = v.blue.length = 8; 1255 v.red.length = v.green.length = v.blue.length = 8;
1254 v.transp.offset = 24; 1256 v.transp.offset = 24;
1255 v.transp.length = 8; 1257 v.transp.length = 8;
1256 break; 1258 break;
1257 } 1259 }
1258 1260
1259 if (v.xoffset < 0) 1261 if (v.xoffset < 0)
1260 v.xoffset = 0; 1262 v.xoffset = 0;
1261 if (v.yoffset < 0) 1263 if (v.yoffset < 0)
1262 v.yoffset = 0; 1264 v.yoffset = 0;
1263 1265
1264 if (v.xoffset > v.xres_virtual - v.xres) 1266 if (v.xoffset > v.xres_virtual - v.xres)
1265 v.xoffset = v.xres_virtual - v.xres; 1267 v.xoffset = v.xres_virtual - v.xres;
1266 if (v.yoffset > v.yres_virtual - v.yres) 1268 if (v.yoffset > v.yres_virtual - v.yres)
1267 v.yoffset = v.yres_virtual - v.yres; 1269 v.yoffset = v.yres_virtual - v.yres;
1268 1270
1269 v.red.msb_right = v.green.msb_right = v.blue.msb_right = 1271 v.red.msb_right = v.green.msb_right = v.blue.msb_right =
1270 v.transp.msb_right = 0; 1272 v.transp.msb_right = 0;
1271 1273
1272 *var = v; 1274 *var = v;
1273 1275
1274 return 0; 1276 return 0;
1275 } 1277 }
1276 1278
1277 static int 1279 static int
1278 intelfb_set_par(struct fb_info *info) 1280 intelfb_set_par(struct fb_info *info)
1279 { 1281 {
1280 struct intelfb_hwstate *hw; 1282 struct intelfb_hwstate *hw;
1281 struct intelfb_info *dinfo = GET_DINFO(info); 1283 struct intelfb_info *dinfo = GET_DINFO(info);
1282 1284
1283 if (FIXED_MODE(dinfo)) { 1285 if (FIXED_MODE(dinfo)) {
1284 ERR_MSG("Changing the video mode is not supported.\n"); 1286 ERR_MSG("Changing the video mode is not supported.\n");
1285 return -EINVAL; 1287 return -EINVAL;
1286 } 1288 }
1287 1289
1288 hw = kmalloc(sizeof(*hw), GFP_ATOMIC); 1290 hw = kmalloc(sizeof(*hw), GFP_ATOMIC);
1289 if (!hw) 1291 if (!hw)
1290 return -ENOMEM; 1292 return -ENOMEM;
1291 1293
1292 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, 1294 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,
1293 info->var.yres, info->var.bits_per_pixel); 1295 info->var.yres, info->var.bits_per_pixel);
1294 1296
1295 intelfb_blank(FB_BLANK_POWERDOWN, info); 1297 intelfb_blank(FB_BLANK_POWERDOWN, info);
1296 1298
1297 if (ACCEL(dinfo, info)) 1299 if (ACCEL(dinfo, info))
1298 intelfbhw_2d_stop(dinfo); 1300 intelfbhw_2d_stop(dinfo);
1299 1301
1300 memcpy(hw, &dinfo->save_state, sizeof(*hw)); 1302 memcpy(hw, &dinfo->save_state, sizeof(*hw));
1301 if (intelfbhw_mode_to_hw(dinfo, hw, &info->var)) 1303 if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))
1302 goto invalid_mode; 1304 goto invalid_mode;
1303 if (intelfbhw_program_mode(dinfo, hw, 0)) 1305 if (intelfbhw_program_mode(dinfo, hw, 0))
1304 goto invalid_mode; 1306 goto invalid_mode;
1305 1307
1306 #if REGDUMP > 0 1308 #if REGDUMP > 0
1307 intelfbhw_read_hw_state(dinfo, hw, 0); 1309 intelfbhw_read_hw_state(dinfo, hw, 0);
1308 intelfbhw_print_hw_state(dinfo, hw); 1310 intelfbhw_print_hw_state(dinfo, hw);
1309 #endif 1311 #endif
1310 1312
1311 update_dinfo(dinfo, &info->var); 1313 update_dinfo(dinfo, &info->var);
1312 1314
1313 if (ACCEL(dinfo, info)) 1315 if (ACCEL(dinfo, info))
1314 intelfbhw_2d_start(dinfo); 1316 intelfbhw_2d_start(dinfo);
1315 1317
1316 intelfb_pan_display(&info->var, info); 1318 intelfb_pan_display(&info->var, info);
1317 1319
1318 intelfb_blank(FB_BLANK_UNBLANK, info); 1320 intelfb_blank(FB_BLANK_UNBLANK, info);
1319 1321
1320 if (ACCEL(dinfo, info)) { 1322 if (ACCEL(dinfo, info)) {
1321 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | 1323 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
1322 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1324 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1323 FBINFO_HWACCEL_IMAGEBLIT; 1325 FBINFO_HWACCEL_IMAGEBLIT;
1324 } else { 1326 } else {
1325 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1327 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1326 } 1328 }
1327 kfree(hw); 1329 kfree(hw);
1328 return 0; 1330 return 0;
1329 invalid_mode: 1331 invalid_mode:
1330 kfree(hw); 1332 kfree(hw);
1331 return -EINVAL; 1333 return -EINVAL;
1332 } 1334 }
1333 1335
1334 static int 1336 static int
1335 intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1337 intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1336 unsigned blue, unsigned transp, struct fb_info *info) 1338 unsigned blue, unsigned transp, struct fb_info *info)
1337 { 1339 {
1338 struct intelfb_info *dinfo = GET_DINFO(info); 1340 struct intelfb_info *dinfo = GET_DINFO(info);
1339 1341
1340 #if VERBOSE > 0 1342 #if VERBOSE > 0
1341 DBG_MSG("intelfb_setcolreg: regno %d, depth %d\n", regno, dinfo->depth); 1343 DBG_MSG("intelfb_setcolreg: regno %d, depth %d\n", regno, dinfo->depth);
1342 #endif 1344 #endif
1343 1345
1344 if (regno > 255) 1346 if (regno > 255)
1345 return 1; 1347 return 1;
1346 1348
1347 switch (dinfo->depth) { 1349 switch (dinfo->depth) {
1348 case 8: 1350 case 8:
1349 { 1351 {
1350 red >>= 8; 1352 red >>= 8;
1351 green >>= 8; 1353 green >>= 8;
1352 blue >>= 8; 1354 blue >>= 8;
1353 1355
1354 intelfbhw_setcolreg(dinfo, regno, red, green, blue, 1356 intelfbhw_setcolreg(dinfo, regno, red, green, blue,
1355 transp); 1357 transp);
1356 } 1358 }
1357 break; 1359 break;
1358 case 15: 1360 case 15:
1359 dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) | 1361 dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
1360 ((green & 0xf800) >> 6) | 1362 ((green & 0xf800) >> 6) |
1361 ((blue & 0xf800) >> 11); 1363 ((blue & 0xf800) >> 11);
1362 break; 1364 break;
1363 case 16: 1365 case 16:
1364 dinfo->pseudo_palette[regno] = (red & 0xf800) | 1366 dinfo->pseudo_palette[regno] = (red & 0xf800) |
1365 ((green & 0xfc00) >> 5) | 1367 ((green & 0xfc00) >> 5) |
1366 ((blue & 0xf800) >> 11); 1368 ((blue & 0xf800) >> 11);
1367 break; 1369 break;
1368 case 24: 1370 case 24:
1369 dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) | 1371 dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) |
1370 (green & 0xff00) | 1372 (green & 0xff00) |
1371 ((blue & 0xff00) >> 8); 1373 ((blue & 0xff00) >> 8);
1372 break; 1374 break;
1373 } 1375 }
1374 return 0; 1376 return 0;
1375 } 1377 }
1376 1378
1377 static int 1379 static int
1378 intelfb_blank(int blank, struct fb_info *info) 1380 intelfb_blank(int blank, struct fb_info *info)
1379 { 1381 {
1380 intelfbhw_do_blank(blank, info); 1382 intelfbhw_do_blank(blank, info);
1381 return 0; 1383 return 0;
1382 } 1384 }
1383 1385
1384 static int 1386 static int
1385 intelfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 1387 intelfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1386 { 1388 {
1387 intelfbhw_pan_display(var, info); 1389 intelfbhw_pan_display(var, info);
1388 return 0; 1390 return 0;
1389 } 1391 }
1390 1392
1391 /* When/if we have our own ioctls. */ 1393 /* When/if we have our own ioctls. */
1392 static int 1394 static int
1393 intelfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 1395 intelfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1394 unsigned long arg, struct fb_info *info) 1396 unsigned long arg, struct fb_info *info)
1395 { 1397 {
1396 int retval = 0; 1398 int retval = 0;
1397 1399
1398 return retval; 1400 return retval;
1399 } 1401 }
1400 1402
1401 static void 1403 static void
1402 intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect) 1404 intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
1403 { 1405 {
1404 struct intelfb_info *dinfo = GET_DINFO(info); 1406 struct intelfb_info *dinfo = GET_DINFO(info);
1405 u32 rop, color; 1407 u32 rop, color;
1406 1408
1407 #if VERBOSE > 0 1409 #if VERBOSE > 0
1408 DBG_MSG("intelfb_fillrect\n"); 1410 DBG_MSG("intelfb_fillrect\n");
1409 #endif 1411 #endif
1410 1412
1411 if (!ACCEL(dinfo, info) || dinfo->depth == 4) 1413 if (!ACCEL(dinfo, info) || dinfo->depth == 4)
1412 return cfb_fillrect(info, rect); 1414 return cfb_fillrect(info, rect);
1413 1415
1414 if (rect->rop == ROP_COPY) 1416 if (rect->rop == ROP_COPY)
1415 rop = PAT_ROP_GXCOPY; 1417 rop = PAT_ROP_GXCOPY;
1416 else // ROP_XOR 1418 else // ROP_XOR
1417 rop = PAT_ROP_GXXOR; 1419 rop = PAT_ROP_GXXOR;
1418 1420
1419 if (dinfo->depth != 8) 1421 if (dinfo->depth != 8)
1420 color = dinfo->pseudo_palette[rect->color]; 1422 color = dinfo->pseudo_palette[rect->color];
1421 else 1423 else
1422 color = rect->color; 1424 color = rect->color;
1423 1425
1424 intelfbhw_do_fillrect(dinfo, rect->dx, rect->dy, 1426 intelfbhw_do_fillrect(dinfo, rect->dx, rect->dy,
1425 rect->width, rect->height, color, 1427 rect->width, rect->height, color,
1426 dinfo->pitch, info->var.bits_per_pixel, 1428 dinfo->pitch, info->var.bits_per_pixel,
1427 rop); 1429 rop);
1428 } 1430 }
1429 1431
1430 static void 1432 static void
1431 intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region) 1433 intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1432 { 1434 {
1433 struct intelfb_info *dinfo = GET_DINFO(info); 1435 struct intelfb_info *dinfo = GET_DINFO(info);
1434 1436
1435 #if VERBOSE > 0 1437 #if VERBOSE > 0
1436 DBG_MSG("intelfb_copyarea\n"); 1438 DBG_MSG("intelfb_copyarea\n");
1437 #endif 1439 #endif
1438 1440
1439 if (!ACCEL(dinfo, info) || dinfo->depth == 4) 1441 if (!ACCEL(dinfo, info) || dinfo->depth == 4)
1440 return cfb_copyarea(info, region); 1442 return cfb_copyarea(info, region);
1441 1443
1442 intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx, 1444 intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx,
1443 region->dy, region->width, region->height, 1445 region->dy, region->width, region->height,
1444 dinfo->pitch, info->var.bits_per_pixel); 1446 dinfo->pitch, info->var.bits_per_pixel);
1445 } 1447 }
1446 1448
1447 static void 1449 static void
1448 intelfb_imageblit(struct fb_info *info, const struct fb_image *image) 1450 intelfb_imageblit(struct fb_info *info, const struct fb_image *image)
1449 { 1451 {
1450 struct intelfb_info *dinfo = GET_DINFO(info); 1452 struct intelfb_info *dinfo = GET_DINFO(info);
1451 u32 fgcolor, bgcolor; 1453 u32 fgcolor, bgcolor;
1452 1454
1453 #if VERBOSE > 0 1455 #if VERBOSE > 0
1454 DBG_MSG("intelfb_imageblit\n"); 1456 DBG_MSG("intelfb_imageblit\n");
1455 #endif 1457 #endif
1456 1458
1457 if (!ACCEL(dinfo, info) || dinfo->depth == 4 1459 if (!ACCEL(dinfo, info) || dinfo->depth == 4
1458 || image->depth != 1) 1460 || image->depth != 1)
1459 return cfb_imageblit(info, image); 1461 return cfb_imageblit(info, image);
1460 1462
1461 if (dinfo->depth != 8) { 1463 if (dinfo->depth != 8) {
1462 fgcolor = dinfo->pseudo_palette[image->fg_color]; 1464 fgcolor = dinfo->pseudo_palette[image->fg_color];
1463 bgcolor = dinfo->pseudo_palette[image->bg_color]; 1465 bgcolor = dinfo->pseudo_palette[image->bg_color];
1464 } else { 1466 } else {
1465 fgcolor = image->fg_color; 1467 fgcolor = image->fg_color;
1466 bgcolor = image->bg_color; 1468 bgcolor = image->bg_color;
1467 } 1469 }
1468 1470
1469 if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width, 1471 if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width,
1470 image->height, image->data, 1472 image->height, image->data,
1471 image->dx, image->dy, 1473 image->dx, image->dy,
1472 dinfo->pitch, info->var.bits_per_pixel)) 1474 dinfo->pitch, info->var.bits_per_pixel))
1473 return cfb_imageblit(info, image); 1475 return cfb_imageblit(info, image);
1474 } 1476 }
1475 1477
1476 static int 1478 static int
1477 intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1479 intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1478 { 1480 {
1479 struct intelfb_info *dinfo = GET_DINFO(info); 1481 struct intelfb_info *dinfo = GET_DINFO(info);
1480 1482
1481 #if VERBOSE > 0 1483 #if VERBOSE > 0
1482 DBG_MSG("intelfb_cursor\n"); 1484 DBG_MSG("intelfb_cursor\n");
1483 #endif 1485 #endif
1484 1486
1485 if (!dinfo->hwcursor) 1487 if (!dinfo->hwcursor)
1486 return soft_cursor(info, cursor); 1488 return soft_cursor(info, cursor);
1487 1489
1488 intelfbhw_cursor_hide(dinfo); 1490 intelfbhw_cursor_hide(dinfo);
1489 1491
1490 /* If XFree killed the cursor - restore it */ 1492 /* If XFree killed the cursor - restore it */
1491 if (INREG(CURSOR_A_BASEADDR) != dinfo->cursor.offset << 12) { 1493 if (INREG(CURSOR_A_BASEADDR) != dinfo->cursor.offset << 12) {
1492 u32 fg, bg; 1494 u32 fg, bg;
1493 1495
1494 DBG_MSG("the cursor was killed - restore it !!\n"); 1496 DBG_MSG("the cursor was killed - restore it !!\n");
1495 DBG_MSG("size %d, %d pos %d, %d\n", 1497 DBG_MSG("size %d, %d pos %d, %d\n",
1496 cursor->image.width, cursor->image.height, 1498 cursor->image.width, cursor->image.height,
1497 cursor->image.dx, cursor->image.dy); 1499 cursor->image.dx, cursor->image.dy);
1498 1500
1499 intelfbhw_cursor_init(dinfo); 1501 intelfbhw_cursor_init(dinfo);
1500 intelfbhw_cursor_reset(dinfo); 1502 intelfbhw_cursor_reset(dinfo);
1501 intelfbhw_cursor_setpos(dinfo, cursor->image.dx, 1503 intelfbhw_cursor_setpos(dinfo, cursor->image.dx,
1502 cursor->image.dy); 1504 cursor->image.dy);
1503 1505
1504 if (dinfo->depth != 8) { 1506 if (dinfo->depth != 8) {
1505 fg =dinfo->pseudo_palette[cursor->image.fg_color]; 1507 fg =dinfo->pseudo_palette[cursor->image.fg_color];
1506 bg =dinfo->pseudo_palette[cursor->image.bg_color]; 1508 bg =dinfo->pseudo_palette[cursor->image.bg_color];
1507 } else { 1509 } else {
1508 fg = cursor->image.fg_color; 1510 fg = cursor->image.fg_color;
1509 bg = cursor->image.bg_color; 1511 bg = cursor->image.bg_color;
1510 } 1512 }
1511 intelfbhw_cursor_setcolor(dinfo, bg, fg); 1513 intelfbhw_cursor_setcolor(dinfo, bg, fg);
1512 intelfbhw_cursor_load(dinfo, cursor->image.width, 1514 intelfbhw_cursor_load(dinfo, cursor->image.width,
1513 cursor->image.height, 1515 cursor->image.height,
1514 dinfo->cursor_src); 1516 dinfo->cursor_src);
1515 1517
1516 if (cursor->enable) 1518 if (cursor->enable)
1517 intelfbhw_cursor_show(dinfo); 1519 intelfbhw_cursor_show(dinfo);
1518 return 0; 1520 return 0;
1519 } 1521 }
1520 1522
1521 if (cursor->set & FB_CUR_SETPOS) { 1523 if (cursor->set & FB_CUR_SETPOS) {
1522 u32 dx, dy; 1524 u32 dx, dy;
1523 1525
1524 dx = cursor->image.dx - info->var.xoffset; 1526 dx = cursor->image.dx - info->var.xoffset;
1525 dy = cursor->image.dy - info->var.yoffset; 1527 dy = cursor->image.dy - info->var.yoffset;
1526 1528
1527 intelfbhw_cursor_setpos(dinfo, dx, dy); 1529 intelfbhw_cursor_setpos(dinfo, dx, dy);
1528 } 1530 }
1529 1531
1530 if (cursor->set & FB_CUR_SETSIZE) { 1532 if (cursor->set & FB_CUR_SETSIZE) {
1531 if (cursor->image.width > 64 || cursor->image.height > 64) 1533 if (cursor->image.width > 64 || cursor->image.height > 64)
1532 return -ENXIO; 1534 return -ENXIO;
1533 1535
1534 intelfbhw_cursor_reset(dinfo); 1536 intelfbhw_cursor_reset(dinfo);
1535 } 1537 }
1536 1538
1537 if (cursor->set & FB_CUR_SETCMAP) { 1539 if (cursor->set & FB_CUR_SETCMAP) {
1538 u32 fg, bg; 1540 u32 fg, bg;
1539 1541
1540 if (dinfo->depth != 8) { 1542 if (dinfo->depth != 8) {
1541 fg = dinfo->pseudo_palette[cursor->image.fg_color]; 1543 fg = dinfo->pseudo_palette[cursor->image.fg_color];
1542 bg = dinfo->pseudo_palette[cursor->image.bg_color]; 1544 bg = dinfo->pseudo_palette[cursor->image.bg_color];
1543 } else { 1545 } else {
1544 fg = cursor->image.fg_color; 1546 fg = cursor->image.fg_color;
1545 bg = cursor->image.bg_color; 1547 bg = cursor->image.bg_color;
1546 } 1548 }
1547 1549
1548 intelfbhw_cursor_setcolor(dinfo, bg, fg); 1550 intelfbhw_cursor_setcolor(dinfo, bg, fg);
1549 } 1551 }
1550 1552
1551 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) { 1553 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1552 u32 s_pitch = (ROUND_UP_TO(cursor->image.width, 8) / 8); 1554 u32 s_pitch = (ROUND_UP_TO(cursor->image.width, 8) / 8);
1553 u32 size = s_pitch * cursor->image.height; 1555 u32 size = s_pitch * cursor->image.height;
1554 u8 *dat = (u8 *) cursor->image.data; 1556 u8 *dat = (u8 *) cursor->image.data;
1555 u8 *msk = (u8 *) cursor->mask; 1557 u8 *msk = (u8 *) cursor->mask;
1556 u8 src[64]; 1558 u8 src[64];
1557 u32 i; 1559 u32 i;
1558 1560
1559 if (cursor->image.depth != 1) 1561 if (cursor->image.depth != 1)
1560 return -ENXIO; 1562 return -ENXIO;
1561 1563
1562 switch (cursor->rop) { 1564 switch (cursor->rop) {
1563 case ROP_XOR: 1565 case ROP_XOR:
1564 for (i = 0; i < size; i++) 1566 for (i = 0; i < size; i++)
1565 src[i] = dat[i] ^ msk[i]; 1567 src[i] = dat[i] ^ msk[i];
1566 break; 1568 break;
1567 case ROP_COPY: 1569 case ROP_COPY:
1568 default: 1570 default:
1569 for (i = 0; i < size; i++) 1571 for (i = 0; i < size; i++)
1570 src[i] = dat[i] & msk[i]; 1572 src[i] = dat[i] & msk[i];
1571 break; 1573 break;
1572 } 1574 }
1573 1575
1574 /* save the bitmap to restore it when XFree will 1576 /* save the bitmap to restore it when XFree will
1575 make the cursor dirty */ 1577 make the cursor dirty */
1576 memcpy(dinfo->cursor_src, src, size); 1578 memcpy(dinfo->cursor_src, src, size);
1577 1579
1578 intelfbhw_cursor_load(dinfo, cursor->image.width, 1580 intelfbhw_cursor_load(dinfo, cursor->image.width,
1579 cursor->image.height, src); 1581 cursor->image.height, src);
1580 } 1582 }
1581 1583
1582 if (cursor->enable) 1584 if (cursor->enable)
1583 intelfbhw_cursor_show(dinfo); 1585 intelfbhw_cursor_show(dinfo);
1584 1586
1585 return 0; 1587 return 0;
1586 } 1588 }
1587 1589
1588 static int 1590 static int
1589 intelfb_sync(struct fb_info *info) 1591 intelfb_sync(struct fb_info *info)
1590 { 1592 {
1591 struct intelfb_info *dinfo = GET_DINFO(info); 1593 struct intelfb_info *dinfo = GET_DINFO(info);
1592 1594
1593 #if VERBOSE > 0 1595 #if VERBOSE > 0
1594 DBG_MSG("intelfb_sync\n"); 1596 DBG_MSG("intelfb_sync\n");
1595 #endif 1597 #endif
1596 1598
1597 if (dinfo->ring_lockup) 1599 if (dinfo->ring_lockup)
1598 return 0; 1600 return 0;
1599 1601
1600 intelfbhw_do_sync(dinfo); 1602 intelfbhw_do_sync(dinfo);
1601 return 0; 1603 return 0;
1602 } 1604 }
1603 1605
1604 1606
drivers/video/intelfb/intelfbhw.c
1 /* 1 /*
2 * intelfb 2 * intelfb
3 * 3 *
4 * Linux framebuffer driver for Intel(R) 865G integrated graphics chips. 4 * Linux framebuffer driver for Intel(R) 865G integrated graphics chips.
5 * 5 *
6 * Copyright ยฉ 2002, 2003 David Dawes <dawes@xfree86.org> 6 * Copyright ยฉ 2002, 2003 David Dawes <dawes@xfree86.org>
7 * 2004 Sylvain Meyer 7 * 2004 Sylvain Meyer
8 * 8 *
9 * This driver consists of two parts. The first part (intelfbdrv.c) provides 9 * This driver consists of two parts. The first part (intelfbdrv.c) provides
10 * the basic fbdev interfaces, is derived in part from the radeonfb and 10 * the basic fbdev interfaces, is derived in part from the radeonfb and
11 * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c) 11 * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c)
12 * provides the code to program the hardware. Most of it is derived from 12 * provides the code to program the hardware. Most of it is derived from
13 * the i810/i830 XFree86 driver. The HW-specific code is covered here 13 * the i810/i830 XFree86 driver. The HW-specific code is covered here
14 * under a dual license (GPL and MIT/XFree86 license). 14 * under a dual license (GPL and MIT/XFree86 license).
15 * 15 *
16 * Author: David Dawes 16 * Author: David Dawes
17 * 17 *
18 */ 18 */
19 19
20 /* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */ 20 /* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */
21 21
22 #include <linux/config.h> 22 #include <linux/config.h>
23 #include <linux/module.h> 23 #include <linux/module.h>
24 #include <linux/kernel.h> 24 #include <linux/kernel.h>
25 #include <linux/errno.h> 25 #include <linux/errno.h>
26 #include <linux/string.h> 26 #include <linux/string.h>
27 #include <linux/mm.h> 27 #include <linux/mm.h>
28 #include <linux/tty.h> 28 #include <linux/tty.h>
29 #include <linux/slab.h> 29 #include <linux/slab.h>
30 #include <linux/delay.h> 30 #include <linux/delay.h>
31 #include <linux/fb.h> 31 #include <linux/fb.h>
32 #include <linux/ioport.h> 32 #include <linux/ioport.h>
33 #include <linux/init.h> 33 #include <linux/init.h>
34 #include <linux/pci.h> 34 #include <linux/pci.h>
35 #include <linux/vmalloc.h> 35 #include <linux/vmalloc.h>
36 #include <linux/pagemap.h> 36 #include <linux/pagemap.h>
37 #include <linux/version.h> 37 #include <linux/version.h>
38 38
39 #include <asm/io.h> 39 #include <asm/io.h>
40 40
41 #include "intelfb.h" 41 #include "intelfb.h"
42 #include "intelfbhw.h" 42 #include "intelfbhw.h"
43 43
44 int 44 int
45 intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset, 45 intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset,
46 int *mobile) 46 int *mobile)
47 { 47 {
48 u32 tmp; 48 u32 tmp;
49 49
50 if (!pdev || !name || !chipset || !mobile) 50 if (!pdev || !name || !chipset || !mobile)
51 return 1; 51 return 1;
52 52
53 switch (pdev->device) { 53 switch (pdev->device) {
54 case PCI_DEVICE_ID_INTEL_830M: 54 case PCI_DEVICE_ID_INTEL_830M:
55 *name = "Intel(R) 830M"; 55 *name = "Intel(R) 830M";
56 *chipset = INTEL_830M; 56 *chipset = INTEL_830M;
57 *mobile = 1; 57 *mobile = 1;
58 return 0; 58 return 0;
59 case PCI_DEVICE_ID_INTEL_845G: 59 case PCI_DEVICE_ID_INTEL_845G:
60 *name = "Intel(R) 845G"; 60 *name = "Intel(R) 845G";
61 *chipset = INTEL_845G; 61 *chipset = INTEL_845G;
62 *mobile = 0; 62 *mobile = 0;
63 return 0; 63 return 0;
64 case PCI_DEVICE_ID_INTEL_85XGM: 64 case PCI_DEVICE_ID_INTEL_85XGM:
65 tmp = 0; 65 tmp = 0;
66 *mobile = 1; 66 *mobile = 1;
67 pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp); 67 pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp);
68 switch ((tmp >> INTEL_85X_VARIANT_SHIFT) & 68 switch ((tmp >> INTEL_85X_VARIANT_SHIFT) &
69 INTEL_85X_VARIANT_MASK) { 69 INTEL_85X_VARIANT_MASK) {
70 case INTEL_VAR_855GME: 70 case INTEL_VAR_855GME:
71 *name = "Intel(R) 855GME"; 71 *name = "Intel(R) 855GME";
72 *chipset = INTEL_855GME; 72 *chipset = INTEL_855GME;
73 return 0; 73 return 0;
74 case INTEL_VAR_855GM: 74 case INTEL_VAR_855GM:
75 *name = "Intel(R) 855GM"; 75 *name = "Intel(R) 855GM";
76 *chipset = INTEL_855GM; 76 *chipset = INTEL_855GM;
77 return 0; 77 return 0;
78 case INTEL_VAR_852GME: 78 case INTEL_VAR_852GME:
79 *name = "Intel(R) 852GME"; 79 *name = "Intel(R) 852GME";
80 *chipset = INTEL_852GME; 80 *chipset = INTEL_852GME;
81 return 0; 81 return 0;
82 case INTEL_VAR_852GM: 82 case INTEL_VAR_852GM:
83 *name = "Intel(R) 852GM"; 83 *name = "Intel(R) 852GM";
84 *chipset = INTEL_852GM; 84 *chipset = INTEL_852GM;
85 return 0; 85 return 0;
86 default: 86 default:
87 *name = "Intel(R) 852GM/855GM"; 87 *name = "Intel(R) 852GM/855GM";
88 *chipset = INTEL_85XGM; 88 *chipset = INTEL_85XGM;
89 return 0; 89 return 0;
90 } 90 }
91 break; 91 break;
92 case PCI_DEVICE_ID_INTEL_865G: 92 case PCI_DEVICE_ID_INTEL_865G:
93 *name = "Intel(R) 865G"; 93 *name = "Intel(R) 865G";
94 *chipset = INTEL_865G; 94 *chipset = INTEL_865G;
95 *mobile = 0; 95 *mobile = 0;
96 return 0; 96 return 0;
97 case PCI_DEVICE_ID_INTEL_915G: 97 case PCI_DEVICE_ID_INTEL_915G:
98 *name = "Intel(R) 915G"; 98 *name = "Intel(R) 915G";
99 *chipset = INTEL_915G; 99 *chipset = INTEL_915G;
100 *mobile = 0; 100 *mobile = 0;
101 return 0; 101 return 0;
102 case PCI_DEVICE_ID_INTEL_915GM:
103 *name = "Intel(R) 915GM";
104 *chipset = INTEL_915GM;
105 *mobile = 1;
106 return 0;
102 default: 107 default:
103 return 1; 108 return 1;
104 } 109 }
105 } 110 }
106 111
107 int 112 int
108 intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, 113 intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
109 int *stolen_size) 114 int *stolen_size)
110 { 115 {
111 struct pci_dev *bridge_dev; 116 struct pci_dev *bridge_dev;
112 u16 tmp; 117 u16 tmp;
113 118
114 if (!pdev || !aperture_size || !stolen_size) 119 if (!pdev || !aperture_size || !stolen_size)
115 return 1; 120 return 1;
116 121
117 /* Find the bridge device. It is always 0:0.0 */ 122 /* Find the bridge device. It is always 0:0.0 */
118 if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) { 123 if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) {
119 ERR_MSG("cannot find bridge device\n"); 124 ERR_MSG("cannot find bridge device\n");
120 return 1; 125 return 1;
121 } 126 }
122 127
123 /* Get the fb aperture size and "stolen" memory amount. */ 128 /* Get the fb aperture size and "stolen" memory amount. */
124 tmp = 0; 129 tmp = 0;
125 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); 130 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
126 switch (pdev->device) { 131 switch (pdev->device) {
127 case PCI_DEVICE_ID_INTEL_830M: 132 case PCI_DEVICE_ID_INTEL_830M:
128 case PCI_DEVICE_ID_INTEL_845G: 133 case PCI_DEVICE_ID_INTEL_845G:
129 if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) 134 if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M)
130 *aperture_size = MB(64); 135 *aperture_size = MB(64);
131 else 136 else
132 *aperture_size = MB(128); 137 *aperture_size = MB(128);
133 switch (tmp & INTEL_830_GMCH_GMS_MASK) { 138 switch (tmp & INTEL_830_GMCH_GMS_MASK) {
134 case INTEL_830_GMCH_GMS_STOLEN_512: 139 case INTEL_830_GMCH_GMS_STOLEN_512:
135 *stolen_size = KB(512) - KB(132); 140 *stolen_size = KB(512) - KB(132);
136 return 0; 141 return 0;
137 case INTEL_830_GMCH_GMS_STOLEN_1024: 142 case INTEL_830_GMCH_GMS_STOLEN_1024:
138 *stolen_size = MB(1) - KB(132); 143 *stolen_size = MB(1) - KB(132);
139 return 0; 144 return 0;
140 case INTEL_830_GMCH_GMS_STOLEN_8192: 145 case INTEL_830_GMCH_GMS_STOLEN_8192:
141 *stolen_size = MB(8) - KB(132); 146 *stolen_size = MB(8) - KB(132);
142 return 0; 147 return 0;
143 case INTEL_830_GMCH_GMS_LOCAL: 148 case INTEL_830_GMCH_GMS_LOCAL:
144 ERR_MSG("only local memory found\n"); 149 ERR_MSG("only local memory found\n");
145 return 1; 150 return 1;
146 case INTEL_830_GMCH_GMS_DISABLED: 151 case INTEL_830_GMCH_GMS_DISABLED:
147 ERR_MSG("video memory is disabled\n"); 152 ERR_MSG("video memory is disabled\n");
148 return 1; 153 return 1;
149 default: 154 default:
150 ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n", 155 ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n",
151 tmp & INTEL_830_GMCH_GMS_MASK); 156 tmp & INTEL_830_GMCH_GMS_MASK);
152 return 1; 157 return 1;
153 } 158 }
154 break; 159 break;
155 default: 160 default:
156 *aperture_size = MB(128); 161 *aperture_size = MB(128);
157 switch (tmp & INTEL_855_GMCH_GMS_MASK) { 162 switch (tmp & INTEL_855_GMCH_GMS_MASK) {
158 case INTEL_855_GMCH_GMS_STOLEN_1M: 163 case INTEL_855_GMCH_GMS_STOLEN_1M:
159 *stolen_size = MB(1) - KB(132); 164 *stolen_size = MB(1) - KB(132);
160 return 0; 165 return 0;
161 case INTEL_855_GMCH_GMS_STOLEN_4M: 166 case INTEL_855_GMCH_GMS_STOLEN_4M:
162 *stolen_size = MB(4) - KB(132); 167 *stolen_size = MB(4) - KB(132);
163 return 0; 168 return 0;
164 case INTEL_855_GMCH_GMS_STOLEN_8M: 169 case INTEL_855_GMCH_GMS_STOLEN_8M:
165 *stolen_size = MB(8) - KB(132); 170 *stolen_size = MB(8) - KB(132);
166 return 0; 171 return 0;
167 case INTEL_855_GMCH_GMS_STOLEN_16M: 172 case INTEL_855_GMCH_GMS_STOLEN_16M:
168 *stolen_size = MB(16) - KB(132); 173 *stolen_size = MB(16) - KB(132);
169 return 0; 174 return 0;
170 case INTEL_855_GMCH_GMS_STOLEN_32M: 175 case INTEL_855_GMCH_GMS_STOLEN_32M:
171 *stolen_size = MB(32) - KB(132); 176 *stolen_size = MB(32) - KB(132);
172 return 0; 177 return 0;
173 case INTEL_915G_GMCH_GMS_STOLEN_48M: 178 case INTEL_915G_GMCH_GMS_STOLEN_48M:
174 *stolen_size = MB(48) - KB(132); 179 *stolen_size = MB(48) - KB(132);
175 return 0; 180 return 0;
176 case INTEL_915G_GMCH_GMS_STOLEN_64M: 181 case INTEL_915G_GMCH_GMS_STOLEN_64M:
177 *stolen_size = MB(64) - KB(132); 182 *stolen_size = MB(64) - KB(132);
178 return 0; 183 return 0;
179 case INTEL_855_GMCH_GMS_DISABLED: 184 case INTEL_855_GMCH_GMS_DISABLED:
180 ERR_MSG("video memory is disabled\n"); 185 ERR_MSG("video memory is disabled\n");
181 return 0; 186 return 0;
182 default: 187 default:
183 ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n", 188 ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n",
184 tmp & INTEL_855_GMCH_GMS_MASK); 189 tmp & INTEL_855_GMCH_GMS_MASK);
185 return 1; 190 return 1;
186 } 191 }
187 } 192 }
188 } 193 }
189 194
190 int 195 int
191 intelfbhw_check_non_crt(struct intelfb_info *dinfo) 196 intelfbhw_check_non_crt(struct intelfb_info *dinfo)
192 { 197 {
193 int dvo = 0; 198 int dvo = 0;
194 199
195 if (INREG(LVDS) & PORT_ENABLE) 200 if (INREG(LVDS) & PORT_ENABLE)
196 dvo |= LVDS_PORT; 201 dvo |= LVDS_PORT;
197 if (INREG(DVOA) & PORT_ENABLE) 202 if (INREG(DVOA) & PORT_ENABLE)
198 dvo |= DVOA_PORT; 203 dvo |= DVOA_PORT;
199 if (INREG(DVOB) & PORT_ENABLE) 204 if (INREG(DVOB) & PORT_ENABLE)
200 dvo |= DVOB_PORT; 205 dvo |= DVOB_PORT;
201 if (INREG(DVOC) & PORT_ENABLE) 206 if (INREG(DVOC) & PORT_ENABLE)
202 dvo |= DVOC_PORT; 207 dvo |= DVOC_PORT;
203 208
204 return dvo; 209 return dvo;
205 } 210 }
206 211
207 const char * 212 const char *
208 intelfbhw_dvo_to_string(int dvo) 213 intelfbhw_dvo_to_string(int dvo)
209 { 214 {
210 if (dvo & DVOA_PORT) 215 if (dvo & DVOA_PORT)
211 return "DVO port A"; 216 return "DVO port A";
212 else if (dvo & DVOB_PORT) 217 else if (dvo & DVOB_PORT)
213 return "DVO port B"; 218 return "DVO port B";
214 else if (dvo & DVOC_PORT) 219 else if (dvo & DVOC_PORT)
215 return "DVO port C"; 220 return "DVO port C";
216 else if (dvo & LVDS_PORT) 221 else if (dvo & LVDS_PORT)
217 return "LVDS port"; 222 return "LVDS port";
218 else 223 else
219 return NULL; 224 return NULL;
220 } 225 }
221 226
222 227
223 int 228 int
224 intelfbhw_validate_mode(struct intelfb_info *dinfo, 229 intelfbhw_validate_mode(struct intelfb_info *dinfo,
225 struct fb_var_screeninfo *var) 230 struct fb_var_screeninfo *var)
226 { 231 {
227 int bytes_per_pixel; 232 int bytes_per_pixel;
228 int tmp; 233 int tmp;
229 234
230 #if VERBOSE > 0 235 #if VERBOSE > 0
231 DBG_MSG("intelfbhw_validate_mode\n"); 236 DBG_MSG("intelfbhw_validate_mode\n");
232 #endif 237 #endif
233 238
234 bytes_per_pixel = var->bits_per_pixel / 8; 239 bytes_per_pixel = var->bits_per_pixel / 8;
235 if (bytes_per_pixel == 3) 240 if (bytes_per_pixel == 3)
236 bytes_per_pixel = 4; 241 bytes_per_pixel = 4;
237 242
238 /* Check if enough video memory. */ 243 /* Check if enough video memory. */
239 tmp = var->yres_virtual * var->xres_virtual * bytes_per_pixel; 244 tmp = var->yres_virtual * var->xres_virtual * bytes_per_pixel;
240 if (tmp > dinfo->fb.size) { 245 if (tmp > dinfo->fb.size) {
241 WRN_MSG("Not enough video ram for mode " 246 WRN_MSG("Not enough video ram for mode "
242 "(%d KByte vs %d KByte).\n", 247 "(%d KByte vs %d KByte).\n",
243 BtoKB(tmp), BtoKB(dinfo->fb.size)); 248 BtoKB(tmp), BtoKB(dinfo->fb.size));
244 return 1; 249 return 1;
245 } 250 }
246 251
247 /* Check if x/y limits are OK. */ 252 /* Check if x/y limits are OK. */
248 if (var->xres - 1 > HACTIVE_MASK) { 253 if (var->xres - 1 > HACTIVE_MASK) {
249 WRN_MSG("X resolution too large (%d vs %d).\n", 254 WRN_MSG("X resolution too large (%d vs %d).\n",
250 var->xres, HACTIVE_MASK + 1); 255 var->xres, HACTIVE_MASK + 1);
251 return 1; 256 return 1;
252 } 257 }
253 if (var->yres - 1 > VACTIVE_MASK) { 258 if (var->yres - 1 > VACTIVE_MASK) {
254 WRN_MSG("Y resolution too large (%d vs %d).\n", 259 WRN_MSG("Y resolution too large (%d vs %d).\n",
255 var->yres, VACTIVE_MASK + 1); 260 var->yres, VACTIVE_MASK + 1);
256 return 1; 261 return 1;
257 } 262 }
258 263
259 /* Check for interlaced/doublescan modes. */ 264 /* Check for interlaced/doublescan modes. */
260 if (var->vmode & FB_VMODE_INTERLACED) { 265 if (var->vmode & FB_VMODE_INTERLACED) {
261 WRN_MSG("Mode is interlaced.\n"); 266 WRN_MSG("Mode is interlaced.\n");
262 return 1; 267 return 1;
263 } 268 }
264 if (var->vmode & FB_VMODE_DOUBLE) { 269 if (var->vmode & FB_VMODE_DOUBLE) {
265 WRN_MSG("Mode is double-scan.\n"); 270 WRN_MSG("Mode is double-scan.\n");
266 return 1; 271 return 1;
267 } 272 }
268 273
269 /* Check if clock is OK. */ 274 /* Check if clock is OK. */
270 tmp = 1000000000 / var->pixclock; 275 tmp = 1000000000 / var->pixclock;
271 if (tmp < MIN_CLOCK) { 276 if (tmp < MIN_CLOCK) {
272 WRN_MSG("Pixel clock is too low (%d MHz vs %d MHz).\n", 277 WRN_MSG("Pixel clock is too low (%d MHz vs %d MHz).\n",
273 (tmp + 500) / 1000, MIN_CLOCK / 1000); 278 (tmp + 500) / 1000, MIN_CLOCK / 1000);
274 return 1; 279 return 1;
275 } 280 }
276 if (tmp > MAX_CLOCK) { 281 if (tmp > MAX_CLOCK) {
277 WRN_MSG("Pixel clock is too high (%d MHz vs %d MHz).\n", 282 WRN_MSG("Pixel clock is too high (%d MHz vs %d MHz).\n",
278 (tmp + 500) / 1000, MAX_CLOCK / 1000); 283 (tmp + 500) / 1000, MAX_CLOCK / 1000);
279 return 1; 284 return 1;
280 } 285 }
281 286
282 return 0; 287 return 0;
283 } 288 }
284 289
285 int 290 int
286 intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 291 intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
287 { 292 {
288 struct intelfb_info *dinfo = GET_DINFO(info); 293 struct intelfb_info *dinfo = GET_DINFO(info);
289 u32 offset, xoffset, yoffset; 294 u32 offset, xoffset, yoffset;
290 295
291 #if VERBOSE > 0 296 #if VERBOSE > 0
292 DBG_MSG("intelfbhw_pan_display\n"); 297 DBG_MSG("intelfbhw_pan_display\n");
293 #endif 298 #endif
294 299
295 xoffset = ROUND_DOWN_TO(var->xoffset, 8); 300 xoffset = ROUND_DOWN_TO(var->xoffset, 8);
296 yoffset = var->yoffset; 301 yoffset = var->yoffset;
297 302
298 if ((xoffset + var->xres > var->xres_virtual) || 303 if ((xoffset + var->xres > var->xres_virtual) ||
299 (yoffset + var->yres > var->yres_virtual)) 304 (yoffset + var->yres > var->yres_virtual))
300 return -EINVAL; 305 return -EINVAL;
301 306
302 offset = (yoffset * dinfo->pitch) + 307 offset = (yoffset * dinfo->pitch) +
303 (xoffset * var->bits_per_pixel) / 8; 308 (xoffset * var->bits_per_pixel) / 8;
304 309
305 offset += dinfo->fb.offset << 12; 310 offset += dinfo->fb.offset << 12;
306 311
307 OUTREG(DSPABASE, offset); 312 OUTREG(DSPABASE, offset);
308 313
309 return 0; 314 return 0;
310 } 315 }
311 316
312 /* Blank the screen. */ 317 /* Blank the screen. */
313 void 318 void
314 intelfbhw_do_blank(int blank, struct fb_info *info) 319 intelfbhw_do_blank(int blank, struct fb_info *info)
315 { 320 {
316 struct intelfb_info *dinfo = GET_DINFO(info); 321 struct intelfb_info *dinfo = GET_DINFO(info);
317 u32 tmp; 322 u32 tmp;
318 323
319 #if VERBOSE > 0 324 #if VERBOSE > 0
320 DBG_MSG("intelfbhw_do_blank: blank is %d\n", blank); 325 DBG_MSG("intelfbhw_do_blank: blank is %d\n", blank);
321 #endif 326 #endif
322 327
323 /* Turn plane A on or off */ 328 /* Turn plane A on or off */
324 tmp = INREG(DSPACNTR); 329 tmp = INREG(DSPACNTR);
325 if (blank) 330 if (blank)
326 tmp &= ~DISPPLANE_PLANE_ENABLE; 331 tmp &= ~DISPPLANE_PLANE_ENABLE;
327 else 332 else
328 tmp |= DISPPLANE_PLANE_ENABLE; 333 tmp |= DISPPLANE_PLANE_ENABLE;
329 OUTREG(DSPACNTR, tmp); 334 OUTREG(DSPACNTR, tmp);
330 /* Flush */ 335 /* Flush */
331 tmp = INREG(DSPABASE); 336 tmp = INREG(DSPABASE);
332 OUTREG(DSPABASE, tmp); 337 OUTREG(DSPABASE, tmp);
333 338
334 /* Turn off/on the HW cursor */ 339 /* Turn off/on the HW cursor */
335 #if VERBOSE > 0 340 #if VERBOSE > 0
336 DBG_MSG("cursor_on is %d\n", dinfo->cursor_on); 341 DBG_MSG("cursor_on is %d\n", dinfo->cursor_on);
337 #endif 342 #endif
338 if (dinfo->cursor_on) { 343 if (dinfo->cursor_on) {
339 if (blank) { 344 if (blank) {
340 intelfbhw_cursor_hide(dinfo); 345 intelfbhw_cursor_hide(dinfo);
341 } else { 346 } else {
342 intelfbhw_cursor_show(dinfo); 347 intelfbhw_cursor_show(dinfo);
343 } 348 }
344 dinfo->cursor_on = 1; 349 dinfo->cursor_on = 1;
345 } 350 }
346 dinfo->cursor_blanked = blank; 351 dinfo->cursor_blanked = blank;
347 352
348 /* Set DPMS level */ 353 /* Set DPMS level */
349 tmp = INREG(ADPA) & ~ADPA_DPMS_CONTROL_MASK; 354 tmp = INREG(ADPA) & ~ADPA_DPMS_CONTROL_MASK;
350 switch (blank) { 355 switch (blank) {
351 case FB_BLANK_UNBLANK: 356 case FB_BLANK_UNBLANK:
352 case FB_BLANK_NORMAL: 357 case FB_BLANK_NORMAL:
353 tmp |= ADPA_DPMS_D0; 358 tmp |= ADPA_DPMS_D0;
354 break; 359 break;
355 case FB_BLANK_VSYNC_SUSPEND: 360 case FB_BLANK_VSYNC_SUSPEND:
356 tmp |= ADPA_DPMS_D1; 361 tmp |= ADPA_DPMS_D1;
357 break; 362 break;
358 case FB_BLANK_HSYNC_SUSPEND: 363 case FB_BLANK_HSYNC_SUSPEND:
359 tmp |= ADPA_DPMS_D2; 364 tmp |= ADPA_DPMS_D2;
360 break; 365 break;
361 case FB_BLANK_POWERDOWN: 366 case FB_BLANK_POWERDOWN:
362 tmp |= ADPA_DPMS_D3; 367 tmp |= ADPA_DPMS_D3;
363 break; 368 break;
364 } 369 }
365 OUTREG(ADPA, tmp); 370 OUTREG(ADPA, tmp);
366 371
367 return; 372 return;
368 } 373 }
369 374
370 375
371 void 376 void
372 intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, 377 intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
373 unsigned red, unsigned green, unsigned blue, 378 unsigned red, unsigned green, unsigned blue,
374 unsigned transp) 379 unsigned transp)
375 { 380 {
376 #if VERBOSE > 0 381 #if VERBOSE > 0
377 DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n", 382 DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n",
378 regno, red, green, blue); 383 regno, red, green, blue);
379 #endif 384 #endif
380 385
381 u32 palette_reg = (dinfo->pipe == PIPE_A) ? 386 u32 palette_reg = (dinfo->pipe == PIPE_A) ?
382 PALETTE_A : PALETTE_B; 387 PALETTE_A : PALETTE_B;
383 388
384 OUTREG(palette_reg + (regno << 2), 389 OUTREG(palette_reg + (regno << 2),
385 (red << PALETTE_8_RED_SHIFT) | 390 (red << PALETTE_8_RED_SHIFT) |
386 (green << PALETTE_8_GREEN_SHIFT) | 391 (green << PALETTE_8_GREEN_SHIFT) |
387 (blue << PALETTE_8_BLUE_SHIFT)); 392 (blue << PALETTE_8_BLUE_SHIFT));
388 } 393 }
389 394
390 395
391 int 396 int
392 intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, 397 intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
393 int flag) 398 int flag)
394 { 399 {
395 int i; 400 int i;
396 401
397 #if VERBOSE > 0 402 #if VERBOSE > 0
398 DBG_MSG("intelfbhw_read_hw_state\n"); 403 DBG_MSG("intelfbhw_read_hw_state\n");
399 #endif 404 #endif
400 405
401 if (!hw || !dinfo) 406 if (!hw || !dinfo)
402 return -1; 407 return -1;
403 408
404 /* Read in as much of the HW state as possible. */ 409 /* Read in as much of the HW state as possible. */
405 hw->vga0_divisor = INREG(VGA0_DIVISOR); 410 hw->vga0_divisor = INREG(VGA0_DIVISOR);
406 hw->vga1_divisor = INREG(VGA1_DIVISOR); 411 hw->vga1_divisor = INREG(VGA1_DIVISOR);
407 hw->vga_pd = INREG(VGAPD); 412 hw->vga_pd = INREG(VGAPD);
408 hw->dpll_a = INREG(DPLL_A); 413 hw->dpll_a = INREG(DPLL_A);
409 hw->dpll_b = INREG(DPLL_B); 414 hw->dpll_b = INREG(DPLL_B);
410 hw->fpa0 = INREG(FPA0); 415 hw->fpa0 = INREG(FPA0);
411 hw->fpa1 = INREG(FPA1); 416 hw->fpa1 = INREG(FPA1);
412 hw->fpb0 = INREG(FPB0); 417 hw->fpb0 = INREG(FPB0);
413 hw->fpb1 = INREG(FPB1); 418 hw->fpb1 = INREG(FPB1);
414 419
415 if (flag == 1) 420 if (flag == 1)
416 return flag; 421 return flag;
417 422
418 #if 0 423 #if 0
419 /* This seems to be a problem with the 852GM/855GM */ 424 /* This seems to be a problem with the 852GM/855GM */
420 for (i = 0; i < PALETTE_8_ENTRIES; i++) { 425 for (i = 0; i < PALETTE_8_ENTRIES; i++) {
421 hw->palette_a[i] = INREG(PALETTE_A + (i << 2)); 426 hw->palette_a[i] = INREG(PALETTE_A + (i << 2));
422 hw->palette_b[i] = INREG(PALETTE_B + (i << 2)); 427 hw->palette_b[i] = INREG(PALETTE_B + (i << 2));
423 } 428 }
424 #endif 429 #endif
425 430
426 if (flag == 2) 431 if (flag == 2)
427 return flag; 432 return flag;
428 433
429 hw->htotal_a = INREG(HTOTAL_A); 434 hw->htotal_a = INREG(HTOTAL_A);
430 hw->hblank_a = INREG(HBLANK_A); 435 hw->hblank_a = INREG(HBLANK_A);
431 hw->hsync_a = INREG(HSYNC_A); 436 hw->hsync_a = INREG(HSYNC_A);
432 hw->vtotal_a = INREG(VTOTAL_A); 437 hw->vtotal_a = INREG(VTOTAL_A);
433 hw->vblank_a = INREG(VBLANK_A); 438 hw->vblank_a = INREG(VBLANK_A);
434 hw->vsync_a = INREG(VSYNC_A); 439 hw->vsync_a = INREG(VSYNC_A);
435 hw->src_size_a = INREG(SRC_SIZE_A); 440 hw->src_size_a = INREG(SRC_SIZE_A);
436 hw->bclrpat_a = INREG(BCLRPAT_A); 441 hw->bclrpat_a = INREG(BCLRPAT_A);
437 hw->htotal_b = INREG(HTOTAL_B); 442 hw->htotal_b = INREG(HTOTAL_B);
438 hw->hblank_b = INREG(HBLANK_B); 443 hw->hblank_b = INREG(HBLANK_B);
439 hw->hsync_b = INREG(HSYNC_B); 444 hw->hsync_b = INREG(HSYNC_B);
440 hw->vtotal_b = INREG(VTOTAL_B); 445 hw->vtotal_b = INREG(VTOTAL_B);
441 hw->vblank_b = INREG(VBLANK_B); 446 hw->vblank_b = INREG(VBLANK_B);
442 hw->vsync_b = INREG(VSYNC_B); 447 hw->vsync_b = INREG(VSYNC_B);
443 hw->src_size_b = INREG(SRC_SIZE_B); 448 hw->src_size_b = INREG(SRC_SIZE_B);
444 hw->bclrpat_b = INREG(BCLRPAT_B); 449 hw->bclrpat_b = INREG(BCLRPAT_B);
445 450
446 if (flag == 3) 451 if (flag == 3)
447 return flag; 452 return flag;
448 453
449 hw->adpa = INREG(ADPA); 454 hw->adpa = INREG(ADPA);
450 hw->dvoa = INREG(DVOA); 455 hw->dvoa = INREG(DVOA);
451 hw->dvob = INREG(DVOB); 456 hw->dvob = INREG(DVOB);
452 hw->dvoc = INREG(DVOC); 457 hw->dvoc = INREG(DVOC);
453 hw->dvoa_srcdim = INREG(DVOA_SRCDIM); 458 hw->dvoa_srcdim = INREG(DVOA_SRCDIM);
454 hw->dvob_srcdim = INREG(DVOB_SRCDIM); 459 hw->dvob_srcdim = INREG(DVOB_SRCDIM);
455 hw->dvoc_srcdim = INREG(DVOC_SRCDIM); 460 hw->dvoc_srcdim = INREG(DVOC_SRCDIM);
456 hw->lvds = INREG(LVDS); 461 hw->lvds = INREG(LVDS);
457 462
458 if (flag == 4) 463 if (flag == 4)
459 return flag; 464 return flag;
460 465
461 hw->pipe_a_conf = INREG(PIPEACONF); 466 hw->pipe_a_conf = INREG(PIPEACONF);
462 hw->pipe_b_conf = INREG(PIPEBCONF); 467 hw->pipe_b_conf = INREG(PIPEBCONF);
463 hw->disp_arb = INREG(DISPARB); 468 hw->disp_arb = INREG(DISPARB);
464 469
465 if (flag == 5) 470 if (flag == 5)
466 return flag; 471 return flag;
467 472
468 hw->cursor_a_control = INREG(CURSOR_A_CONTROL); 473 hw->cursor_a_control = INREG(CURSOR_A_CONTROL);
469 hw->cursor_b_control = INREG(CURSOR_B_CONTROL); 474 hw->cursor_b_control = INREG(CURSOR_B_CONTROL);
470 hw->cursor_a_base = INREG(CURSOR_A_BASEADDR); 475 hw->cursor_a_base = INREG(CURSOR_A_BASEADDR);
471 hw->cursor_b_base = INREG(CURSOR_B_BASEADDR); 476 hw->cursor_b_base = INREG(CURSOR_B_BASEADDR);
472 477
473 if (flag == 6) 478 if (flag == 6)
474 return flag; 479 return flag;
475 480
476 for (i = 0; i < 4; i++) { 481 for (i = 0; i < 4; i++) {
477 hw->cursor_a_palette[i] = INREG(CURSOR_A_PALETTE0 + (i << 2)); 482 hw->cursor_a_palette[i] = INREG(CURSOR_A_PALETTE0 + (i << 2));
478 hw->cursor_b_palette[i] = INREG(CURSOR_B_PALETTE0 + (i << 2)); 483 hw->cursor_b_palette[i] = INREG(CURSOR_B_PALETTE0 + (i << 2));
479 } 484 }
480 485
481 if (flag == 7) 486 if (flag == 7)
482 return flag; 487 return flag;
483 488
484 hw->cursor_size = INREG(CURSOR_SIZE); 489 hw->cursor_size = INREG(CURSOR_SIZE);
485 490
486 if (flag == 8) 491 if (flag == 8)
487 return flag; 492 return flag;
488 493
489 hw->disp_a_ctrl = INREG(DSPACNTR); 494 hw->disp_a_ctrl = INREG(DSPACNTR);
490 hw->disp_b_ctrl = INREG(DSPBCNTR); 495 hw->disp_b_ctrl = INREG(DSPBCNTR);
491 hw->disp_a_base = INREG(DSPABASE); 496 hw->disp_a_base = INREG(DSPABASE);
492 hw->disp_b_base = INREG(DSPBBASE); 497 hw->disp_b_base = INREG(DSPBBASE);
493 hw->disp_a_stride = INREG(DSPASTRIDE); 498 hw->disp_a_stride = INREG(DSPASTRIDE);
494 hw->disp_b_stride = INREG(DSPBSTRIDE); 499 hw->disp_b_stride = INREG(DSPBSTRIDE);
495 500
496 if (flag == 9) 501 if (flag == 9)
497 return flag; 502 return flag;
498 503
499 hw->vgacntrl = INREG(VGACNTRL); 504 hw->vgacntrl = INREG(VGACNTRL);
500 505
501 if (flag == 10) 506 if (flag == 10)
502 return flag; 507 return flag;
503 508
504 hw->add_id = INREG(ADD_ID); 509 hw->add_id = INREG(ADD_ID);
505 510
506 if (flag == 11) 511 if (flag == 11)
507 return flag; 512 return flag;
508 513
509 for (i = 0; i < 7; i++) { 514 for (i = 0; i < 7; i++) {
510 hw->swf0x[i] = INREG(SWF00 + (i << 2)); 515 hw->swf0x[i] = INREG(SWF00 + (i << 2));
511 hw->swf1x[i] = INREG(SWF10 + (i << 2)); 516 hw->swf1x[i] = INREG(SWF10 + (i << 2));
512 if (i < 3) 517 if (i < 3)
513 hw->swf3x[i] = INREG(SWF30 + (i << 2)); 518 hw->swf3x[i] = INREG(SWF30 + (i << 2));
514 } 519 }
515 520
516 for (i = 0; i < 8; i++) 521 for (i = 0; i < 8; i++)
517 hw->fence[i] = INREG(FENCE + (i << 2)); 522 hw->fence[i] = INREG(FENCE + (i << 2));
518 523
519 hw->instpm = INREG(INSTPM); 524 hw->instpm = INREG(INSTPM);
520 hw->mem_mode = INREG(MEM_MODE); 525 hw->mem_mode = INREG(MEM_MODE);
521 hw->fw_blc_0 = INREG(FW_BLC_0); 526 hw->fw_blc_0 = INREG(FW_BLC_0);
522 hw->fw_blc_1 = INREG(FW_BLC_1); 527 hw->fw_blc_1 = INREG(FW_BLC_1);
523 528
524 return 0; 529 return 0;
525 } 530 }
526 531
527 532
528 void 533 void
529 intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) 534 intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
530 { 535 {
531 #if REGDUMP 536 #if REGDUMP
532 int i, m1, m2, n, p1, p2; 537 int i, m1, m2, n, p1, p2;
533 538
534 DBG_MSG("intelfbhw_print_hw_state\n"); 539 DBG_MSG("intelfbhw_print_hw_state\n");
535 540
536 if (!hw || !dinfo) 541 if (!hw || !dinfo)
537 return; 542 return;
538 /* Read in as much of the HW state as possible. */ 543 /* Read in as much of the HW state as possible. */
539 printk("hw state dump start\n"); 544 printk("hw state dump start\n");
540 printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor); 545 printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor);
541 printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor); 546 printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor);
542 printk(" VGAPD: 0x%08x\n", hw->vga_pd); 547 printk(" VGAPD: 0x%08x\n", hw->vga_pd);
543 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 548 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
544 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 549 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
545 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 550 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
546 if (hw->vga_pd & VGAPD_0_P1_FORCE_DIV2) 551 if (hw->vga_pd & VGAPD_0_P1_FORCE_DIV2)
547 p1 = 0; 552 p1 = 0;
548 else 553 else
549 p1 = (hw->vga_pd >> VGAPD_0_P1_SHIFT) & DPLL_P1_MASK; 554 p1 = (hw->vga_pd >> VGAPD_0_P1_SHIFT) & DPLL_P1_MASK;
550 p2 = (hw->vga_pd >> VGAPD_0_P2_SHIFT) & DPLL_P2_MASK; 555 p2 = (hw->vga_pd >> VGAPD_0_P2_SHIFT) & DPLL_P2_MASK;
551 printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 556 printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
552 m1, m2, n, p1, p2); 557 m1, m2, n, p1, p2);
553 printk(" VGA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 558 printk(" VGA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2));
554 559
555 n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 560 n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
556 m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 561 m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
557 m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 562 m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
558 if (hw->vga_pd & VGAPD_1_P1_FORCE_DIV2) 563 if (hw->vga_pd & VGAPD_1_P1_FORCE_DIV2)
559 p1 = 0; 564 p1 = 0;
560 else 565 else
561 p1 = (hw->vga_pd >> VGAPD_1_P1_SHIFT) & DPLL_P1_MASK; 566 p1 = (hw->vga_pd >> VGAPD_1_P1_SHIFT) & DPLL_P1_MASK;
562 p2 = (hw->vga_pd >> VGAPD_1_P2_SHIFT) & DPLL_P2_MASK; 567 p2 = (hw->vga_pd >> VGAPD_1_P2_SHIFT) & DPLL_P2_MASK;
563 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 568 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
564 m1, m2, n, p1, p2); 569 m1, m2, n, p1, p2);
565 printk(" VGA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 570 printk(" VGA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2));
566 571
567 printk(" DPLL_A: 0x%08x\n", hw->dpll_a); 572 printk(" DPLL_A: 0x%08x\n", hw->dpll_a);
568 printk(" DPLL_B: 0x%08x\n", hw->dpll_b); 573 printk(" DPLL_B: 0x%08x\n", hw->dpll_b);
569 printk(" FPA0: 0x%08x\n", hw->fpa0); 574 printk(" FPA0: 0x%08x\n", hw->fpa0);
570 printk(" FPA1: 0x%08x\n", hw->fpa1); 575 printk(" FPA1: 0x%08x\n", hw->fpa1);
571 printk(" FPB0: 0x%08x\n", hw->fpb0); 576 printk(" FPB0: 0x%08x\n", hw->fpb0);
572 printk(" FPB1: 0x%08x\n", hw->fpb1); 577 printk(" FPB1: 0x%08x\n", hw->fpb1);
573 578
574 n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 579 n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
575 m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 580 m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
576 m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 581 m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
577 if (hw->dpll_a & DPLL_P1_FORCE_DIV2) 582 if (hw->dpll_a & DPLL_P1_FORCE_DIV2)
578 p1 = 0; 583 p1 = 0;
579 else 584 else
580 p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; 585 p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK;
581 p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; 586 p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK;
582 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 587 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
583 m1, m2, n, p1, p2); 588 m1, m2, n, p1, p2);
584 printk(" PLLA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 589 printk(" PLLA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2));
585 590
586 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 591 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
587 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 592 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
588 m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 593 m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
589 if (hw->dpll_a & DPLL_P1_FORCE_DIV2) 594 if (hw->dpll_a & DPLL_P1_FORCE_DIV2)
590 p1 = 0; 595 p1 = 0;
591 else 596 else
592 p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; 597 p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK;
593 p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; 598 p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK;
594 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 599 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
595 m1, m2, n, p1, p2); 600 m1, m2, n, p1, p2);
596 printk(" PLLA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 601 printk(" PLLA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2));
597 602
598 #if 0 603 #if 0
599 printk(" PALETTE_A:\n"); 604 printk(" PALETTE_A:\n");
600 for (i = 0; i < PALETTE_8_ENTRIES) 605 for (i = 0; i < PALETTE_8_ENTRIES)
601 printk(" %3d: 0x%08x\n", i, hw->palette_a[i]; 606 printk(" %3d: 0x%08x\n", i, hw->palette_a[i];
602 printk(" PALETTE_B:\n"); 607 printk(" PALETTE_B:\n");
603 for (i = 0; i < PALETTE_8_ENTRIES) 608 for (i = 0; i < PALETTE_8_ENTRIES)
604 printk(" %3d: 0x%08x\n", i, hw->palette_b[i]; 609 printk(" %3d: 0x%08x\n", i, hw->palette_b[i];
605 #endif 610 #endif
606 611
607 printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a); 612 printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a);
608 printk(" HBLANK_A: 0x%08x\n", hw->hblank_a); 613 printk(" HBLANK_A: 0x%08x\n", hw->hblank_a);
609 printk(" HSYNC_A: 0x%08x\n", hw->hsync_a); 614 printk(" HSYNC_A: 0x%08x\n", hw->hsync_a);
610 printk(" VTOTAL_A: 0x%08x\n", hw->vtotal_a); 615 printk(" VTOTAL_A: 0x%08x\n", hw->vtotal_a);
611 printk(" VBLANK_A: 0x%08x\n", hw->vblank_a); 616 printk(" VBLANK_A: 0x%08x\n", hw->vblank_a);
612 printk(" VSYNC_A: 0x%08x\n", hw->vsync_a); 617 printk(" VSYNC_A: 0x%08x\n", hw->vsync_a);
613 printk(" SRC_SIZE_A: 0x%08x\n", hw->src_size_a); 618 printk(" SRC_SIZE_A: 0x%08x\n", hw->src_size_a);
614 printk(" BCLRPAT_A: 0x%08x\n", hw->bclrpat_a); 619 printk(" BCLRPAT_A: 0x%08x\n", hw->bclrpat_a);
615 printk(" HTOTAL_B: 0x%08x\n", hw->htotal_b); 620 printk(" HTOTAL_B: 0x%08x\n", hw->htotal_b);
616 printk(" HBLANK_B: 0x%08x\n", hw->hblank_b); 621 printk(" HBLANK_B: 0x%08x\n", hw->hblank_b);
617 printk(" HSYNC_B: 0x%08x\n", hw->hsync_b); 622 printk(" HSYNC_B: 0x%08x\n", hw->hsync_b);
618 printk(" VTOTAL_B: 0x%08x\n", hw->vtotal_b); 623 printk(" VTOTAL_B: 0x%08x\n", hw->vtotal_b);
619 printk(" VBLANK_B: 0x%08x\n", hw->vblank_b); 624 printk(" VBLANK_B: 0x%08x\n", hw->vblank_b);
620 printk(" VSYNC_B: 0x%08x\n", hw->vsync_b); 625 printk(" VSYNC_B: 0x%08x\n", hw->vsync_b);
621 printk(" SRC_SIZE_B: 0x%08x\n", hw->src_size_b); 626 printk(" SRC_SIZE_B: 0x%08x\n", hw->src_size_b);
622 printk(" BCLRPAT_B: 0x%08x\n", hw->bclrpat_b); 627 printk(" BCLRPAT_B: 0x%08x\n", hw->bclrpat_b);
623 628
624 printk(" ADPA: 0x%08x\n", hw->adpa); 629 printk(" ADPA: 0x%08x\n", hw->adpa);
625 printk(" DVOA: 0x%08x\n", hw->dvoa); 630 printk(" DVOA: 0x%08x\n", hw->dvoa);
626 printk(" DVOB: 0x%08x\n", hw->dvob); 631 printk(" DVOB: 0x%08x\n", hw->dvob);
627 printk(" DVOC: 0x%08x\n", hw->dvoc); 632 printk(" DVOC: 0x%08x\n", hw->dvoc);
628 printk(" DVOA_SRCDIM: 0x%08x\n", hw->dvoa_srcdim); 633 printk(" DVOA_SRCDIM: 0x%08x\n", hw->dvoa_srcdim);
629 printk(" DVOB_SRCDIM: 0x%08x\n", hw->dvob_srcdim); 634 printk(" DVOB_SRCDIM: 0x%08x\n", hw->dvob_srcdim);
630 printk(" DVOC_SRCDIM: 0x%08x\n", hw->dvoc_srcdim); 635 printk(" DVOC_SRCDIM: 0x%08x\n", hw->dvoc_srcdim);
631 printk(" LVDS: 0x%08x\n", hw->lvds); 636 printk(" LVDS: 0x%08x\n", hw->lvds);
632 637
633 printk(" PIPEACONF: 0x%08x\n", hw->pipe_a_conf); 638 printk(" PIPEACONF: 0x%08x\n", hw->pipe_a_conf);
634 printk(" PIPEBCONF: 0x%08x\n", hw->pipe_b_conf); 639 printk(" PIPEBCONF: 0x%08x\n", hw->pipe_b_conf);
635 printk(" DISPARB: 0x%08x\n", hw->disp_arb); 640 printk(" DISPARB: 0x%08x\n", hw->disp_arb);
636 641
637 printk(" CURSOR_A_CONTROL: 0x%08x\n", hw->cursor_a_control); 642 printk(" CURSOR_A_CONTROL: 0x%08x\n", hw->cursor_a_control);
638 printk(" CURSOR_B_CONTROL: 0x%08x\n", hw->cursor_b_control); 643 printk(" CURSOR_B_CONTROL: 0x%08x\n", hw->cursor_b_control);
639 printk(" CURSOR_A_BASEADDR: 0x%08x\n", hw->cursor_a_base); 644 printk(" CURSOR_A_BASEADDR: 0x%08x\n", hw->cursor_a_base);
640 printk(" CURSOR_B_BASEADDR: 0x%08x\n", hw->cursor_b_base); 645 printk(" CURSOR_B_BASEADDR: 0x%08x\n", hw->cursor_b_base);
641 646
642 printk(" CURSOR_A_PALETTE: "); 647 printk(" CURSOR_A_PALETTE: ");
643 for (i = 0; i < 4; i++) { 648 for (i = 0; i < 4; i++) {
644 printk("0x%08x", hw->cursor_a_palette[i]); 649 printk("0x%08x", hw->cursor_a_palette[i]);
645 if (i < 3) 650 if (i < 3)
646 printk(", "); 651 printk(", ");
647 } 652 }
648 printk("\n"); 653 printk("\n");
649 printk(" CURSOR_B_PALETTE: "); 654 printk(" CURSOR_B_PALETTE: ");
650 for (i = 0; i < 4; i++) { 655 for (i = 0; i < 4; i++) {
651 printk("0x%08x", hw->cursor_b_palette[i]); 656 printk("0x%08x", hw->cursor_b_palette[i]);
652 if (i < 3) 657 if (i < 3)
653 printk(", "); 658 printk(", ");
654 } 659 }
655 printk("\n"); 660 printk("\n");
656 661
657 printk(" CURSOR_SIZE: 0x%08x\n", hw->cursor_size); 662 printk(" CURSOR_SIZE: 0x%08x\n", hw->cursor_size);
658 663
659 printk(" DSPACNTR: 0x%08x\n", hw->disp_a_ctrl); 664 printk(" DSPACNTR: 0x%08x\n", hw->disp_a_ctrl);
660 printk(" DSPBCNTR: 0x%08x\n", hw->disp_b_ctrl); 665 printk(" DSPBCNTR: 0x%08x\n", hw->disp_b_ctrl);
661 printk(" DSPABASE: 0x%08x\n", hw->disp_a_base); 666 printk(" DSPABASE: 0x%08x\n", hw->disp_a_base);
662 printk(" DSPBBASE: 0x%08x\n", hw->disp_b_base); 667 printk(" DSPBBASE: 0x%08x\n", hw->disp_b_base);
663 printk(" DSPASTRIDE: 0x%08x\n", hw->disp_a_stride); 668 printk(" DSPASTRIDE: 0x%08x\n", hw->disp_a_stride);
664 printk(" DSPBSTRIDE: 0x%08x\n", hw->disp_b_stride); 669 printk(" DSPBSTRIDE: 0x%08x\n", hw->disp_b_stride);
665 670
666 printk(" VGACNTRL: 0x%08x\n", hw->vgacntrl); 671 printk(" VGACNTRL: 0x%08x\n", hw->vgacntrl);
667 printk(" ADD_ID: 0x%08x\n", hw->add_id); 672 printk(" ADD_ID: 0x%08x\n", hw->add_id);
668 673
669 for (i = 0; i < 7; i++) { 674 for (i = 0; i < 7; i++) {
670 printk(" SWF0%d 0x%08x\n", i, 675 printk(" SWF0%d 0x%08x\n", i,
671 hw->swf0x[i]); 676 hw->swf0x[i]);
672 } 677 }
673 for (i = 0; i < 7; i++) { 678 for (i = 0; i < 7; i++) {
674 printk(" SWF1%d 0x%08x\n", i, 679 printk(" SWF1%d 0x%08x\n", i,
675 hw->swf1x[i]); 680 hw->swf1x[i]);
676 } 681 }
677 for (i = 0; i < 3; i++) { 682 for (i = 0; i < 3; i++) {
678 printk(" SWF3%d 0x%08x\n", i, 683 printk(" SWF3%d 0x%08x\n", i,
679 hw->swf3x[i]); 684 hw->swf3x[i]);
680 } 685 }
681 for (i = 0; i < 8; i++) 686 for (i = 0; i < 8; i++)
682 printk(" FENCE%d 0x%08x\n", i, 687 printk(" FENCE%d 0x%08x\n", i,
683 hw->fence[i]); 688 hw->fence[i]);
684 689
685 printk(" INSTPM 0x%08x\n", hw->instpm); 690 printk(" INSTPM 0x%08x\n", hw->instpm);
686 printk(" MEM_MODE 0x%08x\n", hw->mem_mode); 691 printk(" MEM_MODE 0x%08x\n", hw->mem_mode);
687 printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0); 692 printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0);
688 printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1); 693 printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1);
689 694
690 printk("hw state dump end\n"); 695 printk("hw state dump end\n");
691 #endif 696 #endif
692 } 697 }
693 698
694 /* Split the M parameter into M1 and M2. */ 699 /* Split the M parameter into M1 and M2. */
695 static int 700 static int
696 splitm(unsigned int m, unsigned int *retm1, unsigned int *retm2) 701 splitm(unsigned int m, unsigned int *retm1, unsigned int *retm2)
697 { 702 {
698 int m1, m2; 703 int m1, m2;
699 704
700 m1 = (m - 2 - (MIN_M2 + MAX_M2) / 2) / 5 - 2; 705 m1 = (m - 2 - (MIN_M2 + MAX_M2) / 2) / 5 - 2;
701 if (m1 < MIN_M1) 706 if (m1 < MIN_M1)
702 m1 = MIN_M1; 707 m1 = MIN_M1;
703 if (m1 > MAX_M1) 708 if (m1 > MAX_M1)
704 m1 = MAX_M1; 709 m1 = MAX_M1;
705 m2 = m - 5 * (m1 + 2) - 2; 710 m2 = m - 5 * (m1 + 2) - 2;
706 if (m2 < MIN_M2 || m2 > MAX_M2 || m2 >= m1) { 711 if (m2 < MIN_M2 || m2 > MAX_M2 || m2 >= m1) {
707 return 1; 712 return 1;
708 } else { 713 } else {
709 *retm1 = (unsigned int)m1; 714 *retm1 = (unsigned int)m1;
710 *retm2 = (unsigned int)m2; 715 *retm2 = (unsigned int)m2;
711 return 0; 716 return 0;
712 } 717 }
713 } 718 }
714 719
715 /* Split the P parameter into P1 and P2. */ 720 /* Split the P parameter into P1 and P2. */
716 static int 721 static int
717 splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2) 722 splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2)
718 { 723 {
719 int p1, p2; 724 int p1, p2;
720 725
721 if (p % 4 == 0) 726 if (p % 4 == 0)
722 p2 = 1; 727 p2 = 1;
723 else 728 else
724 p2 = 0; 729 p2 = 0;
725 p1 = (p / (1 << (p2 + 1))) - 2; 730 p1 = (p / (1 << (p2 + 1))) - 2;
726 if (p % 4 == 0 && p1 < MIN_P1) { 731 if (p % 4 == 0 && p1 < MIN_P1) {
727 p2 = 0; 732 p2 = 0;
728 p1 = (p / (1 << (p2 + 1))) - 2; 733 p1 = (p / (1 << (p2 + 1))) - 2;
729 } 734 }
730 if (p1 < MIN_P1 || p1 > MAX_P1 || (p1 + 2) * (1 << (p2 + 1)) != p) { 735 if (p1 < MIN_P1 || p1 > MAX_P1 || (p1 + 2) * (1 << (p2 + 1)) != p) {
731 return 1; 736 return 1;
732 } else { 737 } else {
733 *retp1 = (unsigned int)p1; 738 *retp1 = (unsigned int)p1;
734 *retp2 = (unsigned int)p2; 739 *retp2 = (unsigned int)p2;
735 return 0; 740 return 0;
736 } 741 }
737 } 742 }
738 743
739 static int 744 static int
740 calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, 745 calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
741 u32 *retp2, u32 *retclock) 746 u32 *retp2, u32 *retclock)
742 { 747 {
743 u32 m1, m2, n, p1, p2, n1; 748 u32 m1, m2, n, p1, p2, n1;
744 u32 f_vco, p, p_best = 0, m, f_out; 749 u32 f_vco, p, p_best = 0, m, f_out;
745 u32 err_max, err_target, err_best = 10000000; 750 u32 err_max, err_target, err_best = 10000000;
746 u32 n_best = 0, m_best = 0, f_best, f_err; 751 u32 n_best = 0, m_best = 0, f_best, f_err;
747 u32 p_min, p_max, p_inc, div_min, div_max; 752 u32 p_min, p_max, p_inc, div_min, div_max;
748 753
749 /* Accept 0.5% difference, but aim for 0.1% */ 754 /* Accept 0.5% difference, but aim for 0.1% */
750 err_max = 5 * clock / 1000; 755 err_max = 5 * clock / 1000;
751 err_target = clock / 1000; 756 err_target = clock / 1000;
752 757
753 DBG_MSG("Clock is %d\n", clock); 758 DBG_MSG("Clock is %d\n", clock);
754 759
755 div_max = MAX_VCO_FREQ / clock; 760 div_max = MAX_VCO_FREQ / clock;
756 div_min = ROUND_UP_TO(MIN_VCO_FREQ, clock) / clock; 761 div_min = ROUND_UP_TO(MIN_VCO_FREQ, clock) / clock;
757 762
758 if (clock <= P_TRANSITION_CLOCK) 763 if (clock <= P_TRANSITION_CLOCK)
759 p_inc = 4; 764 p_inc = 4;
760 else 765 else
761 p_inc = 2; 766 p_inc = 2;
762 p_min = ROUND_UP_TO(div_min, p_inc); 767 p_min = ROUND_UP_TO(div_min, p_inc);
763 p_max = ROUND_DOWN_TO(div_max, p_inc); 768 p_max = ROUND_DOWN_TO(div_max, p_inc);
764 if (p_min < MIN_P) 769 if (p_min < MIN_P)
765 p_min = 4; 770 p_min = 4;
766 if (p_max > MAX_P) 771 if (p_max > MAX_P)
767 p_max = 128; 772 p_max = 128;
768 773
769 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); 774 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc);
770 775
771 p = p_min; 776 p = p_min;
772 do { 777 do {
773 if (splitp(p, &p1, &p2)) { 778 if (splitp(p, &p1, &p2)) {
774 WRN_MSG("cannot split p = %d\n", p); 779 WRN_MSG("cannot split p = %d\n", p);
775 p += p_inc; 780 p += p_inc;
776 continue; 781 continue;
777 } 782 }
778 n = MIN_N; 783 n = MIN_N;
779 f_vco = clock * p; 784 f_vco = clock * p;
780 785
781 do { 786 do {
782 m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK; 787 m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK;
783 if (m < MIN_M) 788 if (m < MIN_M)
784 m = MIN_M; 789 m = MIN_M;
785 if (m > MAX_M) 790 if (m > MAX_M)
786 m = MAX_M; 791 m = MAX_M;
787 f_out = CALC_VCLOCK3(m, n, p); 792 f_out = CALC_VCLOCK3(m, n, p);
788 if (splitm(m, &m1, &m2)) { 793 if (splitm(m, &m1, &m2)) {
789 WRN_MSG("cannot split m = %d\n", m); 794 WRN_MSG("cannot split m = %d\n", m);
790 n++; 795 n++;
791 continue; 796 continue;
792 } 797 }
793 if (clock > f_out) 798 if (clock > f_out)
794 f_err = clock - f_out; 799 f_err = clock - f_out;
795 else 800 else
796 f_err = f_out - clock; 801 f_err = f_out - clock;
797 802
798 if (f_err < err_best) { 803 if (f_err < err_best) {
799 m_best = m; 804 m_best = m;
800 n_best = n; 805 n_best = n;
801 p_best = p; 806 p_best = p;
802 f_best = f_out; 807 f_best = f_out;
803 err_best = f_err; 808 err_best = f_err;
804 } 809 }
805 n++; 810 n++;
806 } while ((n <= MAX_N) && (f_out >= clock)); 811 } while ((n <= MAX_N) && (f_out >= clock));
807 p += p_inc; 812 p += p_inc;
808 } while ((p <= p_max)); 813 } while ((p <= p_max));
809 814
810 if (!m_best) { 815 if (!m_best) {
811 WRN_MSG("cannot find parameters for clock %d\n", clock); 816 WRN_MSG("cannot find parameters for clock %d\n", clock);
812 return 1; 817 return 1;
813 } 818 }
814 m = m_best; 819 m = m_best;
815 n = n_best; 820 n = n_best;
816 p = p_best; 821 p = p_best;
817 splitm(m, &m1, &m2); 822 splitm(m, &m1, &m2);
818 splitp(p, &p1, &p2); 823 splitp(p, &p1, &p2);
819 n1 = n - 2; 824 n1 = n - 2;
820 825
821 DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), " 826 DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), "
822 "f: %d (%d), VCO: %d\n", 827 "f: %d (%d), VCO: %d\n",
823 m, m1, m2, n, n1, p, p1, p2, 828 m, m1, m2, n, n1, p, p1, p2,
824 CALC_VCLOCK3(m, n, p), CALC_VCLOCK(m1, m2, n1, p1, p2), 829 CALC_VCLOCK3(m, n, p), CALC_VCLOCK(m1, m2, n1, p1, p2),
825 CALC_VCLOCK3(m, n, p) * p); 830 CALC_VCLOCK3(m, n, p) * p);
826 *retm1 = m1; 831 *retm1 = m1;
827 *retm2 = m2; 832 *retm2 = m2;
828 *retn = n1; 833 *retn = n1;
829 *retp1 = p1; 834 *retp1 = p1;
830 *retp2 = p2; 835 *retp2 = p2;
831 *retclock = CALC_VCLOCK(m1, m2, n1, p1, p2); 836 *retclock = CALC_VCLOCK(m1, m2, n1, p1, p2);
832 837
833 return 0; 838 return 0;
834 } 839 }
835 840
836 static __inline__ int 841 static __inline__ int
837 check_overflow(u32 value, u32 limit, const char *description) 842 check_overflow(u32 value, u32 limit, const char *description)
838 { 843 {
839 if (value > limit) { 844 if (value > limit) {
840 WRN_MSG("%s value %d exceeds limit %d\n", 845 WRN_MSG("%s value %d exceeds limit %d\n",
841 description, value, limit); 846 description, value, limit);
842 return 1; 847 return 1;
843 } 848 }
844 return 0; 849 return 0;
845 } 850 }
846 851
847 /* It is assumed that hw is filled in with the initial state information. */ 852 /* It is assumed that hw is filled in with the initial state information. */
848 int 853 int
849 intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, 854 intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
850 struct fb_var_screeninfo *var) 855 struct fb_var_screeninfo *var)
851 { 856 {
852 int pipe = PIPE_A; 857 int pipe = PIPE_A;
853 u32 *dpll, *fp0, *fp1; 858 u32 *dpll, *fp0, *fp1;
854 u32 m1, m2, n, p1, p2, clock_target, clock; 859 u32 m1, m2, n, p1, p2, clock_target, clock;
855 u32 hsync_start, hsync_end, hblank_start, hblank_end, htotal, hactive; 860 u32 hsync_start, hsync_end, hblank_start, hblank_end, htotal, hactive;
856 u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive; 861 u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive;
857 u32 vsync_pol, hsync_pol; 862 u32 vsync_pol, hsync_pol;
858 u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf; 863 u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf;
859 864
860 DBG_MSG("intelfbhw_mode_to_hw\n"); 865 DBG_MSG("intelfbhw_mode_to_hw\n");
861 866
862 /* Disable VGA */ 867 /* Disable VGA */
863 hw->vgacntrl |= VGA_DISABLE; 868 hw->vgacntrl |= VGA_DISABLE;
864 869
865 /* Check whether pipe A or pipe B is enabled. */ 870 /* Check whether pipe A or pipe B is enabled. */
866 if (hw->pipe_a_conf & PIPECONF_ENABLE) 871 if (hw->pipe_a_conf & PIPECONF_ENABLE)
867 pipe = PIPE_A; 872 pipe = PIPE_A;
868 else if (hw->pipe_b_conf & PIPECONF_ENABLE) 873 else if (hw->pipe_b_conf & PIPECONF_ENABLE)
869 pipe = PIPE_B; 874 pipe = PIPE_B;
870 875
871 /* Set which pipe's registers will be set. */ 876 /* Set which pipe's registers will be set. */
872 if (pipe == PIPE_B) { 877 if (pipe == PIPE_B) {
873 dpll = &hw->dpll_b; 878 dpll = &hw->dpll_b;
874 fp0 = &hw->fpb0; 879 fp0 = &hw->fpb0;
875 fp1 = &hw->fpb1; 880 fp1 = &hw->fpb1;
876 hs = &hw->hsync_b; 881 hs = &hw->hsync_b;
877 hb = &hw->hblank_b; 882 hb = &hw->hblank_b;
878 ht = &hw->htotal_b; 883 ht = &hw->htotal_b;
879 vs = &hw->vsync_b; 884 vs = &hw->vsync_b;
880 vb = &hw->vblank_b; 885 vb = &hw->vblank_b;
881 vt = &hw->vtotal_b; 886 vt = &hw->vtotal_b;
882 ss = &hw->src_size_b; 887 ss = &hw->src_size_b;
883 pipe_conf = &hw->pipe_b_conf; 888 pipe_conf = &hw->pipe_b_conf;
884 } else { 889 } else {
885 dpll = &hw->dpll_a; 890 dpll = &hw->dpll_a;
886 fp0 = &hw->fpa0; 891 fp0 = &hw->fpa0;
887 fp1 = &hw->fpa1; 892 fp1 = &hw->fpa1;
888 hs = &hw->hsync_a; 893 hs = &hw->hsync_a;
889 hb = &hw->hblank_a; 894 hb = &hw->hblank_a;
890 ht = &hw->htotal_a; 895 ht = &hw->htotal_a;
891 vs = &hw->vsync_a; 896 vs = &hw->vsync_a;
892 vb = &hw->vblank_a; 897 vb = &hw->vblank_a;
893 vt = &hw->vtotal_a; 898 vt = &hw->vtotal_a;
894 ss = &hw->src_size_a; 899 ss = &hw->src_size_a;
895 pipe_conf = &hw->pipe_a_conf; 900 pipe_conf = &hw->pipe_a_conf;
896 } 901 }
897 902
898 /* Use ADPA register for sync control. */ 903 /* Use ADPA register for sync control. */
899 hw->adpa &= ~ADPA_USE_VGA_HVPOLARITY; 904 hw->adpa &= ~ADPA_USE_VGA_HVPOLARITY;
900 905
901 /* sync polarity */ 906 /* sync polarity */
902 hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 907 hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ?
903 ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW; 908 ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW;
904 vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 909 vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ?
905 ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW; 910 ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW;
906 hw->adpa &= ~((ADPA_SYNC_ACTIVE_MASK << ADPA_VSYNC_ACTIVE_SHIFT) | 911 hw->adpa &= ~((ADPA_SYNC_ACTIVE_MASK << ADPA_VSYNC_ACTIVE_SHIFT) |
907 (ADPA_SYNC_ACTIVE_MASK << ADPA_HSYNC_ACTIVE_SHIFT)); 912 (ADPA_SYNC_ACTIVE_MASK << ADPA_HSYNC_ACTIVE_SHIFT));
908 hw->adpa |= (hsync_pol << ADPA_HSYNC_ACTIVE_SHIFT) | 913 hw->adpa |= (hsync_pol << ADPA_HSYNC_ACTIVE_SHIFT) |
909 (vsync_pol << ADPA_VSYNC_ACTIVE_SHIFT); 914 (vsync_pol << ADPA_VSYNC_ACTIVE_SHIFT);
910 915
911 /* Connect correct pipe to the analog port DAC */ 916 /* Connect correct pipe to the analog port DAC */
912 hw->adpa &= ~(PIPE_MASK << ADPA_PIPE_SELECT_SHIFT); 917 hw->adpa &= ~(PIPE_MASK << ADPA_PIPE_SELECT_SHIFT);
913 hw->adpa |= (pipe << ADPA_PIPE_SELECT_SHIFT); 918 hw->adpa |= (pipe << ADPA_PIPE_SELECT_SHIFT);
914 919
915 /* Set DPMS state to D0 (on) */ 920 /* Set DPMS state to D0 (on) */
916 hw->adpa &= ~ADPA_DPMS_CONTROL_MASK; 921 hw->adpa &= ~ADPA_DPMS_CONTROL_MASK;
917 hw->adpa |= ADPA_DPMS_D0; 922 hw->adpa |= ADPA_DPMS_D0;
918 923
919 hw->adpa |= ADPA_DAC_ENABLE; 924 hw->adpa |= ADPA_DAC_ENABLE;
920 925
921 *dpll |= (DPLL_VCO_ENABLE | DPLL_VGA_MODE_DISABLE); 926 *dpll |= (DPLL_VCO_ENABLE | DPLL_VGA_MODE_DISABLE);
922 *dpll &= ~(DPLL_RATE_SELECT_MASK | DPLL_REFERENCE_SELECT_MASK); 927 *dpll &= ~(DPLL_RATE_SELECT_MASK | DPLL_REFERENCE_SELECT_MASK);
923 *dpll |= (DPLL_REFERENCE_DEFAULT | DPLL_RATE_SELECT_FP0); 928 *dpll |= (DPLL_REFERENCE_DEFAULT | DPLL_RATE_SELECT_FP0);
924 929
925 /* Desired clock in kHz */ 930 /* Desired clock in kHz */
926 clock_target = 1000000000 / var->pixclock; 931 clock_target = 1000000000 / var->pixclock;
927 932
928 if (calc_pll_params(clock_target, &m1, &m2, &n, &p1, &p2, &clock)) { 933 if (calc_pll_params(clock_target, &m1, &m2, &n, &p1, &p2, &clock)) {
929 WRN_MSG("calc_pll_params failed\n"); 934 WRN_MSG("calc_pll_params failed\n");
930 return 1; 935 return 1;
931 } 936 }
932 937
933 /* Check for overflow. */ 938 /* Check for overflow. */
934 if (check_overflow(p1, DPLL_P1_MASK, "PLL P1 parameter")) 939 if (check_overflow(p1, DPLL_P1_MASK, "PLL P1 parameter"))
935 return 1; 940 return 1;
936 if (check_overflow(p2, DPLL_P2_MASK, "PLL P2 parameter")) 941 if (check_overflow(p2, DPLL_P2_MASK, "PLL P2 parameter"))
937 return 1; 942 return 1;
938 if (check_overflow(m1, FP_DIVISOR_MASK, "PLL M1 parameter")) 943 if (check_overflow(m1, FP_DIVISOR_MASK, "PLL M1 parameter"))
939 return 1; 944 return 1;
940 if (check_overflow(m2, FP_DIVISOR_MASK, "PLL M2 parameter")) 945 if (check_overflow(m2, FP_DIVISOR_MASK, "PLL M2 parameter"))
941 return 1; 946 return 1;
942 if (check_overflow(n, FP_DIVISOR_MASK, "PLL N parameter")) 947 if (check_overflow(n, FP_DIVISOR_MASK, "PLL N parameter"))
943 return 1; 948 return 1;
944 949
945 *dpll &= ~DPLL_P1_FORCE_DIV2; 950 *dpll &= ~DPLL_P1_FORCE_DIV2;
946 *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | 951 *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) |
947 (DPLL_P1_MASK << DPLL_P1_SHIFT)); 952 (DPLL_P1_MASK << DPLL_P1_SHIFT));
948 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); 953 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT);
949 *fp0 = (n << FP_N_DIVISOR_SHIFT) | 954 *fp0 = (n << FP_N_DIVISOR_SHIFT) |
950 (m1 << FP_M1_DIVISOR_SHIFT) | 955 (m1 << FP_M1_DIVISOR_SHIFT) |
951 (m2 << FP_M2_DIVISOR_SHIFT); 956 (m2 << FP_M2_DIVISOR_SHIFT);
952 *fp1 = *fp0; 957 *fp1 = *fp0;
953 958
954 hw->dvob &= ~PORT_ENABLE; 959 hw->dvob &= ~PORT_ENABLE;
955 hw->dvoc &= ~PORT_ENABLE; 960 hw->dvoc &= ~PORT_ENABLE;
956 961
957 /* Use display plane A. */ 962 /* Use display plane A. */
958 hw->disp_a_ctrl |= DISPPLANE_PLANE_ENABLE; 963 hw->disp_a_ctrl |= DISPPLANE_PLANE_ENABLE;
959 hw->disp_a_ctrl &= ~DISPPLANE_GAMMA_ENABLE; 964 hw->disp_a_ctrl &= ~DISPPLANE_GAMMA_ENABLE;
960 hw->disp_a_ctrl &= ~DISPPLANE_PIXFORMAT_MASK; 965 hw->disp_a_ctrl &= ~DISPPLANE_PIXFORMAT_MASK;
961 switch (intelfb_var_to_depth(var)) { 966 switch (intelfb_var_to_depth(var)) {
962 case 8: 967 case 8:
963 hw->disp_a_ctrl |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE; 968 hw->disp_a_ctrl |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE;
964 break; 969 break;
965 case 15: 970 case 15:
966 hw->disp_a_ctrl |= DISPPLANE_15_16BPP; 971 hw->disp_a_ctrl |= DISPPLANE_15_16BPP;
967 break; 972 break;
968 case 16: 973 case 16:
969 hw->disp_a_ctrl |= DISPPLANE_16BPP; 974 hw->disp_a_ctrl |= DISPPLANE_16BPP;
970 break; 975 break;
971 case 24: 976 case 24:
972 hw->disp_a_ctrl |= DISPPLANE_32BPP_NO_ALPHA; 977 hw->disp_a_ctrl |= DISPPLANE_32BPP_NO_ALPHA;
973 break; 978 break;
974 } 979 }
975 hw->disp_a_ctrl &= ~(PIPE_MASK << DISPPLANE_SEL_PIPE_SHIFT); 980 hw->disp_a_ctrl &= ~(PIPE_MASK << DISPPLANE_SEL_PIPE_SHIFT);
976 hw->disp_a_ctrl |= (pipe << DISPPLANE_SEL_PIPE_SHIFT); 981 hw->disp_a_ctrl |= (pipe << DISPPLANE_SEL_PIPE_SHIFT);
977 982
978 /* Set CRTC registers. */ 983 /* Set CRTC registers. */
979 hactive = var->xres; 984 hactive = var->xres;
980 hsync_start = hactive + var->right_margin; 985 hsync_start = hactive + var->right_margin;
981 hsync_end = hsync_start + var->hsync_len; 986 hsync_end = hsync_start + var->hsync_len;
982 htotal = hsync_end + var->left_margin; 987 htotal = hsync_end + var->left_margin;
983 hblank_start = hactive; 988 hblank_start = hactive;
984 hblank_end = htotal; 989 hblank_end = htotal;
985 990
986 DBG_MSG("H: act %d, ss %d, se %d, tot %d bs %d, be %d\n", 991 DBG_MSG("H: act %d, ss %d, se %d, tot %d bs %d, be %d\n",
987 hactive, hsync_start, hsync_end, htotal, hblank_start, 992 hactive, hsync_start, hsync_end, htotal, hblank_start,
988 hblank_end); 993 hblank_end);
989 994
990 vactive = var->yres; 995 vactive = var->yres;
991 vsync_start = vactive + var->lower_margin; 996 vsync_start = vactive + var->lower_margin;
992 vsync_end = vsync_start + var->vsync_len; 997 vsync_end = vsync_start + var->vsync_len;
993 vtotal = vsync_end + var->upper_margin; 998 vtotal = vsync_end + var->upper_margin;
994 vblank_start = vactive; 999 vblank_start = vactive;
995 vblank_end = vtotal; 1000 vblank_end = vtotal;
996 vblank_end = vsync_end + 1; 1001 vblank_end = vsync_end + 1;
997 1002
998 DBG_MSG("V: act %d, ss %d, se %d, tot %d bs %d, be %d\n", 1003 DBG_MSG("V: act %d, ss %d, se %d, tot %d bs %d, be %d\n",
999 vactive, vsync_start, vsync_end, vtotal, vblank_start, 1004 vactive, vsync_start, vsync_end, vtotal, vblank_start,
1000 vblank_end); 1005 vblank_end);
1001 1006
1002 /* Adjust for register values, and check for overflow. */ 1007 /* Adjust for register values, and check for overflow. */
1003 hactive--; 1008 hactive--;
1004 if (check_overflow(hactive, HACTIVE_MASK, "CRTC hactive")) 1009 if (check_overflow(hactive, HACTIVE_MASK, "CRTC hactive"))
1005 return 1; 1010 return 1;
1006 hsync_start--; 1011 hsync_start--;
1007 if (check_overflow(hsync_start, HSYNCSTART_MASK, "CRTC hsync_start")) 1012 if (check_overflow(hsync_start, HSYNCSTART_MASK, "CRTC hsync_start"))
1008 return 1; 1013 return 1;
1009 hsync_end--; 1014 hsync_end--;
1010 if (check_overflow(hsync_end, HSYNCEND_MASK, "CRTC hsync_end")) 1015 if (check_overflow(hsync_end, HSYNCEND_MASK, "CRTC hsync_end"))
1011 return 1; 1016 return 1;
1012 htotal--; 1017 htotal--;
1013 if (check_overflow(htotal, HTOTAL_MASK, "CRTC htotal")) 1018 if (check_overflow(htotal, HTOTAL_MASK, "CRTC htotal"))
1014 return 1; 1019 return 1;
1015 hblank_start--; 1020 hblank_start--;
1016 if (check_overflow(hblank_start, HBLANKSTART_MASK, "CRTC hblank_start")) 1021 if (check_overflow(hblank_start, HBLANKSTART_MASK, "CRTC hblank_start"))
1017 return 1; 1022 return 1;
1018 hblank_end--; 1023 hblank_end--;
1019 if (check_overflow(hblank_end, HBLANKEND_MASK, "CRTC hblank_end")) 1024 if (check_overflow(hblank_end, HBLANKEND_MASK, "CRTC hblank_end"))
1020 return 1; 1025 return 1;
1021 1026
1022 vactive--; 1027 vactive--;
1023 if (check_overflow(vactive, VACTIVE_MASK, "CRTC vactive")) 1028 if (check_overflow(vactive, VACTIVE_MASK, "CRTC vactive"))
1024 return 1; 1029 return 1;
1025 vsync_start--; 1030 vsync_start--;
1026 if (check_overflow(vsync_start, VSYNCSTART_MASK, "CRTC vsync_start")) 1031 if (check_overflow(vsync_start, VSYNCSTART_MASK, "CRTC vsync_start"))
1027 return 1; 1032 return 1;
1028 vsync_end--; 1033 vsync_end--;
1029 if (check_overflow(vsync_end, VSYNCEND_MASK, "CRTC vsync_end")) 1034 if (check_overflow(vsync_end, VSYNCEND_MASK, "CRTC vsync_end"))
1030 return 1; 1035 return 1;
1031 vtotal--; 1036 vtotal--;
1032 if (check_overflow(vtotal, VTOTAL_MASK, "CRTC vtotal")) 1037 if (check_overflow(vtotal, VTOTAL_MASK, "CRTC vtotal"))
1033 return 1; 1038 return 1;
1034 vblank_start--; 1039 vblank_start--;
1035 if (check_overflow(vblank_start, VBLANKSTART_MASK, "CRTC vblank_start")) 1040 if (check_overflow(vblank_start, VBLANKSTART_MASK, "CRTC vblank_start"))
1036 return 1; 1041 return 1;
1037 vblank_end--; 1042 vblank_end--;
1038 if (check_overflow(vblank_end, VBLANKEND_MASK, "CRTC vblank_end")) 1043 if (check_overflow(vblank_end, VBLANKEND_MASK, "CRTC vblank_end"))
1039 return 1; 1044 return 1;
1040 1045
1041 *ht = (htotal << HTOTAL_SHIFT) | (hactive << HACTIVE_SHIFT); 1046 *ht = (htotal << HTOTAL_SHIFT) | (hactive << HACTIVE_SHIFT);
1042 *hb = (hblank_start << HBLANKSTART_SHIFT) | 1047 *hb = (hblank_start << HBLANKSTART_SHIFT) |
1043 (hblank_end << HSYNCEND_SHIFT); 1048 (hblank_end << HSYNCEND_SHIFT);
1044 *hs = (hsync_start << HSYNCSTART_SHIFT) | (hsync_end << HSYNCEND_SHIFT); 1049 *hs = (hsync_start << HSYNCSTART_SHIFT) | (hsync_end << HSYNCEND_SHIFT);
1045 1050
1046 *vt = (vtotal << VTOTAL_SHIFT) | (vactive << VACTIVE_SHIFT); 1051 *vt = (vtotal << VTOTAL_SHIFT) | (vactive << VACTIVE_SHIFT);
1047 *vb = (vblank_start << VBLANKSTART_SHIFT) | 1052 *vb = (vblank_start << VBLANKSTART_SHIFT) |
1048 (vblank_end << VSYNCEND_SHIFT); 1053 (vblank_end << VSYNCEND_SHIFT);
1049 *vs = (vsync_start << VSYNCSTART_SHIFT) | (vsync_end << VSYNCEND_SHIFT); 1054 *vs = (vsync_start << VSYNCSTART_SHIFT) | (vsync_end << VSYNCEND_SHIFT);
1050 *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) | 1055 *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) |
1051 (vactive << SRC_SIZE_VERT_SHIFT); 1056 (vactive << SRC_SIZE_VERT_SHIFT);
1052 1057
1053 hw->disp_a_stride = var->xres_virtual * var->bits_per_pixel / 8; 1058 hw->disp_a_stride = var->xres_virtual * var->bits_per_pixel / 8;
1054 DBG_MSG("pitch is %d\n", hw->disp_a_stride); 1059 DBG_MSG("pitch is %d\n", hw->disp_a_stride);
1055 1060
1056 hw->disp_a_base = hw->disp_a_stride * var->yoffset + 1061 hw->disp_a_base = hw->disp_a_stride * var->yoffset +
1057 var->xoffset * var->bits_per_pixel / 8; 1062 var->xoffset * var->bits_per_pixel / 8;
1058 1063
1059 hw->disp_a_base += dinfo->fb.offset << 12; 1064 hw->disp_a_base += dinfo->fb.offset << 12;
1060 1065
1061 /* Check stride alignment. */ 1066 /* Check stride alignment. */
1062 if (hw->disp_a_stride % STRIDE_ALIGNMENT != 0) { 1067 if (hw->disp_a_stride % STRIDE_ALIGNMENT != 0) {
1063 WRN_MSG("display stride %d has bad alignment %d\n", 1068 WRN_MSG("display stride %d has bad alignment %d\n",
1064 hw->disp_a_stride, STRIDE_ALIGNMENT); 1069 hw->disp_a_stride, STRIDE_ALIGNMENT);
1065 return 1; 1070 return 1;
1066 } 1071 }
1067 1072
1068 /* Set the palette to 8-bit mode. */ 1073 /* Set the palette to 8-bit mode. */
1069 *pipe_conf &= ~PIPECONF_GAMMA; 1074 *pipe_conf &= ~PIPECONF_GAMMA;
1070 return 0; 1075 return 0;
1071 } 1076 }
1072 1077
1073 /* Program a (non-VGA) video mode. */ 1078 /* Program a (non-VGA) video mode. */
1074 int 1079 int
1075 intelfbhw_program_mode(struct intelfb_info *dinfo, 1080 intelfbhw_program_mode(struct intelfb_info *dinfo,
1076 const struct intelfb_hwstate *hw, int blank) 1081 const struct intelfb_hwstate *hw, int blank)
1077 { 1082 {
1078 int pipe = PIPE_A; 1083 int pipe = PIPE_A;
1079 u32 tmp; 1084 u32 tmp;
1080 const u32 *dpll, *fp0, *fp1, *pipe_conf; 1085 const u32 *dpll, *fp0, *fp1, *pipe_conf;
1081 const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss; 1086 const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss;
1082 u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg; 1087 u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg;
1083 u32 hsync_reg, htotal_reg, hblank_reg; 1088 u32 hsync_reg, htotal_reg, hblank_reg;
1084 u32 vsync_reg, vtotal_reg, vblank_reg; 1089 u32 vsync_reg, vtotal_reg, vblank_reg;
1085 u32 src_size_reg; 1090 u32 src_size_reg;
1086 1091
1087 /* Assume single pipe, display plane A, analog CRT. */ 1092 /* Assume single pipe, display plane A, analog CRT. */
1088 1093
1089 #if VERBOSE > 0 1094 #if VERBOSE > 0
1090 DBG_MSG("intelfbhw_program_mode\n"); 1095 DBG_MSG("intelfbhw_program_mode\n");
1091 #endif 1096 #endif
1092 1097
1093 /* Disable VGA */ 1098 /* Disable VGA */
1094 tmp = INREG(VGACNTRL); 1099 tmp = INREG(VGACNTRL);
1095 tmp |= VGA_DISABLE; 1100 tmp |= VGA_DISABLE;
1096 OUTREG(VGACNTRL, tmp); 1101 OUTREG(VGACNTRL, tmp);
1097 1102
1098 /* Check whether pipe A or pipe B is enabled. */ 1103 /* Check whether pipe A or pipe B is enabled. */
1099 if (hw->pipe_a_conf & PIPECONF_ENABLE) 1104 if (hw->pipe_a_conf & PIPECONF_ENABLE)
1100 pipe = PIPE_A; 1105 pipe = PIPE_A;
1101 else if (hw->pipe_b_conf & PIPECONF_ENABLE) 1106 else if (hw->pipe_b_conf & PIPECONF_ENABLE)
1102 pipe = PIPE_B; 1107 pipe = PIPE_B;
1103 1108
1104 dinfo->pipe = pipe; 1109 dinfo->pipe = pipe;
1105 1110
1106 if (pipe == PIPE_B) { 1111 if (pipe == PIPE_B) {
1107 dpll = &hw->dpll_b; 1112 dpll = &hw->dpll_b;
1108 fp0 = &hw->fpb0; 1113 fp0 = &hw->fpb0;
1109 fp1 = &hw->fpb1; 1114 fp1 = &hw->fpb1;
1110 pipe_conf = &hw->pipe_b_conf; 1115 pipe_conf = &hw->pipe_b_conf;
1111 hs = &hw->hsync_b; 1116 hs = &hw->hsync_b;
1112 hb = &hw->hblank_b; 1117 hb = &hw->hblank_b;
1113 ht = &hw->htotal_b; 1118 ht = &hw->htotal_b;
1114 vs = &hw->vsync_b; 1119 vs = &hw->vsync_b;
1115 vb = &hw->vblank_b; 1120 vb = &hw->vblank_b;
1116 vt = &hw->vtotal_b; 1121 vt = &hw->vtotal_b;
1117 ss = &hw->src_size_b; 1122 ss = &hw->src_size_b;
1118 dpll_reg = DPLL_B; 1123 dpll_reg = DPLL_B;
1119 fp0_reg = FPB0; 1124 fp0_reg = FPB0;
1120 fp1_reg = FPB1; 1125 fp1_reg = FPB1;
1121 pipe_conf_reg = PIPEBCONF; 1126 pipe_conf_reg = PIPEBCONF;
1122 hsync_reg = HSYNC_B; 1127 hsync_reg = HSYNC_B;
1123 htotal_reg = HTOTAL_B; 1128 htotal_reg = HTOTAL_B;
1124 hblank_reg = HBLANK_B; 1129 hblank_reg = HBLANK_B;
1125 vsync_reg = VSYNC_B; 1130 vsync_reg = VSYNC_B;
1126 vtotal_reg = VTOTAL_B; 1131 vtotal_reg = VTOTAL_B;
1127 vblank_reg = VBLANK_B; 1132 vblank_reg = VBLANK_B;
1128 src_size_reg = SRC_SIZE_B; 1133 src_size_reg = SRC_SIZE_B;
1129 } else { 1134 } else {
1130 dpll = &hw->dpll_a; 1135 dpll = &hw->dpll_a;
1131 fp0 = &hw->fpa0; 1136 fp0 = &hw->fpa0;
1132 fp1 = &hw->fpa1; 1137 fp1 = &hw->fpa1;
1133 pipe_conf = &hw->pipe_a_conf; 1138 pipe_conf = &hw->pipe_a_conf;
1134 hs = &hw->hsync_a; 1139 hs = &hw->hsync_a;
1135 hb = &hw->hblank_a; 1140 hb = &hw->hblank_a;
1136 ht = &hw->htotal_a; 1141 ht = &hw->htotal_a;
1137 vs = &hw->vsync_a; 1142 vs = &hw->vsync_a;
1138 vb = &hw->vblank_a; 1143 vb = &hw->vblank_a;
1139 vt = &hw->vtotal_a; 1144 vt = &hw->vtotal_a;
1140 ss = &hw->src_size_a; 1145 ss = &hw->src_size_a;
1141 dpll_reg = DPLL_A; 1146 dpll_reg = DPLL_A;
1142 fp0_reg = FPA0; 1147 fp0_reg = FPA0;
1143 fp1_reg = FPA1; 1148 fp1_reg = FPA1;
1144 pipe_conf_reg = PIPEACONF; 1149 pipe_conf_reg = PIPEACONF;
1145 hsync_reg = HSYNC_A; 1150 hsync_reg = HSYNC_A;
1146 htotal_reg = HTOTAL_A; 1151 htotal_reg = HTOTAL_A;
1147 hblank_reg = HBLANK_A; 1152 hblank_reg = HBLANK_A;
1148 vsync_reg = VSYNC_A; 1153 vsync_reg = VSYNC_A;
1149 vtotal_reg = VTOTAL_A; 1154 vtotal_reg = VTOTAL_A;
1150 vblank_reg = VBLANK_A; 1155 vblank_reg = VBLANK_A;
1151 src_size_reg = SRC_SIZE_A; 1156 src_size_reg = SRC_SIZE_A;
1152 } 1157 }
1153 1158
1154 /* Disable planes A and B. */ 1159 /* Disable planes A and B. */
1155 tmp = INREG(DSPACNTR); 1160 tmp = INREG(DSPACNTR);
1156 tmp &= ~DISPPLANE_PLANE_ENABLE; 1161 tmp &= ~DISPPLANE_PLANE_ENABLE;
1157 OUTREG(DSPACNTR, tmp); 1162 OUTREG(DSPACNTR, tmp);
1158 tmp = INREG(DSPBCNTR); 1163 tmp = INREG(DSPBCNTR);
1159 tmp &= ~DISPPLANE_PLANE_ENABLE; 1164 tmp &= ~DISPPLANE_PLANE_ENABLE;
1160 OUTREG(DSPBCNTR, tmp); 1165 OUTREG(DSPBCNTR, tmp);
1161 1166
1162 /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ 1167 /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */
1163 mdelay(20); 1168 mdelay(20);
1164 1169
1165 /* Disable Sync */ 1170 /* Disable Sync */
1166 tmp = INREG(ADPA); 1171 tmp = INREG(ADPA);
1167 tmp &= ~ADPA_DPMS_CONTROL_MASK; 1172 tmp &= ~ADPA_DPMS_CONTROL_MASK;
1168 tmp |= ADPA_DPMS_D3; 1173 tmp |= ADPA_DPMS_D3;
1169 OUTREG(ADPA, tmp); 1174 OUTREG(ADPA, tmp);
1170 1175
1171 /* turn off pipe */ 1176 /* turn off pipe */
1172 tmp = INREG(pipe_conf_reg); 1177 tmp = INREG(pipe_conf_reg);
1173 tmp &= ~PIPECONF_ENABLE; 1178 tmp &= ~PIPECONF_ENABLE;
1174 OUTREG(pipe_conf_reg, tmp); 1179 OUTREG(pipe_conf_reg, tmp);
1175 1180
1176 /* turn off PLL */ 1181 /* turn off PLL */
1177 tmp = INREG(dpll_reg); 1182 tmp = INREG(dpll_reg);
1178 dpll_reg &= ~DPLL_VCO_ENABLE; 1183 dpll_reg &= ~DPLL_VCO_ENABLE;
1179 OUTREG(dpll_reg, tmp); 1184 OUTREG(dpll_reg, tmp);
1180 1185
1181 /* Set PLL parameters */ 1186 /* Set PLL parameters */
1182 OUTREG(dpll_reg, *dpll & ~DPLL_VCO_ENABLE); 1187 OUTREG(dpll_reg, *dpll & ~DPLL_VCO_ENABLE);
1183 OUTREG(fp0_reg, *fp0); 1188 OUTREG(fp0_reg, *fp0);
1184 OUTREG(fp1_reg, *fp1); 1189 OUTREG(fp1_reg, *fp1);
1185 1190
1186 /* Set pipe parameters */ 1191 /* Set pipe parameters */
1187 OUTREG(hsync_reg, *hs); 1192 OUTREG(hsync_reg, *hs);
1188 OUTREG(hblank_reg, *hb); 1193 OUTREG(hblank_reg, *hb);
1189 OUTREG(htotal_reg, *ht); 1194 OUTREG(htotal_reg, *ht);
1190 OUTREG(vsync_reg, *vs); 1195 OUTREG(vsync_reg, *vs);
1191 OUTREG(vblank_reg, *vb); 1196 OUTREG(vblank_reg, *vb);
1192 OUTREG(vtotal_reg, *vt); 1197 OUTREG(vtotal_reg, *vt);
1193 OUTREG(src_size_reg, *ss); 1198 OUTREG(src_size_reg, *ss);
1194 1199
1195 /* Set DVOs B/C */ 1200 /* Set DVOs B/C */
1196 OUTREG(DVOB, hw->dvob); 1201 OUTREG(DVOB, hw->dvob);
1197 OUTREG(DVOC, hw->dvoc); 1202 OUTREG(DVOC, hw->dvoc);
1198 1203
1199 /* Set ADPA */ 1204 /* Set ADPA */
1200 OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3); 1205 OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3);
1201 1206
1202 /* Enable PLL */ 1207 /* Enable PLL */
1203 tmp = INREG(dpll_reg); 1208 tmp = INREG(dpll_reg);
1204 tmp |= DPLL_VCO_ENABLE; 1209 tmp |= DPLL_VCO_ENABLE;
1205 OUTREG(dpll_reg, tmp); 1210 OUTREG(dpll_reg, tmp);
1206 1211
1207 /* Enable pipe */ 1212 /* Enable pipe */
1208 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); 1213 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE);
1209 1214
1210 /* Enable sync */ 1215 /* Enable sync */
1211 tmp = INREG(ADPA); 1216 tmp = INREG(ADPA);
1212 tmp &= ~ADPA_DPMS_CONTROL_MASK; 1217 tmp &= ~ADPA_DPMS_CONTROL_MASK;
1213 tmp |= ADPA_DPMS_D0; 1218 tmp |= ADPA_DPMS_D0;
1214 OUTREG(ADPA, tmp); 1219 OUTREG(ADPA, tmp);
1215 1220
1216 /* setup display plane */ 1221 /* setup display plane */
1217 if (dinfo->pdev->device == PCI_DEVICE_ID_INTEL_830M) { 1222 if (dinfo->pdev->device == PCI_DEVICE_ID_INTEL_830M) {
1218 /* 1223 /*
1219 * i830M errata: the display plane must be enabled 1224 * i830M errata: the display plane must be enabled
1220 * to allow writes to the other bits in the plane 1225 * to allow writes to the other bits in the plane
1221 * control register. 1226 * control register.
1222 */ 1227 */
1223 tmp = INREG(DSPACNTR); 1228 tmp = INREG(DSPACNTR);
1224 if ((tmp & DISPPLANE_PLANE_ENABLE) != DISPPLANE_PLANE_ENABLE) { 1229 if ((tmp & DISPPLANE_PLANE_ENABLE) != DISPPLANE_PLANE_ENABLE) {
1225 tmp |= DISPPLANE_PLANE_ENABLE; 1230 tmp |= DISPPLANE_PLANE_ENABLE;
1226 OUTREG(DSPACNTR, tmp); 1231 OUTREG(DSPACNTR, tmp);
1227 OUTREG(DSPACNTR, 1232 OUTREG(DSPACNTR,
1228 hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); 1233 hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE);
1229 mdelay(1); 1234 mdelay(1);
1230 } 1235 }
1231 } 1236 }
1232 1237
1233 OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); 1238 OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE);
1234 OUTREG(DSPASTRIDE, hw->disp_a_stride); 1239 OUTREG(DSPASTRIDE, hw->disp_a_stride);
1235 OUTREG(DSPABASE, hw->disp_a_base); 1240 OUTREG(DSPABASE, hw->disp_a_base);
1236 1241
1237 /* Enable plane */ 1242 /* Enable plane */
1238 if (!blank) { 1243 if (!blank) {
1239 tmp = INREG(DSPACNTR); 1244 tmp = INREG(DSPACNTR);
1240 tmp |= DISPPLANE_PLANE_ENABLE; 1245 tmp |= DISPPLANE_PLANE_ENABLE;
1241 OUTREG(DSPACNTR, tmp); 1246 OUTREG(DSPACNTR, tmp);
1242 OUTREG(DSPABASE, hw->disp_a_base); 1247 OUTREG(DSPABASE, hw->disp_a_base);
1243 } 1248 }
1244 1249
1245 return 0; 1250 return 0;
1246 } 1251 }
1247 1252
1248 /* forward declarations */ 1253 /* forward declarations */
1249 static void refresh_ring(struct intelfb_info *dinfo); 1254 static void refresh_ring(struct intelfb_info *dinfo);
1250 static void reset_state(struct intelfb_info *dinfo); 1255 static void reset_state(struct intelfb_info *dinfo);
1251 static void do_flush(struct intelfb_info *dinfo); 1256 static void do_flush(struct intelfb_info *dinfo);
1252 1257
1253 static int 1258 static int
1254 wait_ring(struct intelfb_info *dinfo, int n) 1259 wait_ring(struct intelfb_info *dinfo, int n)
1255 { 1260 {
1256 int i = 0; 1261 int i = 0;
1257 unsigned long end; 1262 unsigned long end;
1258 u32 last_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1263 u32 last_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1259 1264
1260 #if VERBOSE > 0 1265 #if VERBOSE > 0
1261 DBG_MSG("wait_ring: %d\n", n); 1266 DBG_MSG("wait_ring: %d\n", n);
1262 #endif 1267 #endif
1263 1268
1264 end = jiffies + (HZ * 3); 1269 end = jiffies + (HZ * 3);
1265 while (dinfo->ring_space < n) { 1270 while (dinfo->ring_space < n) {
1266 dinfo->ring_head = (u8 __iomem *)(INREG(PRI_RING_HEAD) & 1271 dinfo->ring_head = (u8 __iomem *)(INREG(PRI_RING_HEAD) &
1267 RING_HEAD_MASK); 1272 RING_HEAD_MASK);
1268 if (dinfo->ring_tail + RING_MIN_FREE < 1273 if (dinfo->ring_tail + RING_MIN_FREE <
1269 (u32 __iomem) dinfo->ring_head) 1274 (u32 __iomem) dinfo->ring_head)
1270 dinfo->ring_space = (u32 __iomem) dinfo->ring_head 1275 dinfo->ring_space = (u32 __iomem) dinfo->ring_head
1271 - (dinfo->ring_tail + RING_MIN_FREE); 1276 - (dinfo->ring_tail + RING_MIN_FREE);
1272 else 1277 else
1273 dinfo->ring_space = (dinfo->ring.size + 1278 dinfo->ring_space = (dinfo->ring.size +
1274 (u32 __iomem) dinfo->ring_head) 1279 (u32 __iomem) dinfo->ring_head)
1275 - (dinfo->ring_tail + RING_MIN_FREE); 1280 - (dinfo->ring_tail + RING_MIN_FREE);
1276 if ((u32 __iomem) dinfo->ring_head != last_head) { 1281 if ((u32 __iomem) dinfo->ring_head != last_head) {
1277 end = jiffies + (HZ * 3); 1282 end = jiffies + (HZ * 3);
1278 last_head = (u32 __iomem) dinfo->ring_head; 1283 last_head = (u32 __iomem) dinfo->ring_head;
1279 } 1284 }
1280 i++; 1285 i++;
1281 if (time_before(end, jiffies)) { 1286 if (time_before(end, jiffies)) {
1282 if (!i) { 1287 if (!i) {
1283 /* Try again */ 1288 /* Try again */
1284 reset_state(dinfo); 1289 reset_state(dinfo);
1285 refresh_ring(dinfo); 1290 refresh_ring(dinfo);
1286 do_flush(dinfo); 1291 do_flush(dinfo);
1287 end = jiffies + (HZ * 3); 1292 end = jiffies + (HZ * 3);
1288 i = 1; 1293 i = 1;
1289 } else { 1294 } else {
1290 WRN_MSG("ring buffer : space: %d wanted %d\n", 1295 WRN_MSG("ring buffer : space: %d wanted %d\n",
1291 dinfo->ring_space, n); 1296 dinfo->ring_space, n);
1292 WRN_MSG("lockup - turning off hardware " 1297 WRN_MSG("lockup - turning off hardware "
1293 "acceleration\n"); 1298 "acceleration\n");
1294 dinfo->ring_lockup = 1; 1299 dinfo->ring_lockup = 1;
1295 break; 1300 break;
1296 } 1301 }
1297 } 1302 }
1298 udelay(1); 1303 udelay(1);
1299 } 1304 }
1300 return i; 1305 return i;
1301 } 1306 }
1302 1307
1303 static void 1308 static void
1304 do_flush(struct intelfb_info *dinfo) { 1309 do_flush(struct intelfb_info *dinfo) {
1305 START_RING(2); 1310 START_RING(2);
1306 OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); 1311 OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
1307 OUT_RING(MI_NOOP); 1312 OUT_RING(MI_NOOP);
1308 ADVANCE_RING(); 1313 ADVANCE_RING();
1309 } 1314 }
1310 1315
1311 void 1316 void
1312 intelfbhw_do_sync(struct intelfb_info *dinfo) 1317 intelfbhw_do_sync(struct intelfb_info *dinfo)
1313 { 1318 {
1314 #if VERBOSE > 0 1319 #if VERBOSE > 0
1315 DBG_MSG("intelfbhw_do_sync\n"); 1320 DBG_MSG("intelfbhw_do_sync\n");
1316 #endif 1321 #endif
1317 1322
1318 if (!dinfo->accel) 1323 if (!dinfo->accel)
1319 return; 1324 return;
1320 1325
1321 /* 1326 /*
1322 * Send a flush, then wait until the ring is empty. This is what 1327 * Send a flush, then wait until the ring is empty. This is what
1323 * the XFree86 driver does, and actually it doesn't seem a lot worse 1328 * the XFree86 driver does, and actually it doesn't seem a lot worse
1324 * than the recommended method (both have problems). 1329 * than the recommended method (both have problems).
1325 */ 1330 */
1326 do_flush(dinfo); 1331 do_flush(dinfo);
1327 wait_ring(dinfo, dinfo->ring.size - RING_MIN_FREE); 1332 wait_ring(dinfo, dinfo->ring.size - RING_MIN_FREE);
1328 dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE; 1333 dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE;
1329 } 1334 }
1330 1335
1331 static void 1336 static void
1332 refresh_ring(struct intelfb_info *dinfo) 1337 refresh_ring(struct intelfb_info *dinfo)
1333 { 1338 {
1334 #if VERBOSE > 0 1339 #if VERBOSE > 0
1335 DBG_MSG("refresh_ring\n"); 1340 DBG_MSG("refresh_ring\n");
1336 #endif 1341 #endif
1337 1342
1338 dinfo->ring_head = (u8 __iomem *) (INREG(PRI_RING_HEAD) & 1343 dinfo->ring_head = (u8 __iomem *) (INREG(PRI_RING_HEAD) &
1339 RING_HEAD_MASK); 1344 RING_HEAD_MASK);
1340 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; 1345 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
1341 if (dinfo->ring_tail + RING_MIN_FREE < (u32 __iomem)dinfo->ring_head) 1346 if (dinfo->ring_tail + RING_MIN_FREE < (u32 __iomem)dinfo->ring_head)
1342 dinfo->ring_space = (u32 __iomem) dinfo->ring_head 1347 dinfo->ring_space = (u32 __iomem) dinfo->ring_head
1343 - (dinfo->ring_tail + RING_MIN_FREE); 1348 - (dinfo->ring_tail + RING_MIN_FREE);
1344 else 1349 else
1345 dinfo->ring_space = (dinfo->ring.size + 1350 dinfo->ring_space = (dinfo->ring.size +
1346 (u32 __iomem) dinfo->ring_head) 1351 (u32 __iomem) dinfo->ring_head)
1347 - (dinfo->ring_tail + RING_MIN_FREE); 1352 - (dinfo->ring_tail + RING_MIN_FREE);
1348 } 1353 }
1349 1354
1350 static void 1355 static void
1351 reset_state(struct intelfb_info *dinfo) 1356 reset_state(struct intelfb_info *dinfo)
1352 { 1357 {
1353 int i; 1358 int i;
1354 u32 tmp; 1359 u32 tmp;
1355 1360
1356 #if VERBOSE > 0 1361 #if VERBOSE > 0
1357 DBG_MSG("reset_state\n"); 1362 DBG_MSG("reset_state\n");
1358 #endif 1363 #endif
1359 1364
1360 for (i = 0; i < FENCE_NUM; i++) 1365 for (i = 0; i < FENCE_NUM; i++)
1361 OUTREG(FENCE + (i << 2), 0); 1366 OUTREG(FENCE + (i << 2), 0);
1362 1367
1363 /* Flush the ring buffer if it's enabled. */ 1368 /* Flush the ring buffer if it's enabled. */
1364 tmp = INREG(PRI_RING_LENGTH); 1369 tmp = INREG(PRI_RING_LENGTH);
1365 if (tmp & RING_ENABLE) { 1370 if (tmp & RING_ENABLE) {
1366 #if VERBOSE > 0 1371 #if VERBOSE > 0
1367 DBG_MSG("reset_state: ring was enabled\n"); 1372 DBG_MSG("reset_state: ring was enabled\n");
1368 #endif 1373 #endif
1369 refresh_ring(dinfo); 1374 refresh_ring(dinfo);
1370 intelfbhw_do_sync(dinfo); 1375 intelfbhw_do_sync(dinfo);
1371 DO_RING_IDLE(); 1376 DO_RING_IDLE();
1372 } 1377 }
1373 1378
1374 OUTREG(PRI_RING_LENGTH, 0); 1379 OUTREG(PRI_RING_LENGTH, 0);
1375 OUTREG(PRI_RING_HEAD, 0); 1380 OUTREG(PRI_RING_HEAD, 0);
1376 OUTREG(PRI_RING_TAIL, 0); 1381 OUTREG(PRI_RING_TAIL, 0);
1377 OUTREG(PRI_RING_START, 0); 1382 OUTREG(PRI_RING_START, 0);
1378 } 1383 }
1379 1384
1380 /* Stop the 2D engine, and turn off the ring buffer. */ 1385 /* Stop the 2D engine, and turn off the ring buffer. */
1381 void 1386 void
1382 intelfbhw_2d_stop(struct intelfb_info *dinfo) 1387 intelfbhw_2d_stop(struct intelfb_info *dinfo)
1383 { 1388 {
1384 #if VERBOSE > 0 1389 #if VERBOSE > 0
1385 DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", dinfo->accel, 1390 DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", dinfo->accel,
1386 dinfo->ring_active); 1391 dinfo->ring_active);
1387 #endif 1392 #endif
1388 1393
1389 if (!dinfo->accel) 1394 if (!dinfo->accel)
1390 return; 1395 return;
1391 1396
1392 dinfo->ring_active = 0; 1397 dinfo->ring_active = 0;
1393 reset_state(dinfo); 1398 reset_state(dinfo);
1394 } 1399 }
1395 1400
1396 /* 1401 /*
1397 * Enable the ring buffer, and initialise the 2D engine. 1402 * Enable the ring buffer, and initialise the 2D engine.
1398 * It is assumed that the graphics engine has been stopped by previously 1403 * It is assumed that the graphics engine has been stopped by previously
1399 * calling intelfb_2d_stop(). 1404 * calling intelfb_2d_stop().
1400 */ 1405 */
1401 void 1406 void
1402 intelfbhw_2d_start(struct intelfb_info *dinfo) 1407 intelfbhw_2d_start(struct intelfb_info *dinfo)
1403 { 1408 {
1404 #if VERBOSE > 0 1409 #if VERBOSE > 0
1405 DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n", 1410 DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n",
1406 dinfo->accel, dinfo->ring_active); 1411 dinfo->accel, dinfo->ring_active);
1407 #endif 1412 #endif
1408 1413
1409 if (!dinfo->accel) 1414 if (!dinfo->accel)
1410 return; 1415 return;
1411 1416
1412 /* Initialise the primary ring buffer. */ 1417 /* Initialise the primary ring buffer. */
1413 OUTREG(PRI_RING_LENGTH, 0); 1418 OUTREG(PRI_RING_LENGTH, 0);
1414 OUTREG(PRI_RING_TAIL, 0); 1419 OUTREG(PRI_RING_TAIL, 0);
1415 OUTREG(PRI_RING_HEAD, 0); 1420 OUTREG(PRI_RING_HEAD, 0);
1416 1421
1417 OUTREG(PRI_RING_START, dinfo->ring.physical & RING_START_MASK); 1422 OUTREG(PRI_RING_START, dinfo->ring.physical & RING_START_MASK);
1418 OUTREG(PRI_RING_LENGTH, 1423 OUTREG(PRI_RING_LENGTH,
1419 ((dinfo->ring.size - GTT_PAGE_SIZE) & RING_LENGTH_MASK) | 1424 ((dinfo->ring.size - GTT_PAGE_SIZE) & RING_LENGTH_MASK) |
1420 RING_NO_REPORT | RING_ENABLE); 1425 RING_NO_REPORT | RING_ENABLE);
1421 refresh_ring(dinfo); 1426 refresh_ring(dinfo);
1422 dinfo->ring_active = 1; 1427 dinfo->ring_active = 1;
1423 } 1428 }
1424 1429
1425 /* 2D fillrect (solid fill or invert) */ 1430 /* 2D fillrect (solid fill or invert) */
1426 void 1431 void
1427 intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, u32 h, 1432 intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, u32 h,
1428 u32 color, u32 pitch, u32 bpp, u32 rop) 1433 u32 color, u32 pitch, u32 bpp, u32 rop)
1429 { 1434 {
1430 u32 br00, br09, br13, br14, br16; 1435 u32 br00, br09, br13, br14, br16;
1431 1436
1432 #if VERBOSE > 0 1437 #if VERBOSE > 0
1433 DBG_MSG("intelfbhw_do_fillrect: (%d,%d) %dx%d, c 0x%06x, p %d bpp %d, " 1438 DBG_MSG("intelfbhw_do_fillrect: (%d,%d) %dx%d, c 0x%06x, p %d bpp %d, "
1434 "rop 0x%02x\n", x, y, w, h, color, pitch, bpp, rop); 1439 "rop 0x%02x\n", x, y, w, h, color, pitch, bpp, rop);
1435 #endif 1440 #endif
1436 1441
1437 br00 = COLOR_BLT_CMD; 1442 br00 = COLOR_BLT_CMD;
1438 br09 = dinfo->fb_start + (y * pitch + x * (bpp / 8)); 1443 br09 = dinfo->fb_start + (y * pitch + x * (bpp / 8));
1439 br13 = (rop << ROP_SHIFT) | pitch; 1444 br13 = (rop << ROP_SHIFT) | pitch;
1440 br14 = (h << HEIGHT_SHIFT) | ((w * (bpp / 8)) << WIDTH_SHIFT); 1445 br14 = (h << HEIGHT_SHIFT) | ((w * (bpp / 8)) << WIDTH_SHIFT);
1441 br16 = color; 1446 br16 = color;
1442 1447
1443 switch (bpp) { 1448 switch (bpp) {
1444 case 8: 1449 case 8:
1445 br13 |= COLOR_DEPTH_8; 1450 br13 |= COLOR_DEPTH_8;
1446 break; 1451 break;
1447 case 16: 1452 case 16:
1448 br13 |= COLOR_DEPTH_16; 1453 br13 |= COLOR_DEPTH_16;
1449 break; 1454 break;
1450 case 32: 1455 case 32:
1451 br13 |= COLOR_DEPTH_32; 1456 br13 |= COLOR_DEPTH_32;
1452 br00 |= WRITE_ALPHA | WRITE_RGB; 1457 br00 |= WRITE_ALPHA | WRITE_RGB;
1453 break; 1458 break;
1454 } 1459 }
1455 1460
1456 START_RING(6); 1461 START_RING(6);
1457 OUT_RING(br00); 1462 OUT_RING(br00);
1458 OUT_RING(br13); 1463 OUT_RING(br13);
1459 OUT_RING(br14); 1464 OUT_RING(br14);
1460 OUT_RING(br09); 1465 OUT_RING(br09);
1461 OUT_RING(br16); 1466 OUT_RING(br16);
1462 OUT_RING(MI_NOOP); 1467 OUT_RING(MI_NOOP);
1463 ADVANCE_RING(); 1468 ADVANCE_RING();
1464 1469
1465 #if VERBOSE > 0 1470 #if VERBOSE > 0
1466 DBG_MSG("ring = 0x%08x, 0x%08x (%d)\n", dinfo->ring_head, 1471 DBG_MSG("ring = 0x%08x, 0x%08x (%d)\n", dinfo->ring_head,
1467 dinfo->ring_tail, dinfo->ring_space); 1472 dinfo->ring_tail, dinfo->ring_space);
1468 #endif 1473 #endif
1469 } 1474 }
1470 1475
1471 void 1476 void
1472 intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury, 1477 intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury,
1473 u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch, u32 bpp) 1478 u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch, u32 bpp)
1474 { 1479 {
1475 u32 br00, br09, br11, br12, br13, br22, br23, br26; 1480 u32 br00, br09, br11, br12, br13, br22, br23, br26;
1476 1481
1477 #if VERBOSE > 0 1482 #if VERBOSE > 0
1478 DBG_MSG("intelfbhw_do_bitblt: (%d,%d)->(%d,%d) %dx%d, p %d bpp %d\n", 1483 DBG_MSG("intelfbhw_do_bitblt: (%d,%d)->(%d,%d) %dx%d, p %d bpp %d\n",
1479 curx, cury, dstx, dsty, w, h, pitch, bpp); 1484 curx, cury, dstx, dsty, w, h, pitch, bpp);
1480 #endif 1485 #endif
1481 1486
1482 br00 = XY_SRC_COPY_BLT_CMD; 1487 br00 = XY_SRC_COPY_BLT_CMD;
1483 br09 = dinfo->fb_start; 1488 br09 = dinfo->fb_start;
1484 br11 = (pitch << PITCH_SHIFT); 1489 br11 = (pitch << PITCH_SHIFT);
1485 br12 = dinfo->fb_start; 1490 br12 = dinfo->fb_start;
1486 br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT); 1491 br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT);
1487 br22 = (dstx << WIDTH_SHIFT) | (dsty << HEIGHT_SHIFT); 1492 br22 = (dstx << WIDTH_SHIFT) | (dsty << HEIGHT_SHIFT);
1488 br23 = ((dstx + w) << WIDTH_SHIFT) | 1493 br23 = ((dstx + w) << WIDTH_SHIFT) |
1489 ((dsty + h) << HEIGHT_SHIFT); 1494 ((dsty + h) << HEIGHT_SHIFT);
1490 br26 = (curx << WIDTH_SHIFT) | (cury << HEIGHT_SHIFT); 1495 br26 = (curx << WIDTH_SHIFT) | (cury << HEIGHT_SHIFT);
1491 1496
1492 switch (bpp) { 1497 switch (bpp) {
1493 case 8: 1498 case 8:
1494 br13 |= COLOR_DEPTH_8; 1499 br13 |= COLOR_DEPTH_8;
1495 break; 1500 break;
1496 case 16: 1501 case 16:
1497 br13 |= COLOR_DEPTH_16; 1502 br13 |= COLOR_DEPTH_16;
1498 break; 1503 break;
1499 case 32: 1504 case 32:
1500 br13 |= COLOR_DEPTH_32; 1505 br13 |= COLOR_DEPTH_32;
1501 br00 |= WRITE_ALPHA | WRITE_RGB; 1506 br00 |= WRITE_ALPHA | WRITE_RGB;
1502 break; 1507 break;
1503 } 1508 }
1504 1509
1505 START_RING(8); 1510 START_RING(8);
1506 OUT_RING(br00); 1511 OUT_RING(br00);
1507 OUT_RING(br13); 1512 OUT_RING(br13);
1508 OUT_RING(br22); 1513 OUT_RING(br22);
1509 OUT_RING(br23); 1514 OUT_RING(br23);
1510 OUT_RING(br09); 1515 OUT_RING(br09);
1511 OUT_RING(br26); 1516 OUT_RING(br26);
1512 OUT_RING(br11); 1517 OUT_RING(br11);
1513 OUT_RING(br12); 1518 OUT_RING(br12);
1514 ADVANCE_RING(); 1519 ADVANCE_RING();
1515 } 1520 }
1516 1521
1517 int 1522 int
1518 intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w, 1523 intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
1519 u32 h, const u8* cdat, u32 x, u32 y, u32 pitch, u32 bpp) 1524 u32 h, const u8* cdat, u32 x, u32 y, u32 pitch, u32 bpp)
1520 { 1525 {
1521 int nbytes, ndwords, pad, tmp; 1526 int nbytes, ndwords, pad, tmp;
1522 u32 br00, br09, br13, br18, br19, br22, br23; 1527 u32 br00, br09, br13, br18, br19, br22, br23;
1523 int dat, ix, iy, iw; 1528 int dat, ix, iy, iw;
1524 int i, j; 1529 int i, j;
1525 1530
1526 #if VERBOSE > 0 1531 #if VERBOSE > 0
1527 DBG_MSG("intelfbhw_do_drawglyph: (%d,%d) %dx%d\n", x, y, w, h); 1532 DBG_MSG("intelfbhw_do_drawglyph: (%d,%d) %dx%d\n", x, y, w, h);
1528 #endif 1533 #endif
1529 1534
1530 /* size in bytes of a padded scanline */ 1535 /* size in bytes of a padded scanline */
1531 nbytes = ROUND_UP_TO(w, 16) / 8; 1536 nbytes = ROUND_UP_TO(w, 16) / 8;
1532 1537
1533 /* Total bytes of padded scanline data to write out. */ 1538 /* Total bytes of padded scanline data to write out. */
1534 nbytes = nbytes * h; 1539 nbytes = nbytes * h;
1535 1540
1536 /* 1541 /*
1537 * Check if the glyph data exceeds the immediate mode limit. 1542 * Check if the glyph data exceeds the immediate mode limit.
1538 * It would take a large font (1K pixels) to hit this limit. 1543 * It would take a large font (1K pixels) to hit this limit.
1539 */ 1544 */
1540 if (nbytes > MAX_MONO_IMM_SIZE) 1545 if (nbytes > MAX_MONO_IMM_SIZE)
1541 return 0; 1546 return 0;
1542 1547
1543 /* Src data is packaged a dword (32-bit) at a time. */ 1548 /* Src data is packaged a dword (32-bit) at a time. */
1544 ndwords = ROUND_UP_TO(nbytes, 4) / 4; 1549 ndwords = ROUND_UP_TO(nbytes, 4) / 4;
1545 1550
1546 /* 1551 /*
1547 * Ring has to be padded to a quad word. But because the command starts 1552 * Ring has to be padded to a quad word. But because the command starts
1548 with 7 bytes, pad only if there is an even number of ndwords 1553 with 7 bytes, pad only if there is an even number of ndwords
1549 */ 1554 */
1550 pad = !(ndwords % 2); 1555 pad = !(ndwords % 2);
1551 1556
1552 tmp = (XY_MONO_SRC_IMM_BLT_CMD & DW_LENGTH_MASK) + ndwords; 1557 tmp = (XY_MONO_SRC_IMM_BLT_CMD & DW_LENGTH_MASK) + ndwords;
1553 br00 = (XY_MONO_SRC_IMM_BLT_CMD & ~DW_LENGTH_MASK) | tmp; 1558 br00 = (XY_MONO_SRC_IMM_BLT_CMD & ~DW_LENGTH_MASK) | tmp;
1554 br09 = dinfo->fb_start; 1559 br09 = dinfo->fb_start;
1555 br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT); 1560 br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT);
1556 br18 = bg; 1561 br18 = bg;
1557 br19 = fg; 1562 br19 = fg;
1558 br22 = (x << WIDTH_SHIFT) | (y << HEIGHT_SHIFT); 1563 br22 = (x << WIDTH_SHIFT) | (y << HEIGHT_SHIFT);
1559 br23 = ((x + w) << WIDTH_SHIFT) | ((y + h) << HEIGHT_SHIFT); 1564 br23 = ((x + w) << WIDTH_SHIFT) | ((y + h) << HEIGHT_SHIFT);
1560 1565
1561 switch (bpp) { 1566 switch (bpp) {
1562 case 8: 1567 case 8:
1563 br13 |= COLOR_DEPTH_8; 1568 br13 |= COLOR_DEPTH_8;
1564 break; 1569 break;
1565 case 16: 1570 case 16:
1566 br13 |= COLOR_DEPTH_16; 1571 br13 |= COLOR_DEPTH_16;
1567 break; 1572 break;
1568 case 32: 1573 case 32:
1569 br13 |= COLOR_DEPTH_32; 1574 br13 |= COLOR_DEPTH_32;
1570 br00 |= WRITE_ALPHA | WRITE_RGB; 1575 br00 |= WRITE_ALPHA | WRITE_RGB;
1571 break; 1576 break;
1572 } 1577 }
1573 1578
1574 START_RING(8 + ndwords); 1579 START_RING(8 + ndwords);
1575 OUT_RING(br00); 1580 OUT_RING(br00);
1576 OUT_RING(br13); 1581 OUT_RING(br13);
1577 OUT_RING(br22); 1582 OUT_RING(br22);
1578 OUT_RING(br23); 1583 OUT_RING(br23);
1579 OUT_RING(br09); 1584 OUT_RING(br09);
1580 OUT_RING(br18); 1585 OUT_RING(br18);
1581 OUT_RING(br19); 1586 OUT_RING(br19);
1582 ix = iy = 0; 1587 ix = iy = 0;
1583 iw = ROUND_UP_TO(w, 8) / 8; 1588 iw = ROUND_UP_TO(w, 8) / 8;
1584 while (ndwords--) { 1589 while (ndwords--) {
1585 dat = 0; 1590 dat = 0;
1586 for (j = 0; j < 2; ++j) { 1591 for (j = 0; j < 2; ++j) {
1587 for (i = 0; i < 2; ++i) { 1592 for (i = 0; i < 2; ++i) {
1588 if (ix != iw || i == 0) 1593 if (ix != iw || i == 0)
1589 dat |= cdat[iy*iw + ix++] << (i+j*2)*8; 1594 dat |= cdat[iy*iw + ix++] << (i+j*2)*8;
1590 } 1595 }
1591 if (ix == iw && iy != (h-1)) { 1596 if (ix == iw && iy != (h-1)) {
1592 ix = 0; 1597 ix = 0;
1593 ++iy; 1598 ++iy;
1594 } 1599 }
1595 } 1600 }
1596 OUT_RING(dat); 1601 OUT_RING(dat);
1597 } 1602 }
1598 if (pad) 1603 if (pad)
1599 OUT_RING(MI_NOOP); 1604 OUT_RING(MI_NOOP);
1600 ADVANCE_RING(); 1605 ADVANCE_RING();
1601 1606
1602 return 1; 1607 return 1;
1603 } 1608 }
1604 1609
1605 /* HW cursor functions. */ 1610 /* HW cursor functions. */
1606 void 1611 void
1607 intelfbhw_cursor_init(struct intelfb_info *dinfo) 1612 intelfbhw_cursor_init(struct intelfb_info *dinfo)
1608 { 1613 {
1609 u32 tmp; 1614 u32 tmp;
1610 1615
1611 #if VERBOSE > 0 1616 #if VERBOSE > 0
1612 DBG_MSG("intelfbhw_cursor_init\n"); 1617 DBG_MSG("intelfbhw_cursor_init\n");
1613 #endif 1618 #endif
1614 1619
1615 if (dinfo->mobile) { 1620 if (dinfo->mobile) {
1616 if (!dinfo->cursor.physical) 1621 if (!dinfo->cursor.physical)
1617 return; 1622 return;
1618 tmp = INREG(CURSOR_A_CONTROL); 1623 tmp = INREG(CURSOR_A_CONTROL);
1619 tmp &= ~(CURSOR_MODE_MASK | CURSOR_MOBILE_GAMMA_ENABLE | 1624 tmp &= ~(CURSOR_MODE_MASK | CURSOR_MOBILE_GAMMA_ENABLE |
1620 CURSOR_MEM_TYPE_LOCAL | 1625 CURSOR_MEM_TYPE_LOCAL |
1621 (1 << CURSOR_PIPE_SELECT_SHIFT)); 1626 (1 << CURSOR_PIPE_SELECT_SHIFT));
1622 tmp |= CURSOR_MODE_DISABLE; 1627 tmp |= CURSOR_MODE_DISABLE;
1623 OUTREG(CURSOR_A_CONTROL, tmp); 1628 OUTREG(CURSOR_A_CONTROL, tmp);
1624 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1629 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1625 } else { 1630 } else {
1626 tmp = INREG(CURSOR_CONTROL); 1631 tmp = INREG(CURSOR_CONTROL);
1627 tmp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE | 1632 tmp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
1628 CURSOR_ENABLE | CURSOR_STRIDE_MASK); 1633 CURSOR_ENABLE | CURSOR_STRIDE_MASK);
1629 tmp = CURSOR_FORMAT_3C; 1634 tmp = CURSOR_FORMAT_3C;
1630 OUTREG(CURSOR_CONTROL, tmp); 1635 OUTREG(CURSOR_CONTROL, tmp);
1631 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.offset << 12); 1636 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.offset << 12);
1632 tmp = (64 << CURSOR_SIZE_H_SHIFT) | 1637 tmp = (64 << CURSOR_SIZE_H_SHIFT) |
1633 (64 << CURSOR_SIZE_V_SHIFT); 1638 (64 << CURSOR_SIZE_V_SHIFT);
1634 OUTREG(CURSOR_SIZE, tmp); 1639 OUTREG(CURSOR_SIZE, tmp);
1635 } 1640 }
1636 } 1641 }
1637 1642
1638 void 1643 void
1639 intelfbhw_cursor_hide(struct intelfb_info *dinfo) 1644 intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1640 { 1645 {
1641 u32 tmp; 1646 u32 tmp;
1642 1647
1643 #if VERBOSE > 0 1648 #if VERBOSE > 0
1644 DBG_MSG("intelfbhw_cursor_hide\n"); 1649 DBG_MSG("intelfbhw_cursor_hide\n");
1645 #endif 1650 #endif
1646 1651
1647 dinfo->cursor_on = 0; 1652 dinfo->cursor_on = 0;
1648 if (dinfo->mobile) { 1653 if (dinfo->mobile) {
1649 if (!dinfo->cursor.physical) 1654 if (!dinfo->cursor.physical)
1650 return; 1655 return;
1651 tmp = INREG(CURSOR_A_CONTROL); 1656 tmp = INREG(CURSOR_A_CONTROL);
1652 tmp &= ~CURSOR_MODE_MASK; 1657 tmp &= ~CURSOR_MODE_MASK;
1653 tmp |= CURSOR_MODE_DISABLE; 1658 tmp |= CURSOR_MODE_DISABLE;
1654 OUTREG(CURSOR_A_CONTROL, tmp); 1659 OUTREG(CURSOR_A_CONTROL, tmp);
1655 /* Flush changes */ 1660 /* Flush changes */
1656 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1661 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1657 } else { 1662 } else {
1658 tmp = INREG(CURSOR_CONTROL); 1663 tmp = INREG(CURSOR_CONTROL);
1659 tmp &= ~CURSOR_ENABLE; 1664 tmp &= ~CURSOR_ENABLE;
1660 OUTREG(CURSOR_CONTROL, tmp); 1665 OUTREG(CURSOR_CONTROL, tmp);
1661 } 1666 }
1662 } 1667 }
1663 1668
1664 void 1669 void
1665 intelfbhw_cursor_show(struct intelfb_info *dinfo) 1670 intelfbhw_cursor_show(struct intelfb_info *dinfo)
1666 { 1671 {
1667 u32 tmp; 1672 u32 tmp;
1668 1673
1669 #if VERBOSE > 0 1674 #if VERBOSE > 0
1670 DBG_MSG("intelfbhw_cursor_show\n"); 1675 DBG_MSG("intelfbhw_cursor_show\n");
1671 #endif 1676 #endif
1672 1677
1673 dinfo->cursor_on = 1; 1678 dinfo->cursor_on = 1;
1674 1679
1675 if (dinfo->cursor_blanked) 1680 if (dinfo->cursor_blanked)
1676 return; 1681 return;
1677 1682
1678 if (dinfo->mobile) { 1683 if (dinfo->mobile) {
1679 if (!dinfo->cursor.physical) 1684 if (!dinfo->cursor.physical)
1680 return; 1685 return;
1681 tmp = INREG(CURSOR_A_CONTROL); 1686 tmp = INREG(CURSOR_A_CONTROL);
1682 tmp &= ~CURSOR_MODE_MASK; 1687 tmp &= ~CURSOR_MODE_MASK;
1683 tmp |= CURSOR_MODE_64_4C_AX; 1688 tmp |= CURSOR_MODE_64_4C_AX;
1684 OUTREG(CURSOR_A_CONTROL, tmp); 1689 OUTREG(CURSOR_A_CONTROL, tmp);
1685 /* Flush changes */ 1690 /* Flush changes */
1686 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1691 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1687 } else { 1692 } else {
1688 tmp = INREG(CURSOR_CONTROL); 1693 tmp = INREG(CURSOR_CONTROL);
1689 tmp |= CURSOR_ENABLE; 1694 tmp |= CURSOR_ENABLE;
1690 OUTREG(CURSOR_CONTROL, tmp); 1695 OUTREG(CURSOR_CONTROL, tmp);
1691 } 1696 }
1692 } 1697 }
1693 1698
1694 void 1699 void
1695 intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y) 1700 intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1696 { 1701 {
1697 u32 tmp; 1702 u32 tmp;
1698 1703
1699 #if VERBOSE > 0 1704 #if VERBOSE > 0
1700 DBG_MSG("intelfbhw_cursor_setpos: (%d, %d)\n", x, y); 1705 DBG_MSG("intelfbhw_cursor_setpos: (%d, %d)\n", x, y);
1701 #endif 1706 #endif
1702 1707
1703 /* 1708 /*
1704 * Sets the position. The coordinates are assumed to already 1709 * Sets the position. The coordinates are assumed to already
1705 * have any offset adjusted. Assume that the cursor is never 1710 * have any offset adjusted. Assume that the cursor is never
1706 * completely off-screen, and that x, y are always >= 0. 1711 * completely off-screen, and that x, y are always >= 0.
1707 */ 1712 */
1708 1713
1709 tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | 1714 tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |
1710 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); 1715 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1711 OUTREG(CURSOR_A_POSITION, tmp); 1716 OUTREG(CURSOR_A_POSITION, tmp);
1712 } 1717 }
1713 1718
1714 void 1719 void
1715 intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg) 1720 intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1716 { 1721 {
1717 #if VERBOSE > 0 1722 #if VERBOSE > 0
1718 DBG_MSG("intelfbhw_cursor_setcolor\n"); 1723 DBG_MSG("intelfbhw_cursor_setcolor\n");
1719 #endif 1724 #endif
1720 1725
1721 OUTREG(CURSOR_A_PALETTE0, bg & CURSOR_PALETTE_MASK); 1726 OUTREG(CURSOR_A_PALETTE0, bg & CURSOR_PALETTE_MASK);
1722 OUTREG(CURSOR_A_PALETTE1, fg & CURSOR_PALETTE_MASK); 1727 OUTREG(CURSOR_A_PALETTE1, fg & CURSOR_PALETTE_MASK);
1723 OUTREG(CURSOR_A_PALETTE2, fg & CURSOR_PALETTE_MASK); 1728 OUTREG(CURSOR_A_PALETTE2, fg & CURSOR_PALETTE_MASK);
1724 OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK); 1729 OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK);
1725 } 1730 }
1726 1731
1727 void 1732 void
1728 intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height, 1733 intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
1729 u8 *data) 1734 u8 *data)
1730 { 1735 {
1731 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1736 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1732 int i, j, w = width / 8; 1737 int i, j, w = width / 8;
1733 int mod = width % 8, t_mask, d_mask; 1738 int mod = width % 8, t_mask, d_mask;
1734 1739
1735 #if VERBOSE > 0 1740 #if VERBOSE > 0
1736 DBG_MSG("intelfbhw_cursor_load\n"); 1741 DBG_MSG("intelfbhw_cursor_load\n");
1737 #endif 1742 #endif
1738 1743
1739 if (!dinfo->cursor.virtual) 1744 if (!dinfo->cursor.virtual)
1740 return; 1745 return;
1741 1746
1742 t_mask = 0xff >> mod; 1747 t_mask = 0xff >> mod;
1743 d_mask = ~(0xff >> mod); 1748 d_mask = ~(0xff >> mod);
1744 for (i = height; i--; ) { 1749 for (i = height; i--; ) {
1745 for (j = 0; j < w; j++) { 1750 for (j = 0; j < w; j++) {
1746 writeb(0x00, addr + j); 1751 writeb(0x00, addr + j);
1747 writeb(*(data++), addr + j+8); 1752 writeb(*(data++), addr + j+8);
1748 } 1753 }
1749 if (mod) { 1754 if (mod) {
1750 writeb(t_mask, addr + j); 1755 writeb(t_mask, addr + j);
1751 writeb(*(data++) & d_mask, addr + j+8); 1756 writeb(*(data++) & d_mask, addr + j+8);
1752 } 1757 }
1753 addr += 16; 1758 addr += 16;
1754 } 1759 }
1755 } 1760 }
1756 1761
1757 void 1762 void
1758 intelfbhw_cursor_reset(struct intelfb_info *dinfo) { 1763 intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
1759 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1764 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1760 int i, j; 1765 int i, j;
1761 1766
1762 #if VERBOSE > 0 1767 #if VERBOSE > 0
1763 DBG_MSG("intelfbhw_cursor_reset\n"); 1768 DBG_MSG("intelfbhw_cursor_reset\n");
1764 #endif 1769 #endif
1765 1770
1766 if (!dinfo->cursor.virtual) 1771 if (!dinfo->cursor.virtual)
1767 return; 1772 return;
1768 1773
1769 for (i = 64; i--; ) { 1774 for (i = 64; i--; ) {
1770 for (j = 0; j < 8; j++) { 1775 for (j = 0; j < 8; j++) {
1771 writeb(0xff, addr + j+0); 1776 writeb(0xff, addr + j+0);
1772 writeb(0x00, addr + j+8); 1777 writeb(0x00, addr + j+8);
1773 } 1778 }
1774 addr += 16; 1779 addr += 16;
1775 } 1780 }
1776 } 1781 }
1777 1782