]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/video/ati_radeon_fb.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / drivers / video / ati_radeon_fb.c
1 /*
2  * ATI Radeon Video card Framebuffer driver.
3  *
4  * Copyright 2007 Freescale Semiconductor, Inc.
5  * Zhang Wei <wei.zhang@freescale.com>
6  * Jason Jin <jason.jin@freescale.com>
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  *
26  * Some codes of this file is partly ported from Linux kernel
27  * ATI video framebuffer driver.
28  *
29  * Now the driver is tested on below ATI chips:
30  *   9200
31  *   X300
32  *   X700
33  *
34  */
35
36 #include <common.h>
37
38 #include <command.h>
39 #include <pci.h>
40 #include <asm/processor.h>
41 #include <asm/errno.h>
42 #include <asm/io.h>
43 #include <malloc.h>
44 #include <video_fb.h>
45 #include "videomodes.h"
46
47 #include <radeon.h>
48 #include "ati_ids.h"
49 #include "ati_radeon_fb.h"
50
51 #undef DEBUG
52
53 #ifdef DEBUG
54 #define DPRINT(x...) printf(x)
55 #else
56 #define DPRINT(x...) do{}while(0)
57 #endif
58
59 #ifndef min_t
60 #define min_t(type,x,y) \
61         ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
62 #endif
63
64 #define MAX_MAPPED_VRAM (2048*2048*4)
65 #define MIN_MAPPED_VRAM (1024*768*1)
66
67 #define RADEON_BUFFER_ALIGN             0x00000fff
68 #define SURF_UPPER_BOUND(x,y,bpp)       (((((x) * (((y) + 15) & ~15) * (bpp)/8) + RADEON_BUFFER_ALIGN) \
69                                           & ~RADEON_BUFFER_ALIGN) - 1)
70 #define RADEON_CRT_PITCH(width, bpp)    ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) | \
71                                          ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) << 16))
72
73 #define CRTC_H_TOTAL_DISP_VAL(htotal, hdisp) \
74                 (((((htotal) / 8) - 1) & 0x3ff) | (((((hdisp) / 8) - 1) & 0x1ff) << 16))
75 #define CRTC_HSYNC_STRT_WID_VAL(hsync_srtr, hsync_wid) \
76                 (((hsync_srtr) & 0x1fff) | (((hsync_wid) & 0x3f) << 16))
77 #define CRTC_V_TOTAL_DISP_VAL(vtotal, vdisp) \
78                 ((((vtotal) - 1) & 0xffff) | (((vdisp) - 1) << 16))
79 #define CRTC_VSYNC_STRT_WID_VAL(vsync_srtr, vsync_wid) \
80                 ((((vsync_srtr) - 1) & 0xfff) | (((vsync_wid) & 0x1f) << 16))
81
82 /*#define PCI_VENDOR_ID_ATI*/
83 #define PCI_CHIP_RV280_5960             0x5960
84 #define PCI_CHIP_RV280_5961             0x5961
85 #define PCI_CHIP_RV280_5962             0x5962
86 #define PCI_CHIP_RV280_5964             0x5964
87 #define PCI_CHIP_RV280_5C63             0x5C63
88 #define PCI_CHIP_RV370_5B60             0x5B60
89 #define PCI_CHIP_RV380_5657             0x5657
90 #define PCI_CHIP_R420_554d              0x554d
91
92 static struct pci_device_id ati_radeon_pci_ids[] = {
93         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
94         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
95         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
96         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
97         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5C63},
98         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
99         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
100         {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
101         {0, 0}
102 };
103
104 static u16 ati_radeon_id_family_table[][2] = {
105         {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
106         {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
107         {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
108         {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
109         {PCI_CHIP_RV280_5C63, CHIP_FAMILY_RV280},
110         {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
111         {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
112         {PCI_CHIP_R420_554d,  CHIP_FAMILY_R420},
113         {0, 0}
114 };
115
116 u16 get_radeon_id_family(u16 device)
117 {
118         int i;
119         for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
120                 if (ati_radeon_id_family_table[0][i] == device)
121                         return ati_radeon_id_family_table[0][i + 1];
122         return 0;
123 }
124
125 struct radeonfb_info *rinfo;
126
127 static void radeon_identify_vram(struct radeonfb_info *rinfo)
128 {
129         u32 tmp;
130
131         /* framebuffer size */
132         if ((rinfo->family == CHIP_FAMILY_RS100) ||
133                 (rinfo->family == CHIP_FAMILY_RS200) ||
134                 (rinfo->family == CHIP_FAMILY_RS300)) {
135                 u32 tom = INREG(NB_TOM);
136                 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
137
138                 radeon_fifo_wait(6);
139                 OUTREG(MC_FB_LOCATION, tom);
140                 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
141                 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
142                 OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
143
144                 /* This is supposed to fix the crtc2 noise problem. */
145                 OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
146
147                 if ((rinfo->family == CHIP_FAMILY_RS100) ||
148                         (rinfo->family == CHIP_FAMILY_RS200)) {
149                 /* This is to workaround the asic bug for RMX, some versions
150                    of BIOS dosen't have this register initialized correctly.
151                 */
152                         OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
153                                 ~CRTC_H_CUTOFF_ACTIVE_EN);
154                 }
155         } else {
156                 tmp = INREG(CONFIG_MEMSIZE);
157         }
158
159         /* mem size is bits [28:0], mask off the rest */
160         rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
161
162         /*
163          * Hack to get around some busted production M6's
164          * reporting no ram
165          */
166         if (rinfo->video_ram == 0) {
167                 switch (rinfo->pdev.device) {
168                 case PCI_CHIP_RADEON_LY:
169                 case PCI_CHIP_RADEON_LZ:
170                         rinfo->video_ram = 8192 * 1024;
171                         break;
172                 default:
173                         break;
174                 }
175         }
176
177         /*
178          * Now try to identify VRAM type
179          */
180         if ((rinfo->family >= CHIP_FAMILY_R300) ||
181             (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
182                 rinfo->vram_ddr = 1;
183         else
184                 rinfo->vram_ddr = 0;
185
186         tmp = INREG(MEM_CNTL);
187         if (IS_R300_VARIANT(rinfo)) {
188                 tmp &=  R300_MEM_NUM_CHANNELS_MASK;
189                 switch (tmp) {
190                 case 0:  rinfo->vram_width = 64; break;
191                 case 1:  rinfo->vram_width = 128; break;
192                 case 2:  rinfo->vram_width = 256; break;
193                 default: rinfo->vram_width = 128; break;
194                 }
195         } else if ((rinfo->family == CHIP_FAMILY_RV100) ||
196                    (rinfo->family == CHIP_FAMILY_RS100) ||
197                    (rinfo->family == CHIP_FAMILY_RS200)){
198                 if (tmp & RV100_MEM_HALF_MODE)
199                         rinfo->vram_width = 32;
200                 else
201                         rinfo->vram_width = 64;
202         } else {
203                 if (tmp & MEM_NUM_CHANNELS_MASK)
204                         rinfo->vram_width = 128;
205                 else
206                         rinfo->vram_width = 64;
207         }
208
209         /* This may not be correct, as some cards can have half of channel disabled
210          * ToDo: identify these cases
211          */
212
213         DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
214                rinfo->video_ram / 1024,
215                rinfo->vram_ddr ? "DDR" : "SDRAM",
216                rinfo->vram_width);
217
218 }
219
220 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
221 {
222         int i;
223
224         radeon_fifo_wait(20);
225
226 #if 0
227         /* Workaround from XFree */
228         if (rinfo->is_mobility) {
229                 /* A temporal workaround for the occational blanking on certain laptop
230                  * panels. This appears to related to the PLL divider registers
231                  * (fail to lock?). It occurs even when all dividers are the same
232                  * with their old settings. In this case we really don't need to
233                  * fiddle with PLL registers. By doing this we can avoid the blanking
234                  * problem with some panels.
235                  */
236                 if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
237                     (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
238                                           (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
239                         /* We still have to force a switch to selected PPLL div thanks to
240                          * an XFree86 driver bug which will switch it away in some cases
241                          * even when using UseFDev */
242                         OUTREGP(CLOCK_CNTL_INDEX,
243                                 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
244                                 ~PPLL_DIV_SEL_MASK);
245                         radeon_pll_errata_after_index(rinfo);
246                         radeon_pll_errata_after_data(rinfo);
247                         return;
248                 }
249         }
250 #endif
251         if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
252
253         /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
254         OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
255
256         /* Reset PPLL & enable atomic update */
257         OUTPLLP(PPLL_CNTL,
258                 PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
259                 ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
260
261         /* Switch to selected PPLL divider */
262         OUTREGP(CLOCK_CNTL_INDEX,
263                 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
264                 ~PPLL_DIV_SEL_MASK);
265
266         /* Set PPLL ref. div */
267         if (rinfo->family == CHIP_FAMILY_R300 ||
268             rinfo->family == CHIP_FAMILY_RS300 ||
269             rinfo->family == CHIP_FAMILY_R350 ||
270             rinfo->family == CHIP_FAMILY_RV350) {
271                 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
272                         /* When restoring console mode, use saved PPLL_REF_DIV
273                          * setting.
274                          */
275                         OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
276                 } else {
277                         /* R300 uses ref_div_acc field as real ref divider */
278                         OUTPLLP(PPLL_REF_DIV,
279                                 (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
280                                 ~R300_PPLL_REF_DIV_ACC_MASK);
281                 }
282         } else
283                 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
284
285         /* Set PPLL divider 3 & post divider*/
286         OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
287         OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
288
289         /* Write update */
290         while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
291                 ;
292         OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
293
294         /* Wait read update complete */
295         /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
296            the cause yet, but this workaround will mask the problem for now.
297            Other chips usually will pass at the very first test, so the
298            workaround shouldn't have any effect on them. */
299         for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
300                 ;
301
302         OUTPLL(HTOTAL_CNTL, 0);
303
304         /* Clear reset & atomic update */
305         OUTPLLP(PPLL_CNTL, 0,
306                 ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
307
308         /* We may want some locking ... oh well */
309         udelay(5000);
310
311         /* Switch back VCLK source to PPLL */
312         OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
313 }
314
315 typedef struct {
316         u16 reg;
317         u32 val;
318 } reg_val;
319
320 #if 0   /* unused ? -> scheduled for removal */
321 /* these common regs are cleared before mode setting so they do not
322  * interfere with anything
323  */
324 static reg_val common_regs[] = {
325         { OVR_CLR, 0 },
326         { OVR_WID_LEFT_RIGHT, 0 },
327         { OVR_WID_TOP_BOTTOM, 0 },
328         { OV0_SCALE_CNTL, 0 },
329         { SUBPIC_CNTL, 0 },
330         { VIPH_CONTROL, 0 },
331         { I2C_CNTL_1, 0 },
332         { GEN_INT_CNTL, 0 },
333         { CAP0_TRIG_CNTL, 0 },
334         { CAP1_TRIG_CNTL, 0 },
335 };
336 #endif /* 0 */
337
338 void radeon_setmode(void)
339 {
340         struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
341
342         mode->crtc_gen_cntl = 0x03000200;
343         mode->crtc_ext_cntl = 0x00008048;
344         mode->dac_cntl = 0xff002100;
345         mode->crtc_h_total_disp = 0x4f0063;
346         mode->crtc_h_sync_strt_wid = 0x8c02a2;
347         mode->crtc_v_total_disp = 0x01df020c;
348         mode->crtc_v_sync_strt_wid = 0x8201ea;
349         mode->crtc_pitch = 0x00500050;
350
351         OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
352         OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
353                 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
354         OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
355         OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
356         OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
357         OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
358         OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
359         OUTREG(CRTC_OFFSET, 0);
360         OUTREG(CRTC_OFFSET_CNTL, 0);
361         OUTREG(CRTC_PITCH, mode->crtc_pitch);
362
363         mode->clk_cntl_index = 0x300;
364         mode->ppll_ref_div = 0xc;
365         mode->ppll_div_3 = 0x00030059;
366
367         radeon_write_pll_regs(rinfo, mode);
368 }
369
370 static void set_pal(void)
371 {
372         int idx, val = 0;
373
374         for (idx = 0; idx < 256; idx++) {
375                 OUTREG8(PALETTE_INDEX, idx);
376                 OUTREG(PALETTE_DATA, val);
377                 val += 0x00010101;
378         }
379 }
380
381 void radeon_setmode_9200(int vesa_idx, int bpp)
382 {
383         struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
384
385         mode->crtc_gen_cntl = CRTC_EN | CRTC_EXT_DISP_EN;
386         mode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON;
387         mode->dac_cntl = DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN;
388         mode->crtc_offset_cntl = CRTC_OFFSET_CNTL__CRTC_TILE_EN;
389
390         switch (bpp) {
391         case 24:
392                 mode->crtc_gen_cntl |= 0x6 << 8; /* x888 */
393 #if defined(__BIG_ENDIAN)
394                 mode->surface_cntl = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
395                 mode->surf_info[0] = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
396 #endif
397                 break;
398         case 16:
399                 mode->crtc_gen_cntl |= 0x4 << 8; /* 565 */
400 #if defined(__BIG_ENDIAN)
401                 mode->surface_cntl = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
402                 mode->surf_info[0] = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
403 #endif
404                 break;
405         default:
406                 mode->crtc_gen_cntl |= 0x2 << 8; /* palette */
407                 mode->surface_cntl = 0x00000000;
408                 break;
409         }
410
411         switch (vesa_idx) {
412         case RES_MODE_1280x1024:
413                 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1688,1280);
414                 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(1066,1024);
415                 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(1025,3);
416 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
417                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1288,18);
418                 mode->ppll_div_3 = 0x00010078;
419 #else /* default @ 60 Hz */
420                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1320,14);
421                 mode->ppll_div_3 = 0x00010060;
422 #endif
423                 /*
424                  * for this mode pitch expands to the same value for 32, 16 and 8 bpp,
425                  * so we set it here once only.
426                  */
427                 mode->crtc_pitch = RADEON_CRT_PITCH(1280,32);
428                 switch (bpp) {
429                 case 24:
430                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 4 / 16);
431                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,32);
432                         break;
433                 case 16:
434                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 2 / 16);
435                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,16);
436                         break;
437                 default: /* 8 bpp */
438                         mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1280 * 1 / 16);
439                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,8);
440                         break;
441                 }
442                 break;
443         case RES_MODE_1024x768:
444 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
445                 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1312,1024);
446                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1032,12);
447                 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(800,768);
448                 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(769,3);
449                 mode->ppll_div_3 = 0x0002008c;
450 #else /* @ 60 Hz */
451                 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1344,1024);
452                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1040,17) | CRTC_H_SYNC_POL;
453                 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(806,768);
454                 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(771,6) | CRTC_V_SYNC_POL;
455                 mode->ppll_div_3 = 0x00020074;
456 #endif
457                 /* also same pitch value for 32, 16 and 8 bpp */
458                 mode->crtc_pitch = RADEON_CRT_PITCH(1024,32);
459                 switch (bpp) {
460                 case 24:
461                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 4 / 16);
462                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,32);
463                         break;
464                 case 16:
465                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 2 / 16);
466                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,16);
467                         break;
468                 default: /* 8 bpp */
469                         mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
470                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,8);
471                         break;
472                 }
473                 break;
474         case RES_MODE_800x600:
475                 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1056,800);
476 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
477                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(808,10);
478                 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(625,600);
479                 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,3);
480                 mode->ppll_div_3 = 0x000300b0;
481 #else /* @ 60 Hz */
482                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(832,16);
483                 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(628,600);
484                 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,4);
485                 mode->ppll_div_3 = 0x0003008e;
486 #endif
487                 switch (bpp) {
488                 case 24:
489                         mode->crtc_pitch = RADEON_CRT_PITCH(832,32);
490                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (832 * 4 / 16);
491                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(832,600,32);
492                         break;
493                 case 16:
494                         mode->crtc_pitch = RADEON_CRT_PITCH(896,16);
495                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (896 * 2 / 16);
496                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(896,600,16);
497                         break;
498                 default: /* 8 bpp */
499                         mode->crtc_pitch = RADEON_CRT_PITCH(1024,8);
500                         mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
501                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,600,8);
502                         break;
503                 }
504                 break;
505         default: /* RES_MODE_640x480 */
506 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
507                 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(840,640);
508                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(648,8) | CRTC_H_SYNC_POL;
509                 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(500,480);
510                 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(481,3) | CRTC_V_SYNC_POL;
511                 mode->ppll_div_3 = 0x00030070;
512 #else /* @ 60 Hz */
513                 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(800,640);
514                 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(674,12) | CRTC_H_SYNC_POL;
515                 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(525,480);
516                 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(491,2) | CRTC_V_SYNC_POL;
517                 mode->ppll_div_3 = 0x00030059;
518 #endif
519                 /* also same pitch value for 32, 16 and 8 bpp */
520                 mode->crtc_pitch = RADEON_CRT_PITCH(640,32);
521                 switch (bpp) {
522                 case 24:
523                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 4 / 16);
524                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,32);
525                         break;
526                 case 16:
527                         mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 2 / 16);
528                         mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,16);
529                         break;
530                 default: /* 8 bpp */
531                         mode->crtc_offset_cntl = 0x00000000;
532                         break;
533                 }
534                 break;
535         }
536
537         OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
538         OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
539                 (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
540         OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
541         OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
542         OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
543         OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
544         OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
545         OUTREG(CRTC_OFFSET, 0);
546         OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl);
547         OUTREG(CRTC_PITCH, mode->crtc_pitch);
548         OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
549
550         mode->clk_cntl_index = 0x300;
551         mode->ppll_ref_div = 0xc;
552
553         radeon_write_pll_regs(rinfo, mode);
554
555         OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
556                 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
557         OUTREG(SURFACE0_INFO, mode->surf_info[0]);
558         OUTREG(SURFACE0_LOWER_BOUND, 0);
559         OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]);
560         OUTREG(SURFACE_CNTL, mode->surface_cntl);
561
562         if (bpp > 8)
563                 set_pal();
564
565         free(mode);
566 }
567
568 #include "../bios_emulator/include/biosemu.h"
569 extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
570
571 int radeon_probe(struct radeonfb_info *rinfo)
572 {
573         pci_dev_t pdev;
574         u16 did;
575
576         pdev = pci_find_devices(ati_radeon_pci_ids, 0);
577
578         if (pdev != -1) {
579                 pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
580                 printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
581                                 PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
582                                 (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
583
584                 strcpy(rinfo->name, "ATI Radeon");
585                 rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
586                 rinfo->pdev.device = did;
587                 rinfo->family = get_radeon_id_family(rinfo->pdev.device);
588                 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
589                                 &rinfo->fb_base_phys);
590                 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
591                                 &rinfo->mmio_base_phys);
592                 rinfo->fb_base_phys &= 0xfffff000;
593                 rinfo->mmio_base_phys &= ~0x04;
594
595                 rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
596                 DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
597                 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
598                 DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
599                 /* PostBIOS with x86 emulater */
600                 BootVideoCardBIOS(pdev, NULL, 0);
601
602                 /*
603                  * Check for errata
604                  * (These will be added in the future for the chipfamily
605                  * R300, RV200, RS200, RV100, RS100.)
606                  */
607
608                 /* Get VRAM size and type */
609                 radeon_identify_vram(rinfo);
610
611                 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
612                                 rinfo->video_ram);
613                 rinfo->fb_base = (void *)rinfo->fb_base_phys;
614
615                 DPRINT("Radeon: framebuffer base phy address 0x%08x," \
616                       "MMIO base phy address 0x%08x," \
617                       "framebuffer local base 0x%08x.\n ",
618                       rinfo->fb_base_phys, rinfo->mmio_base_phys,
619                       rinfo->fb_local_base);
620
621                 return 0;
622         }
623         return -1;
624 }
625
626 /*
627  * The Graphic Device
628  */
629 GraphicDevice ctfb;
630
631 #define CURSOR_SIZE     0x1000  /* in KByte for HW Cursor */
632 #define PATTERN_ADR     (pGD->dprBase + CURSOR_SIZE)    /* pattern Memory after Cursor Memory */
633 #define PATTERN_SIZE    8*8*4   /* 4 Bytes per Pixel 8 x 8 Pixel */
634 #define ACCELMEMORY     (CURSOR_SIZE + PATTERN_SIZE)    /* reserved Memory for BITBlt and hw cursor */
635
636 void *video_hw_init(void)
637 {
638         GraphicDevice *pGD = (GraphicDevice *) & ctfb;
639         u32 *vm;
640         char *penv;
641         unsigned long t1, hsynch, vsynch;
642         int bits_per_pixel, i, tmp, vesa_idx = 0, videomode;
643         struct ctfb_res_modes *res_mode;
644         struct ctfb_res_modes var_mode;
645
646         rinfo = malloc(sizeof(struct radeonfb_info));
647
648         printf("Video: ");
649         if(radeon_probe(rinfo)) {
650                 printf("No radeon video card found!\n");
651                 return NULL;
652         }
653
654         tmp = 0;
655
656         videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
657         /* get video mode via environment */
658         if ((penv = getenv ("videomode")) != NULL) {
659                 /* deceide if it is a string */
660                 if (penv[0] <= '9') {
661                         videomode = (int) simple_strtoul (penv, NULL, 16);
662                         tmp = 1;
663                 }
664         } else {
665                 tmp = 1;
666         }
667         if (tmp) {
668                 /* parameter are vesa modes */
669                 /* search params */
670                 for (i = 0; i < VESA_MODES_COUNT; i++) {
671                         if (vesa_modes[i].vesanr == videomode)
672                                 break;
673                 }
674                 if (i == VESA_MODES_COUNT) {
675                         printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE);
676                         i = 0;
677                 }
678                 res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex];
679                 bits_per_pixel = vesa_modes[i].bits_per_pixel;
680                 vesa_idx = vesa_modes[i].resindex;
681         } else {
682                 res_mode = (struct ctfb_res_modes *) &var_mode;
683                 bits_per_pixel = video_get_params (res_mode, penv);
684         }
685
686         /* calculate hsynch and vsynch freq (info only) */
687         t1 = (res_mode->left_margin + res_mode->xres +
688               res_mode->right_margin + res_mode->hsync_len) / 8;
689         t1 *= 8;
690         t1 *= res_mode->pixclock;
691         t1 /= 1000;
692         hsynch = 1000000000L / t1;
693         t1 *= (res_mode->upper_margin + res_mode->yres +
694                res_mode->lower_margin + res_mode->vsync_len);
695         t1 /= 1000;
696         vsynch = 1000000000L / t1;
697
698         /* fill in Graphic device struct */
699         sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
700                  res_mode->yres, bits_per_pixel, (hsynch / 1000),
701                  (vsynch / 1000));
702         printf ("%s\n", pGD->modeIdent);
703         pGD->winSizeX = res_mode->xres;
704         pGD->winSizeY = res_mode->yres;
705         pGD->plnSizeX = res_mode->xres;
706         pGD->plnSizeY = res_mode->yres;
707
708         switch (bits_per_pixel) {
709         case 24:
710                 pGD->gdfBytesPP = 4;
711                 pGD->gdfIndex = GDF_32BIT_X888RGB;
712                 if (res_mode->xres == 800) {
713                         pGD->winSizeX = 832;
714                         pGD->plnSizeX = 832;
715                 }
716                 break;
717         case 16:
718                 pGD->gdfBytesPP = 2;
719                 pGD->gdfIndex = GDF_16BIT_565RGB;
720                 if (res_mode->xres == 800) {
721                         pGD->winSizeX = 896;
722                         pGD->plnSizeX = 896;
723                 }
724                 break;
725         default:
726                 if (res_mode->xres == 800) {
727                         pGD->winSizeX = 1024;
728                         pGD->plnSizeX = 1024;
729                 }
730                 pGD->gdfBytesPP = 1;
731                 pGD->gdfIndex = GDF__8BIT_INDEX;
732                 break;
733         }
734
735         pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
736         pGD->pciBase = rinfo->fb_base_phys;
737         pGD->frameAdrs = rinfo->fb_base_phys;
738         pGD->memSize = 64 * 1024 * 1024;
739
740         /* Cursor Start Address */
741         pGD->dprBase =
742             (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
743         if ((pGD->dprBase & 0x0fff) != 0) {
744                 /* allign it */
745                 pGD->dprBase &= 0xfffff000;
746                 pGD->dprBase += 0x00001000;
747         }
748         DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
749                 PATTERN_ADR);
750         pGD->vprBase = rinfo->fb_base_phys;     /* Dummy */
751         pGD->cprBase = rinfo->fb_base_phys;     /* Dummy */
752         /* set up Hardware */
753
754         /* Clear video memory (only visible screen area) */
755         i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4;
756         vm = (unsigned int *) pGD->pciBase;
757         while (i--)
758                 *vm++ = 0;
759         /*SetDrawingEngine (bits_per_pixel);*/
760
761         if (rinfo->family == CHIP_FAMILY_RV280)
762                 radeon_setmode_9200(vesa_idx, bits_per_pixel);
763         else
764                 radeon_setmode();
765
766         return ((void *) pGD);
767 }
768
769 void video_set_lut (unsigned int index, /* color number */
770                unsigned char r, /* red */
771                unsigned char g, /* green */
772                unsigned char b  /* blue */
773                )
774 {
775         OUTREG(PALETTE_INDEX, index);
776         OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);
777 }