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