]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/video/ati_radeon_fb.c
ati_radeon: return with error when emulator fails
[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                 if (!BootVideoCardBIOS(pdev, NULL, 0))
601                         return -1;
602
603                 /*
604                  * Check for errata
605                  * (These will be added in the future for the chipfamily
606                  * R300, RV200, RS200, RV100, RS100.)
607                  */
608
609                 /* Get VRAM size and type */
610                 radeon_identify_vram(rinfo);
611
612                 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
613                                 rinfo->video_ram);
614                 rinfo->fb_base = (void *)rinfo->fb_base_phys;
615
616                 DPRINT("Radeon: framebuffer base phy address 0x%08x," \
617                       "MMIO base phy address 0x%08x," \
618                       "framebuffer local base 0x%08x.\n ",
619                       rinfo->fb_base_phys, rinfo->mmio_base_phys,
620                       rinfo->fb_local_base);
621
622                 return 0;
623         }
624         return -1;
625 }
626
627 /*
628  * The Graphic Device
629  */
630 GraphicDevice ctfb;
631
632 #define CURSOR_SIZE     0x1000  /* in KByte for HW Cursor */
633 #define PATTERN_ADR     (pGD->dprBase + CURSOR_SIZE)    /* pattern Memory after Cursor Memory */
634 #define PATTERN_SIZE    8*8*4   /* 4 Bytes per Pixel 8 x 8 Pixel */
635 #define ACCELMEMORY     (CURSOR_SIZE + PATTERN_SIZE)    /* reserved Memory for BITBlt and hw cursor */
636
637 void *video_hw_init(void)
638 {
639         GraphicDevice *pGD = (GraphicDevice *) & ctfb;
640         u32 *vm;
641         char *penv;
642         unsigned long t1, hsynch, vsynch;
643         int bits_per_pixel, i, tmp, vesa_idx = 0, videomode;
644         struct ctfb_res_modes *res_mode;
645         struct ctfb_res_modes var_mode;
646
647         rinfo = malloc(sizeof(struct radeonfb_info));
648
649         printf("Video: ");
650         if(radeon_probe(rinfo)) {
651                 printf("No radeon video card found!\n");
652                 return NULL;
653         }
654
655         tmp = 0;
656
657         videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
658         /* get video mode via environment */
659         if ((penv = getenv ("videomode")) != NULL) {
660                 /* deceide if it is a string */
661                 if (penv[0] <= '9') {
662                         videomode = (int) simple_strtoul (penv, NULL, 16);
663                         tmp = 1;
664                 }
665         } else {
666                 tmp = 1;
667         }
668         if (tmp) {
669                 /* parameter are vesa modes */
670                 /* search params */
671                 for (i = 0; i < VESA_MODES_COUNT; i++) {
672                         if (vesa_modes[i].vesanr == videomode)
673                                 break;
674                 }
675                 if (i == VESA_MODES_COUNT) {
676                         printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE);
677                         i = 0;
678                 }
679                 res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex];
680                 bits_per_pixel = vesa_modes[i].bits_per_pixel;
681                 vesa_idx = vesa_modes[i].resindex;
682         } else {
683                 res_mode = (struct ctfb_res_modes *) &var_mode;
684                 bits_per_pixel = video_get_params (res_mode, penv);
685         }
686
687         /* calculate hsynch and vsynch freq (info only) */
688         t1 = (res_mode->left_margin + res_mode->xres +
689               res_mode->right_margin + res_mode->hsync_len) / 8;
690         t1 *= 8;
691         t1 *= res_mode->pixclock;
692         t1 /= 1000;
693         hsynch = 1000000000L / t1;
694         t1 *= (res_mode->upper_margin + res_mode->yres +
695                res_mode->lower_margin + res_mode->vsync_len);
696         t1 /= 1000;
697         vsynch = 1000000000L / t1;
698
699         /* fill in Graphic device struct */
700         sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
701                  res_mode->yres, bits_per_pixel, (hsynch / 1000),
702                  (vsynch / 1000));
703         printf ("%s\n", pGD->modeIdent);
704         pGD->winSizeX = res_mode->xres;
705         pGD->winSizeY = res_mode->yres;
706         pGD->plnSizeX = res_mode->xres;
707         pGD->plnSizeY = res_mode->yres;
708
709         switch (bits_per_pixel) {
710         case 24:
711                 pGD->gdfBytesPP = 4;
712                 pGD->gdfIndex = GDF_32BIT_X888RGB;
713                 if (res_mode->xres == 800) {
714                         pGD->winSizeX = 832;
715                         pGD->plnSizeX = 832;
716                 }
717                 break;
718         case 16:
719                 pGD->gdfBytesPP = 2;
720                 pGD->gdfIndex = GDF_16BIT_565RGB;
721                 if (res_mode->xres == 800) {
722                         pGD->winSizeX = 896;
723                         pGD->plnSizeX = 896;
724                 }
725                 break;
726         default:
727                 if (res_mode->xres == 800) {
728                         pGD->winSizeX = 1024;
729                         pGD->plnSizeX = 1024;
730                 }
731                 pGD->gdfBytesPP = 1;
732                 pGD->gdfIndex = GDF__8BIT_INDEX;
733                 break;
734         }
735
736         pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
737         pGD->pciBase = rinfo->fb_base_phys;
738         pGD->frameAdrs = rinfo->fb_base_phys;
739         pGD->memSize = 64 * 1024 * 1024;
740
741         /* Cursor Start Address */
742         pGD->dprBase =
743             (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
744         if ((pGD->dprBase & 0x0fff) != 0) {
745                 /* allign it */
746                 pGD->dprBase &= 0xfffff000;
747                 pGD->dprBase += 0x00001000;
748         }
749         DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
750                 PATTERN_ADR);
751         pGD->vprBase = rinfo->fb_base_phys;     /* Dummy */
752         pGD->cprBase = rinfo->fb_base_phys;     /* Dummy */
753         /* set up Hardware */
754
755         /* Clear video memory (only visible screen area) */
756         i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4;
757         vm = (unsigned int *) pGD->pciBase;
758         while (i--)
759                 *vm++ = 0;
760         /*SetDrawingEngine (bits_per_pixel);*/
761
762         if (rinfo->family == CHIP_FAMILY_RV280)
763                 radeon_setmode_9200(vesa_idx, bits_per_pixel);
764         else
765                 radeon_setmode();
766
767         return ((void *) pGD);
768 }
769
770 void video_set_lut (unsigned int index, /* color number */
771                unsigned char r, /* red */
772                unsigned char g, /* green */
773                unsigned char b  /* blue */
774                )
775 {
776         OUTREG(PALETTE_INDEX, index);
777         OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);
778 }