|
|
|
|
@@ -59,14 +59,16 @@
|
|
|
|
|
#include "ati_ids.h"
|
|
|
|
|
#include "driver_mem.h"
|
|
|
|
|
#include "bas_printf.h"
|
|
|
|
|
#include "bas_string.h"
|
|
|
|
|
#include "exceptions.h" /* for set_ipl() */
|
|
|
|
|
|
|
|
|
|
#define DBG_RADEON
|
|
|
|
|
#ifdef DBG_RADEON
|
|
|
|
|
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
|
|
|
|
|
#define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0)
|
|
|
|
|
#else
|
|
|
|
|
#define dbg(format, arg...) do {;} while (0)
|
|
|
|
|
#endif /* DBG_RADEON */
|
|
|
|
|
#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0)
|
|
|
|
|
|
|
|
|
|
extern void run_bios(struct radeonfb_info *rinfo);
|
|
|
|
|
|
|
|
|
|
@@ -239,7 +241,8 @@ extern struct fb_info *info_fb;
|
|
|
|
|
#define rinfo ((struct radeonfb_info *) info_fb->par)
|
|
|
|
|
static uint32_t inreg(uint32_t addr)
|
|
|
|
|
{
|
|
|
|
|
return INREG(addr);
|
|
|
|
|
return swpl(*(uint32_t *)(rinfo->mmio_base + addr));
|
|
|
|
|
//return INREG(addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void outreg(uint32_t addr, uint32_t val)
|
|
|
|
|
@@ -360,7 +363,13 @@ static int radeon_map_ROM(struct radeonfb_info *rinfo)
|
|
|
|
|
|
|
|
|
|
uint32_t temp;
|
|
|
|
|
|
|
|
|
|
temp = INREG(MPP_TB_CONFIG);
|
|
|
|
|
dbg("mmio_base=%p\r\n", rinfo->mmio_base);
|
|
|
|
|
dbg("bios_seg=%p\r\n", rinfo->bios_seg);
|
|
|
|
|
dbg("bios_seg_phys=%p\r\n", rinfo->bios_seg_phys);
|
|
|
|
|
|
|
|
|
|
temp = inreg(MPP_TB_CONFIG);
|
|
|
|
|
|
|
|
|
|
dbg("temp=%d\r\n", temp);
|
|
|
|
|
temp &= 0x00ffffffu;
|
|
|
|
|
temp |= 0x04 << 24;
|
|
|
|
|
OUTREG(MPP_TB_CONFIG, temp);
|
|
|
|
|
@@ -368,21 +377,22 @@ static int radeon_map_ROM(struct radeonfb_info *rinfo)
|
|
|
|
|
|
|
|
|
|
if (rinfo->bios_seg == NULL)
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: ROM failed to map\r\n", __FUNCTION__);
|
|
|
|
|
dbg("ROM failed to map\r\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Very simple test to make sure it appeared */
|
|
|
|
|
if (BIOS_IN16(0) != 0xaa55)
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: Invalid ROM signature", __FUNCTION__);
|
|
|
|
|
dbg("Invalid ROM signature");
|
|
|
|
|
goto failed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Look for the PCI data to check the ROM type */
|
|
|
|
|
dptr = BIOS_IN16(0x18);
|
|
|
|
|
|
|
|
|
|
/* Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM
|
|
|
|
|
/*
|
|
|
|
|
* Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM
|
|
|
|
|
* for now, until I've verified this works everywhere. The goal here is more
|
|
|
|
|
* to phase out Open Firmware images.
|
|
|
|
|
*
|
|
|
|
|
@@ -408,35 +418,35 @@ static int radeon_map_ROM(struct radeonfb_info *rinfo)
|
|
|
|
|
*/
|
|
|
|
|
if (BIOS_IN32(dptr) != (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P'))
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: PCI DATA signature in ROM incorrect: %p\r\n", __FUNCTION__, BIOS_IN32(dptr));
|
|
|
|
|
dbg("PCI DATA signature in ROM incorrect: %p\r\n", BIOS_IN32(dptr));
|
|
|
|
|
goto anyway;
|
|
|
|
|
}
|
|
|
|
|
rom_type = BIOS_IN8(dptr + 0x14);
|
|
|
|
|
switch(rom_type)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
dbg("%s: Found Intel x86 BIOS ROM Image\r\n", __FUNCTION__);
|
|
|
|
|
dbg("Found Intel x86 BIOS ROM Image\r\n");
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
dbg("%s: Found Open Firmware ROM Image\r\n", __FUNCTION__);
|
|
|
|
|
dbg("Found Open Firmware ROM Image\r\n");
|
|
|
|
|
goto failed;
|
|
|
|
|
case 2:
|
|
|
|
|
dbg("%s: Found HP PA-RISC ROM Image\r\n", __FUNCTION__);
|
|
|
|
|
dbg("Found HP PA-RISC ROM Image\r\n");
|
|
|
|
|
goto failed;
|
|
|
|
|
default:
|
|
|
|
|
dbg("%s: Found unknown type %d ROM Image\r\n", rom_type, __FUNCTION__);
|
|
|
|
|
dbg("Found unknown type %d ROM Image\r\n", rom_type);
|
|
|
|
|
goto failed;
|
|
|
|
|
}
|
|
|
|
|
anyway:
|
|
|
|
|
/* Locate the flat panel infos, do some sanity checking !!! */
|
|
|
|
|
rinfo->fp_bios_start = BIOS_IN16(0x48);
|
|
|
|
|
dbg("%s: BIOS start offset: %p\r\n", __FUNCTION__, BIOS_IN16(0x48));
|
|
|
|
|
dbg("BIOS start offset: %p\r\n", BIOS_IN16(0x48));
|
|
|
|
|
|
|
|
|
|
/* Save BIOS PLL informations */
|
|
|
|
|
{
|
|
|
|
|
uint16_t pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30);
|
|
|
|
|
|
|
|
|
|
dbg("%s: BIOS PLL info block offset: %p\r\n", __FUNCTION__, BIOS_IN16(rinfo->fp_bios_start + 0x30));
|
|
|
|
|
dbg("BIOS PLL info block offset: %p\r\n", BIOS_IN16(rinfo->fp_bios_start + 0x30));
|
|
|
|
|
rinfo->bios_pll.sclk = BIOS_IN16(pll_info_block + 0x08);
|
|
|
|
|
rinfo->bios_pll.mclk = BIOS_IN16(pll_info_block + 0x0a);
|
|
|
|
|
rinfo->bios_pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e);
|
|
|
|
|
@@ -470,7 +480,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
|
|
|
|
|
* Ugh, we cut interrupts, bad bad bad, but we want some precision
|
|
|
|
|
* here, so... --BenH
|
|
|
|
|
*/
|
|
|
|
|
dbg("%s: radeon_probe_pll_params\r\n", __FUNCTION__);
|
|
|
|
|
dbg("radeon_probe_pll_params\r\n");
|
|
|
|
|
|
|
|
|
|
/* Flush PCI buffers ? */
|
|
|
|
|
tmp = INREG16(DEVICE_ID);
|
|
|
|
|
@@ -515,15 +525,15 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
|
|
|
|
|
set_ipl(ipl);
|
|
|
|
|
|
|
|
|
|
hz = US_TO_TIMER(1000000.0) / (double)(stop_tv - start_tv);
|
|
|
|
|
dbg("%s:hz %d\r\n", __FUNCTION__, (int32_t) hz);
|
|
|
|
|
dbg("hz %d\r\n", (int32_t) hz);
|
|
|
|
|
|
|
|
|
|
hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8;
|
|
|
|
|
vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1);
|
|
|
|
|
dbg("%s:hTotal=%d\r\n", __FUNCTION__, hTotal);
|
|
|
|
|
dbg("%s:vTotal=%d\r\n", __FUNCTION__, vTotal);
|
|
|
|
|
dbg("hTotal=%d\r\n", hTotal);
|
|
|
|
|
dbg("vTotal=%d\r\n", vTotal);
|
|
|
|
|
|
|
|
|
|
vclk = (double) hTotal * (double) vTotal * hz;
|
|
|
|
|
dbg("%s:vclk=%d\r\n", __FUNCTION__, (int) vclk);
|
|
|
|
|
dbg("vclk=%d\r\n", (int) vclk);
|
|
|
|
|
|
|
|
|
|
switch ((INPLL(PPLL_REF_DIV) & 0x30000) >> 16)
|
|
|
|
|
{
|
|
|
|
|
@@ -595,7 +605,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
|
|
|
|
|
xtal = 2950;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: xtal calculation failed: %d\r\n", __FUNCTION__, xtal);
|
|
|
|
|
dbg("xtal calculation failed: %d\r\n", xtal);
|
|
|
|
|
return -1; /* error */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -628,7 +638,7 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
|
|
|
|
|
* incomplete, however. It does provide ppll_max and _min values
|
|
|
|
|
* even for most other methods, however.
|
|
|
|
|
*/
|
|
|
|
|
dbg("%s:\r\n", __FUNCTION__);
|
|
|
|
|
dbg("\r\n");
|
|
|
|
|
|
|
|
|
|
switch(rinfo->chipset)
|
|
|
|
|
{
|
|
|
|
|
@@ -701,7 +711,7 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
|
|
|
|
|
rinfo->pll.ref_div = rinfo->bios_pll.ref_div;
|
|
|
|
|
rinfo->pll.ppll_min = rinfo->bios_pll.ppll_min;
|
|
|
|
|
rinfo->pll.ppll_max = rinfo->bios_pll.ppll_max;
|
|
|
|
|
dbg("%s: Retreived PLL infos from BIOS\r\n", __FUNCTION__);
|
|
|
|
|
dbg("Retreived PLL infos from BIOS\r\n");
|
|
|
|
|
|
|
|
|
|
goto found;
|
|
|
|
|
}
|
|
|
|
|
@@ -712,14 +722,14 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
|
|
|
|
|
*/
|
|
|
|
|
if (radeon_probe_pll_params(rinfo) == 0)
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: Retreived PLL infos from registers\r\n", __FUNCTION__);
|
|
|
|
|
dbg("Retreived PLL infos from registers\r\n");
|
|
|
|
|
goto found;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Fall back to already-set defaults...
|
|
|
|
|
*/
|
|
|
|
|
dbg("%s: Used default PLL infos\r\n", __FUNCTION__);
|
|
|
|
|
dbg("Used default PLL infos\r\n");
|
|
|
|
|
|
|
|
|
|
found:
|
|
|
|
|
/*
|
|
|
|
|
@@ -732,9 +742,9 @@ found:
|
|
|
|
|
if (rinfo->pll.sclk == 0)
|
|
|
|
|
rinfo->pll.sclk = 20000;
|
|
|
|
|
|
|
|
|
|
dbg("%s: Reference=%d MHz (RefDiv=0x%x) Memory=%d MHz\r\n", __FUNCTION__,
|
|
|
|
|
dbg("Reference=%d MHz (RefDiv=0x%x) Memory=%d MHz\r\n",
|
|
|
|
|
rinfo->pll.ref_clk / 100, rinfo->pll.ref_div, rinfo->pll.mclk / 100);
|
|
|
|
|
dbg("%s: System=%d MHz PLL min %d, max %d\r\n", __FUNCTION__,
|
|
|
|
|
dbg("System=%d MHz PLL min %d, max %d\r\n",
|
|
|
|
|
rinfo->pll.sclk / 100, rinfo->pll.ppll_min, rinfo->pll.ppll_max);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -753,13 +763,13 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|
|
|
|
int nom, den;
|
|
|
|
|
uint32_t pitch;
|
|
|
|
|
|
|
|
|
|
dbg("%s:\r\n", __FUNCTION__);
|
|
|
|
|
dbg("\r\n");
|
|
|
|
|
|
|
|
|
|
/* clocks over 135 MHz have heat isues with DVI on RV100 */
|
|
|
|
|
if ((rinfo->mon1_type == MT_DFP) && (rinfo->family == CHIP_FAMILY_RV100) && ((100000000 / var->pixclock) > 13500))
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: mode %d x %d x %d", __FUNCTION__, var->xres, var->yres, var->bits_per_pixel);
|
|
|
|
|
dbg("%s: rejected, RV100 DVI clock over 135 MHz\r\n", __FUNCTION__);
|
|
|
|
|
dbg("mode %d x %d x %d", var->xres, var->yres, var->bits_per_pixel);
|
|
|
|
|
dbg("rejected, RV100 DVI clock over 135 MHz\r\n");
|
|
|
|
|
|
|
|
|
|
return -1; //-EINVAL;
|
|
|
|
|
}
|
|
|
|
|
@@ -862,7 +872,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|
|
|
|
|
|
|
|
|
if (((v.xres_virtual * v.yres_virtual * nom) / den) > info->screen_size)
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: mode %d x %d rejected (screen size too small)\r\n", __FUNCTION__, v.xres_virtual, v.yres_virtual);
|
|
|
|
|
dbg("mode %d x %d rejected (screen size too small)\r\n", v.xres_virtual, v.yres_virtual);
|
|
|
|
|
return -1; //-EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -884,7 +894,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|
|
|
|
v.red.msb_right = v.green.msb_right = v.blue.msb_right = 0;
|
|
|
|
|
v.transp.offset = v.transp.length = v.transp.msb_right = 0;
|
|
|
|
|
|
|
|
|
|
dbg("%s: using mode %d x %d \r\n", __FUNCTION__, v.xres, v.yres);
|
|
|
|
|
dbg("using mode %d x %d \r\n", v.xres, v.yres);
|
|
|
|
|
|
|
|
|
|
memcpy(var, &v, sizeof(v));
|
|
|
|
|
|
|
|
|
|
@@ -1986,8 +1996,8 @@ static int radeon_set_fbinfo(struct radeonfb_info *rinfo)
|
|
|
|
|
else if (info->screen_size > MIN_MAPPED_VRAM)
|
|
|
|
|
info->screen_size = MIN_MAPPED_VRAM;
|
|
|
|
|
|
|
|
|
|
dbg("%s: ram_base %p\r\n", __FUNCTION__, info->screen_base);
|
|
|
|
|
dbg("%s: ram_size %p\r\n", __FUNCTION__, info->ram_size);
|
|
|
|
|
dbg("ram_base %p\r\n", info->screen_base);
|
|
|
|
|
dbg("ram_size %p\r\n", info->ram_size);
|
|
|
|
|
|
|
|
|
|
/* Fill fix common fields */
|
|
|
|
|
memcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
|
|
|
|
|
@@ -2089,24 +2099,24 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
|
|
|
|
|
*/
|
|
|
|
|
switch(rinfo->family)
|
|
|
|
|
{
|
|
|
|
|
case CHIP_FAMILY_LEGACY: dbg("%s chip type: %s\r\n", __FUNCTION__, "LEGACY"); break;
|
|
|
|
|
case CHIP_FAMILY_RADEON: dbg("%s chip type: %s\r\n", __FUNCTION__, "RADEON"); break;
|
|
|
|
|
case CHIP_FAMILY_RV100: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV100"); break;
|
|
|
|
|
case CHIP_FAMILY_RS100: dbg("%s chip type: %s\r\n", __FUNCTION__, "RS100"); break;
|
|
|
|
|
case CHIP_FAMILY_RV200: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV200"); break;
|
|
|
|
|
case CHIP_FAMILY_RS200: dbg("%s chip type: %s\r\n", __FUNCTION__, "RS200"); break;
|
|
|
|
|
case CHIP_FAMILY_R200: dbg("%s chip type: %s\r\n", __FUNCTION__, "R200"); break;
|
|
|
|
|
case CHIP_FAMILY_RV250: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV250"); break;
|
|
|
|
|
case CHIP_FAMILY_RS300: dbg("%s chip type: %s\r\n", __FUNCTION__, "RS300"); break;
|
|
|
|
|
case CHIP_FAMILY_RV280: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV280"); break;
|
|
|
|
|
case CHIP_FAMILY_R300: dbg("%s chip type: %s\r\n", __FUNCTION__, "R300"); break;
|
|
|
|
|
case CHIP_FAMILY_R350: dbg("%s chip type: %s\r\n", __FUNCTION__, "R350"); break;
|
|
|
|
|
case CHIP_FAMILY_RV350: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV350"); break;
|
|
|
|
|
case CHIP_FAMILY_RV380: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV380"); break;
|
|
|
|
|
case CHIP_FAMILY_R420: dbg("%s chip type: %s\r\n", __FUNCTION__, "R420"); break;
|
|
|
|
|
default: dbg("%s chip type: %s\r\n", "UNKNOW"); break;
|
|
|
|
|
case CHIP_FAMILY_LEGACY: dbg("chip type: %s\r\n", "LEGACY"); break;
|
|
|
|
|
case CHIP_FAMILY_RADEON: dbg("chip type: %s\r\n", "RADEON"); break;
|
|
|
|
|
case CHIP_FAMILY_RV100: dbg("chip type: %s\r\n", "RV100"); break;
|
|
|
|
|
case CHIP_FAMILY_RS100: dbg("chip type: %s\r\n", "RS100"); break;
|
|
|
|
|
case CHIP_FAMILY_RV200: dbg("chip type: %s\r\n", "RV200"); break;
|
|
|
|
|
case CHIP_FAMILY_RS200: dbg("chip type: %s\r\n", "RS200"); break;
|
|
|
|
|
case CHIP_FAMILY_R200: dbg("chip type: %s\r\n", "R200"); break;
|
|
|
|
|
case CHIP_FAMILY_RV250: dbg("chip type: %s\r\n", "RV250"); break;
|
|
|
|
|
case CHIP_FAMILY_RS300: dbg("chip type: %s\r\n", "RS300"); break;
|
|
|
|
|
case CHIP_FAMILY_RV280: dbg("chip type: %s\r\n", "RV280"); break;
|
|
|
|
|
case CHIP_FAMILY_R300: dbg("chip type: %s\r\n", "R300"); break;
|
|
|
|
|
case CHIP_FAMILY_R350: dbg("chip type: %s\r\n", "R350"); break;
|
|
|
|
|
case CHIP_FAMILY_RV350: dbg("chip type: %s\r\n", "RV350"); break;
|
|
|
|
|
case CHIP_FAMILY_RV380: dbg("chip type: %s\r\n", "RV380"); break;
|
|
|
|
|
case CHIP_FAMILY_R420: dbg("chip type: %s\r\n", "R420"); break;
|
|
|
|
|
default: dbg("chip type: %s\r\n", "UNKNOW"); break;
|
|
|
|
|
}
|
|
|
|
|
dbg("%s: found %d KB of %d bits wide %s video RAM\r\n", __FUNCTION__, rinfo->video_ram / 1024,
|
|
|
|
|
dbg("found %d KB of %d bits wide %s video RAM\r\n", rinfo->video_ram / 1024,
|
|
|
|
|
rinfo->vram_width, rinfo->vram_ddr ? "DDR " : "SDRAM ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2116,11 +2126,11 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
struct radeonfb_info *rinfo;
|
|
|
|
|
struct pci_rd *pci_rsc_desc;
|
|
|
|
|
|
|
|
|
|
dbg("%s:\r\n", __FUNCTION__);
|
|
|
|
|
dbg("\r\n");
|
|
|
|
|
info = framebuffer_alloc(sizeof(struct radeonfb_info));
|
|
|
|
|
if (!info)
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: could not allocate frame buffer\r\n", __FUNCTION__);
|
|
|
|
|
dbg("could not allocate frame buffer\r\n");
|
|
|
|
|
return -1; // -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2128,8 +2138,11 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
|
|
|
|
|
rinfo->info = info;
|
|
|
|
|
rinfo->handle = handle;
|
|
|
|
|
|
|
|
|
|
strcpy((char *) rinfo->name, "ATI Radeon XX ");
|
|
|
|
|
rinfo->name[11] = (char) (ent->device >> 8);
|
|
|
|
|
rinfo->name[12] = (char) ent->device;
|
|
|
|
|
|
|
|
|
|
rinfo->family = ent->driver_data & CHIP_FAMILY_MASK;
|
|
|
|
|
rinfo->chipset = ent->device;
|
|
|
|
|
rinfo->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0;
|
|
|
|
|
@@ -2137,7 +2150,7 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
rinfo->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0;
|
|
|
|
|
|
|
|
|
|
/* Set base addrs */
|
|
|
|
|
dbg("%s: Set base addrs\r\n", __FUNCTION__);
|
|
|
|
|
dbg("Set base addrs\r\n");
|
|
|
|
|
rinfo->fb_base_phys = rinfo->mmio_base_phys = rinfo->io_base_phys = 0xFFFFFFFF;
|
|
|
|
|
rinfo->mapped_vram = 0;
|
|
|
|
|
rinfo->mmio_base = rinfo->io_base = NULL;
|
|
|
|
|
@@ -2149,10 +2162,10 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
uint16_t flags;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: flags %p\r\n", __FUNCTION__, pci_rsc_desc->flags);
|
|
|
|
|
dbg("%s: start %p\r\n", __FUNCTION__, pci_rsc_desc->start);
|
|
|
|
|
dbg("%s: offset 0x%x\r\n", __FUNCTION__, pci_rsc_desc->offset);
|
|
|
|
|
dbg("%s: length 0x%x\r\n", __FUNCTION__, pci_rsc_desc->length);
|
|
|
|
|
dbg("flags %p\r\n", pci_rsc_desc->flags);
|
|
|
|
|
dbg(" start %p\r\n", pci_rsc_desc->start);
|
|
|
|
|
dbg(" offset 0x%x\r\n", pci_rsc_desc->offset);
|
|
|
|
|
dbg(" length 0x%x\r\n", pci_rsc_desc->length);
|
|
|
|
|
|
|
|
|
|
if (!(pci_rsc_desc->flags & FLG_IO))
|
|
|
|
|
{
|
|
|
|
|
@@ -2165,30 +2178,44 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
if ((pci_rsc_desc->flags & FLG_ENDMASK) == ORD_MOTOROLA)
|
|
|
|
|
{
|
|
|
|
|
rinfo->big_endian = 0; /* host bridge make swapping intel -> motorola */
|
|
|
|
|
dbg("%s: host bridge is big endian\r\n", __FUNCTION__);
|
|
|
|
|
dbg("host bridge is big endian\r\n");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rinfo->big_endian = 1; /* radeon make swapping intel -> motorola */
|
|
|
|
|
dbg("%s: host bridge is little endian\r\n", __FUNCTION__);
|
|
|
|
|
dbg("host bridge is little endian\r\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xprintf("framebuffer dump:\r\n");
|
|
|
|
|
hexdump((uint8_t *) rinfo->fb_base_phys, 0x10);
|
|
|
|
|
xprintf("change framebuffer contents\r\n");
|
|
|
|
|
* (uint32_t *) rinfo->fb_base_phys = 0x01234567;
|
|
|
|
|
* (uint32_t *) (rinfo->fb_base_phys + 8) = 0x89abcdef;
|
|
|
|
|
hexdump((uint8_t *) rinfo->fb_base_phys, 0x10);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if ((pci_rsc_desc->length >= RADEON_REGSIZE) && (pci_rsc_desc->length < 0x100000))
|
|
|
|
|
{
|
|
|
|
|
if (pci_rsc_desc->flags & FLG_ROM)
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: FLG_ROM resource descriptor found\r\n", __FUNCTION__);
|
|
|
|
|
dbg("%s: start = %p, size = 0x%x\r\n", __FUNCTION__, pci_rsc_desc->start, pci_rsc_desc->length);
|
|
|
|
|
dbg("%s: bios_seg = %p\r\n", __FUNCTION__, rinfo->bios_seg);
|
|
|
|
|
dbg("FLG_ROM resource descriptor found\r\n");
|
|
|
|
|
dbg(" start = %p, size = 0x%x\r\n", pci_rsc_desc->start, pci_rsc_desc->length);
|
|
|
|
|
dbg(" bios_seg = %p\r\n", rinfo->bios_seg);
|
|
|
|
|
|
|
|
|
|
if (rinfo->bios_seg == NULL)
|
|
|
|
|
{
|
|
|
|
|
rinfo->bios_seg_phys = pci_rsc_desc->start;
|
|
|
|
|
if (BIOS_IN16(0) == 0xaa55)
|
|
|
|
|
{
|
|
|
|
|
rinfo->bios_seg = (void *) (pci_rsc_desc->offset + pci_rsc_desc->start);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: BIOS_IN16(0) was %x (expected 0xaa55)\r\n", __FUNCTION__, BIOS_IN16(0));
|
|
|
|
|
dbg("rinfo->bios_seg[0] (%p) was %x (expected 0xaa55)\r\n",
|
|
|
|
|
rinfo->bios_seg_phys, * (uint16_t *) rinfo->bios_seg_phys);
|
|
|
|
|
xprintf("bios_seg_phys dump:\r\n");
|
|
|
|
|
hexdump((uint8_t *) rinfo->bios_seg_phys, 0x100);
|
|
|
|
|
|
|
|
|
|
rinfo->bios_seg_phys = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -2199,6 +2226,9 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
{
|
|
|
|
|
rinfo->mmio_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start);
|
|
|
|
|
rinfo->mmio_base_phys = pci_rsc_desc->start;
|
|
|
|
|
|
|
|
|
|
xprintf("mmio_base dump:\r\n");
|
|
|
|
|
hexdump((uint8_t *) rinfo->mmio_base_phys, 0x100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -2209,6 +2239,9 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
{
|
|
|
|
|
rinfo->io_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start);
|
|
|
|
|
rinfo->io_base_phys = pci_rsc_desc->start;
|
|
|
|
|
|
|
|
|
|
xprintf("io_base dump:\r\n");
|
|
|
|
|
hexdump((uint8_t *) rinfo->io_base_phys, 0x100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
flags = pci_rsc_desc->flags;
|
|
|
|
|
@@ -2216,24 +2249,24 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
} while (!(flags & FLG_LAST));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
dbg("%s: get_resource error\r\n", __FUNCTION__);
|
|
|
|
|
dbg("get_resource error\r\n");
|
|
|
|
|
|
|
|
|
|
/* map the regions */
|
|
|
|
|
dbg("%s: map memory regions\r\n", __FUNCTION__);
|
|
|
|
|
dbg("map memory regions\r\n");
|
|
|
|
|
if (rinfo->mmio_base == NULL)
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: cannot map MMIO\r\n", __FUNCTION__);
|
|
|
|
|
dbg("cannot map MMIO\r\n");
|
|
|
|
|
framebuffer_release(info);
|
|
|
|
|
return -2; //(-EIO);
|
|
|
|
|
}
|
|
|
|
|
dbg("%s: mmio_base_phys %p, mmio_base %p\r\n", __FUNCTION__, rinfo->mmio_base_phys, rinfo->mmio_base);
|
|
|
|
|
dbg("%s: io_base_phys %p, io_base %p\r\n", __FUNCTION__, rinfo->io_base_phys, rinfo->io_base);
|
|
|
|
|
dbg("%s: fb_base_phys %p, fb_base %p\r\n", __FUNCTION__, rinfo->fb_base_phys, rinfo->fb_base);
|
|
|
|
|
dbg("mmio_base_phys %p, mmio_base %p\r\n", rinfo->mmio_base_phys, rinfo->mmio_base);
|
|
|
|
|
dbg("io_base_phys %p, io_base %p\r\n", rinfo->io_base_phys, rinfo->io_base);
|
|
|
|
|
dbg("fb_base_phys %p, fb_base %p\r\n", rinfo->fb_base_phys, rinfo->fb_base);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check for errata
|
|
|
|
|
*/
|
|
|
|
|
dbg("%s: check for errata\r\n", __FUNCTION__);
|
|
|
|
|
dbg("check for errata\r\n");
|
|
|
|
|
rinfo->errata = 0;
|
|
|
|
|
if (rinfo->family == CHIP_FAMILY_R300
|
|
|
|
|
&& (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) == CFG_ATI_REV_A11)
|
|
|
|
|
@@ -2249,22 +2282,22 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
* Map the BIOS ROM if any and retreive PLL parameters from
|
|
|
|
|
* the BIOS.
|
|
|
|
|
*/
|
|
|
|
|
dbg("%s: bios_seg_phys %p\r\n", __FUNCTION__, rinfo->bios_seg_phys);
|
|
|
|
|
dbg("%s: map the BIOS ROM\r\n", __FUNCTION__);
|
|
|
|
|
dbg("bios_seg_phys %p\r\n", rinfo->bios_seg_phys);
|
|
|
|
|
dbg("map the BIOS ROM\r\n");
|
|
|
|
|
radeon_map_ROM(rinfo);
|
|
|
|
|
|
|
|
|
|
/* Run VGA BIOS */
|
|
|
|
|
if ((rinfo->bios_seg != NULL))
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: run VGA BIOS\r\n", __FUNCTION__);
|
|
|
|
|
dbg("run VGA BIOS\r\n");
|
|
|
|
|
run_bios(rinfo);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: could not run VGA bios - rinfo->bios_seg is NULL\r\n", __FUNCTION__);
|
|
|
|
|
dbg("could not run VGA bios - rinfo->bios_seg is NULL\r\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dbg("%s: fixup display base address \r\n", __FUNCTION__);
|
|
|
|
|
dbg("fixup display base address \r\n");
|
|
|
|
|
|
|
|
|
|
OUTREG(MC_FB_LOCATION, 0x7fff0000);
|
|
|
|
|
rinfo->fb_local_base = 0;
|
|
|
|
|
@@ -2279,52 +2312,52 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
OUTREG(OV0_BASE_ADDR, 0);
|
|
|
|
|
|
|
|
|
|
/* Get VRAM size and type */
|
|
|
|
|
dbg("%s: get VRAM size\r\n", __FUNCTION__);
|
|
|
|
|
dbg("get VRAM size\r\n");
|
|
|
|
|
radeon_identify_vram(rinfo);
|
|
|
|
|
|
|
|
|
|
if ((rinfo->fb_base == NULL)
|
|
|
|
|
|| ((rinfo->video_ram > rinfo->mapped_vram) && (rinfo->mapped_vram < MIN_MAPPED_VRAM * 2)))
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: cannot map FB, video ram: %d KB\r\n", __FUNCTION__, rinfo->mapped_vram / 1024);
|
|
|
|
|
dbg("cannot map FB, video ram: %d KB\r\n", rinfo->mapped_vram / 1024);
|
|
|
|
|
framebuffer_release(info);
|
|
|
|
|
return -2; //(-EIO);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dbg("%s: %d KB of VRAM mapped to %p\r\n", __FUNCTION__, rinfo->mapped_vram / 1024, rinfo->fb_base);
|
|
|
|
|
dbg("%d KB of VRAM mapped to %p\r\n", rinfo->mapped_vram / 1024, rinfo->fb_base);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get informations about the board's PLL */
|
|
|
|
|
dbg("%s: get informations about the board's PLL\r\n", __FUNCTION__);
|
|
|
|
|
dbg("get informations about the board's PLL\r\n");
|
|
|
|
|
radeon_get_pllinfo(rinfo);
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_FB_RADEON_I2C
|
|
|
|
|
/* Register I2C bus */
|
|
|
|
|
dbg("%s: register I2C bus\r\n", __FUNCTION__);
|
|
|
|
|
dbg("register I2C bus\r\n");
|
|
|
|
|
radeon_create_i2c_busses(rinfo);
|
|
|
|
|
#endif /* CONFIG_FB_RADEON_I2C */
|
|
|
|
|
|
|
|
|
|
/* set all the vital stuff */
|
|
|
|
|
dbg("%s: set all the vital stuff\r\n", __FUNCTION__);
|
|
|
|
|
dbg("set all the vital stuff\r\n");
|
|
|
|
|
radeon_set_fbinfo(rinfo);
|
|
|
|
|
|
|
|
|
|
/* set offscreen memory descriptor */
|
|
|
|
|
dbg("%s: set offscreen memory descriptor\r\n", __FUNCTION__);
|
|
|
|
|
dbg("set offscreen memory descriptor\r\n");
|
|
|
|
|
offscreen_init(info);
|
|
|
|
|
|
|
|
|
|
/* Probe screen types */
|
|
|
|
|
dbg("%s: probe screen types, monitor_layout: 0x%x\r\n", __FUNCTION__, monitor_layout);
|
|
|
|
|
dbg("probe screen types, monitor_layout: 0x%x\r\n", monitor_layout);
|
|
|
|
|
radeon_probe_screens(rinfo, monitor_layout, (int) ignore_edid);
|
|
|
|
|
|
|
|
|
|
/* Build mode list, check out panel native model */
|
|
|
|
|
dbg("%s: build mode list\r\n", __FUNCTION__);
|
|
|
|
|
dbg("build mode list\r\n");
|
|
|
|
|
radeon_check_modes(rinfo, &resolution);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* save current mode regs before we switch into the new one
|
|
|
|
|
* so we can restore this upon exit
|
|
|
|
|
*/
|
|
|
|
|
dbg("%s: save current mode\r\n", __FUNCTION__);
|
|
|
|
|
dbg("save current mode\r\n");
|
|
|
|
|
radeon_save_state(rinfo, &rinfo->init_state);
|
|
|
|
|
memcpy(&rinfo->state, &rinfo->init_state, sizeof(struct radeon_regs));
|
|
|
|
|
|
|
|
|
|
@@ -2332,7 +2365,7 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
|
|
|
|
|
// DPRINT("radeonfb: radeonfb_pci_register: setup power management\r\n");
|
|
|
|
|
// radeonfb_pm_init(rinfo, (int)default_dynclk);
|
|
|
|
|
|
|
|
|
|
dbg("%s: install VBL timer\r\n", __FUNCTION__);
|
|
|
|
|
dbg("install VBL timer\r\n");
|
|
|
|
|
rinfo->lvds_timer = 0;
|
|
|
|
|
#ifndef DRIVER_IN_ROM
|
|
|
|
|
install_vbl_timer(radeon_timer_func, 1); /* remove old vector */
|
|
|
|
|
|