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