OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [video/] [radeonfb.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.