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