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