1 /*
2 * drivers/video/radeonfb.c
3 * framebuffer driver for ATI Radeon chipset video boards
4 *
5 * Copyright 2000 Ani Joshi <ajoshi@kernel.crashing.org>
6 *
7 *
8 * ChangeLog:
9 * 2000-08-03 initial version 0.0.1
10 * 2000-09-10 more bug fixes, public release 0.0.5
11 * 2001-02-19 mode bug fixes, 0.0.7
12 * 2001-07-05 fixed scrolling issues, engine initialization,
13 * and minor mode tweaking, 0.0.9
14 * 2001-09-07 Radeon VE support, Nick Kurshev
15 * blanking, pan_display, and cmap fixes, 0.1.0
16 * 2001-10-10 Radeon 7500 and 8500 support, and experimental
17 * flat panel support, 0.1.1
18 * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2
19 * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3
20 * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt
21 * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4
22 * 2002-06-02 console switching, mode set fixes, accel fixes
23 * 2002-06-03 MTRR support, Peter Horton, 0.1.5
24 * 2002-09-21 rv250, r300, m9 initial support,
25 * added mirror option, 0.1.6
26 * 2003-04-10 accel engine fixes, 0.1.7
27 * 2003-04-12 Mac PowerBook sleep fixes, Benjamin Herrenschmidt,
28 * 0.1.8
29 *
30 * Other change (--BenH)
31 *
32 * 2003-01-01 - Tweaks for PLL on some iBooks
33 * - Fix SURFACE_CNTL usage on r9000
34 * 2003-03-23 - Added new Power Management code from ATI
35 * - Added default PLL values for r300 from lkml
36 * - Fix mirror ioctl result code (that ioctl still need some
37 * rework to actually use the second head)
38 * 2003-03-26 - Never set TMDS_PLL_EN, it seem to break more than
39 * just old r300's
40 * 2003-04-02 - Got final word from ATI, TMDS_PLL_EN has to be flipped
41 * depending if we are dealing with an "RV" card or not
42 * - Comsetic changes to sleep code, make it a bit more robust
43 * hopefully
44 * - Fix 800x600-8 mode accel (Daniel Mantione)
45 * - Fix scaling on LCDs (not yet preserving aspect ratio though)
46 * - Properly set scroll mode to SCROLL_YREDRAW when accel
47 * is disabled from fbset
48 * - Add some more radeon PCI IDs & default PLL values
49 * 2003-04-05 - Update the code that retreive the panel infos from the
50 * BIOS to match what XFree is doing
51 * - Avoid a divide by 0 when failing to retreive those infos
52 * 2003-04-07 - Fix the M6 video RAM workaround
53 * - Some bits in the PM code were flipped, fix that.
54 * - RB2D_DSTCACHE_MODE shouldn't be cleared on r300 (and
55 * maybe not on others according to a comment in XFree, but
56 * we keep working code for now).
57 * - Use ROP3_S for rectangle fill
58 * 2003-04-10 - Re-change the pitch workaround. We now align the pitch
59 * when accel is enabled for a given mode, and we don't when
60 * accel is disabled. That should properly deal with all cases
61 * and allows us to remove the "special case" accel code
62 * - Bring in XFree workaround to not write the same value to
63 * the PLL (can cause blanking of some panels)
64 * - Bring in some of Peter Horton fixes (accel reset, cleanups)
65 * still some more to get in though...
66 * - Back to use of ROP3_P for rectangle fill (hrm...)
67 * 2003-04-11 - Properly reset accel engine on each console switch so
68 * we work around switching from XFree leaving it in a weird
69 * state. Also extend the comparison of values causing us to
70 * reload the mode on console switch.
71 * 2003-04-30 - For BIOS returned LCD infos, assume high sync polarity
72 * 2003-07-08 - Fix an oops during boot related to disp not beeing initialized
73 * when modedb called us back for set_var. Remove bogus refs to
74 * RADEON_PM chip, this is really a mach64 chip, not a Radeon.
75 * Add some DFP blanking support
76 * 2003-07-11 - Merged with Ani's 0.1.8 version
77 *
78 * Special thanks to ATI DevRel team for their hardware donations,
79 * and for spending the time to fix the power management code !
80 *
81 * Note: This driver in in bad need of beeing completely re-organized.
82 * My long term plans, if I ever get enough time for that, is
83 * to split the actual mode setting code so it can properly
84 * work on any head, the probe code, which will be stuffed with
85 * OF parsing on PPC and i2c fallback (look at what XFree does)
86 * and the PM code ought to be in a separate file. --BenH.
87 *
88 *
89 * Known Bugs:
90 *
91 * - Incompatible with ATI FireGL drivers. They are playing with things
92 * like MC_FB_LOCATION behind our back. Not much we can do. This is
93 * becoming a real problem as DRI is also playing with those and the
94 * GATOS CVS as well in a different way.
95 * We should really define _once for all_ the way we want those setup
96 * and do it the same way everywhere or we won't be able to keep
97 * compatibility with radeonfb.
98 * IMHO, the proper setup is what radeon_fixup_apertures() does on
99 * PPC when SET_MC_FB_FROM_APERTURE is defined (not the case currently
100 * because of compatiblity problems with DRI). This is, I think, also
101 * what GATOS does. We shall ask ATI what they do in the FireGL drivers
102 * - We don't preserve aspect ratio on scaled modes on LCDs yet
103 * - The way we retreive the BIOS informations probably doesn't work with
104 * anything but the primary card since we need a "live" BIOS image in
105 * memory to find the tables configured by the BIOS during POST stage.
106 */
107
108
109 #define RADEON_VERSION "0.1.8-ben"
110
111
112 #include <linux/config.h>
113 #include <linux/module.h>
114 #include <linux/kernel.h>
115 #include <linux/errno.h>
116 #include <linux/string.h>
117 #include <linux/mm.h>
118 #include <linux/tty.h>
119 #include <linux/slab.h>
120 #include <linux/delay.h>
121 #include <linux/fb.h>
122 #include <linux/console.h>
123 #include <linux/vt_kern.h>
124 #include <linux/selection.h>
125 #include <linux/ioport.h>
126 #include <linux/init.h>
127 #include <linux/pci.h>
128 #include <linux/vmalloc.h>
129
130 #include <asm/io.h>
131 #include <asm/uaccess.h>
132 #ifdef CONFIG_ALL_PPC
133 #include <asm/prom.h>
134 #include <asm/pci-bridge.h>
135 #include <video/macmodes.h>
136
137 #ifdef CONFIG_NVRAM
138 #include <linux/nvram.h>
139 #endif
140
141 #ifdef CONFIG_PMAC_BACKLIGHT
142 #include <asm/backlight.h>
143 #endif
144
145 #ifdef CONFIG_BOOTX_TEXT
146 #include <asm/btext.h>
147 #endif
148
149 #ifdef CONFIG_ADB_PMU
150 #include <linux/adb.h>
151 #include <linux/pmu.h>
152 #endif
153
154 #endif /* CONFIG_ALL_PPC */
155
156 #ifdef CONFIG_MTRR
157 #include <asm/mtrr.h>
158 #endif
159
160 #include <video/fbcon.h>
161 #include <video/fbcon-cfb8.h>
162 #include <video/fbcon-cfb16.h>
163 #include <video/fbcon-cfb24.h>
164 #include <video/fbcon-cfb32.h>
165
166 #include "radeon.h"
167
168 #include <linux/radeonfb.h>
169
170
171 #define DEBUG 0
172
173 #if DEBUG
174 #define RTRACE printk
175 #else
176 #define RTRACE if(0) printk
177 #endif
178
179 #define MAX_MAPPED_VRAM (2048*2048*4)
180 #define MIN_MAPPED_VRAM (1024*768*1)
181
182 enum radeon_chips {
183 RADEON_QD,
184 RADEON_QE,
185 RADEON_QF,
186 RADEON_QG,
187 RADEON_QY,
188 RADEON_QZ,
189 RADEON_LW,
190 RADEON_LX,
191 RADEON_LY,
192 RADEON_LZ,
193 RADEON_QL,
194 RADEON_QN,
195 RADEON_QO,
196 RADEON_Ql,
197 RADEON_BB,
198 RADEON_QM,
199 RADEON_QW,
200 RADEON_QX,
201 RADEON_Id,
202 RADEON_Ie,
203 RADEON_If,
204 RADEON_Ig,
205 RADEON_Y_,
206 RADEON_Ya,
207 RADEON_Yd,
208 RADEON_Ld,
209 RADEON_Le,
210 RADEON_Lf,
211 RADEON_Lg,
212 RADEON_ND,
213 RADEON_NE,
214 RADEON_NF,
215 RADEON_NG,
216 RADEON_AE,
217 RADEON_AF,
218 RADEON_AD,
219 RADEON_NH,
220 RADEON_NI,
221 RADEON_AP,
222 RADEON_AQ,
223 RADEON_AR,
224 };
225
226 enum radeon_arch {
227 RADEON_R100,
228 RADEON_M6,
229 RADEON_RV100,
230 RADEON_R200,
231 RADEON_M7,
232 RADEON_RV200,
233 RADEON_M9,
234 RADEON_RV250,
235 RADEON_RV280,
236 RADEON_R300,
237 RADEON_R350,
238 RADEON_RV350,
239 };
240
241 static struct radeon_chip_info {
242 const char *name;
243 unsigned char arch;
244 } radeon_chip_info[] __devinitdata = {
245 { "QD", RADEON_R100 },
246 { "QE", RADEON_R100 },
247 { "QF", RADEON_R100 },
248 { "QG", RADEON_R100 },
249 { "VE QY", RADEON_RV100 },
250 { "VE QZ", RADEON_RV100 },
251 { "M7 LW", RADEON_M7 },
252 { "M7 LX", RADEON_M7 },
253 { "M6 LY", RADEON_M6 },
254 { "M6 LZ", RADEON_M6 },
255 { "8500 QL", RADEON_R200 },
256 { "8500 QN", RADEON_R200 },
257 { "8500 QO", RADEON_R200 },
258 { "8500 Ql", RADEON_R200 },
259 { "8500 BB", RADEON_R200 },
260 { "9100 QM", RADEON_R200 },
261 { "7500 QW", RADEON_RV200 },
262 { "7500 QX", RADEON_RV200 },
263 { "9000 Id", RADEON_RV250 },
264 { "9000 Ie", RADEON_RV250 },
265 { "9000 If", RADEON_RV250 },
266 { "9000 Ig", RADEON_RV250 },
267 { "9200 Y", RADEON_RV280 },
268 { "9200 Ya", RADEON_RV280 },
269 { "9200 Yd", RADEON_RV280 },
270 { "M9 Ld", RADEON_M9 },
271 { "M9 Le", RADEON_M9 },
272 { "M9 Lf", RADEON_M9 },
273 { "M9 Lg", RADEON_M9 },
274 { "9700 ND", RADEON_R300 },
275 { "9700 NE", RADEON_R300 },
276 { "9700 NF", RADEON_R350 },
277 { "9700 NG", RADEON_R350 },
278 { "9700 AE", RADEON_R300 },
279 { "9700 AF", RADEON_R300 },
280 { "9500 AD", RADEON_R300 },
281 { "9800 NH", RADEON_R350 },
282 { "9800 NI", RADEON_R350 },
283 { "9600 AP", RADEON_RV350 },
284 { "9600 AQ", RADEON_RV350 },
285 { "9600 AR", RADEON_RV350 },
286 };
287
288
289 enum radeon_montype
290 {
291 MT_NONE,
292 MT_CRT, /* CRT */
293 MT_LCD, /* LCD */
294 MT_DFP, /* DVI */
295 MT_CTV, /* composite TV */
296 MT_STV /* S-Video out */
297 };
298
299
300 static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
301 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
302 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
303 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
304 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
305 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
306 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
307 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
308 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX},
309 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
310 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
311 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
312 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN},
313 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO},
314 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql},
315 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB},
316 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QM},
317 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
318 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX},
319 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id},
320 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
321 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
322 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
323 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
324 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
325 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf},
326 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg},
327 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND},
328 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE},
329 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF},
330 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG},
331 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AE},
332 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AF},
333 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NH, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NH},
334 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NI, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NI},
335 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Y_, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Y_},
336 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ya, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ya},
337 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd},
338 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AD},
339 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AP},
340 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AQ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AQ},
341 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AR},
342 { 0, }
343 };
344 MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
345
346
347 typedef struct {
348 u16 reg;
349 u32 val;
350 } reg_val;
351
352
353 /* these common regs are cleared before mode setting so they do not
354 * interfere with anything
355 */
356 reg_val common_regs[] = {
357 { OVR_CLR, 0 },
358 { OVR_WID_LEFT_RIGHT, 0 },
359 { OVR_WID_TOP_BOTTOM, 0 },
360 { OV0_SCALE_CNTL, 0 },
361 { SUBPIC_CNTL, 0 },
362 { VIPH_CONTROL, 0 },
363 { I2C_CNTL_1, 0 },
364 { GEN_INT_CNTL, 0 },
365 { CAP0_TRIG_CNTL, 0 },
366 };
367
368 reg_val common_regs_m6[] = {
369 { OVR_CLR, 0 },
370 { OVR_WID_LEFT_RIGHT, 0 },
371 { OVR_WID_TOP_BOTTOM, 0 },
372 { OV0_SCALE_CNTL, 0 },
373 { SUBPIC_CNTL, 0 },
374 { GEN_INT_CNTL, 0 },
375 { CAP0_TRIG_CNTL, 0 }
376 };
377
378
379 #define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
380 #define COMMON_REGS_M6_SIZE = (sizeof(common_regs)/sizeof(common_regs_m6[0]))
381
382 typedef struct {
383 u8 clock_chip_type;
384 u8 struct_size;
385 u8 accelerator_entry;
386 u8 VGA_entry;
387 u16 VGA_table_offset;
388 u16 POST_table_offset;
389 u16 XCLK;
390 u16 MCLK;
391 u8 num_PLL_blocks;
392 u8 size_PLL_blocks;
393 u16 PCLK_ref_freq;
394 u16 PCLK_ref_divider;
395 u32 PCLK_min_freq;
396 u32 PCLK_max_freq;
397 u16 MCLK_ref_freq;
398 u16 MCLK_ref_divider;
399 u32 MCLK_min_freq;
400 u32 MCLK_max_freq;
401 u16 XCLK_ref_freq;
402 u16 XCLK_ref_divider;
403 u32 XCLK_min_freq;
404 u32 XCLK_max_freq;
405 } __attribute__ ((packed)) PLL_BLOCK;
406
407
408 struct pll_info {
409 int ppll_max;
410 int ppll_min;
411 int xclk;
412 int ref_div;
413 int ref_clk;
414 };
415
416
417 struct ram_info {
418 int ml;
419 int mb;
420 int trcd;
421 int trp;
422 int twr;
423 int cl;
424 int tr2w;
425 int loop_latency;
426 int rloop;
427 };
428
429
430 struct radeon_regs {
431 /* CRTC regs */
432 u32 crtc_h_total_disp;
433 u32 crtc_h_sync_strt_wid;
434 u32 crtc_v_total_disp;
435 u32 crtc_v_sync_strt_wid;
436 u32 crtc_pitch;
437 u32 crtc_gen_cntl;
438 u32 crtc_ext_cntl;
439 u32 crtc_more_cntl;
440 u32 dac_cntl;
441
442 u32 flags;
443 u32 pix_clock;
444 int xres, yres;
445
446 /* DDA regs */
447 u32 dda_config;
448 u32 dda_on_off;
449
450 /* PLL regs */
451 u32 ppll_div_3;
452 u32 ppll_ref_div;
453
454 /* Flat panel regs */
455 u32 fp_crtc_h_total_disp;
456 u32 fp_crtc_v_total_disp;
457 u32 fp_gen_cntl;
458 u32 fp_h_sync_strt_wid;
459 u32 fp_horz_stretch;
460 u32 fp_panel_cntl;
461 u32 fp_v_sync_strt_wid;
462 u32 fp_vert_stretch;
463 u32 lvds_gen_cntl;
464 u32 lvds_pll_cntl;
465 u32 tmds_crc;
466 u32 tmds_transmitter_cntl;
467
468 /* Dynamic clock control */
469 u32 vclk_ecp_cntl;
470
471 /* Endian control */
472 u32 surface_cntl;
473 };
474
475
476 struct radeonfb_info {
477 struct fb_info info;
478
479 struct radeon_regs state;
480 struct radeon_regs init_state;
481
482 char name[16];
483 char ram_type[12];
484
485 unsigned long mmio_base_phys;
486 unsigned long fb_base_phys;
487
488 unsigned long mmio_base;
489 unsigned long fb_base;
490
491 unsigned long fb_local_base;
492
493 struct pci_dev *pdev;
494
495 unsigned char *EDID;
496 unsigned char *bios_seg;
497
498 struct display disp;
499 int currcon;
500 struct display *currcon_display;
501
502 struct { u8 red, green, blue, pad; } palette[256];
503
504 short chipset;
505 unsigned char arch;
506 unsigned int video_ram;
507 u8 rev;
508 int pitch, bpp, depth;
509 int xres, yres, pixclock;
510 int xres_virtual, yres_virtual;
511
512 int use_default_var;
513 int got_dfpinfo;
514
515 int hasCRTC2;
516 int crtDisp_type;
517 int dviDisp_type;
518
519 int panel_xres, panel_yres;
520 int clock;
521 int hOver_plus, hSync_width, hblank;
522 int vOver_plus, vSync_width, vblank;
523 int hAct_high, vAct_high, interlaced;
524 int synct, misc;
525
526 u32 dp_gui_master_cntl;
527
528 struct pll_info pll;
529 int pll_output_freq, post_div, fb_div;
530
531 struct ram_info ram;
532
533 int mtrr_hdl;
534
535 #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
536 union {
537 #if defined(FBCON_HAS_CFB16)
538 u_int16_t cfb16[16];
539 #endif
540 #if defined(FBCON_HAS_CFB24)
541 u_int32_t cfb24[16];
542 #endif
543 #if defined(FBCON_HAS_CFB32)
544 u_int32_t cfb32[16];
545 #endif
546 } con_cmap;
547 #endif
548
549 #ifdef CONFIG_PMAC_PBOOK
550 int pm_reg;
551 u32 save_regs[64];
552 u32 mdll, mdll2;
553 #endif
554
555 int asleep;
556
557 struct radeonfb_info *next;
558 };
559
560
561 static struct fb_var_screeninfo radeonfb_default_var = {
562 640, 480, 640, 480, 0, 0, 8, 0,
563 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
564 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
565 0, FB_VMODE_NONINTERLACED
566 };
567
568
569 /*
570 * IO macros
571 */
572
573 #define INREG8(addr) readb((rinfo->mmio_base)+addr)
574 #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
575 #define INREG(addr) readl((rinfo->mmio_base)+addr)
576 #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
577
578 #define OUTPLL(addr,val) \
579 do { \
580 OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
581 OUTREG(CLOCK_CNTL_DATA, val); \
582 } while (0) \
583
584 #define OUTPLLP(addr,val,mask) \
585 do { \
586 unsigned int _tmp = INPLL(addr); \
587 _tmp &= (mask); \
588 _tmp |= (val); \
589 OUTPLL(addr, _tmp); \
590 } while (0)
591
592 #define OUTREGP(addr,val,mask) \
593 do { \
594 unsigned int _tmp = INREG(addr); \
595 _tmp &= (mask); \
596 _tmp |= (val); \
597 OUTREG(addr, _tmp); \
598 } while (0)
599
600
_INPLL(struct radeonfb_info * rinfo,u32 addr)601 static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
602 {
603 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
604 return (INREG(CLOCK_CNTL_DATA));
605 }
606
607 #define INPLL(addr) _INPLL(rinfo, addr)
608
609 #define PRIMARY_MONITOR(rinfo) ((rinfo->dviDisp_type != MT_NONE) && \
610 (rinfo->dviDisp_type != MT_STV) && \
611 (rinfo->dviDisp_type != MT_CTV) ? \
612 rinfo->dviDisp_type : rinfo->crtDisp_type)
613
GET_MON_NAME(int type)614 static char *GET_MON_NAME(int type)
615 {
616 char *pret = NULL;
617
618 switch (type) {
619 case MT_NONE:
620 pret = "no";
621 break;
622 case MT_CRT:
623 pret = "CRT";
624 break;
625 case MT_DFP:
626 pret = "DFP";
627 break;
628 case MT_LCD:
629 pret = "LCD";
630 break;
631 case MT_CTV:
632 pret = "CTV";
633 break;
634 case MT_STV:
635 pret = "STV";
636 break;
637 }
638
639 return pret;
640 }
641
642
643 /*
644 * 2D engine routines
645 */
646
radeon_engine_flush(struct radeonfb_info * rinfo)647 static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
648 {
649 int i;
650
651 /* initiate flush */
652 OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
653 ~RB2D_DC_FLUSH_ALL);
654
655 for (i=0; i < 2000000; i++) {
656 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
657 break;
658 }
659 }
660
661
_radeon_fifo_wait(struct radeonfb_info * rinfo,int entries)662 static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
663 {
664 int i;
665
666 for (i=0; i<2000000; i++)
667 if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
668 return;
669 }
670
671
_radeon_engine_idle(struct radeonfb_info * rinfo)672 static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
673 {
674 int i;
675
676 /* ensure FIFO is empty before waiting for idle */
677 _radeon_fifo_wait (rinfo, 64);
678
679 for (i=0; i<2000000; i++) {
680 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
681 radeon_engine_flush (rinfo);
682 return;
683 }
684 }
685 }
686
687
688 #define radeon_engine_idle() _radeon_engine_idle(rinfo)
689 #define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
690
691
692
693 /*
694 * helper routines
695 */
696
radeon_get_dstbpp(u16 depth)697 static __inline__ u32 radeon_get_dstbpp(u16 depth)
698 {
699 switch (depth) {
700 case 8:
701 return DST_8BPP;
702 case 15:
703 return DST_15BPP;
704 case 16:
705 return DST_16BPP;
706 case 32:
707 return DST_32BPP;
708 default:
709 return 0;
710 }
711 }
712
713
var_to_depth(const struct fb_var_screeninfo * var)714 static inline int var_to_depth(const struct fb_var_screeninfo *var)
715 {
716 if (var->bits_per_pixel != 16)
717 return var->bits_per_pixel;
718 return (var->green.length == 6) ? 16 : 15;
719 }
720
721
_radeon_engine_reset(struct radeonfb_info * rinfo)722 static void _radeon_engine_reset(struct radeonfb_info *rinfo)
723 {
724 u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
725 u32 host_path_cntl;
726
727 radeon_engine_flush (rinfo);
728
729 /* Some ASICs have bugs with dynamic-on feature, which are
730 * ASIC-version dependent, so we force all blocks on for now
731 * -- from XFree86
732 * We don't do that on macs, things just work here with dynamic
733 * clocking... --BenH
734 */
735 #ifdef CONFIG_ALL_PPC
736 if (_machine != _MACH_Pmac && rinfo->hasCRTC2)
737 #else
738 if (rinfo->hasCRTC2)
739 #endif
740 {
741 u32 tmp;
742
743 tmp = INPLL(SCLK_CNTL);
744 OUTPLL(SCLK_CNTL, ((tmp & ~DYN_STOP_LAT_MASK) |
745 CP_MAX_DYN_STOP_LAT |
746 SCLK_FORCEON_MASK));
747
748 if (rinfo->arch == RADEON_RV200)
749 {
750 tmp = INPLL(SCLK_MORE_CNTL);
751 OUTPLL(SCLK_MORE_CNTL, tmp | SCLK_MORE_FORCEON);
752 }
753 }
754
755 clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
756 mclk_cntl = INPLL(MCLK_CNTL);
757
758 OUTPLL(MCLK_CNTL, (mclk_cntl |
759 FORCEON_MCLKA |
760 FORCEON_MCLKB |
761 FORCEON_YCLKA |
762 FORCEON_YCLKB |
763 FORCEON_MC |
764 FORCEON_AIC));
765
766 host_path_cntl = INREG(HOST_PATH_CNTL);
767 rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
768
769 if (rinfo->arch == RADEON_R300) {
770 u32 tmp;
771
772 OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
773 SOFT_RESET_CP |
774 SOFT_RESET_HI |
775 SOFT_RESET_E2));
776 INREG(RBBM_SOFT_RESET);
777 OUTREG(RBBM_SOFT_RESET, 0);
778 tmp = INREG(RB2D_DSTCACHE_MODE);
779 OUTREG(RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */
780 } else {
781 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
782 SOFT_RESET_CP |
783 SOFT_RESET_HI |
784 SOFT_RESET_SE |
785 SOFT_RESET_RE |
786 SOFT_RESET_PP |
787 SOFT_RESET_E2 |
788 SOFT_RESET_RB);
789 INREG(RBBM_SOFT_RESET);
790 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
791 ~(SOFT_RESET_CP |
792 SOFT_RESET_HI |
793 SOFT_RESET_SE |
794 SOFT_RESET_RE |
795 SOFT_RESET_PP |
796 SOFT_RESET_E2 |
797 SOFT_RESET_RB));
798 INREG(RBBM_SOFT_RESET);
799 }
800
801 OUTREG(HOST_PATH_CNTL, host_path_cntl | HDP_SOFT_RESET);
802 INREG(HOST_PATH_CNTL);
803 OUTREG(HOST_PATH_CNTL, host_path_cntl);
804
805 if (rinfo->arch != RADEON_R300)
806 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
807
808 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
809 OUTPLL(MCLK_CNTL, mclk_cntl);
810
811 return;
812 }
813
814 #define radeon_engine_reset() _radeon_engine_reset(rinfo)
815
816
round_div(int num,int den)817 static __inline__ int round_div(int num, int den)
818 {
819 return (num + (den / 2)) / den;
820 }
821
min_bits_req(int val)822 static __inline__ int min_bits_req(int val)
823 {
824 int bits_req = 0;
825
826 if (val == 0)
827 bits_req = 1;
828
829 while (val) {
830 val >>= 1;
831 bits_req++;
832 }
833
834 return (bits_req);
835 }
836
_max(int val1,int val2)837 static __inline__ int _max(int val1, int val2)
838 {
839 if (val1 >= val2)
840 return val1;
841 else
842 return val2;
843 }
844
845
846
847 /*
848 * globals
849 */
850
851 static char fontname[40] __initdata;
852 static char *mode_option __initdata;
853 static char noaccel = 0;
854 static char mirror = 0;
855 static int panel_yres __initdata = 0;
856 static char force_dfp __initdata = 0;
857 static char force_crt __initdata = 0;
858 static char force_nolcd __initdata = 0;
859 static struct radeonfb_info *board_list = NULL;
860 static char nomtrr __initdata = 0;
861
862 #ifdef FBCON_HAS_CFB8
863 static struct display_switch fbcon_radeon8;
864 #endif
865
866 #ifdef FBCON_HAS_CFB16
867 static struct display_switch fbcon_radeon16;
868 #endif
869
870 #ifdef FBCON_HAS_CFB32
871 static struct display_switch fbcon_radeon32;
872 #endif
873
874
875 /*
876 * prototypes
877 */
878
879 static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
880 struct fb_info *info);
881 static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
882 struct fb_info *info);
883 static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
884 struct fb_info *info);
885 static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
886 struct fb_info *info);
887 static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
888 struct fb_info *info);
889 static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
890 struct fb_info *info);
891 static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
892 unsigned long arg, int con, struct fb_info *info);
893 static int radeonfb_switch (int con, struct fb_info *info);
894 static int radeonfb_updatevar (int con, struct fb_info *info);
895 static void radeonfb_blank (int blank, struct fb_info *info);
896 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
897 static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
898 unsigned *blue, unsigned *transp,
899 struct fb_info *info);
900 static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
901 unsigned blue, unsigned transp, struct fb_info *info);
902 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);
903 static void radeon_save_state (struct radeonfb_info *rinfo,
904 struct radeon_regs *save);
905 static int radeon_engine_init (struct radeonfb_info *rinfo);
906 static void radeon_load_video_mode (struct radeonfb_info *rinfo,
907 struct fb_var_screeninfo *mode);
908 static void radeon_write_mode (struct radeonfb_info *rinfo,
909 struct radeon_regs *mode);
910 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
911 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
912 static int radeonfb_pci_register (struct pci_dev *pdev,
913 const struct pci_device_id *ent);
914 static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
915 static int radeon_do_set_var (struct fb_var_screeninfo *var, int con,
916 int real, struct fb_info *info);
917
918 #ifdef CONFIG_PMAC_PBOOK
919 static int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
920 static struct pmu_sleep_notifier radeon_sleep_notifier = {
921 radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
922 };
923 #endif /* CONFIG_PMAC_PBOOK */
924 #ifdef CONFIG_PMAC_BACKLIGHT
925 static int radeon_set_backlight_enable(int on, int level, void *data);
926 static int radeon_set_backlight_level(int level, void *data);
927 static struct backlight_controller radeon_backlight_controller = {
928 radeon_set_backlight_enable,
929 radeon_set_backlight_level
930 };
931 static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value);
932 static u32 INMC(struct radeonfb_info *rinfo, u8 indx);
933 static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo);
934 static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo);
935 static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo);
936 static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required);
937 static void radeon_pm_enable_dll(struct radeonfb_info *rinfo);
938 static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo);
939 #endif /* CONFIG_PMAC_BACKLIGHT */
940
941 static struct fb_ops radeon_fb_ops = {
942 owner: THIS_MODULE,
943 fb_get_fix: radeonfb_get_fix,
944 fb_get_var: radeonfb_get_var,
945 fb_set_var: radeonfb_set_var,
946 fb_get_cmap: radeonfb_get_cmap,
947 fb_set_cmap: radeonfb_set_cmap,
948 fb_pan_display: radeonfb_pan_display,
949 fb_ioctl: radeonfb_ioctl,
950 };
951
952
953 static struct pci_driver radeonfb_driver = {
954 name: "radeonfb",
955 id_table: radeonfb_pci_table,
956 probe: radeonfb_pci_register,
957 remove: __devexit_p(radeonfb_pci_unregister),
958 };
959
960
radeonfb_init(void)961 int __init radeonfb_init (void)
962 {
963 return pci_module_init (&radeonfb_driver);
964 }
965
966
radeonfb_exit(void)967 void __exit radeonfb_exit (void)
968 {
969 pci_unregister_driver (&radeonfb_driver);
970 }
971
972
radeonfb_setup(char * options)973 int __init radeonfb_setup (char *options)
974 {
975 char *this_opt;
976
977 if (!options || !*options)
978 return 0;
979
980 while ((this_opt = strsep (&options, ",")) != NULL) {
981 if (!*this_opt)
982 continue;
983 if (!strncmp (this_opt, "font:", 5)) {
984 char *p;
985 int i;
986
987 p = this_opt + 5;
988 for (i=0; i<sizeof (fontname) - 1; i++)
989 if (!*p || *p == ' ' || *p == ',')
990 break;
991 memcpy(fontname, this_opt + 5, i);
992 } else if (!strncmp(this_opt, "noaccel", 7)) {
993 noaccel = 1;
994 } else if (!strncmp(this_opt, "mirror", 6)) {
995 mirror = 1;
996 } else if (!strncmp(this_opt, "dfp", 3)) {
997 force_dfp = 1;
998 force_nolcd = 1;
999 } else if (!strncmp(this_opt, "crt", 3)) {
1000 force_crt = 1;
1001 force_nolcd = 1;
1002 } else if (!strncmp(this_opt, "nolcd", 5)) {
1003 force_nolcd = 1;
1004 } else if (!strncmp(this_opt, "panel_yres:", 11)) {
1005 panel_yres = simple_strtoul((this_opt+11), NULL, 0);
1006 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1007 nomtrr = 1;
1008 } else
1009 mode_option = this_opt;
1010 }
1011
1012 return 0;
1013 }
1014
1015 #ifdef MODULE
1016 module_init(radeonfb_init);
1017 module_exit(radeonfb_exit);
1018 #endif
1019
1020
1021 MODULE_AUTHOR("Ani Joshi");
1022 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
1023 MODULE_LICENSE("GPL");
1024
1025 MODULE_PARM(noaccel, "i");
1026 MODULE_PARM_DESC(noaccel, "Disable (1) or enable (0) the usage of the 2d accel engine");
1027 MODULE_PARM(force_dfp, "i");
1028 MODULE_PARM_DESC(force_dfp,"Force (1) the usage of a digital flat panel");
1029 MODULE_PARM(force_crt, "i");
1030 MODULE_PARM_DESC(force_crt,"Force (1) the usage of a CRT monitor");
1031 MODULE_PARM(force_nolcd, "i");
1032 MODULE_PARM_DESC(force_nolcd,"Avoid (1) the usage of a digital flat panel");
1033
radeon_find_rom(struct radeonfb_info * rinfo)1034 static unsigned char *radeon_find_rom(struct radeonfb_info *rinfo)
1035 {
1036 #if defined(__i386__)
1037 /* I simplified this code as we used to miss the signatures in
1038 * a lot of case. It's now closer to XFree, we just don't check
1039 * for signatures at all... Something better will have to be done
1040 * later obviously
1041 */
1042 u32 segstart;
1043 unsigned char *rom_base;
1044
1045 for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
1046 rom_base = (char *)ioremap(segstart, 0x1000);
1047 if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
1048 return rom_base;
1049 iounmap(rom_base);
1050 }
1051 #endif
1052 return NULL;
1053 }
1054
1055 #ifdef CONFIG_ALL_PPC
radeon_read_OF(struct radeonfb_info * rinfo)1056 static int radeon_read_OF (struct radeonfb_info *rinfo)
1057 {
1058 struct device_node *dp;
1059 unsigned int *xtal;
1060
1061 dp = pci_device_to_OF_node(rinfo->pdev);
1062 if (dp == NULL)
1063 return 0;
1064
1065 xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);
1066 if ((xtal == NULL) || (*xtal == 0))
1067 return 0;
1068
1069 rinfo->pll.ref_clk = *xtal / 10;
1070
1071 return 1;
1072 }
1073 #endif
1074
radeon_get_pllinfo(struct radeonfb_info * rinfo,char * bios_seg)1075 static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
1076 {
1077 void *bios_header;
1078 void *header_ptr;
1079 u16 bios_header_offset, pll_info_offset;
1080 PLL_BLOCK pll;
1081
1082 if (bios_seg) {
1083 bios_header = bios_seg + 0x48L;
1084 header_ptr = bios_header;
1085
1086 bios_header_offset = readw(header_ptr);
1087 bios_header = bios_seg + bios_header_offset;
1088 bios_header += 0x30;
1089
1090 header_ptr = bios_header;
1091 pll_info_offset = readw(header_ptr);
1092 header_ptr = bios_seg + pll_info_offset;
1093
1094 memcpy_fromio(&pll, header_ptr, 50);
1095
1096 /* Consider ref clock to be sane between 1000 and 5000,
1097 * just in case we tapped the wrong BIOS...
1098 */
1099 if (pll.PCLK_ref_freq < 1000 || pll.PCLK_ref_freq > 5000)
1100 goto use_defaults;
1101
1102 rinfo->pll.xclk = (u32)pll.XCLK;
1103 rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
1104 rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
1105 rinfo->pll.ppll_min = pll.PCLK_min_freq;
1106 rinfo->pll.ppll_max = pll.PCLK_max_freq;
1107
1108 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
1109 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1110 } else {
1111 #ifdef CONFIG_ALL_PPC
1112 if (radeon_read_OF(rinfo)) {
1113 unsigned int tmp, Nx, M, ref_div, xclk;
1114
1115 tmp = INPLL(M_SPLL_REF_FB_DIV);
1116 ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
1117
1118 Nx = (tmp & 0xff00) >> 8;
1119 M = (tmp & 0xff);
1120 xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
1121 (2 * M)));
1122
1123 rinfo->pll.xclk = xclk;
1124 rinfo->pll.ref_div = ref_div;
1125 rinfo->pll.ppll_min = 12000;
1126 rinfo->pll.ppll_max = 35000;
1127
1128 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
1129 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1130
1131 return;
1132 }
1133 #endif
1134 use_defaults:
1135 /* No BIOS or BIOS not found, use defaults
1136 *
1137 * NOTE: Those defaults settings are rather "randomly" picked from
1138 * informations we found so far, but we would really need some
1139 * better mecanism to get them. Recent XFree can +/- probe for
1140 * the proper clocks.
1141 */
1142 switch (rinfo->arch) {
1143 case RADEON_RV200:
1144 rinfo->pll.ppll_max = 35000;
1145 rinfo->pll.ppll_min = 12000;
1146 rinfo->pll.xclk = 23000;
1147 rinfo->pll.ref_div = 12;
1148 rinfo->pll.ref_clk = 2700;
1149 break;
1150 case RADEON_R200:
1151 rinfo->pll.ppll_max = 35000;
1152 rinfo->pll.ppll_min = 12000;
1153 rinfo->pll.xclk = 27500;
1154 rinfo->pll.ref_div = 12;
1155 rinfo->pll.ref_clk = 2700;
1156 break;
1157 case RADEON_RV250:
1158 rinfo->pll.ppll_max = 35000;
1159 rinfo->pll.ppll_min = 12000;
1160 rinfo->pll.xclk = 25000;
1161 rinfo->pll.ref_div = 12;
1162 rinfo->pll.ref_clk = 2700;
1163 break;
1164 case RADEON_R300:
1165 rinfo->pll.ppll_max = 40000;
1166 rinfo->pll.ppll_min = 20000;
1167 rinfo->pll.xclk = 27000;
1168 rinfo->pll.ref_div = 12;
1169 rinfo->pll.ref_clk = 2700;
1170 break;
1171 case RADEON_R100:
1172 default:
1173 rinfo->pll.ppll_max = 35000;
1174 rinfo->pll.ppll_min = 12000;
1175 rinfo->pll.xclk = 16600;
1176 rinfo->pll.ref_div = 67;
1177 rinfo->pll.ref_clk = 2700;
1178 break;
1179 }
1180
1181 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
1182 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1183 }
1184 }
1185
1186
radeon_get_moninfo(struct radeonfb_info * rinfo)1187 static void radeon_get_moninfo (struct radeonfb_info *rinfo)
1188 {
1189 u32 tmp = INREG(RADEON_BIOS_4_SCRATCH);
1190
1191 if (force_dfp) {
1192 printk("radeonfb: forcing DFP\n");
1193 rinfo->dviDisp_type = MT_DFP;
1194 return;
1195 } else if (force_crt) {
1196 printk("radeonfb: forcing CRT\n");
1197 rinfo->dviDisp_type = MT_NONE;
1198 rinfo->crtDisp_type = MT_CRT;
1199 return;
1200 }
1201
1202
1203 if (rinfo->hasCRTC2 && tmp) {
1204 /* primary DVI port */
1205 if (tmp & 0x08)
1206 rinfo->dviDisp_type = MT_DFP;
1207 else if (tmp & 0x4)
1208 rinfo->dviDisp_type = MT_LCD;
1209 else if (tmp & 0x200)
1210 rinfo->dviDisp_type = MT_CRT;
1211 else if (tmp & 0x10)
1212 rinfo->dviDisp_type = MT_CTV;
1213 else if (tmp & 0x20)
1214 rinfo->dviDisp_type = MT_STV;
1215
1216 /* secondary CRT port */
1217 if (tmp & 0x2)
1218 rinfo->crtDisp_type = MT_CRT;
1219 else if (tmp & 0x800)
1220 rinfo->crtDisp_type = MT_DFP;
1221 else if (tmp & 0x400)
1222 rinfo->crtDisp_type = MT_LCD;
1223 else if (tmp & 0x1000)
1224 rinfo->crtDisp_type = MT_CTV;
1225 else if (tmp & 0x2000)
1226 rinfo->crtDisp_type = MT_STV;
1227 } else {
1228 rinfo->dviDisp_type = MT_NONE;
1229
1230 tmp = INREG(FP_GEN_CNTL);
1231
1232 if (tmp & FP_EN_TMDS)
1233 rinfo->crtDisp_type = MT_DFP;
1234 else
1235 rinfo->crtDisp_type = MT_CRT;
1236 }
1237 }
1238
1239 #ifdef CONFIG_ALL_PPC
radeon_get_EDID_OF(struct radeonfb_info * rinfo)1240 static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
1241 {
1242 struct device_node *dp;
1243 unsigned char *pedid = NULL;
1244 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };
1245 int i;
1246
1247 dp = pci_device_to_OF_node(rinfo->pdev);
1248 while (dp != NULL) {
1249 for (i = 0; propnames[i] != NULL; ++i) {
1250 pedid = (unsigned char *)
1251 get_property(dp, propnames[i], NULL);
1252 if (pedid != NULL) {
1253 rinfo->EDID = pedid;
1254 return 1;
1255 }
1256 }
1257 dp = dp->child;
1258 }
1259 return 0;
1260 }
1261 #endif /* CONFIG_ALL_PPC */
1262
radeon_get_EDID(struct radeonfb_info * rinfo)1263 static void radeon_get_EDID(struct radeonfb_info *rinfo)
1264 {
1265 #ifdef CONFIG_ALL_PPC
1266 if (!radeon_get_EDID_OF(rinfo))
1267 RTRACE("radeonfb: could not retrieve EDID from OF\n");
1268 #else
1269 /* XXX use other methods later */
1270 #endif
1271 }
1272
1273 #ifdef CONFIG_ALL_PPC
1274 #undef SET_MC_FB_FROM_APERTURE
1275 static void
radeon_fixup_apertures(struct radeonfb_info * rinfo)1276 radeon_fixup_apertures(struct radeonfb_info *rinfo)
1277 {
1278 u32 save_crtc_gen_cntl, save_crtc2_gen_cntl;
1279 u32 save_crtc_ext_cntl;
1280 u32 aper_base, aper_size;
1281 u32 agp_base;
1282
1283 /* First, we disable display to avoid interfering */
1284 if (rinfo->hasCRTC2) {
1285 save_crtc2_gen_cntl = INREG(CRTC2_GEN_CNTL);
1286 OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl | CRTC2_DISP_REQ_EN_B);
1287 }
1288 save_crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
1289 save_crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
1290
1291 OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl | CRTC_DISPLAY_DIS);
1292 OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
1293 mdelay(100);
1294
1295 aper_base = INREG(CONFIG_APER_0_BASE);
1296 aper_size = INREG(CONFIG_APER_SIZE);
1297
1298 #ifdef SET_MC_FB_FROM_APERTURE
1299 /* Set framebuffer to be at the same address as set in PCI BAR */
1300 OUTREG(MC_FB_LOCATION,
1301 ((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16));
1302 rinfo->fb_local_base = aper_base;
1303 #else
1304 OUTREG(MC_FB_LOCATION, 0x7fff0000);
1305 rinfo->fb_local_base = 0;
1306 #endif
1307 agp_base = aper_base + aper_size;
1308 if (agp_base & 0xf0000000)
1309 agp_base = (aper_base | 0x0fffffff) + 1;
1310
1311 /* Set AGP to be just after the framebuffer on a 256Mb boundary. This
1312 * assumes the FB isn't mapped to 0xf0000000 or above, but this is
1313 * always the case on PPCs afaik.
1314 */
1315 #ifdef SET_MC_FB_FROM_APERTURE
1316 OUTREG(MC_AGP_LOCATION, 0xffff0000 | (agp_base >> 16));
1317 #else
1318 OUTREG(MC_AGP_LOCATION, 0xffffe000);
1319 #endif
1320
1321 /* Fixup the display base addresses & engine offsets while we
1322 * are at it as well
1323 */
1324 #ifdef SET_MC_FB_FROM_APERTURE
1325 OUTREG(DISPLAY_BASE_ADDR, aper_base);
1326 if (rinfo->hasCRTC2)
1327 OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);
1328 #else
1329 OUTREG(DISPLAY_BASE_ADDR, 0);
1330 if (rinfo->hasCRTC2)
1331 OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0);
1332 #endif
1333 mdelay(100);
1334
1335 /* Restore display settings */
1336 OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl);
1337 OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl);
1338 if (rinfo->hasCRTC2)
1339 OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl);
1340
1341 #if 0
1342 printk("aper_base: %08x MC_FB_LOC to: %08x, MC_AGP_LOC to: %08x\n",
1343 aper_base,
1344 ((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16),
1345 0xffff0000 | (agp_base >> 16));
1346 #endif
1347 }
1348 #endif /* CONFIG_ALL_PPC */
1349
radeon_dfp_parse_EDID(struct radeonfb_info * rinfo)1350 static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
1351 {
1352 unsigned char *block = rinfo->EDID;
1353
1354 if (!block)
1355 return 0;
1356
1357 /* jump to the detailed timing block section */
1358 block += 54;
1359
1360 rinfo->clock = (block[0] + (block[1] << 8));
1361 rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
1362 rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
1363 rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
1364 rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1365 rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1366 rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1367 rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1368 rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1369 rinfo->interlaced = ((block[17] & 0x80) >> 7);
1370 rinfo->synct = ((block[17] & 0x18) >> 3);
1371 rinfo->misc = ((block[17] & 0x06) >> 1);
1372 rinfo->hAct_high = rinfo->vAct_high = 0;
1373 if (rinfo->synct == 3) {
1374 if (rinfo->misc & 2)
1375 rinfo->hAct_high = 1;
1376 if (rinfo->misc & 1)
1377 rinfo->vAct_high = 1;
1378 }
1379
1380 RTRACE("hOver_plus = %d\t hSync_width = %d\n", rinfo->hOver_plus,
1381 rinfo->hSync_width);
1382 RTRACE("vOver_plus = %d\t vSync_width = %d\n", rinfo->vOver_plus,
1383 rinfo->vSync_width);
1384 RTRACE("hblank = %d\t vblank = %d\n", rinfo->hblank,
1385 rinfo->vblank);
1386 RTRACE("sync = %d\n", rinfo->synct);
1387 RTRACE("misc = %d\n", rinfo->misc);
1388 RTRACE("clock = %d\n", rinfo->clock);
1389 printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
1390 rinfo->panel_xres, rinfo->panel_yres);
1391
1392 rinfo->got_dfpinfo = 1;
1393
1394 return 1;
1395 }
1396
radeon_update_default_var(struct radeonfb_info * rinfo)1397 static void radeon_update_default_var(struct radeonfb_info *rinfo)
1398 {
1399 struct fb_var_screeninfo *var = &radeonfb_default_var;
1400
1401 /*
1402 * Update default var to match the lcd monitor's native resolution
1403 */
1404 var->xres = rinfo->panel_xres;
1405 var->yres = rinfo->panel_yres;
1406 var->xres_virtual = rinfo->panel_xres;
1407 var->yres_virtual = rinfo->panel_yres;
1408 var->xoffset = var->yoffset = 0;
1409 var->bits_per_pixel = 8;
1410 var->pixclock = 100000000 / rinfo->clock;
1411 var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
1412 var->right_margin = rinfo->hOver_plus;
1413 var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
1414 var->lower_margin = rinfo->vOver_plus;
1415 var->hsync_len = rinfo->hSync_width;
1416 var->vsync_len = rinfo->vSync_width;
1417 var->sync = 0;
1418 if (rinfo->hAct_high)
1419 var->sync |= FB_SYNC_HOR_HIGH_ACT;
1420 if (rinfo->vAct_high)
1421 var->sync |= FB_SYNC_VERT_HIGH_ACT;
1422
1423 var->vmode = 0;
1424 if (rinfo->interlaced)
1425 var->vmode |= FB_VMODE_INTERLACED;
1426
1427 rinfo->use_default_var = 1;
1428 }
1429
1430 /* Copied from XFree86 4.3 --BenH */
1431 static int
radeon_get_dfpinfo_BIOS(struct radeonfb_info * rinfo,unsigned char * fpbiosstart)1432 radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart)
1433 {
1434 unsigned char *tmp;
1435 unsigned short offset;
1436
1437 offset = readw(fpbiosstart + 0x34);
1438 if (offset != 0)
1439 offset = readw(rinfo->bios_seg + offset + 2);
1440 if (offset == 0) {
1441 printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1442 return 0;
1443 }
1444 tmp = rinfo->bios_seg + offset;
1445
1446 /* This is an EDID block */
1447 rinfo->clock = readw(tmp);
1448 rinfo->panel_xres = (readb(tmp + 2) + ((readb(tmp + 4) & 0xf0) << 4));
1449 rinfo->hblank = (readb(tmp + 3) + ((readb(tmp + 4) & 0x0f) << 8));
1450 rinfo->panel_yres = (readb(tmp + 5) + ((readb(tmp + 7) & 0xf0) << 4));
1451 rinfo->vblank = (readb(tmp + 6) + ((readb(tmp + 7) & 0x0f) << 8));
1452 rinfo->hOver_plus = (readb(tmp + 8) + ((readb(tmp + 11) & 0xc0) << 2));
1453 rinfo->hSync_width = (readb(tmp + 9) + ((readb(tmp + 11) & 0x30) << 4));
1454 rinfo->vOver_plus = ((readb(tmp + 10) >> 4) + ((readb(tmp + 11) & 0x0c) << 2));
1455 rinfo->vSync_width = ((readb(tmp + 10) & 0x0f) + ((readb(tmp + 11) & 0x03) << 4));
1456 rinfo->interlaced = ((readb(tmp + 17) & 0x80) >> 7);
1457 rinfo->synct = ((readb(tmp + 17) & 0x18) >> 3);
1458 rinfo->misc = ((readb(tmp + 17) & 0x06) >> 1);
1459 rinfo->hAct_high = rinfo->vAct_high = 0;
1460 if (rinfo->synct == 3) {
1461 if (rinfo->misc & 2)
1462 rinfo->hAct_high = 1;
1463 if (rinfo->misc & 1)
1464 rinfo->vAct_high = 1;
1465 }
1466
1467 printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
1468 rinfo->panel_xres, rinfo->panel_yres);
1469
1470 rinfo->got_dfpinfo = 1;
1471 return 1;
1472 }
1473
1474
1475 static int
radeon_get_lcdinfo_BIOS(struct radeonfb_info * rinfo,unsigned char * fpbiosstart)1476 radeon_get_lcdinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart)
1477 {
1478 unsigned char *tmp, *tmp0;
1479 unsigned char stmp[30];
1480 unsigned short offset;
1481 int i;
1482
1483 offset = readw(fpbiosstart + 0x40);
1484 if (offset == 0) {
1485 printk("radeonfb: Failed to detect LCD panel info using BIOS\n");
1486 return 0;
1487 }
1488 tmp = rinfo->bios_seg + offset;
1489
1490 for(i=0; i<24; i++)
1491 stmp[i] = readb(tmp+i+1);
1492 stmp[24] = 0;
1493 printk("radeonfb: panel ID string: %s\n", stmp);
1494 rinfo->panel_xres = readw(tmp + 25);
1495 rinfo->panel_yres = readw(tmp + 27);
1496 printk("radeonfb: detected LCD panel size from BIOS: %dx%d\n",
1497 rinfo->panel_xres, rinfo->panel_yres);
1498
1499 for(i=0; i<20; i++) {
1500 tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
1501 if (tmp0 == 0)
1502 break;
1503 if ((readw(tmp0) == rinfo->panel_xres) &&
1504 (readw(tmp0+2) == rinfo->panel_yres)) {
1505 rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
1506 rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
1507 rinfo->hSync_width = readb(tmp0+23) * 8;
1508 rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
1509 rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
1510 rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
1511 rinfo->clock = readw(tmp0+9);
1512 /* We don't know that the H/V sync active level should be
1513 make the same assumptions as XFree does - High Active */
1514 rinfo->vAct_high=1;
1515 rinfo->hAct_high=1;
1516 rinfo->got_dfpinfo = 1;
1517 return 1;
1518 }
1519 }
1520 return 0;
1521 }
1522
radeon_get_panelinfo_BIOS(struct radeonfb_info * rinfo)1523 static int radeon_get_panelinfo_BIOS(struct radeonfb_info *rinfo)
1524 {
1525 unsigned char *fpbiosstart;
1526
1527 if (!rinfo->bios_seg)
1528 return 0;
1529
1530 if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
1531 printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1532 return 0;
1533 }
1534
1535 if (rinfo->dviDisp_type == MT_LCD)
1536 return radeon_get_lcdinfo_BIOS(rinfo, fpbiosstart);
1537 else if (rinfo->dviDisp_type == MT_DFP)
1538 return radeon_get_dfpinfo_BIOS(rinfo, fpbiosstart);
1539
1540 return 0;
1541 }
1542
1543
1544
radeon_get_dfpinfo(struct radeonfb_info * rinfo)1545 static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
1546 {
1547 unsigned int tmp;
1548 unsigned short a, b;
1549
1550 if (radeon_get_panelinfo_BIOS(rinfo))
1551 radeon_update_default_var(rinfo);
1552
1553 if (radeon_dfp_parse_EDID(rinfo))
1554 radeon_update_default_var(rinfo);
1555
1556 if (!rinfo->got_dfpinfo) {
1557 /*
1558 * it seems all else has failed now and we
1559 * resort to probing registers for our DFP info
1560 */
1561 if (panel_yres) {
1562 rinfo->panel_yres = panel_yres;
1563 } else {
1564 tmp = INREG(FP_VERT_STRETCH);
1565 tmp &= 0x00fff000;
1566 rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
1567 }
1568
1569 switch (rinfo->panel_yres) {
1570 case 480:
1571 rinfo->panel_xres = 640;
1572 break;
1573 case 600:
1574 rinfo->panel_xres = 800;
1575 break;
1576 case 768:
1577 rinfo->panel_xres = 1024;
1578 break;
1579 case 1024:
1580 rinfo->panel_xres = 1280;
1581 break;
1582 case 1050:
1583 rinfo->panel_xres = 1400;
1584 break;
1585 case 1200:
1586 rinfo->panel_xres = 1600;
1587 break;
1588 default:
1589 printk("radeonfb: Failed to detect DFP panel size\n");
1590 return 0;
1591 }
1592
1593 printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
1594 rinfo->panel_xres, rinfo->panel_yres);
1595
1596 tmp = INREG(FP_CRTC_H_TOTAL_DISP);
1597 a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
1598 b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
1599 rinfo->hblank = (a - b + 1) * 8;
1600
1601 tmp = INREG(FP_H_SYNC_STRT_WID);
1602 rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
1603 FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
1604 rinfo->hOver_plus *= 8;
1605 rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
1606 FP_H_SYNC_WID_SHIFT);
1607 rinfo->hSync_width *= 8;
1608 tmp = INREG(FP_CRTC_V_TOTAL_DISP);
1609 a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
1610 b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
1611 rinfo->vblank = a - b /* + 24 */ ;
1612
1613 tmp = INREG(FP_V_SYNC_STRT_WID);
1614 rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
1615 - b + 1;
1616 rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
1617 FP_V_SYNC_WID_SHIFT);
1618
1619 /* XXX */
1620 /* We should calculate the pixclock as well here... --BenH.
1621 */
1622
1623 return 1;
1624 }
1625
1626 return 1;
1627 }
1628
radeonfb_pci_register(struct pci_dev * pdev,const struct pci_device_id * ent)1629 static int radeonfb_pci_register (struct pci_dev *pdev,
1630 const struct pci_device_id *ent)
1631 {
1632 struct radeonfb_info *rinfo;
1633 struct fb_info *fb_info;
1634 struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
1635 u32 tmp;
1636 int i, j;
1637
1638 RTRACE("radeonfb_pci_register BEGIN\n");
1639
1640 rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
1641 if (!rinfo) {
1642 printk ("radeonfb: could not allocate memory\n");
1643 return -ENODEV;
1644 }
1645
1646 memset (rinfo, 0, sizeof (struct radeonfb_info));
1647
1648 fb_info = (struct fb_info *)rinfo;
1649 rinfo->pdev = pdev;
1650 strncpy(rinfo->name, rci->name, 16);
1651 rinfo->arch = rci->arch;
1652
1653 /* enable device */
1654 {
1655 int err;
1656
1657 if ((err = pci_enable_device(pdev))) {
1658 printk("radeonfb: cannot enable device\n");
1659 kfree (rinfo);
1660 return -ENODEV;
1661 }
1662 }
1663
1664 /* set base addrs */
1665 rinfo->fb_base_phys = pci_resource_start (pdev, 0);
1666 rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
1667
1668 /* request the mem regions */
1669 if (!request_mem_region (rinfo->fb_base_phys,
1670 pci_resource_len(pdev, 0), "radeonfb")) {
1671 printk ("radeonfb: cannot reserve FB region\n");
1672 kfree (rinfo);
1673 return -ENODEV;
1674 }
1675
1676 if (!request_mem_region (rinfo->mmio_base_phys,
1677 pci_resource_len(pdev, 2), "radeonfb")) {
1678 printk ("radeonfb: cannot reserve MMIO region\n");
1679 release_mem_region (rinfo->fb_base_phys,
1680 pci_resource_len(pdev, 0));
1681 kfree (rinfo);
1682 return -ENODEV;
1683 }
1684
1685 /* map the regions */
1686 rinfo->mmio_base = (unsigned long) ioremap (rinfo->mmio_base_phys,
1687 RADEON_REGSIZE);
1688 if (!rinfo->mmio_base) {
1689 printk ("radeonfb: cannot map MMIO\n");
1690 release_mem_region (rinfo->mmio_base_phys,
1691 pci_resource_len(pdev, 2));
1692 release_mem_region (rinfo->fb_base_phys,
1693 pci_resource_len(pdev, 0));
1694 kfree (rinfo);
1695 return -ENODEV;
1696 }
1697
1698 rinfo->chipset = pdev->device;
1699
1700 switch (rinfo->arch) {
1701 case RADEON_R100:
1702 rinfo->hasCRTC2 = 0;
1703 break;
1704 default:
1705 /* all the rest have it */
1706 rinfo->hasCRTC2 = 1;
1707 break;
1708 }
1709
1710 if (mirror)
1711 printk("radeonfb: mirroring display to CRT\n");
1712
1713 /* framebuffer size */
1714 tmp = INREG(CONFIG_MEMSIZE);
1715
1716 /* mem size is bits [28:0], mask off the rest */
1717 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
1718
1719 /* ram type */
1720 tmp = INREG(MEM_SDRAM_MODE_REG);
1721 switch ((MEM_CFG_TYPE & tmp) >> 30) {
1722 case 0:
1723 /* SDR SGRAM (2:1) */
1724 strcpy(rinfo->ram_type, "SDR SGRAM");
1725 rinfo->ram.ml = 4;
1726 rinfo->ram.mb = 4;
1727 rinfo->ram.trcd = 1;
1728 rinfo->ram.trp = 2;
1729 rinfo->ram.twr = 1;
1730 rinfo->ram.cl = 2;
1731 rinfo->ram.loop_latency = 16;
1732 rinfo->ram.rloop = 16;
1733
1734 break;
1735 case 1:
1736 /* DDR SGRAM */
1737 strcpy(rinfo->ram_type, "DDR SGRAM");
1738 rinfo->ram.ml = 4;
1739 rinfo->ram.mb = 4;
1740 rinfo->ram.trcd = 3;
1741 rinfo->ram.trp = 3;
1742 rinfo->ram.twr = 2;
1743 rinfo->ram.cl = 3;
1744 rinfo->ram.tr2w = 1;
1745 rinfo->ram.loop_latency = 16;
1746 rinfo->ram.rloop = 16;
1747
1748 break;
1749 default:
1750 /* 64-bit SDR SGRAM */
1751 strcpy(rinfo->ram_type, "SDR SGRAM 64");
1752 rinfo->ram.ml = 4;
1753 rinfo->ram.mb = 8;
1754 rinfo->ram.trcd = 3;
1755 rinfo->ram.trp = 3;
1756 rinfo->ram.twr = 1;
1757 rinfo->ram.cl = 3;
1758 rinfo->ram.tr2w = 1;
1759 rinfo->ram.loop_latency = 17;
1760 rinfo->ram.rloop = 17;
1761
1762 break;
1763 }
1764
1765 rinfo->bios_seg = radeon_find_rom(rinfo);
1766 radeon_get_pllinfo(rinfo, rinfo->bios_seg);
1767
1768 /*
1769 * Hack to get around some busted production M6's
1770 * reporting no ram
1771 */
1772 if (rinfo->video_ram == 0) {
1773 switch (pdev->device) {
1774 case PCI_DEVICE_ID_ATI_RADEON_LY:
1775 case PCI_DEVICE_ID_ATI_RADEON_LZ:
1776 rinfo->video_ram = 8192 * 1024;
1777 break;
1778 default:
1779 break;
1780 }
1781 }
1782
1783
1784 RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
1785
1786 RTRACE("BIOS 4 scratch = %x\n", INREG(RADEON_BIOS_4_SCRATCH));
1787 RTRACE("FP_GEN_CNTL: %x, FP2_GEN_CNTL: %x\n",
1788 INREG(FP_GEN_CNTL), INREG(FP2_GEN_CNTL));
1789 RTRACE("TMDS_TRANSMITTER_CNTL: %x, TMDS_CNTL: %x, LVDS_GEN_CNTL: %x\n",
1790 INREG(TMDS_TRANSMITTER_CNTL), INREG(TMDS_CNTL), INREG(LVDS_GEN_CNTL));
1791 RTRACE("DAC_CNTL: %x, DAC_CNTL2: %x, CRTC_GEN_CNTL: %x\n",
1792 INREG(DAC_CNTL), INREG(DAC_CNTL2), INREG(CRTC_GEN_CNTL));
1793
1794
1795 #if !defined(__powerpc__)
1796 radeon_get_moninfo(rinfo);
1797 #else
1798 switch (rinfo->arch) {
1799 case RADEON_M6:
1800 case RADEON_M7:
1801 case RADEON_M9:
1802 /* If forced to no-LCD, we shut down the backlight */
1803 if (force_nolcd) {
1804 #ifdef CONFIG_PMAC_BACKLIGHT
1805 radeon_set_backlight_enable(0, BACKLIGHT_OFF, rinfo);
1806 #endif
1807 } else {
1808 rinfo->dviDisp_type = MT_LCD;
1809 break;
1810 }
1811 /* Fall through */
1812 default:
1813 radeon_get_moninfo(rinfo);
1814 break;
1815 }
1816 #endif
1817
1818 radeon_get_EDID(rinfo);
1819
1820 if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
1821 (rinfo->crtDisp_type == MT_DFP)) {
1822 if (!radeon_get_dfpinfo(rinfo)) {
1823 iounmap ((void*)rinfo->mmio_base);
1824 release_mem_region (rinfo->mmio_base_phys,
1825 pci_resource_len(pdev, 2));
1826 release_mem_region (rinfo->fb_base_phys,
1827 pci_resource_len(pdev, 0));
1828 kfree (rinfo);
1829 return -ENODEV;
1830 }
1831 }
1832
1833 fb_info->mapped_vram = min_t(unsigned int, MAX_MAPPED_VRAM, rinfo->video_ram);
1834 do {
1835 rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
1836 fb_info->mapped_vram);
1837 if (rinfo->fb_base)
1838 break;
1839
1840 fb_info->mapped_vram /= 2;
1841 } while(fb_info->mapped_vram > MIN_MAPPED_VRAM);
1842
1843 if (!rinfo->fb_base) {
1844 printk ("radeonfb: cannot map FB\n");
1845 iounmap ((void*)rinfo->mmio_base);
1846 release_mem_region (rinfo->mmio_base_phys,
1847 pci_resource_len(pdev, 2));
1848 release_mem_region (rinfo->fb_base_phys,
1849 pci_resource_len(pdev, 0));
1850 kfree (rinfo);
1851 return -ENODEV;
1852 }
1853 RTRACE(KERN_INFO "radeonfb: mapped %dk videoram\n", fb_info->mapped_vram/1024);
1854
1855 /* currcon not yet configured, will be set by first switch */
1856 rinfo->currcon = -1;
1857
1858 /* On PPC, the firmware sets up a memory mapping that tends
1859 * to cause lockups when enabling the engine. We reconfigure
1860 * the card internal memory mappings properly
1861 */
1862 #ifdef CONFIG_ALL_PPC
1863 radeon_fixup_apertures(rinfo);
1864 #else
1865 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
1866 #endif /* CONFIG_ALL_PPC */
1867
1868 /* save current mode regs before we switch into the new one
1869 * so we can restore this upon __exit
1870 */
1871 radeon_save_state (rinfo, &rinfo->init_state);
1872
1873 /* init palette */
1874 for (i=0; i<16; i++) {
1875 j = color_table[i];
1876 rinfo->palette[i].red = default_red[j];
1877 rinfo->palette[i].green = default_grn[j];
1878 rinfo->palette[i].blue = default_blu[j];
1879 }
1880
1881 pci_set_drvdata(pdev, rinfo);
1882 rinfo->next = board_list;
1883 board_list = rinfo;
1884
1885 /* set all the vital stuff */
1886 radeon_set_fbinfo (rinfo);
1887
1888 if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
1889 printk ("radeonfb: could not register framebuffer\n");
1890 iounmap ((void*)rinfo->fb_base);
1891 iounmap ((void*)rinfo->mmio_base);
1892 release_mem_region (rinfo->mmio_base_phys,
1893 pci_resource_len(pdev, 2));
1894 release_mem_region (rinfo->fb_base_phys,
1895 pci_resource_len(pdev, 0));
1896 kfree (rinfo);
1897 return -ENODEV;
1898 }
1899
1900 #ifdef CONFIG_MTRR
1901 rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
1902 rinfo->video_ram,
1903 MTRR_TYPE_WRCOMB, 1);
1904 #endif
1905
1906
1907 #ifdef CONFIG_PMAC_BACKLIGHT
1908 if (rinfo->dviDisp_type == MT_LCD)
1909 register_backlight_controller(&radeon_backlight_controller,
1910 rinfo, "ati");
1911 #endif
1912
1913 printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type,
1914 (rinfo->video_ram/(1024*1024)));
1915
1916 if (rinfo->hasCRTC2) {
1917 printk("radeonfb: DVI port %s monitor connected\n",
1918 GET_MON_NAME(rinfo->dviDisp_type));
1919 printk("radeonfb: CRT port %s monitor connected\n",
1920 GET_MON_NAME(rinfo->crtDisp_type));
1921 } else {
1922 printk("radeonfb: CRT port %s monitor connected\n",
1923 GET_MON_NAME(rinfo->crtDisp_type));
1924 }
1925
1926 #ifdef CONFIG_PMAC_PBOOK
1927 if (rinfo->arch == RADEON_M6 ||
1928 rinfo->arch == RADEON_M7 ||
1929 rinfo->arch == RADEON_M9) {
1930 /* Find PM registers in config space */
1931 rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
1932
1933 /* Enable dynamic PM of chip clocks */
1934 radeon_pm_enable_dynamic_mode(rinfo);
1935
1936 /* Register sleep callbacks */
1937 pmu_register_sleep_notifier(&radeon_sleep_notifier);
1938 printk("radeonfb: Power Management enabled for Mobility chipsets\n");
1939 }
1940 #endif
1941
1942 RTRACE("radeonfb_pci_register END\n");
1943
1944 return 0;
1945 }
1946
1947
1948
radeonfb_pci_unregister(struct pci_dev * pdev)1949 static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
1950 {
1951 struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
1952
1953 if (!rinfo)
1954 return;
1955
1956 /* restore original state */
1957 radeon_write_mode (rinfo, &rinfo->init_state);
1958
1959 #ifdef CONFIG_MTRR
1960 if (rinfo->mtrr_hdl >= 0)
1961 mtrr_del(rinfo->mtrr_hdl, 0, 0);
1962 #endif
1963
1964 unregister_framebuffer ((struct fb_info *) rinfo);
1965
1966 iounmap ((void*)rinfo->mmio_base);
1967 iounmap ((void*)rinfo->fb_base);
1968
1969 release_mem_region (rinfo->mmio_base_phys,
1970 pci_resource_len(pdev, 2));
1971 release_mem_region (rinfo->fb_base_phys,
1972 pci_resource_len(pdev, 0));
1973
1974 kfree (rinfo);
1975 }
1976
1977
radeon_engine_init(struct radeonfb_info * rinfo)1978 static int radeon_engine_init (struct radeonfb_info *rinfo)
1979 {
1980 unsigned long temp;
1981
1982 /* disable 3D engine */
1983 OUTREG(RB3D_CNTL, 0);
1984
1985 radeon_engine_reset ();
1986
1987 radeon_fifo_wait (1);
1988 if (rinfo->arch != RADEON_R300)
1989 OUTREG(RB2D_DSTCACHE_MODE, 0);
1990
1991 radeon_fifo_wait (3);
1992 /* We re-read MC_FB_LOCATION from card as it can have been
1993 * modified by XFree drivers (ouch !)
1994 */
1995 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
1996
1997 OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
1998 (rinfo->fb_local_base >> 10));
1999 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
2000 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
2001
2002 radeon_fifo_wait (1);
2003 #if defined(__BIG_ENDIAN)
2004 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
2005 #else
2006 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
2007 #endif
2008 radeon_fifo_wait (1);
2009 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
2010 DEFAULT_SC_BOTTOM_MAX));
2011
2012 temp = radeon_get_dstbpp(rinfo->depth);
2013 rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
2014
2015 radeon_fifo_wait (1);
2016 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
2017 GMC_BRUSH_SOLID_COLOR |
2018 GMC_SRC_DATATYPE_COLOR));
2019
2020 radeon_fifo_wait (7);
2021
2022 /* clear line drawing regs */
2023 OUTREG(DST_LINE_START, 0);
2024 OUTREG(DST_LINE_END, 0);
2025
2026 /* set brush color regs */
2027 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
2028 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
2029
2030 /* set source color regs */
2031 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
2032 OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
2033
2034 /* default write mask */
2035 OUTREG(DP_WRITE_MSK, 0xffffffff);
2036
2037 radeon_engine_idle ();
2038
2039 return 0;
2040 }
2041
2042
2043
radeon_set_fbinfo(struct radeonfb_info * rinfo)2044 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
2045 {
2046 struct fb_info *info;
2047
2048 info = &rinfo->info;
2049
2050 strcpy (info->modename, rinfo->name);
2051 info->node = -1;
2052 info->flags = FBINFO_FLAG_DEFAULT;
2053 info->fbops = &radeon_fb_ops;
2054 info->display_fg = NULL;
2055 strncpy (info->fontname, fontname, sizeof (info->fontname));
2056 info->fontname[sizeof (info->fontname) - 1] = 0;
2057 info->changevar = NULL;
2058 info->switch_con = radeonfb_switch;
2059 info->updatevar = radeonfb_updatevar;
2060 info->blank = radeonfb_blank;
2061
2062 if (radeon_init_disp (rinfo) < 0)
2063 return -1;
2064
2065 return 0;
2066 }
2067
2068
2069
radeon_init_disp(struct radeonfb_info * rinfo)2070 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
2071 {
2072 struct fb_info *info;
2073 struct display *disp;
2074
2075 info = &rinfo->info;
2076 disp = &rinfo->disp;
2077
2078 disp->var = radeonfb_default_var;
2079
2080 /* We must initialize disp before calling fb_find_mode, as the later
2081 * will cause an implicit call to radeonfb_set_var that could crash
2082 * if disp is NULL
2083 */
2084 info->disp = disp;
2085 rinfo->currcon_display = disp;
2086
2087 #ifndef MODULE
2088 if (mode_option)
2089 fb_find_mode (&disp->var, &rinfo->info, mode_option,
2090 NULL, 0, NULL, 8);
2091 else
2092 #endif
2093 if (!rinfo->use_default_var)
2094 fb_find_mode (&disp->var, &rinfo->info, "640x480-8@60",
2095 NULL, 0, NULL, 0);
2096
2097 disp->var.accel_flags |= FB_ACCELF_TEXT;
2098
2099 /* Do we need that below ? ... */
2100 rinfo->depth = var_to_depth(&disp->var);
2101 rinfo->bpp = disp->var.bits_per_pixel;
2102
2103 /* Apply that dawn mode ! */
2104 radeon_do_set_var(&disp->var, -1, 0, info);
2105
2106 return 0;
2107 }
2108
2109
radeon_set_dispsw(struct radeonfb_info * rinfo,struct display * disp)2110 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp)
2111
2112 {
2113 int accel;
2114
2115 accel = disp->var.accel_flags & FB_ACCELF_TEXT;
2116
2117 disp->dispsw_data = NULL;
2118
2119 disp->screen_base = (char*)rinfo->fb_base;
2120 disp->type = FB_TYPE_PACKED_PIXELS;
2121 disp->type_aux = 0;
2122 disp->ypanstep = 1;
2123 disp->ywrapstep = 0;
2124 disp->can_soft_blank = 1;
2125 disp->inverse = 0;
2126
2127 switch (disp->var.bits_per_pixel) {
2128 #ifdef FBCON_HAS_CFB8
2129 case 8:
2130 disp->visual = FB_VISUAL_PSEUDOCOLOR;
2131 disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
2132 if (accel)
2133 disp->line_length = (disp->var.xres_virtual + 0x3f) & ~0x3f;
2134 else
2135 disp->line_length = disp->var.xres_virtual;
2136 break;
2137 #endif /* FBCON_HAS_CFB8 */
2138
2139 #ifdef FBCON_HAS_CFB16
2140 case 16:
2141 disp->dispsw = accel ? &fbcon_radeon16 : &fbcon_cfb16;
2142 disp->dispsw_data = &rinfo->con_cmap.cfb16;
2143 disp->visual = FB_VISUAL_DIRECTCOLOR;
2144 if (accel)
2145 disp->line_length = (disp->var.xres_virtual * 2 + 0x3f) & ~0x3f;
2146 else
2147 disp->line_length = disp->var.xres_virtual * 2;
2148 break;
2149 #endif /* FBCON_HAS_CFB16 */
2150
2151 #ifdef FBCON_HAS_CFB24
2152 case 24:
2153 disp->dispsw = &fbcon_cfb24;
2154 disp->dispsw_data = &rinfo->con_cmap.cfb24;
2155 disp->visual = FB_VISUAL_DIRECTCOLOR;
2156 if (accel)
2157 disp->line_length = (disp->var.xres_virtual * 3 + 0x3f) & ~0x3f;
2158 else
2159 disp->line_length = disp->var.xres_virtual * 3;
2160 break;
2161 #endif /* FBCON_HAS_CFB24 */
2162
2163 #ifdef FBCON_HAS_CFB32
2164 case 32:
2165 disp->dispsw = accel ? &fbcon_radeon32 : &fbcon_cfb32;
2166 disp->dispsw_data = &rinfo->con_cmap.cfb32;
2167 disp->visual = FB_VISUAL_DIRECTCOLOR;
2168 if (accel)
2169 disp->line_length = (disp->var.xres_virtual * 4 + 0x3f) & ~0x3f;
2170 else
2171 disp->line_length = disp->var.xres_virtual * 4;
2172 break;
2173 #endif /* FBCON_HAS_CFB32 */
2174
2175 default:
2176 printk ("radeonfb: setting fbcon_dummy renderer\n");
2177 disp->dispsw = &fbcon_dummy;
2178 }
2179
2180 return;
2181 }
2182
2183
do_install_cmap(int con,struct fb_info * info)2184 static void do_install_cmap(int con, struct fb_info *info)
2185 {
2186 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2187
2188 if (con != rinfo->currcon)
2189 return;
2190
2191 if (fb_display[con].cmap.len)
2192 fb_set_cmap(&fb_display[con].cmap, 1, radeon_setcolreg, info);
2193 else {
2194 int size = radeon_get_cmap_len(&fb_display[con].var);
2195 fb_set_cmap(fb_default_cmap(size), 1, radeon_setcolreg, info);
2196 }
2197 }
2198
2199
2200
radeonfb_do_maximize(struct radeonfb_info * rinfo,struct fb_var_screeninfo * var,struct fb_var_screeninfo * v,int nom,int den)2201 static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
2202 struct fb_var_screeninfo *var,
2203 struct fb_var_screeninfo *v,
2204 int nom, int den)
2205 {
2206 static struct {
2207 int xres, yres;
2208 } modes[] = {
2209 {1600, 1280},
2210 {1280, 1024},
2211 {1024, 768},
2212 {800, 600},
2213 {640, 480},
2214 {-1, -1}
2215 };
2216 int i;
2217 struct fb_info *fb_info = (struct fb_info *)rinfo;
2218
2219 /* use highest possible virtual resolution */
2220 if (v->xres_virtual == -1 && v->yres_virtual == -1) {
2221 printk("radeonfb: using max available virtual resolution\n");
2222 for (i=0; modes[i].xres != -1; i++) {
2223 if (modes[i].xres * nom / den * modes[i].yres <
2224 fb_info->mapped_vram / 2)
2225 break;
2226 }
2227 if (modes[i].xres == -1) {
2228 printk("radeonfb: could not find virtual resolution that fits into video memory!\n");
2229 return -EINVAL;
2230 }
2231 v->xres_virtual = modes[i].xres;
2232 v->yres_virtual = modes[i].yres;
2233
2234 printk("radeonfb: virtual resolution set to max of %dx%d\n",
2235 v->xres_virtual, v->yres_virtual);
2236 } else if (v->xres_virtual == -1) {
2237 v->xres_virtual = (fb_info->mapped_vram * den /
2238 (nom * v->yres_virtual * 2)) & ~15;
2239 } else if (v->yres_virtual == -1) {
2240 v->xres_virtual = (v->xres_virtual + 15) & ~15;
2241 v->yres_virtual = fb_info->mapped_vram * den /
2242 (nom * v->xres_virtual *2);
2243 } else {
2244 if (v->xres_virtual * nom / den * v->yres_virtual >
2245 fb_info->mapped_vram) {
2246 return -EINVAL;
2247 }
2248 }
2249
2250 if (v->xres_virtual * nom / den >= 8192) {
2251 v->xres_virtual = 8192 * den / nom - 16;
2252 }
2253
2254 if (v->xres_virtual < v->xres)
2255 return -EINVAL;
2256
2257 if (v->yres_virtual < v->yres)
2258 return -EINVAL;
2259
2260 return 0;
2261 }
2262
2263
2264
2265 /*
2266 * fb ops
2267 */
2268
radeonfb_get_fix(struct fb_fix_screeninfo * fix,int con,struct fb_info * info)2269 static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
2270 struct fb_info *info)
2271 {
2272 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2273 struct display *disp;
2274
2275 disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2276
2277 memset (fix, 0, sizeof (struct fb_fix_screeninfo));
2278 sprintf (fix->id, "ATI Radeon %s", rinfo->name);
2279
2280 fix->smem_start = rinfo->fb_base_phys;
2281 fix->smem_len = rinfo->video_ram;
2282
2283 fix->type = disp->type;
2284 fix->type_aux = disp->type_aux;
2285 fix->visual = disp->visual;
2286
2287 fix->xpanstep = 8;
2288 fix->ypanstep = 1;
2289 fix->ywrapstep = 0;
2290
2291 fix->line_length = disp->line_length;
2292
2293 fix->mmio_start = rinfo->mmio_base_phys;
2294 fix->mmio_len = RADEON_REGSIZE;
2295 if (noaccel)
2296 fix->accel = FB_ACCEL_NONE;
2297 else
2298 fix->accel = FB_ACCEL_ATI_RADEON;
2299
2300 return 0;
2301 }
2302
2303
2304
radeonfb_get_var(struct fb_var_screeninfo * var,int con,struct fb_info * info)2305 static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
2306 struct fb_info *info)
2307 {
2308 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2309
2310 *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
2311
2312 return 0;
2313 }
2314
2315
radeon_do_set_var(struct fb_var_screeninfo * var,int con,int real,struct fb_info * info)2316 static int radeon_do_set_var (struct fb_var_screeninfo *var, int con,
2317 int real, struct fb_info *info)
2318 {
2319 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2320 struct display *disp;
2321 struct fb_var_screeninfo v;
2322 int nom, den, accel;
2323 unsigned chgvar = 1;
2324
2325 disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2326
2327 accel = (noaccel == 0) && ((var->accel_flags & FB_ACCELF_TEXT) != 0);
2328
2329 if (con >= 0) {
2330 chgvar = ((disp->var.xres != var->xres) ||
2331 (disp->var.yres != var->yres) ||
2332 (disp->var.xres_virtual != var->xres_virtual) ||
2333 (disp->var.yres_virtual != var->yres_virtual) ||
2334 (disp->var.bits_per_pixel != var->bits_per_pixel) ||
2335 memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
2336 memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
2337 memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)) ||
2338 var->accel_flags != disp->var.accel_flags);
2339 }
2340
2341 try_again:
2342
2343 memcpy (&v, var, sizeof (v));
2344
2345 switch (v.bits_per_pixel) {
2346 case 0 ... 8:
2347 v.bits_per_pixel = 8;
2348 break;
2349 case 9 ... 16:
2350 v.bits_per_pixel = 16;
2351 break;
2352 case 17 ... 24:
2353 v.bits_per_pixel = 24;
2354 break;
2355 case 25 ... 32:
2356 v.bits_per_pixel = 32;
2357 break;
2358 default:
2359 return -EINVAL;
2360 }
2361
2362 switch (var_to_depth(&v)) {
2363 #ifdef FBCON_HAS_CFB8
2364 case 8:
2365 nom = den = 1;
2366 if (accel)
2367 disp->line_length = (v.xres_virtual + 0x3f) & ~0x3f;
2368 else
2369 disp->line_length = v.xres_virtual;
2370 disp->visual = FB_VISUAL_PSEUDOCOLOR;
2371 v.red.offset = v.green.offset = v.blue.offset = 0;
2372 v.red.length = v.green.length = v.blue.length = 8;
2373 v.transp.offset = v.transp.length = 0;
2374 break;
2375 #endif
2376
2377 #ifdef FBCON_HAS_CFB16
2378 case 15:
2379 nom = 2;
2380 den = 1;
2381 if (accel)
2382 disp->line_length = (v.xres_virtual * 2 + 0x3f) & ~0x3f;
2383 else
2384 disp->line_length = v.xres_virtual * 2;
2385 disp->visual = FB_VISUAL_DIRECTCOLOR;
2386 v.red.offset = 10;
2387 v.green.offset = 5;
2388 v.blue.offset = 0;
2389 v.red.length = v.green.length = v.blue.length = 5;
2390 v.transp.offset = v.transp.length = 0;
2391 break;
2392 case 16:
2393 nom = 2;
2394 den = 1;
2395 if (accel)
2396 disp->line_length = (v.xres_virtual * 2 + 0x3f) & ~0x3f;
2397 else
2398 disp->line_length = v.xres_virtual * 2;
2399 disp->visual = FB_VISUAL_DIRECTCOLOR;
2400 v.red.offset = 11;
2401 v.green.offset = 5;
2402 v.blue.offset = 0;
2403 v.red.length = 5;
2404 v.green.length = 6;
2405 v.blue.length = 5;
2406 v.transp.offset = v.transp.length = 0;
2407 break;
2408 #endif
2409
2410 #ifdef FBCON_HAS_CFB24
2411 case 24:
2412 nom = 4;
2413 den = 1;
2414 if (accel)
2415 disp->line_length = (v.xres_virtual * 3 + 0x3f) & ~0x3f;
2416 else
2417 disp->line_length = v.xres_virtual * 3;
2418 disp->visual = FB_VISUAL_DIRECTCOLOR;
2419 v.red.offset = 16;
2420 v.green.offset = 8;
2421 v.blue.offset = 0;
2422 v.red.length = v.blue.length = v.green.length = 8;
2423 v.transp.offset = v.transp.length = 0;
2424 break;
2425 #endif
2426 #ifdef FBCON_HAS_CFB32
2427 case 32:
2428 nom = 4;
2429 den = 1;
2430 if (accel)
2431 disp->line_length = (v.xres_virtual * 4 + 0x3f) & ~0x3f;
2432 else
2433 disp->line_length = v.xres_virtual * 4;
2434 disp->visual = FB_VISUAL_DIRECTCOLOR;
2435 v.red.offset = 16;
2436 v.green.offset = 8;
2437 v.blue.offset = 0;
2438 v.red.length = v.blue.length = v.green.length = 8;
2439 v.transp.offset = 24;
2440 v.transp.length = 8;
2441 break;
2442 #endif
2443 default:
2444 printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
2445 var->xres, var->yres, var->bits_per_pixel);
2446 return -EINVAL;
2447 }
2448
2449 if (((v.xres_virtual * v.yres_virtual * nom) / den) > info->mapped_vram)
2450 return -EINVAL;
2451
2452 if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
2453 return -EINVAL;
2454
2455 if (v.xoffset < 0)
2456 v.xoffset = 0;
2457 if (v.yoffset < 0)
2458 v.yoffset = 0;
2459
2460 if (v.xoffset > v.xres_virtual - v.xres)
2461 v.xoffset = v.xres_virtual - v.xres - 1;
2462
2463 if (v.yoffset > v.yres_virtual - v.yres)
2464 v.yoffset = v.yres_virtual - v.yres - 1;
2465
2466 v.red.msb_right = v.green.msb_right = v.blue.msb_right =
2467 v.transp.offset = v.transp.length =
2468 v.transp.msb_right = 0;
2469
2470 switch (v.activate & FB_ACTIVATE_MASK) {
2471 case FB_ACTIVATE_TEST:
2472 return 0;
2473 case FB_ACTIVATE_NXTOPEN:
2474 case FB_ACTIVATE_NOW:
2475 break;
2476 default:
2477 return -EINVAL;
2478 }
2479
2480 /* Set real accel */
2481 if (accel)
2482 v.accel_flags |= FB_ACCELF_TEXT;
2483 else
2484 v.accel_flags &= ~FB_ACCELF_TEXT;
2485
2486 memcpy (&disp->var, &v, sizeof (v));
2487
2488 if (real)
2489 radeon_load_video_mode (rinfo, &v);
2490 if (accel && real) {
2491 if (radeon_engine_init(rinfo) < 0) {
2492 var->accel_flags &= ~FB_ACCELF_TEXT;
2493 goto try_again;
2494 }
2495 }
2496
2497 if (chgvar) {
2498 radeon_set_dispsw(rinfo, disp);
2499
2500 if (!accel)
2501 disp->scrollmode = SCROLL_YREDRAW;
2502 else
2503 disp->scrollmode = 0;
2504
2505 if (info && info->changevar && con >= 0)
2506 info->changevar(con);
2507 }
2508
2509 if (real)
2510 do_install_cmap(con, info);
2511
2512 return 0;
2513 }
2514
radeonfb_set_var(struct fb_var_screeninfo * var,int con,struct fb_info * info)2515 static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
2516 struct fb_info *info)
2517 {
2518 return radeon_do_set_var(var, con, 1, info);
2519 }
2520
2521
radeonfb_get_cmap(struct fb_cmap * cmap,int kspc,int con,struct fb_info * info)2522 static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
2523 struct fb_info *info)
2524 {
2525 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2526 struct display *disp;
2527
2528 disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2529
2530 if (con == rinfo->currcon) {
2531 int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
2532 return rc;
2533 } else if (disp->cmap.len)
2534 fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
2535 else
2536 fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
2537 cmap, kspc ? 0 : 2);
2538
2539 return 0;
2540 }
2541
2542
2543
radeonfb_set_cmap(struct fb_cmap * cmap,int kspc,int con,struct fb_info * info)2544 static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
2545 struct fb_info *info)
2546 {
2547 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2548 struct display *disp;
2549 unsigned int cmap_len;
2550
2551 disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2552
2553 cmap_len = radeon_get_cmap_len (&disp->var);
2554 if (disp->cmap.len != cmap_len) {
2555 int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
2556 if (err)
2557 return err;
2558 }
2559
2560 if (con == rinfo->currcon) {
2561 int rc = fb_set_cmap (cmap, kspc, radeon_setcolreg, info);
2562 return rc;
2563 } else
2564 fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
2565
2566 return 0;
2567 }
2568
2569
2570
radeonfb_pan_display(struct fb_var_screeninfo * var,int con,struct fb_info * info)2571 static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
2572 struct fb_info *info)
2573 {
2574 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2575
2576 if (((var->xoffset + var->xres) > var->xres_virtual)
2577 || ((var->yoffset + var->yres) > var->yres_virtual))
2578 return -EINVAL;
2579
2580 if (rinfo->asleep)
2581 return 0;
2582
2583 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
2584 * var->bits_per_pixel / 8) & ~7);
2585
2586 return 0;
2587 }
2588
2589
radeonfb_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg,int con,struct fb_info * info)2590 static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
2591 unsigned long arg, int con, struct fb_info *info)
2592 {
2593 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2594 unsigned int tmp;
2595 u32 value = 0;
2596 int rc;
2597
2598 switch (cmd) {
2599 /*
2600 * TODO: set mirror accordingly for non-Mobility chipsets with 2 CRTC's
2601 */
2602 case FBIO_RADEON_SET_MIRROR:
2603 switch (rinfo->arch) {
2604 case RADEON_M6:
2605 case RADEON_M7:
2606 case RADEON_M9:
2607 break;
2608 default:
2609 return -EINVAL;
2610 }
2611
2612 rc = get_user(value, (__u32*)arg);
2613
2614 if (rc)
2615 return rc;
2616
2617 if (value & 0x01) {
2618 tmp = INREG(LVDS_GEN_CNTL);
2619
2620 tmp |= (LVDS_ON | LVDS_BLON);
2621 } else {
2622 tmp = INREG(LVDS_GEN_CNTL);
2623
2624 tmp &= ~(LVDS_ON | LVDS_BLON);
2625 }
2626
2627 OUTREG(LVDS_GEN_CNTL, tmp);
2628
2629 if (value & 0x02) {
2630 tmp = INREG(CRTC_EXT_CNTL);
2631 tmp |= CRTC_CRT_ON;
2632
2633 mirror = 1;
2634 } else {
2635 tmp = INREG(CRTC_EXT_CNTL);
2636 tmp &= ~CRTC_CRT_ON;
2637
2638 mirror = 0;
2639 }
2640
2641 OUTREG(CRTC_EXT_CNTL, tmp);
2642
2643 return 0;
2644
2645 case FBIO_RADEON_GET_MIRROR:
2646 switch (rinfo->arch) {
2647 case RADEON_M6:
2648 case RADEON_M7:
2649 case RADEON_M9:
2650 break;
2651 default:
2652 return -EINVAL;
2653 }
2654
2655 tmp = INREG(LVDS_GEN_CNTL);
2656 if ((LVDS_ON | LVDS_BLON) & tmp)
2657 value |= 0x01;
2658
2659 tmp = INREG(CRTC_EXT_CNTL);
2660 if (CRTC_CRT_ON & tmp)
2661 value |= 0x02;
2662
2663 return put_user(value, (__u32*)arg);
2664 }
2665
2666 return -EINVAL;
2667 }
2668
2669
radeonfb_switch(int con,struct fb_info * info)2670 static int radeonfb_switch (int con, struct fb_info *info)
2671 {
2672 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2673 struct display *disp, *old_disp;
2674 struct fb_cmap *cmap;
2675 int switchmode = 0;
2676
2677 disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2678 old_disp = rinfo->currcon_display;
2679
2680 if (rinfo->currcon >= 0) {
2681 cmap = &(rinfo->currcon_display->cmap);
2682 if (cmap->len)
2683 fb_get_cmap (cmap, 1, radeon_getcolreg, info);
2684 }
2685
2686 if ((old_disp == NULL) || ((disp->var.xres != old_disp->var.xres) ||
2687 (disp->var.yres != old_disp->var.yres) ||
2688 (disp->var.xres_virtual != old_disp->var.xres_virtual) ||
2689 (disp->var.yres_virtual != old_disp->var.yres_virtual) ||
2690 (disp->var.bits_per_pixel != old_disp->var.bits_per_pixel) ||
2691 memcmp (&disp->var.red, &old_disp->var.red, sizeof (old_disp->var.red)) ||
2692 memcmp (&disp->var.green, &old_disp->var.green, sizeof (old_disp->var.green)) ||
2693 memcmp (&disp->var.blue, &old_disp->var.blue, sizeof (old_disp->var.blue)) ||
2694 old_disp->var.accel_flags != disp->var.accel_flags))
2695 switchmode = 1;
2696
2697 if (rinfo->currcon == -1)
2698 switchmode = 1;
2699
2700 try_again:
2701 rinfo->currcon = con;
2702 rinfo->currcon_display = disp;
2703 disp->var.activate = FB_ACTIVATE_NOW;
2704
2705 if (switchmode) {
2706 radeonfb_set_var (&disp->var, con, info);
2707 do_install_cmap(con, info);
2708 } else {
2709 if (radeon_engine_init(rinfo) < 0) {
2710 disp->var.accel_flags &= ~FB_ACCELF_TEXT;
2711 switchmode = 1;
2712 goto try_again;
2713 }
2714 }
2715
2716 radeon_set_dispsw (rinfo, disp);
2717
2718 return 0;
2719 }
2720
2721
radeonfb_updatevar(int con,struct fb_info * info)2722 static int radeonfb_updatevar (int con, struct fb_info *info)
2723 {
2724 int rc;
2725
2726 rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
2727 con, info);
2728
2729 return rc;
2730 }
2731
radeonfb_blank(int blank,struct fb_info * info)2732 static void radeonfb_blank (int blank, struct fb_info *info)
2733 {
2734 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2735 u32 val = INREG(CRTC_EXT_CNTL);
2736 u32 val_lvds = INREG(LVDS_GEN_CNTL);
2737 u32 val_dfp = INREG(FP_GEN_CNTL);
2738
2739 if (rinfo->asleep)
2740 return;
2741
2742 #ifdef CONFIG_PMAC_BACKLIGHT
2743 if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
2744 set_backlight_enable(!blank);
2745 return;
2746 }
2747 #endif
2748
2749 /* reset it */
2750 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
2751 CRTC_VSYNC_DIS);
2752 val_lvds &= ~(LVDS_DISPLAY_DIS);
2753 val_dfp |= FP_FPON | FP_TMDS_EN;
2754
2755 switch (blank) {
2756 case VESA_NO_BLANKING:
2757 break;
2758 case VESA_VSYNC_SUSPEND:
2759 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
2760 break;
2761 case VESA_HSYNC_SUSPEND:
2762 val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
2763 break;
2764 case VESA_POWERDOWN:
2765 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
2766 CRTC_HSYNC_DIS);
2767 val_lvds |= (LVDS_DISPLAY_DIS);
2768 val_dfp &= ~(FP_FPON | FP_TMDS_EN);
2769 break;
2770 }
2771
2772 switch (rinfo->dviDisp_type) {
2773 case MT_LCD:
2774 OUTREG(LVDS_GEN_CNTL, val_lvds);
2775 break;
2776 case MT_DFP:
2777 OUTREG(FP_GEN_CNTL, val_dfp);
2778 break;
2779 case MT_CRT:
2780 default:
2781 OUTREG(CRTC_EXT_CNTL, val);
2782 break;
2783 }
2784 }
2785
2786
radeon_get_cmap_len(const struct fb_var_screeninfo * var)2787 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
2788 {
2789 int rc = 256; /* reasonable default */
2790
2791 switch (var_to_depth(var)) {
2792 case 15:
2793 rc = 32;
2794 break;
2795 case 16:
2796 rc = 64;
2797 break;
2798 }
2799
2800 return rc;
2801 }
2802
2803
radeon_getcolreg(unsigned regno,unsigned * red,unsigned * green,unsigned * blue,unsigned * transp,struct fb_info * info)2804 static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
2805 unsigned *blue, unsigned *transp,
2806 struct fb_info *info)
2807 {
2808 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2809
2810 if (regno > 255)
2811 return 1;
2812
2813 *red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red;
2814 *green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
2815 *blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
2816 *transp = 0;
2817
2818 return 0;
2819 }
2820
2821
2822
radeon_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * info)2823 static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
2824 unsigned blue, unsigned transp, struct fb_info *info)
2825 {
2826 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2827 u32 pindex;
2828
2829 if (regno > 255)
2830 return 1;
2831
2832 red >>= 8;
2833 green >>= 8;
2834 blue >>= 8;
2835 rinfo->palette[regno].red = red;
2836 rinfo->palette[regno].green = green;
2837 rinfo->palette[regno].blue = blue;
2838
2839 /* default */
2840 pindex = regno;
2841
2842 if (!rinfo->asleep) {
2843 u32 dac_cntl2, vclk_cntl;
2844
2845 vclk_cntl = INPLL(VCLK_ECP_CNTL);
2846 OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
2847
2848 /* Make sure we are on first palette */
2849 if (rinfo->hasCRTC2) {
2850 dac_cntl2 = INREG(DAC_CNTL2);
2851 dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
2852 OUTREG(DAC_CNTL2, dac_cntl2);
2853 }
2854
2855 if (rinfo->bpp == 16) {
2856 pindex = regno * 8;
2857
2858 if (rinfo->depth == 16 && regno > 63)
2859 return 1;
2860 if (rinfo->depth == 15 && regno > 31)
2861 return 1;
2862
2863 /* For 565, the green component is mixed one order below */
2864 if (rinfo->depth == 16) {
2865 OUTREG8(PALETTE_INDEX, pindex>>1);
2866 OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
2867 (green << 8) | (rinfo->palette[regno>>1].blue));
2868 green = rinfo->palette[regno<<1].green;
2869 }
2870 }
2871
2872 if (rinfo->depth != 16 || regno < 32) {
2873 OUTREG8(PALETTE_INDEX, pindex);
2874 OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
2875 }
2876
2877 OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
2878 }
2879 if (regno < 16) {
2880 switch (rinfo->depth) {
2881 #ifdef FBCON_HAS_CFB16
2882 case 15:
2883 rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
2884 regno;
2885 break;
2886 case 16:
2887 rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) |
2888 regno;
2889 break;
2890 #endif
2891 #ifdef FBCON_HAS_CFB24
2892 case 24:
2893 rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
2894 break;
2895 #endif
2896 #ifdef FBCON_HAS_CFB32
2897 case 32: {
2898 u32 i;
2899
2900 i = (regno << 8) | regno;
2901 rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
2902 break;
2903 }
2904 #endif
2905 }
2906 }
2907 return 0;
2908
2909 }
2910
2911
radeon_save_state(struct radeonfb_info * rinfo,struct radeon_regs * save)2912 static void radeon_save_state (struct radeonfb_info *rinfo,
2913 struct radeon_regs *save)
2914 {
2915 /* CRTC regs */
2916 save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
2917 save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
2918 save->crtc_more_cntl = INREG(CRTC_MORE_CNTL);
2919 save->dac_cntl = INREG(DAC_CNTL);
2920 save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
2921 save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
2922 save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
2923 save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
2924 save->crtc_pitch = INREG(CRTC_PITCH);
2925 #if defined(__BIG_ENDIAN)
2926 save->surface_cntl = INREG(SURFACE_CNTL);
2927 #endif
2928
2929 /* FP regs */
2930 save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
2931 save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
2932 save->fp_gen_cntl = INREG(FP_GEN_CNTL);
2933 save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID);
2934 save->fp_horz_stretch = INREG(FP_HORZ_STRETCH);
2935 save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID);
2936 save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
2937 save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
2938 save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
2939 save->tmds_crc = INREG(TMDS_CRC);
2940 save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
2941 save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
2942 }
2943
2944
radeon_calc_pll_regs(struct radeonfb_info * rinfo,struct radeon_regs * regs,unsigned long freq)2945 static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs, unsigned long freq)
2946 {
2947 const struct {
2948 int divider;
2949 int bitvalue;
2950 } *post_div,
2951 post_divs[] = {
2952 { 1, 0 },
2953 { 2, 1 },
2954 { 4, 2 },
2955 { 8, 3 },
2956 { 3, 4 },
2957 { 16, 5 },
2958 { 6, 6 },
2959 { 12, 7 },
2960 { 0, 0 },
2961 };
2962
2963 if (freq > rinfo->pll.ppll_max)
2964 freq = rinfo->pll.ppll_max;
2965 if (freq*12 < rinfo->pll.ppll_min)
2966 freq = rinfo->pll.ppll_min / 12;
2967
2968
2969 for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
2970 rinfo->pll_output_freq = post_div->divider * freq;
2971 if (rinfo->pll_output_freq >= rinfo->pll.ppll_min &&
2972 rinfo->pll_output_freq <= rinfo->pll.ppll_max)
2973 break;
2974 }
2975
2976 /* Why do we have those in rinfo at this point ? --BenH */
2977 rinfo->post_div = post_div->divider;
2978 rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
2979 rinfo->pll.ref_clk);
2980 regs->ppll_ref_div = rinfo->pll.ref_div;
2981 regs->ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
2982
2983 #ifdef CONFIG_ALL_PPC
2984 /* Gross hack for iBook with M7 until I find out a proper fix */
2985 if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)
2986 regs->ppll_div_3 = 0x000600ad;
2987 #endif /* CONFIG_ALL_PPC */
2988
2989 RTRACE("post div = 0x%x\n", rinfo->post_div);
2990 RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
2991 RTRACE("ppll_div_3 = 0x%x\n", regs->ppll_div_3);
2992 }
2993
radeon_load_video_mode(struct radeonfb_info * rinfo,struct fb_var_screeninfo * mode)2994 static void radeon_load_video_mode (struct radeonfb_info *rinfo,
2995 struct fb_var_screeninfo *mode)
2996 {
2997 struct radeon_regs newmode;
2998 int hTotal, vTotal, hSyncStart, hSyncEnd,
2999 hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
3000 u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
3001 u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
3002 u32 sync, h_sync_pol, v_sync_pol, dotClock, pixClock;
3003 unsigned int freq;
3004 #if 0
3005 unsigned int xclk_freq, vclk_freq;
3006 int xclk_per_trans, xclk_per_trans_precise;
3007 int useable_precision, roff, ron;
3008 int min_bits;
3009 #endif
3010 int format = 0;
3011 int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
3012 int primary_mon = PRIMARY_MONITOR(rinfo);
3013 int depth = var_to_depth(mode);
3014 int accel = mode->accel_flags & FB_ACCELF_TEXT;
3015
3016 rinfo->xres = mode->xres;
3017 rinfo->yres = mode->yres;
3018 rinfo->xres_virtual = mode->xres_virtual;
3019 rinfo->yres_virtual = mode->yres_virtual;
3020 rinfo->pixclock = mode->pixclock;
3021
3022 hSyncStart = mode->xres + mode->right_margin;
3023 hSyncEnd = hSyncStart + mode->hsync_len;
3024 hTotal = hSyncEnd + mode->left_margin;
3025
3026 vSyncStart = mode->yres + mode->lower_margin;
3027 vSyncEnd = vSyncStart + mode->vsync_len;
3028 vTotal = vSyncEnd + mode->upper_margin;
3029 pixClock = mode->pixclock;
3030
3031 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3032 /* Force the native video mode of the LCD monitor.
3033 * This is complicated, because when the hardware
3034 * stretcher is used, the extra pixels are not counted
3035 * in the horizontal timing parameters. So:
3036 * - For the visible part of the display, we use the
3037 * requested paramters.
3038 * - For the invisible part of the display, we use the
3039 * parameters of the native video mode.
3040 */
3041 if (rinfo->panel_xres < mode->xres)
3042 rinfo->xres = mode->xres = rinfo->panel_xres;
3043 if (rinfo->panel_yres < mode->yres)
3044 rinfo->yres = mode->yres = rinfo->panel_yres;
3045
3046 hTotal = mode->xres + rinfo->hblank;
3047 hSyncStart = mode->xres + rinfo->hOver_plus;
3048 hSyncEnd = hSyncStart + rinfo->hSync_width;
3049
3050 vTotal = mode->yres + rinfo->vblank;
3051 vSyncStart = mode->yres + rinfo->vOver_plus;
3052 vSyncEnd = vSyncStart + rinfo->vSync_width;
3053
3054 /* If we know the LCD clock, we shall use it, unfortunately,
3055 * we may not know it until we have proper EDID probing
3056 */
3057 if (rinfo->clock)
3058 pixClock = 100000000 / rinfo->clock;
3059 }
3060 dotClock = 1000000000 / pixClock;
3061 freq = dotClock / 10; /* x100 */
3062
3063 sync = mode->sync;
3064 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
3065 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
3066
3067 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
3068 hSyncStart, hSyncEnd, hTotal);
3069 RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
3070 vSyncStart, vSyncEnd, vTotal);
3071
3072 hsync_wid = (hSyncEnd - hSyncStart) / 8;
3073 vsync_wid = vSyncEnd - vSyncStart;
3074 if (hsync_wid == 0)
3075 hsync_wid = 1;
3076 else if (hsync_wid > 0x3f) /* max */
3077 hsync_wid = 0x3f;
3078
3079 if (vsync_wid == 0)
3080 vsync_wid = 1;
3081 else if (vsync_wid > 0x1f) /* max */
3082 vsync_wid = 0x1f;
3083
3084 hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
3085 vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
3086
3087 cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
3088
3089 format = radeon_get_dstbpp(depth);
3090 bytpp = mode->bits_per_pixel >> 3;
3091
3092 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
3093 hsync_fudge = hsync_fudge_fp[format-1];
3094 else
3095 hsync_fudge = hsync_adj_tab[format-1];
3096
3097 hsync_start = hSyncStart - 8 + hsync_fudge;
3098
3099 newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
3100 (format << 8);
3101
3102 /* Clear auto-center etc... Maybe we can actually use these
3103 * later, when I implement a scaling mode that keep
3104 * aspect ratio
3105 */
3106 newmode.crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
3107 newmode.crtc_more_cntl &= 0xfffffff0;
3108
3109 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3110 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
3111 if (mirror)
3112 newmode.crtc_ext_cntl |= CRTC_CRT_ON;
3113
3114 newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
3115 CRTC_INTERLACE_EN);
3116 } else {
3117 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
3118 CRTC_CRT_ON;
3119 }
3120
3121 newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
3122 DAC_8BIT_EN;
3123
3124 newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
3125 (((mode->xres / 8) - 1) << 16));
3126
3127 newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
3128 (hsync_wid << 16) | (h_sync_pol << 23));
3129
3130 newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
3131 ((mode->yres - 1) << 16);
3132
3133 newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
3134 (vsync_wid << 16) | (v_sync_pol << 23));
3135
3136 /* We first calculate the engine pitch (we always calculate it as this value may
3137 * be used elsewhere, like when setting us the btext engine
3138 */
3139 rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
3140 & ~(0x3f)) >> 6;
3141 if (accel)
3142 /* Then, re-multiply it to get the CRTC pitch */
3143 newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
3144 else
3145 newmode.crtc_pitch = (mode->xres_virtual >> 3);
3146
3147 newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
3148
3149 /*
3150 * It looks like recent chips have a problem with SURFACE_CNTL,
3151 * setting SURF_TRANSLATION_DIS completely disables the
3152 * swapper as well, so we leave it unset now.
3153 */
3154 newmode.surface_cntl = 0;
3155
3156 #if defined(__BIG_ENDIAN)
3157 /* Setup swapping on both apertures, though we currently
3158 * only use aperture 0, enabling swapper on aperture 1
3159 * won't harm
3160 */
3161 switch (mode->bits_per_pixel) {
3162 case 16:
3163 newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
3164 newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP;
3165 break;
3166 case 24:
3167 case 32:
3168 newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
3169 newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP;
3170 break;
3171 }
3172 #endif
3173
3174 RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n",
3175 newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
3176 RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n",
3177 newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
3178
3179 newmode.xres = mode->xres;
3180 newmode.yres = mode->yres;
3181
3182 rinfo->bpp = mode->bits_per_pixel;
3183 rinfo->depth = depth;
3184
3185 RTRACE("pixclock = %lu\n", (unsigned long)pixClock);
3186 RTRACE("freq = %lu\n", (unsigned long)freq);
3187 radeon_calc_pll_regs(rinfo, &newmode, freq);
3188
3189 newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
3190
3191 #if 0
3192 /* DDA */
3193 /* XXX: Figure out if there is really a DDA on radeons ! I think there
3194 * isn't actually...
3195 */
3196 vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
3197 rinfo->pll.ref_div * rinfo->post_div);
3198 xclk_freq = rinfo->pll.xclk;
3199
3200 xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
3201
3202 min_bits = min_bits_req(xclk_per_trans);
3203 useable_precision = min_bits + 1;
3204
3205 xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
3206 vclk_freq * mode->bits_per_pixel);
3207
3208 ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
3209 2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
3210 xclk_per_trans) << (11 - useable_precision);
3211 roff = xclk_per_trans_precise * (32 - 4);
3212
3213 RTRACE("ron = %d, roff = %d\n", ron, roff);
3214 RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
3215
3216 if ((ron + rinfo->ram.rloop) >= roff) {
3217 printk("radeonfb: error ron out of range\n");
3218 return;
3219 }
3220
3221 newmode.dda_config = (xclk_per_trans_precise |
3222 (useable_precision << 16) |
3223 (rinfo->ram.rloop << 20));
3224 newmode.dda_on_off = (ron << 16) | roff;
3225 #endif
3226
3227 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3228 unsigned int hRatio, vRatio;
3229
3230 if (mode->xres > rinfo->panel_xres)
3231 mode->xres = rinfo->panel_xres;
3232 if (mode->yres > rinfo->panel_yres)
3233 mode->yres = rinfo->panel_yres;
3234
3235 newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
3236 << HORZ_PANEL_SHIFT);
3237 newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
3238 << VERT_PANEL_SHIFT);
3239
3240 if (mode->xres != rinfo->panel_xres) {
3241 hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
3242 rinfo->panel_xres);
3243 newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
3244 (newmode.fp_horz_stretch &
3245 (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
3246 HORZ_AUTO_RATIO_INC)));
3247 newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
3248 HORZ_STRETCH_ENABLE);
3249 }
3250 newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
3251
3252 if (mode->yres != rinfo->panel_yres) {
3253 vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
3254 rinfo->panel_yres);
3255 newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
3256 (newmode.fp_vert_stretch &
3257 (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
3258 newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
3259 VERT_STRETCH_ENABLE);
3260 }
3261 newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
3262
3263 newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
3264 ~(FP_SEL_CRTC2 |
3265 FP_RMX_HVSYNC_CONTROL_EN |
3266 FP_DFP_SYNC_SEL |
3267 FP_CRT_SYNC_SEL |
3268 FP_CRTC_LOCK_8DOT |
3269 FP_USE_SHADOW_EN |
3270 FP_CRTC_USE_SHADOW_VEND |
3271 FP_CRT_SYNC_ALT));
3272
3273 newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
3274 FP_CRTC_DONT_SHADOW_HEND);
3275
3276 newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
3277 newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
3278 newmode.tmds_crc = rinfo->init_state.tmds_crc;
3279 newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
3280
3281 if (primary_mon == MT_LCD) {
3282 newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
3283 newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
3284 } else {
3285 /* DFP */
3286 newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
3287 newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | TMDS_ICHCSEL) &
3288 ~(TMDS_PLLRST);
3289 /* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */
3290 if (rinfo->arch == RADEON_R100 ||
3291 rinfo->arch == RADEON_R200 ||
3292 rinfo->arch == RADEON_R300 ||
3293 rinfo->arch == RADEON_R350)
3294 newmode.tmds_transmitter_cntl &= ~TMDS_PLL_EN;
3295 else
3296 newmode.tmds_transmitter_cntl |= TMDS_PLL_EN;
3297
3298 newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
3299 }
3300
3301 newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |
3302 (((mode->xres / 8) - 1) << 16));
3303 newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |
3304 ((mode->yres - 1) << 16);
3305 newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |
3306 (hsync_wid << 16) | (h_sync_pol << 23));
3307 newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |
3308 (vsync_wid << 16) | (v_sync_pol << 23));
3309 }
3310
3311 /* do it! */
3312 if (!rinfo->asleep)
3313 radeon_write_mode (rinfo, &newmode);
3314
3315 #if defined(CONFIG_BOOTX_TEXT)
3316 btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
3317 rinfo->depth, rinfo->pitch*64);
3318 #endif
3319
3320 return;
3321 }
3322
3323
radeon_write_pll_regs(struct radeonfb_info * rinfo,struct radeon_regs * mode)3324 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
3325 {
3326 /* Workaround from XFree */
3327 if (rinfo->arch < RADEON_R300) {
3328 /* A temporal workaround for the occational blanking on certain laptop panels.
3329 This appears to related to the PLL divider registers (fail to lock?).
3330 It occurs even when all dividers are the same with their old settings.
3331 In this case we really don't need to fiddle with PLL registers.
3332 By doing this we can avoid the blanking problem with some panels.
3333 */
3334 if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
3335 (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
3336 (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK))))
3337 return;
3338 }
3339
3340 while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
3341 PPLL_DIV_SEL_MASK) {
3342 OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
3343 }
3344
3345 OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
3346
3347 while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
3348 (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
3349 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
3350 }
3351
3352 while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
3353 (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
3354 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
3355 }
3356
3357 while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
3358 (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
3359 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
3360 }
3361
3362 OUTPLL(HTOTAL_CNTL, 0);
3363
3364 OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
3365 }
3366
radeon_write_mode(struct radeonfb_info * rinfo,struct radeon_regs * mode)3367 static void radeon_write_mode (struct radeonfb_info *rinfo,
3368 struct radeon_regs *mode)
3369 {
3370 int i;
3371 int primary_mon = PRIMARY_MONITOR(rinfo);
3372
3373 radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);
3374
3375 if (rinfo->arch == RADEON_M6) {
3376 for (i=0; i<8; i++)
3377 OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
3378 } else {
3379 for (i=0; i<9; i++)
3380 OUTREG(common_regs[i].reg, common_regs[i].val);
3381 }
3382
3383 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
3384 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
3385 CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
3386 OUTREG(CRTC_MORE_CNTL, mode->crtc_more_cntl);
3387 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
3388 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
3389 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
3390 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
3391 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
3392 OUTREG(CRTC_OFFSET, 0);
3393 OUTREG(CRTC_OFFSET_CNTL, 0);
3394 OUTREG(CRTC_PITCH, mode->crtc_pitch);
3395 OUTREG(SURFACE_CNTL, mode->surface_cntl);
3396
3397 radeon_write_pll_regs(rinfo, mode);
3398
3399 #if 0
3400 /* Those don't seem to actually exist in radeon's, despite some drivers still
3401 * apparently trying to fill them, including some ATI sample codes ...
3402 * Can someone confirm what's up ? --BenH.
3403 */
3404 OUTREG(DDA_CONFIG, mode->dda_config);
3405 OUTREG(DDA_ON_OFF, mode->dda_on_off);
3406 #endif
3407
3408 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3409 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
3410 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
3411 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
3412 OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
3413 OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
3414 OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
3415 OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
3416 OUTREG(TMDS_CRC, mode->tmds_crc);
3417 OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
3418
3419 if (primary_mon == MT_LCD) {
3420 unsigned int tmp = INREG(LVDS_GEN_CNTL);
3421
3422 mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
3423 mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
3424
3425 if ((tmp & (LVDS_ON | LVDS_BLON)) ==
3426 (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
3427 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
3428 } else {
3429 if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
3430 udelay(1000);
3431 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
3432 } else {
3433 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
3434 LVDS_BLON);
3435 udelay(1000);
3436 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
3437 }
3438 }
3439 }
3440 }
3441
3442 radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);
3443
3444 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
3445
3446 return;
3447 }
3448
3449
3450 #ifdef CONFIG_PMAC_BACKLIGHT
3451
3452 /* TODO: Dbl check these tables, we don't go up to full ON backlight
3453 * in these, possibly because we noticed MacOS doesn't, but I'd prefer
3454 * having some more official numbers from ATI
3455 */
3456 static int backlight_conv_m6[] = {
3457 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
3458 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
3459 };
3460 static int backlight_conv_m7[] = {
3461 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
3462 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
3463 };
3464
3465 /* We turn off the LCD completely instead of just dimming the backlight.
3466 * This provides some greater power saving and the display is useless
3467 * without backlight anyway.
3468 */
3469
3470
radeon_set_backlight_enable(int on,int level,void * data)3471 static int radeon_set_backlight_enable(int on, int level, void *data)
3472 {
3473 struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
3474 unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
3475 int* conv_table;
3476
3477 /* Pardon me for that hack... maybe some day we can figure
3478 * out in what direction backlight should work on a given
3479 * panel ?
3480 */
3481 if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
3482 && !machine_is_compatible("PowerBook4,3"))
3483 conv_table = backlight_conv_m7;
3484 else
3485 conv_table = backlight_conv_m6;
3486
3487 lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
3488 if (on && (level > BACKLIGHT_OFF)) {
3489 lvds_gen_cntl |= LVDS_DIGON;
3490 if ((lvds_gen_cntl & LVDS_ON) == 0) {
3491 lvds_gen_cntl &= ~LVDS_BLON;
3492 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3493 (void)INREG(LVDS_GEN_CNTL);
3494 mdelay(10);
3495 lvds_gen_cntl |= LVDS_BLON;
3496 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3497 }
3498 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
3499 lvds_gen_cntl |= (conv_table[level] <<
3500 LVDS_BL_MOD_LEVEL_SHIFT);
3501 lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
3502 lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
3503 } else {
3504 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
3505 lvds_gen_cntl |= (conv_table[0] <<
3506 LVDS_BL_MOD_LEVEL_SHIFT);
3507 lvds_gen_cntl |= LVDS_DISPLAY_DIS;
3508 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3509 udelay(10);
3510 lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
3511 }
3512
3513 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3514 rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
3515 rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
3516
3517 return 0;
3518 }
3519
radeon_set_backlight_level(int level,void * data)3520 static int radeon_set_backlight_level(int level, void *data)
3521 {
3522 return radeon_set_backlight_enable(1, level, data);
3523 }
3524 #endif /* CONFIG_PMAC_BACKLIGHT */
3525
3526
3527 #ifdef CONFIG_PMAC_PBOOK
3528
3529 /*
3530 * Radeon M6, M7 and M9 Power Management code. This code currently
3531 * only supports the mobile chips in D2 mode, that is typically what
3532 * is used on Apple laptops, it's based from some informations provided by ATI
3533 * along with hours of tracing of MacOS drivers.
3534 *
3535 * New version of this code almost totally rewritten by ATI, many thanks
3536 * for their support.
3537 */
3538
OUTMC(struct radeonfb_info * rinfo,u8 indx,u32 value)3539 static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value)
3540 {
3541 OUTREG( MC_IND_INDEX, indx | MC_IND_INDEX__MC_IND_WR_EN);
3542 OUTREG( MC_IND_DATA, value);
3543 }
3544
INMC(struct radeonfb_info * rinfo,u8 indx)3545 static u32 INMC(struct radeonfb_info *rinfo, u8 indx)
3546 {
3547 OUTREG( MC_IND_INDEX, indx);
3548 return INREG( MC_IND_DATA);
3549 }
3550
radeon_pm_save_regs(struct radeonfb_info * rinfo)3551 static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
3552 {
3553 rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
3554 rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
3555 rinfo->save_regs[2] = INPLL(MCLK_CNTL);
3556 rinfo->save_regs[3] = INPLL(SCLK_CNTL);
3557 rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
3558 rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
3559 rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
3560 rinfo->save_regs[7] = INPLL(MCLK_MISC);
3561 rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
3562
3563 rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
3564 rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
3565 rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
3566 rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
3567 rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
3568 rinfo->save_regs[14] = INREG(BUS_CNTL1);
3569 rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
3570 rinfo->save_regs[16] = INREG(AGP_CNTL);
3571 rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
3572 rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
3573 rinfo->save_regs[19] = INREG(GPIOPAD_A);
3574 rinfo->save_regs[20] = INREG(GPIOPAD_EN);
3575 rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
3576 rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
3577 rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
3578 rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
3579 rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
3580 rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
3581 rinfo->save_regs[27] = INREG(GPIO_MONID);
3582 rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
3583
3584 rinfo->save_regs[29] = INREG(SURFACE_CNTL);
3585 rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
3586 rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
3587 rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
3588 rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
3589 }
3590
radeon_pm_restore_regs(struct radeonfb_info * rinfo)3591 static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
3592 {
3593 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
3594
3595 OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
3596 OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
3597 OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
3598 OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
3599 OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
3600 OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
3601 OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
3602 OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
3603
3604 OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
3605 OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
3606 OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
3607 OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
3608 OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
3609
3610 OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
3611 OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
3612 OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
3613 OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
3614 OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
3615 OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
3616 OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
3617 OUTREG(AGP_CNTL, rinfo->save_regs[16]);
3618 OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
3619 OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
3620
3621 // wait VBL before that one ?
3622 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
3623
3624 OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
3625 OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
3626 OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
3627 OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
3628 OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
3629 OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
3630 OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
3631 OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
3632 OUTREG(GPIO_MONID, rinfo->save_regs[27]);
3633 OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
3634 }
3635
radeon_pm_disable_iopad(struct radeonfb_info * rinfo)3636 static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
3637 {
3638 OUTREG(GPIOPAD_MASK, 0x0001ffff);
3639 OUTREG(GPIOPAD_EN, 0x00000400);
3640 OUTREG(GPIOPAD_A, 0x00000000);
3641 OUTREG(ZV_LCDPAD_MASK, 0x00000000);
3642 OUTREG(ZV_LCDPAD_EN, 0x00000000);
3643 OUTREG(ZV_LCDPAD_A, 0x00000000);
3644 OUTREG(GPIO_VGA_DDC, 0x00030000);
3645 OUTREG(GPIO_DVI_DDC, 0x00000000);
3646 OUTREG(GPIO_MONID, 0x00030000);
3647 OUTREG(GPIO_CRT2_DDC, 0x00000000);
3648 }
3649
radeon_pm_program_v2clk(struct radeonfb_info * rinfo)3650 static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
3651 {
3652 /* Set v2clk to 65MHz */
3653 OUTPLL(pllPIXCLKS_CNTL,
3654 INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
3655
3656 OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
3657 OUTPLL(pllP2PLL_CNTL, 0x0000bf00);
3658 OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W);
3659
3660 OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP);
3661 mdelay(1);
3662
3663 OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET);
3664 mdelay( 1);
3665
3666 OUTPLL(pllPIXCLKS_CNTL,
3667 (INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK)
3668 | (0x03 << PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT));
3669 mdelay( 1);
3670 }
3671
radeon_pm_low_current(struct radeonfb_info * rinfo)3672 static void radeon_pm_low_current(struct radeonfb_info *rinfo)
3673 {
3674 u32 reg;
3675
3676 reg = INREG(BUS_CNTL1);
3677 reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
3678 reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
3679 OUTREG(BUS_CNTL1, reg);
3680
3681 reg = INPLL(PLL_PWRMGT_CNTL);
3682 reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
3683 PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
3684 reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
3685 reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
3686 OUTPLL(PLL_PWRMGT_CNTL, reg);
3687
3688 reg = INREG(TV_DAC_CNTL);
3689 reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
3690 reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
3691 TV_DAC_CNTL_BDACPD |
3692 (8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
3693 OUTREG(TV_DAC_CNTL, reg);
3694
3695 reg = INREG(TMDS_TRANSMITTER_CNTL);
3696 reg &= ~(TMDS_PLL_EN | TMDS_PLLRST);
3697 OUTREG(TMDS_TRANSMITTER_CNTL, reg);
3698
3699 reg = INREG(DAC_CNTL);
3700 reg &= ~DAC_CMP_EN;
3701 OUTREG(DAC_CNTL, reg);
3702
3703 reg = INREG(DAC_CNTL2);
3704 reg &= ~DAC2_CMP_EN;
3705 OUTREG(DAC_CNTL2, reg);
3706
3707 reg = INREG(TV_DAC_CNTL);
3708 reg &= ~TV_DAC_CNTL_DETECT;
3709 OUTREG(TV_DAC_CNTL, reg);
3710 }
3711
radeon_pm_setup_for_suspend(struct radeonfb_info * rinfo)3712 static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
3713 {
3714
3715 u32 sclk_cntl, mclk_cntl, sclk_more_cntl;
3716
3717 u32 pll_pwrmgt_cntl;
3718 u32 clk_pwrmgt_cntl;
3719 u32 clk_pin_cntl;
3720 u32 vclk_ecp_cntl;
3721 u32 pixclks_cntl;
3722 u32 disp_mis_cntl;
3723 u32 disp_pwr_man;
3724
3725
3726 /* Force Core Clocks */
3727 sclk_cntl = INPLL( pllSCLK_CNTL_M6);
3728 sclk_cntl |= SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT|
3729 SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT|
3730 SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT|
3731 SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT|
3732 SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT|
3733 SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT|
3734 SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT|
3735
3736 SCLK_CNTL_M6__FORCE_DISP2|
3737 SCLK_CNTL_M6__FORCE_CP|
3738 SCLK_CNTL_M6__FORCE_HDP|
3739 SCLK_CNTL_M6__FORCE_DISP1|
3740 SCLK_CNTL_M6__FORCE_TOP|
3741 SCLK_CNTL_M6__FORCE_E2|
3742 SCLK_CNTL_M6__FORCE_SE|
3743 SCLK_CNTL_M6__FORCE_IDCT|
3744 SCLK_CNTL_M6__FORCE_VIP|
3745
3746 SCLK_CNTL_M6__FORCE_RE|
3747 SCLK_CNTL_M6__FORCE_PB|
3748 SCLK_CNTL_M6__FORCE_TAM|
3749 SCLK_CNTL_M6__FORCE_TDM|
3750 SCLK_CNTL_M6__FORCE_RB|
3751 SCLK_CNTL_M6__FORCE_TV_SCLK|
3752 SCLK_CNTL_M6__FORCE_SUBPIC|
3753 SCLK_CNTL_M6__FORCE_OV0;
3754
3755 OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
3756
3757 sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
3758 sclk_more_cntl |= SCLK_MORE_CNTL__FORCE_DISPREGS |
3759 SCLK_MORE_CNTL__FORCE_MC_GUI |
3760 SCLK_MORE_CNTL__FORCE_MC_HOST;
3761
3762 OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
3763
3764
3765 mclk_cntl = INPLL( pllMCLK_CNTL_M6);
3766 mclk_cntl &= ~( MCLK_CNTL_M6__FORCE_MCLKA |
3767 MCLK_CNTL_M6__FORCE_MCLKB |
3768 MCLK_CNTL_M6__FORCE_YCLKA |
3769 MCLK_CNTL_M6__FORCE_YCLKB |
3770 MCLK_CNTL_M6__FORCE_MC
3771 );
3772 OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
3773
3774 /* Force Display clocks */
3775 vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
3776 vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
3777 vclk_ecp_cntl |= VCLK_ECP_CNTL__ECP_FORCE_ON;
3778 OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
3779
3780
3781 pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
3782 pixclks_cntl &= ~( PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
3783 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
3784 PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
3785 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
3786 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
3787 PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
3788 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
3789
3790 OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
3791
3792
3793
3794 /* Enable System power management */
3795 pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL);
3796
3797 pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__SPLL_TURNOFF |
3798 PLL_PWRMGT_CNTL__MPLL_TURNOFF|
3799 PLL_PWRMGT_CNTL__PPLL_TURNOFF|
3800 PLL_PWRMGT_CNTL__P2PLL_TURNOFF|
3801 PLL_PWRMGT_CNTL__TVPLL_TURNOFF;
3802
3803 OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
3804
3805 clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
3806
3807 clk_pwrmgt_cntl &= ~( CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF|
3808 CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF|
3809 CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF|
3810 CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF|
3811 CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF|
3812 CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF|
3813 CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF|
3814 CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF|
3815 CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF|
3816 CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN|
3817 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE|
3818 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
3819 CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK
3820 );
3821
3822 clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN | CLK_PWRMGT_CNTL_M6__DISP_PM;
3823
3824 OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
3825
3826 clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
3827
3828 clk_pin_cntl &= ~CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND;
3829 OUTPLL( pllMCLK_MISC, INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND);
3830
3831 /* AGP PLL control */
3832 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID);
3833
3834 OUTREG(BUS_CNTL1,
3835 (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
3836 | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX
3837 OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
3838
3839 clk_pin_cntl &= ~CLK_PIN_CNTL__CG_CLK_TO_OUTPIN;
3840 clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
3841 OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
3842
3843 /* Solano2M */
3844 OUTREG(AGP_CNTL,
3845 (INREG(AGP_CNTL) & ~(AGP_CNTL__MAX_IDLE_CLK_MASK))
3846 | (0x20<<AGP_CNTL__MAX_IDLE_CLK__SHIFT));
3847
3848 /* ACPI mode */
3849 OUTPLL( pllPLL_PWRMGT_CNTL, INPLL( pllPLL_PWRMGT_CNTL) & ~PLL_PWRMGT_CNTL__PM_MODE_SEL);
3850
3851
3852 disp_mis_cntl = INREG(DISP_MISC_CNTL);
3853
3854 disp_mis_cntl &= ~( DISP_MISC_CNTL__SOFT_RESET_GRPH_PP |
3855 DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP |
3856 DISP_MISC_CNTL__SOFT_RESET_OV0_PP |
3857 DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK|
3858 DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK|
3859 DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK|
3860 DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP|
3861 DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK|
3862 DISP_MISC_CNTL__SOFT_RESET_LVDS|
3863 DISP_MISC_CNTL__SOFT_RESET_TMDS|
3864 DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS|
3865 DISP_MISC_CNTL__SOFT_RESET_TV);
3866
3867 OUTREG(DISP_MISC_CNTL, disp_mis_cntl);
3868
3869 disp_pwr_man = INREG(DISP_PWR_MAN);
3870
3871 disp_pwr_man &= ~( DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN |
3872 DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
3873 DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|
3874 DISP_PWR_MAN__DISP_D3_RST|
3875 DISP_PWR_MAN__DISP_D3_REG_RST
3876 );
3877
3878 disp_pwr_man |= DISP_PWR_MAN__DISP_D3_GRPH_RST|
3879 DISP_PWR_MAN__DISP_D3_SUBPIC_RST|
3880 DISP_PWR_MAN__DISP_D3_OV0_RST|
3881 DISP_PWR_MAN__DISP_D1D2_GRPH_RST|
3882 DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST|
3883 DISP_PWR_MAN__DISP_D1D2_OV0_RST|
3884 DISP_PWR_MAN__DIG_TMDS_ENABLE_RST|
3885 DISP_PWR_MAN__TV_ENABLE_RST|
3886 // DISP_PWR_MAN__AUTO_PWRUP_EN|
3887 0;
3888
3889 OUTREG(DISP_PWR_MAN, disp_pwr_man);
3890
3891 clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
3892 pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL) ;
3893 clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
3894 disp_pwr_man = INREG(DISP_PWR_MAN);
3895
3896
3897 /* D2 */
3898 clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__DISP_PM;
3899 pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__MOBILE_SU | PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK;
3900 clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
3901 disp_pwr_man &= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);
3902
3903
3904 OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
3905 OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
3906 OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
3907 OUTREG(DISP_PWR_MAN, disp_pwr_man);
3908
3909 /* disable display request & disable display */
3910 OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN) | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
3911 OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN) | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
3912
3913 mdelay(17);
3914
3915 }
3916
radeon_pm_disable_dynamic_mode(struct radeonfb_info * rinfo)3917 static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
3918 {
3919
3920 u32 sclk_cntl;
3921 u32 mclk_cntl;
3922 u32 sclk_more_cntl;
3923
3924 u32 vclk_ecp_cntl;
3925 u32 pixclks_cntl;
3926
3927 /* Mobility chips only */
3928 if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
3929 return;
3930
3931 /* Force Core Clocks */
3932 sclk_cntl = INPLL( pllSCLK_CNTL_M6);
3933 sclk_cntl |= SCLK_CNTL_M6__FORCE_CP|
3934 SCLK_CNTL_M6__FORCE_HDP|
3935 SCLK_CNTL_M6__FORCE_DISP1|
3936 SCLK_CNTL_M6__FORCE_DISP2|
3937 SCLK_CNTL_M6__FORCE_TOP|
3938 SCLK_CNTL_M6__FORCE_E2|
3939 SCLK_CNTL_M6__FORCE_SE|
3940 SCLK_CNTL_M6__FORCE_IDCT|
3941 SCLK_CNTL_M6__FORCE_VIP|
3942 SCLK_CNTL_M6__FORCE_RE|
3943 SCLK_CNTL_M6__FORCE_PB|
3944 SCLK_CNTL_M6__FORCE_TAM|
3945 SCLK_CNTL_M6__FORCE_TDM|
3946 SCLK_CNTL_M6__FORCE_RB|
3947 SCLK_CNTL_M6__FORCE_TV_SCLK|
3948 SCLK_CNTL_M6__FORCE_SUBPIC|
3949 SCLK_CNTL_M6__FORCE_OV0;
3950 OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
3951
3952
3953
3954 sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
3955 sclk_more_cntl |= SCLK_MORE_CNTL__FORCE_DISPREGS|
3956 SCLK_MORE_CNTL__FORCE_MC_GUI|
3957 SCLK_MORE_CNTL__FORCE_MC_HOST;
3958 OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
3959
3960 /* Force Display clocks */
3961 vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
3962 vclk_ecp_cntl &= ~( VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
3963 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
3964
3965 OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
3966
3967 pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
3968 pixclks_cntl &= ~( PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
3969 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
3970 PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
3971 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
3972 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
3973 PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
3974 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
3975
3976 OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
3977
3978 /* Force Memory Clocks */
3979 mclk_cntl = INPLL( pllMCLK_CNTL_M6);
3980 mclk_cntl |= MCLK_CNTL_M6__FORCE_MCLKA|
3981 MCLK_CNTL_M6__FORCE_MCLKB|
3982 MCLK_CNTL_M6__FORCE_YCLKA|
3983 MCLK_CNTL_M6__FORCE_YCLKB;
3984
3985 OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
3986 }
3987
radeon_pm_enable_dynamic_mode(struct radeonfb_info * rinfo)3988 static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
3989 {
3990 u32 clk_pwrmgt_cntl;
3991 u32 sclk_cntl;
3992 u32 sclk_more_cntl;
3993 u32 clk_pin_cntl;
3994 u32 pixclks_cntl;
3995 u32 vclk_ecp_cntl;
3996 u32 mclk_cntl;
3997 u32 mclk_misc;
3998
3999 /* Mobility chips only */
4000 if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
4001 return;
4002
4003 /* Set Latencies */
4004 clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
4005
4006 clk_pwrmgt_cntl &= ~( CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK|
4007 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
4008 CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK|
4009 CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK);
4010 /* Mode 1 */
4011 clk_pwrmgt_cntl = CLK_PWRMGT_CNTL_M6__MC_CH_MODE|
4012 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE |
4013 (1<<CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT) |
4014 (0<<CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT)|
4015 (0<<CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT);
4016
4017 OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
4018
4019
4020 clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
4021 clk_pin_cntl |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
4022
4023 OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
4024
4025 /* Enable Dyanmic mode for SCLK */
4026
4027 sclk_cntl = INPLL( pllSCLK_CNTL_M6);
4028 sclk_cntl &= SCLK_CNTL_M6__SCLK_SRC_SEL_MASK;
4029 sclk_cntl |= SCLK_CNTL_M6__FORCE_VIP;
4030
4031 OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
4032
4033
4034 sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
4035 sclk_more_cntl &= ~(SCLK_MORE_CNTL__FORCE_DISPREGS);
4036
4037 OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
4038
4039
4040 /* Enable Dynamic mode for PIXCLK & PIX2CLK */
4041
4042 pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
4043
4044 pixclks_cntl|= PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb |
4045 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
4046 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
4047 PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb|
4048 PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb|
4049 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
4050 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb;
4051
4052 OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
4053
4054
4055 vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
4056
4057 vclk_ecp_cntl|= VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
4058 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
4059
4060 OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
4061
4062
4063 /* Enable Dynamic mode for MCLK */
4064 mclk_cntl = INPLL( pllMCLK_CNTL_M6);
4065 mclk_cntl &= ~( MCLK_CNTL_M6__FORCE_MCLKA |
4066 MCLK_CNTL_M6__FORCE_MCLKB |
4067 MCLK_CNTL_M6__FORCE_YCLKA |
4068 MCLK_CNTL_M6__FORCE_YCLKB );
4069 OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
4070
4071 mclk_misc = INPLL(pllMCLK_MISC);
4072 mclk_misc |= MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
4073 MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT|
4074 MCLK_MISC__MC_MCLK_DYN_ENABLE|
4075 MCLK_MISC__IO_MCLK_DYN_ENABLE;
4076
4077 OUTPLL(pllMCLK_MISC, mclk_misc);
4078 }
4079
4080
radeon_pm_yclk_mclk_sync(struct radeonfb_info * rinfo)4081 static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo)
4082 {
4083 u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;
4084
4085 mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1) & ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
4086 mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1) & ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
4087
4088 OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
4089 OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
4090
4091 /* Wassup ? This doesn't seem to be defined, let's hope we are ok this way --BenH */
4092 #ifdef MCLK_YCLK_SYNC_ENABLE
4093 mc_chp_io_cntl_a1 |= (2<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT);
4094 mc_chp_io_cntl_b1 |= (2<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT);
4095 #endif
4096
4097 OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);
4098 OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);
4099
4100 mdelay( 1);
4101 }
4102
radeon_pm_program_mode_reg(struct radeonfb_info * rinfo,u16 value,u8 delay_required)4103 static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required)
4104 {
4105 u32 mem_sdram_mode;
4106
4107 mem_sdram_mode = INREG( MEM_SDRAM_MODE_REG);
4108
4109 mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK;
4110 mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT) | MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;
4111 OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
4112
4113 mem_sdram_mode |= MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
4114 OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
4115
4116 mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
4117 OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
4118
4119 if (delay_required == 1)
4120 while( (INREG( MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A | MC_STATUS__MEM_PWRUP_COMPL_B) ) == 0 )
4121 { };
4122 }
4123
4124
radeon_pm_enable_dll(struct radeonfb_info * rinfo)4125 static void radeon_pm_enable_dll(struct radeonfb_info *rinfo)
4126 {
4127 #define DLL_RESET_DELAY 5
4128 #define DLL_SLEEP_DELAY 1
4129
4130 u32 DLL_CKO_Value = INPLL(pllMDLL_CKO) | MDLL_CKO__MCKOA_SLEEP | MDLL_CKO__MCKOA_RESET;
4131 u32 DLL_CKA_Value = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET;
4132 u32 DLL_CKB_Value = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET;
4133
4134 /* Setting up the DLL range for write */
4135 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
4136 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
4137 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
4138
4139 mdelay( DLL_RESET_DELAY);
4140
4141 /* Channel A */
4142
4143 /* Power Up */
4144 DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_SLEEP );
4145 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
4146 mdelay( DLL_SLEEP_DELAY);
4147
4148 DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_RESET );
4149 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
4150 mdelay( DLL_RESET_DELAY);
4151
4152 /* Power Up */
4153 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_SLEEP );
4154 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
4155 mdelay( DLL_SLEEP_DELAY);
4156
4157 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_RESET );
4158 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
4159 mdelay( DLL_RESET_DELAY);
4160
4161 /* Power Up */
4162 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_SLEEP);
4163 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
4164 mdelay( DLL_SLEEP_DELAY);
4165
4166 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_RESET);
4167 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
4168 mdelay( DLL_RESET_DELAY);
4169
4170
4171 /* Channel B */
4172
4173 /* Power Up */
4174 DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_SLEEP );
4175 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
4176 mdelay( DLL_SLEEP_DELAY);
4177
4178 DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_RESET );
4179 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
4180 mdelay( DLL_RESET_DELAY);
4181
4182 /* Power Up */
4183 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_SLEEP);
4184 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
4185 mdelay( DLL_SLEEP_DELAY);
4186
4187 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_RESET);
4188 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
4189 mdelay( DLL_RESET_DELAY);
4190
4191 /* Power Up */
4192 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_SLEEP);
4193 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
4194 mdelay( DLL_SLEEP_DELAY);
4195
4196 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_RESET);
4197 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
4198 mdelay( DLL_RESET_DELAY);
4199
4200 #undef DLL_RESET_DELAY
4201 #undef DLL_SLEEP_DELAY
4202 }
4203
radeon_pm_full_reset_sdram(struct radeonfb_info * rinfo)4204 static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
4205 {
4206 u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl, fp_gen_cntl, fp2_gen_cntl;
4207
4208 crtcGenCntl = INREG( CRTC_GEN_CNTL);
4209 crtcGenCntl2 = INREG( CRTC2_GEN_CNTL);
4210
4211 memRefreshCntl = INREG( MEM_REFRESH_CNTL);
4212 crtc_more_cntl = INREG( CRTC_MORE_CNTL);
4213 fp_gen_cntl = INREG( FP_GEN_CNTL);
4214 fp2_gen_cntl = INREG( FP2_GEN_CNTL);
4215
4216
4217 OUTREG( CRTC_MORE_CNTL, 0);
4218 OUTREG( FP_GEN_CNTL, 0);
4219 OUTREG( FP2_GEN_CNTL, 0);
4220
4221 OUTREG( CRTC_GEN_CNTL, (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );
4222 OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
4223
4224 /* Disable refresh */
4225 OUTREG( MEM_REFRESH_CNTL, memRefreshCntl | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
4226
4227 /* Reset memory */
4228 OUTREG( MEM_SDRAM_MODE_REG,
4229 INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Not Complete
4230
4231 /* DLL */
4232 radeon_pm_enable_dll(rinfo);
4233
4234 // MLCK /YCLK sync
4235 radeon_pm_yclk_mclk_sync(rinfo);
4236
4237 if ((rinfo->arch == RADEON_M6) || (rinfo->arch == RADEON_M7) || (rinfo->arch == RADEON_M9)) {
4238 radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
4239 radeon_pm_program_mode_reg(rinfo, 0x2001, 1);
4240 radeon_pm_program_mode_reg(rinfo, 0x2002, 1);
4241 radeon_pm_program_mode_reg(rinfo, 0x0132, 1);
4242 radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
4243 }
4244
4245 OUTREG( MEM_SDRAM_MODE_REG,
4246 INREG( MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Complete
4247
4248 OUTREG( MEM_REFRESH_CNTL, memRefreshCntl);
4249
4250 OUTREG( CRTC_GEN_CNTL, crtcGenCntl);
4251 OUTREG( CRTC2_GEN_CNTL, crtcGenCntl2);
4252 OUTREG( FP_GEN_CNTL, fp_gen_cntl);
4253 OUTREG( FP2_GEN_CNTL, fp2_gen_cntl);
4254
4255 OUTREG( CRTC_MORE_CNTL, crtc_more_cntl);
4256
4257 mdelay( 15);
4258 }
4259
4260
radeon_set_suspend(struct radeonfb_info * rinfo,int suspend)4261 static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
4262 {
4263 u16 pwr_cmd;
4264
4265 if (!rinfo->pm_reg)
4266 return;
4267
4268 /* Set the chip into appropriate suspend mode (we use D2,
4269 * D3 would require a compete re-initialization of the chip,
4270 * including PCI config registers, clocks, AGP conf, ...)
4271 */
4272 if (suspend) {
4273 /* Disable dynamic power management of clocks for the
4274 * duration of the suspend/resume process
4275 */
4276 radeon_pm_disable_dynamic_mode(rinfo);
4277 /* Save some registers */
4278 radeon_pm_save_regs(rinfo);
4279
4280 /* Prepare mobility chips for suspend
4281 */
4282 if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9) {
4283 /* Program V2CLK */
4284 radeon_pm_program_v2clk(rinfo);
4285
4286 /* Disable IO PADs */
4287 radeon_pm_disable_iopad(rinfo);
4288
4289 /* Set low current */
4290 radeon_pm_low_current(rinfo);
4291
4292 /* Prepare chip for power management */
4293 radeon_pm_setup_for_suspend(rinfo);
4294
4295 /* Reset the MDLL */
4296 OUTPLL( pllMDLL_CKO, INPLL( pllMDLL_CKO) | MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
4297 }
4298
4299 /* Switch PCI power managment to D2. */
4300 for (;;) {
4301 pci_read_config_word(
4302 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
4303 &pwr_cmd);
4304 if (pwr_cmd & 2)
4305 break;
4306 pci_write_config_word(
4307 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
4308 (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
4309 mdelay(500);
4310 }
4311 } else {
4312 /* Switch back PCI powermanagment to D0 */
4313 mdelay(200);
4314 pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
4315 mdelay(500);
4316
4317 /* Reset the SDRAM controller */
4318 if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
4319 radeon_pm_full_reset_sdram(rinfo);
4320
4321 /* Restore some registers */
4322 radeon_pm_restore_regs(rinfo);
4323 radeon_pm_enable_dynamic_mode(rinfo);
4324 mdelay(10);
4325 }
4326 }
4327
4328 /*
4329 * Save the contents of the framebuffer when we go to sleep,
4330 * and restore it when we wake up again.
4331 */
4332
radeon_sleep_notify(struct pmu_sleep_notifier * self,int when)4333 static int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
4334 {
4335 struct radeonfb_info *rinfo;
4336
4337 for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
4338 struct fb_fix_screeninfo fix;
4339 int nb;
4340 struct display *disp;
4341
4342 disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon];
4343
4344 switch (rinfo->arch) {
4345 case RADEON_M6:
4346 case RADEON_M7:
4347 case RADEON_M9:
4348 break;
4349 default:
4350 return PBOOK_SLEEP_REFUSE;
4351 }
4352
4353 radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
4354 nb = fb_display[fg_console].var.yres * fix.line_length;
4355
4356 switch (when) {
4357 case PBOOK_SLEEP_NOW:
4358 acquire_console_sem();
4359 disp->dispsw = &fbcon_dummy;
4360
4361 if (!noaccel) {
4362 /* Make sure engine is idle and reset */
4363 radeon_engine_idle();
4364 radeon_engine_reset();
4365 radeon_engine_idle();
4366 }
4367
4368 /* Blank display and LCD */
4369 radeonfb_blank(VESA_POWERDOWN+1,
4370 (struct fb_info *)rinfo);
4371
4372 /* Sleep */
4373 rinfo->asleep = 1;
4374 radeon_set_suspend(rinfo, 1);
4375 release_console_sem();
4376
4377 break;
4378 case PBOOK_WAKE:
4379 acquire_console_sem();
4380 /* Wakeup chip*/
4381 radeon_set_suspend(rinfo, 0);
4382
4383 /* Re-set mode */
4384 rinfo->asleep = 0;
4385 radeon_load_video_mode(rinfo, &disp->var);
4386 if ((disp->var.accel_flags & FB_ACCELF_TEXT) && !noaccel)
4387 radeon_engine_init(rinfo);
4388 do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon,
4389 (struct fb_info *)rinfo);
4390 /* Allow fbdev to tap us again */
4391 radeon_set_dispsw(rinfo, disp);
4392
4393 /* Unblank screen */
4394 radeonfb_blank(0, (struct fb_info *)rinfo);
4395 release_console_sem();
4396 break;
4397 }
4398 }
4399
4400 return PBOOK_SLEEP_OK;
4401 }
4402
4403 #endif /* CONFIG_PMAC_PBOOK */
4404
4405 /*
4406 * text console acceleration
4407 */
4408
4409
fbcon_radeon_bmove(struct display * p,int srcy,int srcx,int dsty,int dstx,int height,int width)4410 static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
4411 int dsty, int dstx, int height, int width)
4412 {
4413 struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4414 u32 dp_cntl = DST_LAST_PEL;
4415 u32 dp_cntl_save = 0;
4416
4417 srcx *= fontwidth(p);
4418 srcy *= fontheight(p);
4419 dstx *= fontwidth(p);
4420 dsty *= fontheight(p);
4421 width *= fontwidth(p);
4422 height *= fontheight(p);
4423
4424 if (srcy < dsty) {
4425 srcy += height;
4426 dsty += height;
4427 } else
4428 dp_cntl |= DST_Y_TOP_TO_BOTTOM;
4429
4430 if (srcx < dstx) {
4431 srcx += width;
4432 dstx += width;
4433 } else
4434 dp_cntl |= DST_X_LEFT_TO_RIGHT;
4435
4436 dp_cntl_save = INREG(DP_CNTL);
4437
4438 radeon_fifo_wait(6);
4439 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
4440 GMC_BRUSH_NONE |
4441 GMC_SRC_DATATYPE_COLOR |
4442 ROP3_S |
4443 DP_SRC_SOURCE_MEMORY));
4444 OUTREG(DP_WRITE_MSK, 0xffffffff);
4445 OUTREG(DP_CNTL, dp_cntl);
4446 OUTREG(SRC_Y_X, (srcy << 16) | srcx);
4447 OUTREG(DST_Y_X, (dsty << 16) | dstx);
4448 OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
4449
4450 radeon_fifo_wait(1);
4451 OUTREG(DP_CNTL, dp_cntl_save);
4452
4453 radeon_engine_idle();
4454 }
4455
4456
4457
radeon_rectfill(struct radeonfb_info * rinfo,int dsty,int dstx,int height,int width,u32 clr)4458 static void radeon_rectfill(struct radeonfb_info *rinfo,
4459 int dsty, int dstx,
4460 int height, int width,
4461 u32 clr)
4462 {
4463 radeon_fifo_wait(6);
4464 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
4465 GMC_BRUSH_SOLID_COLOR |
4466 GMC_SRC_DATATYPE_COLOR |
4467 ROP3_P));
4468 OUTREG(DP_BRUSH_FRGD_CLR, clr);
4469 OUTREG(DP_WRITE_MSK, 0xffffffff);
4470 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
4471 OUTREG(DST_Y_X, (dsty << 16) | dstx);
4472 OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
4473
4474 radeon_engine_idle();
4475 }
4476
4477
4478
4479 #ifdef FBCON_HAS_CFB8
4480
fbcon_radeon8_clear(struct vc_data * conp,struct display * p,int srcy,int srcx,int height,int width)4481 static void fbcon_radeon8_clear(struct vc_data *conp, struct display *p,
4482 int srcy, int srcx, int height, int width)
4483 {
4484 struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4485 u32 clr;
4486
4487 clr = attr_bgcol_ec(p, conp);
4488 clr |= (clr << 8);
4489 clr |= (clr << 16);
4490
4491 srcx *= fontwidth(p);
4492 srcy *= fontheight(p);
4493 width *= fontwidth(p);
4494 height *= fontheight(p);
4495
4496 radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
4497 }
4498
4499
4500
4501 static struct display_switch fbcon_radeon8 = {
4502 setup: fbcon_cfb8_setup,
4503 bmove: fbcon_radeon_bmove,
4504 clear: fbcon_radeon8_clear,
4505 putc: fbcon_cfb8_putc,
4506 putcs: fbcon_cfb8_putcs,
4507 revc: fbcon_cfb8_revc,
4508 clear_margins: fbcon_cfb8_clear_margins,
4509 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4510 };
4511 #endif
4512
4513 #ifdef FBCON_HAS_CFB16
4514
4515
fbcon_radeon16_clear(struct vc_data * conp,struct display * p,int srcy,int srcx,int height,int width)4516 static void fbcon_radeon16_clear(struct vc_data *conp, struct display *p,
4517 int srcy, int srcx, int height, int width)
4518 {
4519 struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4520 u32 clr;
4521
4522 clr = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
4523 clr |= (clr << 16);
4524
4525 srcx *= fontwidth(p);
4526 srcy *= fontheight(p);
4527 width *= fontwidth(p);
4528 height *= fontheight(p);
4529
4530 radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
4531 }
4532
4533
4534
4535 static struct display_switch fbcon_radeon16 = {
4536 setup: fbcon_cfb16_setup,
4537 bmove: fbcon_radeon_bmove,
4538 clear: fbcon_radeon16_clear,
4539 putc: fbcon_cfb16_putc,
4540 putcs: fbcon_cfb16_putcs,
4541 revc: fbcon_cfb16_revc,
4542 clear_margins: fbcon_cfb16_clear_margins,
4543 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4544 };
4545 #endif
4546
4547 #ifdef FBCON_HAS_CFB32
4548
4549
fbcon_radeon32_clear(struct vc_data * conp,struct display * p,int srcy,int srcx,int height,int width)4550 static void fbcon_radeon32_clear(struct vc_data *conp, struct display *p,
4551 int srcy, int srcx, int height, int width)
4552 {
4553 struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4554 u32 clr;
4555
4556 clr = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
4557
4558 srcx *= fontwidth(p);
4559 srcy *= fontheight(p);
4560 width *= fontwidth(p);
4561 height *= fontheight(p);
4562
4563 radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
4564 }
4565
4566
4567
4568 static struct display_switch fbcon_radeon32 = {
4569 setup: fbcon_cfb32_setup,
4570 bmove: fbcon_radeon_bmove,
4571 clear: fbcon_radeon32_clear,
4572 putc: fbcon_cfb32_putc,
4573 putcs: fbcon_cfb32_putcs,
4574 revc: fbcon_cfb32_revc,
4575 clear_margins: fbcon_cfb32_clear_margins,
4576 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4577 };
4578 #endif
4579
4580