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