]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/video/ati_radeon_fb.c
0bdaa1c04d7dbc987a0ffccdd3d682199bc02d2f
[karo-tx-uboot.git] / drivers / video / ati_radeon_fb.c
1 /*
2  * ATI Radeon Video card Framebuffer driver.
3  *
4  * Copyright 2007 Freescale Semiconductor, Inc.
5  * Zhang Wei <wei.zhang@freescale.com>
6  * Jason Jin <jason.jin@freescale.com>
7  *
8  * 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
48 #include <radeon.h>
49 #include "ati_ids.h"
50 #include "ati_radeon_fb.h"
51
52 #undef DEBUG
53
54 #ifdef DEBUG
55 #define DPRINT(x...) printf(x)
56 #else
57 #define DPRINT(x...) do{}while(0)
58 #endif
59
60 #ifndef min_t
61 #define min_t(type,x,y) \
62         ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
63 #endif
64
65 #define MAX_MAPPED_VRAM (2048*2048*4)
66 #define MIN_MAPPED_VRAM (1024*768*1)
67
68 /*#define PCI_VENDOR_ID_ATI*/
69 #define PCI_CHIP_RV280_5960             0x5960
70 #define PCI_CHIP_RV280_5961             0x5961
71 #define PCI_CHIP_RV280_5962             0x5962
72 #define PCI_CHIP_RV280_5964             0x5964
73 #define PCI_CHIP_RV370_5B60             0x5B60
74 #define PCI_CHIP_RV380_5657             0x5657
75 #define PCI_CHIP_R420_554d              0x554d
76
77 static struct pci_device_id ati_radeon_pci_ids[] = {
78         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
79         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
80         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
81         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
82         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
83         {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
84         {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
85         {0, 0}
86 };
87
88 static u16 ati_radeon_id_family_table[][2] = {
89         {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
90         {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
91         {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
92         {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
93         {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
94         {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
95         {PCI_CHIP_R420_554d,  CHIP_FAMILY_R420},
96         {0, 0}
97 };
98
99 u16 get_radeon_id_family(u16 device)
100 {
101         int i;
102         for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
103                 if (ati_radeon_id_family_table[0][i] == device)
104                         return ati_radeon_id_family_table[0][i + 1];
105         return 0;
106 }
107
108 struct radeonfb_info *rinfo;
109
110 static void radeon_identify_vram(struct radeonfb_info *rinfo)
111 {
112         u32 tmp;
113
114         /* framebuffer size */
115         if ((rinfo->family == CHIP_FAMILY_RS100) ||
116                 (rinfo->family == CHIP_FAMILY_RS200) ||
117                 (rinfo->family == CHIP_FAMILY_RS300)) {
118                 u32 tom = INREG(NB_TOM);
119                 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
120
121                 radeon_fifo_wait(6);
122                 OUTREG(MC_FB_LOCATION, tom);
123                 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
124                 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
125                 OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
126
127                 /* This is supposed to fix the crtc2 noise problem. */
128                 OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
129
130                 if ((rinfo->family == CHIP_FAMILY_RS100) ||
131                         (rinfo->family == CHIP_FAMILY_RS200)) {
132                 /* This is to workaround the asic bug for RMX, some versions
133                    of BIOS dosen't have this register initialized correctly.
134                 */
135                         OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
136                                 ~CRTC_H_CUTOFF_ACTIVE_EN);
137                 }
138         } else {
139                 tmp = INREG(CONFIG_MEMSIZE);
140         }
141
142         /* mem size is bits [28:0], mask off the rest */
143         rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
144
145         /*
146          * Hack to get around some busted production M6's
147          * reporting no ram
148          */
149         if (rinfo->video_ram == 0) {
150                 switch (rinfo->pdev.device) {
151                 case PCI_CHIP_RADEON_LY:
152                 case PCI_CHIP_RADEON_LZ:
153                         rinfo->video_ram = 8192 * 1024;
154                         break;
155                 default:
156                         break;
157                 }
158         }
159
160         /*
161          * Now try to identify VRAM type
162          */
163         if ((rinfo->family >= CHIP_FAMILY_R300) ||
164             (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
165                 rinfo->vram_ddr = 1;
166         else
167                 rinfo->vram_ddr = 0;
168
169         tmp = INREG(MEM_CNTL);
170         if (IS_R300_VARIANT(rinfo)) {
171                 tmp &=  R300_MEM_NUM_CHANNELS_MASK;
172                 switch (tmp) {
173                 case 0:  rinfo->vram_width = 64; break;
174                 case 1:  rinfo->vram_width = 128; break;
175                 case 2:  rinfo->vram_width = 256; break;
176                 default: rinfo->vram_width = 128; break;
177                 }
178         } else if ((rinfo->family == CHIP_FAMILY_RV100) ||
179                    (rinfo->family == CHIP_FAMILY_RS100) ||
180                    (rinfo->family == CHIP_FAMILY_RS200)){
181                 if (tmp & RV100_MEM_HALF_MODE)
182                         rinfo->vram_width = 32;
183                 else
184                         rinfo->vram_width = 64;
185         } else {
186                 if (tmp & MEM_NUM_CHANNELS_MASK)
187                         rinfo->vram_width = 128;
188                 else
189                         rinfo->vram_width = 64;
190         }
191
192         /* This may not be correct, as some cards can have half of channel disabled
193          * ToDo: identify these cases
194          */
195
196         DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
197                rinfo->video_ram / 1024,
198                rinfo->vram_ddr ? "DDR" : "SDRAM",
199                rinfo->vram_width);
200
201 }
202
203 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
204 {
205         int i;
206
207         radeon_fifo_wait(20);
208
209 #if 0
210         /* Workaround from XFree */
211         if (rinfo->is_mobility) {
212                 /* A temporal workaround for the occational blanking on certain laptop
213                  * panels. This appears to related to the PLL divider registers
214                  * (fail to lock?). It occurs even when all dividers are the same
215                  * with their old settings. In this case we really don't need to
216                  * fiddle with PLL registers. By doing this we can avoid the blanking
217                  * problem with some panels.
218                  */
219                 if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
220                     (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
221                                           (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
222                         /* We still have to force a switch to selected PPLL div thanks to
223                          * an XFree86 driver bug which will switch it away in some cases
224                          * even when using UseFDev */
225                         OUTREGP(CLOCK_CNTL_INDEX,
226                                 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
227                                 ~PPLL_DIV_SEL_MASK);
228                         radeon_pll_errata_after_index(rinfo);
229                         radeon_pll_errata_after_data(rinfo);
230                         return;
231                 }
232         }
233 #endif
234         if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
235
236         /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
237         OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
238
239         /* Reset PPLL & enable atomic update */
240         OUTPLLP(PPLL_CNTL,
241                 PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
242                 ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
243
244         /* Switch to selected PPLL divider */
245         OUTREGP(CLOCK_CNTL_INDEX,
246                 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
247                 ~PPLL_DIV_SEL_MASK);
248
249         /* Set PPLL ref. div */
250         if (rinfo->family == CHIP_FAMILY_R300 ||
251             rinfo->family == CHIP_FAMILY_RS300 ||
252             rinfo->family == CHIP_FAMILY_R350 ||
253             rinfo->family == CHIP_FAMILY_RV350) {
254                 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
255                         /* When restoring console mode, use saved PPLL_REF_DIV
256                          * setting.
257                          */
258                         OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
259                 } else {
260                         /* R300 uses ref_div_acc field as real ref divider */
261                         OUTPLLP(PPLL_REF_DIV,
262                                 (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
263                                 ~R300_PPLL_REF_DIV_ACC_MASK);
264                 }
265         } else
266                 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
267
268         /* Set PPLL divider 3 & post divider*/
269         OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
270         OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
271
272         /* Write update */
273         while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
274                 ;
275         OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
276
277         /* Wait read update complete */
278         /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
279            the cause yet, but this workaround will mask the problem for now.
280            Other chips usually will pass at the very first test, so the
281            workaround shouldn't have any effect on them. */
282         for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
283                 ;
284
285         OUTPLL(HTOTAL_CNTL, 0);
286
287         /* Clear reset & atomic update */
288         OUTPLLP(PPLL_CNTL, 0,
289                 ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
290
291         /* We may want some locking ... oh well */
292         udelay(5000);
293
294         /* Switch back VCLK source to PPLL */
295         OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
296 }
297
298 typedef struct {
299         u16 reg;
300         u32 val;
301 } reg_val;
302
303 #if 0   /* unused ? -> scheduled for removal */
304 /* these common regs are cleared before mode setting so they do not
305  * interfere with anything
306  */
307 static reg_val common_regs[] = {
308         { OVR_CLR, 0 },
309         { OVR_WID_LEFT_RIGHT, 0 },
310         { OVR_WID_TOP_BOTTOM, 0 },
311         { OV0_SCALE_CNTL, 0 },
312         { SUBPIC_CNTL, 0 },
313         { VIPH_CONTROL, 0 },
314         { I2C_CNTL_1, 0 },
315         { GEN_INT_CNTL, 0 },
316         { CAP0_TRIG_CNTL, 0 },
317         { CAP1_TRIG_CNTL, 0 },
318 };
319 #endif /* 0 */
320
321 void radeon_setmode(void)
322 {
323         struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
324
325         mode->crtc_gen_cntl = 0x03000200;
326         mode->crtc_ext_cntl = 0x00008048;
327         mode->dac_cntl = 0xff002100;
328         mode->crtc_h_total_disp = 0x4f0063;
329         mode->crtc_h_sync_strt_wid = 0x8c02a2;
330         mode->crtc_v_total_disp = 0x01df020c;
331         mode->crtc_v_sync_strt_wid = 0x8201ea;
332         mode->crtc_pitch = 0x00500050;
333
334         OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
335         OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
336                 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
337         OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
338         OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
339         OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
340         OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
341         OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
342         OUTREG(CRTC_OFFSET, 0);
343         OUTREG(CRTC_OFFSET_CNTL, 0);
344         OUTREG(CRTC_PITCH, mode->crtc_pitch);
345
346         mode->clk_cntl_index = 0x300;
347         mode->ppll_ref_div = 0xc;
348         mode->ppll_div_3 = 0x00030059;
349
350         radeon_write_pll_regs(rinfo, mode);
351 }
352
353 #include "../bios_emulator/include/biosemu.h"
354 extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
355
356 int radeon_probe(struct radeonfb_info *rinfo)
357 {
358         pci_dev_t pdev;
359         u16 did;
360
361         pdev = pci_find_devices(ati_radeon_pci_ids, 0);
362
363         if (pdev != -1) {
364                 pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
365                 printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
366                                 PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
367                                 (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
368
369                 strcpy(rinfo->name, "ATI Radeon");
370                 rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
371                 rinfo->pdev.device = did;
372                 rinfo->family = get_radeon_id_family(rinfo->pdev.device);
373                 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
374                                 &rinfo->fb_base_phys);
375                 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
376                                 &rinfo->mmio_base_phys);
377                 rinfo->fb_base_phys &= 0xfffff000;
378                 rinfo->mmio_base_phys &= ~0x04;
379
380                 rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
381                 DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
382                 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
383                 DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
384                 /* PostBIOS with x86 emulater */
385                 BootVideoCardBIOS(pdev, NULL, 0);
386
387                 /*
388                  * Check for errata
389                  * (These will be added in the future for the chipfamily
390                  * R300, RV200, RS200, RV100, RS100.)
391                  */
392
393                 /* Get VRAM size and type */
394                 radeon_identify_vram(rinfo);
395
396                 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
397                                 rinfo->video_ram);
398                 rinfo->fb_base = (void *)rinfo->fb_base_phys;
399
400                 DPRINT("Radeon: framebuffer base phy address 0x%08x," \
401                       "MMIO base phy address 0x%08x," \
402                       "framebuffer local base 0x%08x.\n ",
403                       rinfo->fb_base_phys, rinfo->mmio_base_phys,
404                       rinfo->fb_local_base);
405
406                 return 0;
407         }
408         return -1;
409 }
410
411 /*
412  * The Graphic Device
413  */
414 GraphicDevice ctfb;
415
416 #define CURSOR_SIZE     0x1000  /* in KByte for HW Cursor */
417 #define PATTERN_ADR     (pGD->dprBase + CURSOR_SIZE)    /* pattern Memory after Cursor Memory */
418 #define PATTERN_SIZE    8*8*4   /* 4 Bytes per Pixel 8 x 8 Pixel */
419 #define ACCELMEMORY     (CURSOR_SIZE + PATTERN_SIZE)    /* reserved Memory for BITBlt and hw cursor */
420
421 void *video_hw_init(void)
422 {
423         GraphicDevice *pGD = (GraphicDevice *) & ctfb;
424         int i;
425         u32 *vm;
426
427         rinfo = malloc(sizeof(struct radeonfb_info));
428
429         if(radeon_probe(rinfo)) {
430                 printf("No radeon video card found!\n");
431                 return NULL;
432         }
433
434         /* fill in Graphic device struct */
435         sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640,
436                  480, 16, (1000 / 1000),
437                  (2000 / 1000));
438         printf ("%s\n", pGD->modeIdent);
439
440         pGD->winSizeX = 640;
441         pGD->winSizeY = 480;
442         pGD->plnSizeX = 640;
443         pGD->plnSizeY = 480;
444
445         pGD->gdfBytesPP = 1;
446         pGD->gdfIndex = GDF__8BIT_INDEX;
447
448         pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
449         pGD->pciBase = rinfo->fb_base_phys;
450         pGD->frameAdrs = rinfo->fb_base_phys;
451         pGD->memSize = 64 * 1024 * 1024;
452
453         /* Cursor Start Address */
454         pGD->dprBase =
455             (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
456         if ((pGD->dprBase & 0x0fff) != 0) {
457                 /* allign it */
458                 pGD->dprBase &= 0xfffff000;
459                 pGD->dprBase += 0x00001000;
460         }
461         DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
462                 PATTERN_ADR);
463         pGD->vprBase = rinfo->fb_base_phys;     /* Dummy */
464         pGD->cprBase = rinfo->fb_base_phys;     /* Dummy */
465         /* set up Hardware */
466
467         /* Clear video memory */
468         i = pGD->memSize / 4;
469         vm = (unsigned int *) pGD->pciBase;
470         while (i--)
471                 *vm++ = 0;
472         /*SetDrawingEngine (bits_per_pixel);*/
473
474         radeon_setmode();
475
476         return ((void *) pGD);
477 }
478
479 void video_set_lut (unsigned int index, /* color number */
480                unsigned char r, /* red */
481                unsigned char g, /* green */
482                unsigned char b  /* blue */
483                )
484 {
485         OUTREG(PALETTE_INDEX, index);
486         OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);
487 }
488 #endif