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