|
|
host_path_cntl = INREG(HOST_PATH_CNTL); | host_path_cntl = INREG(HOST_PATH_CNTL); |
rbbm_soft_reset = INREG(RBBM_SOFT_RESET); | rbbm_soft_reset = INREG(RBBM_SOFT_RESET); |
| |
if (rinfo->family == CHIP_FAMILY_R300 || |
if (IS_R300_VARIANT(rinfo)) { |
rinfo->family == CHIP_FAMILY_R350 || |
|
rinfo->family == CHIP_FAMILY_RV350) { |
|
u32 tmp; | u32 tmp; |
| |
OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset | | OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset | |
|
|
INREG(HOST_PATH_CNTL); | INREG(HOST_PATH_CNTL); |
OUTREG(HOST_PATH_CNTL, host_path_cntl); | OUTREG(HOST_PATH_CNTL, host_path_cntl); |
| |
if (rinfo->family != CHIP_FAMILY_R300 || |
if (IS_R300_VARIANT(rinfo)) |
rinfo->family != CHIP_FAMILY_R350 || |
|
rinfo->family != CHIP_FAMILY_RV350) |
|
OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); | OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); |
| |
OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); | OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); |
|
|
{ | { |
unsigned long temp; | unsigned long temp; |
| |
/* disable 3D engine */ |
|
OUTREG(RB3D_CNTL, 0); |
|
|
|
radeonfb_engine_reset(rinfo); | radeonfb_engine_reset(rinfo); |
| |
radeon_fifo_wait (1); | radeon_fifo_wait (1); |
if ((rinfo->family != CHIP_FAMILY_R300) && |
if (IS_R300_VARIANT(rinfo)) { |
(rinfo->family != CHIP_FAMILY_R350) && |
temp = INREG(RB2D_DSTCACHE_MODE); |
(rinfo->family != CHIP_FAMILY_RV350)) |
OUTREG(RB2D_DSTCACHE_MODE, temp | (1<<17)); /* FIXME */ |
|
} else { |
OUTREG(RB2D_DSTCACHE_MODE, 0); | OUTREG(RB2D_DSTCACHE_MODE, 0); |
|
} |
| |
radeon_fifo_wait (3); | radeon_fifo_wait (3); |
/* We re-read MC_FB_LOCATION from card as it can have been | /* We re-read MC_FB_LOCATION from card as it can have been |
|
|
return 0; | return 0; |
} | } |
| |
|
static void radeon_detect_bios_type(struct radeonfb_info *rinfo) |
|
{ |
|
#ifndef CONFIG_PPC_OF |
|
int offset = rinfo->fp_bios_start + 4; |
|
unsigned char sign[4]; |
|
|
|
sign[0] = BIOS_IN8(offset); |
|
sign[1] = BIOS_IN8(offset + 1); |
|
sign[2] = BIOS_IN8(offset + 2); |
|
sign[3] = BIOS_IN8(offset + 3); |
|
|
|
if (!memcmp(sign, "ATOM", 4) || !memcmp(sign, "MOTA", 4)) { |
|
rinfo->is_atom_bios = 1; |
|
rinfo->atom_data_start = BIOS_IN16(rinfo->fp_bios_start + 32); |
|
|
|
printk(KERN_INFO "radeonfb: ATOM BIOS signature found\n"); |
|
|
|
return; |
|
} |
|
#endif /* NOT CONFIG_PPC_OF */ |
|
|
|
rinfo->is_atom_bios = 0; |
|
|
|
return; |
|
} |
|
|
/* | /* |
* Retrieve PLL infos by different means (BIOS, Open Firmware, register probing...) | * Retrieve PLL infos by different means (BIOS, Open Firmware, register probing...) |
*/ | */ |
|
|
#endif /* CONFIG_PPC_OF || CONFIG_SPARC */ | #endif /* CONFIG_PPC_OF || CONFIG_SPARC */ |
| |
/* | /* |
* Check out if we have an X86 which gave us some PLL informations |
* Check out if we have an ATOM BIOS which gave us some PLL informations |
* and if yes, retrieve them | * and if yes, retrieve them |
*/ | */ |
|
|
if (!force_measure_pll && rinfo->bios_seg) { | if (!force_measure_pll && rinfo->bios_seg) { |
u16 pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30); |
u16 pll_info_block; |
| |
rinfo->pll.sclk = BIOS_IN16(pll_info_block + 0x08); |
if(rinfo->is_atom_bios) { |
rinfo->pll.mclk = BIOS_IN16(pll_info_block + 0x0a); |
pll_info_block = BIOS_IN16(rinfo->atom_data_start + 12); |
rinfo->pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e); |
|
rinfo->pll.ref_div = BIOS_IN16(pll_info_block + 0x10); |
|
rinfo->pll.ppll_min = BIOS_IN32(pll_info_block + 0x12); |
|
rinfo->pll.ppll_max = BIOS_IN32(pll_info_block + 0x16); |
|
| |
|
rinfo->pll.sclk = BIOS_IN32(pll_info_block + 8); |
|
rinfo->pll.mclk = BIOS_IN32(pll_info_block + 12); |
|
rinfo->pll.ref_clk = BIOS_IN16(pll_info_block + 82); |
|
rinfo->pll.ref_div = 0; /* Have to get it elsewhere */ |
|
rinfo->pll.ppll_min = BIOS_IN16(pll_info_block + 78); |
|
rinfo->pll.ppll_max = BIOS_IN32(pll_info_block + 32); |
|
} else { |
|
/* |
|
* Check out if we have an X86 which gave us some PLL informations |
|
* and if yes, retrieve them |
|
*/ |
|
pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30); |
|
|
|
rinfo->pll.sclk = BIOS_IN16(pll_info_block + 0x08); |
|
rinfo->pll.mclk = BIOS_IN16(pll_info_block + 0x0a); |
|
rinfo->pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e); |
|
rinfo->pll.ref_div = BIOS_IN16(pll_info_block + 0x10); |
|
rinfo->pll.ppll_min = BIOS_IN32(pll_info_block + 0x12); |
|
rinfo->pll.ppll_max = BIOS_IN32(pll_info_block + 0x16); |
|
} |
printk(KERN_INFO "radeonfb: Retrieved PLL infos from BIOS\n"); | printk(KERN_INFO "radeonfb: Retrieved PLL infos from BIOS\n"); |
|
|
goto found; | goto found; |
} | } |
| |
|
|
/* | /* |
* Fall back to already-set defaults... | * Fall back to already-set defaults... |
*/ | */ |
printk(KERN_INFO "radeonfb: Used default PLL infos\n"); |
printk(KERN_INFO "radeonfb: Fall back to default PLL infos\n"); |
| |
found: | found: |
|
/* Check and fix-up the PLL divisor if necessary */ |
|
if (rinfo->pll.ref_div < 2) { |
|
int tmp = INPLL(PPLL_REF_DIV); |
|
if (rinfo->family == CHIP_FAMILY_RS300) { |
|
rinfo->pll.ref_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT; |
|
} else { |
|
rinfo->pll.ref_div = tmp & PPLL_REF_DIV_MASK; |
|
} |
|
|
|
/* Sane default */ |
|
if (rinfo->pll.ref_div < 2) { |
|
printk(KERN_INFO "radeonfb: Set a sane default PLL divisor\n"); |
|
rinfo->pll.ref_div = 12; |
|
} |
|
} |
|
|
/* | /* |
* Some methods fail to retrieve SCLK and MCLK values, we apply default | * Some methods fail to retrieve SCLK and MCLK values, we apply default |
* settings in this case (200Mhz). If that really happne often, we could |
* settings in this case (200Mhz). If that really happen often, we could |
* fetch from registers instead... | * fetch from registers instead... |
*/ | */ |
if (rinfo->pll.mclk == 0) |
if (rinfo->pll.mclk == 0) { |
|
printk(KERN_INFO "radeonfb: Set a sane default MCLK value\n"); |
rinfo->pll.mclk = 20000; | rinfo->pll.mclk = 20000; |
if (rinfo->pll.sclk == 0) |
} |
|
if (rinfo->pll.mclk == 0) { |
|
printk(KERN_INFO "radeonfb: Set a sane default SCLK value\n"); |
rinfo->pll.sclk = 20000; | rinfo->pll.sclk = 20000; |
|
} |
| |
printk("radeonfb: Reference=%d.%02d MHz (RefDiv=%d) Memory=%d.%02d Mhz, System=%d.%02d MHz\n", | printk("radeonfb: Reference=%d.%02d MHz (RefDiv=%d) Memory=%d.%02d Mhz, System=%d.%02d MHz\n", |
rinfo->pll.ref_clk / 100, rinfo->pll.ref_clk % 100, | rinfo->pll.ref_clk / 100, rinfo->pll.ref_clk % 100, |
|
|
if (rinfo->bios_seg == NULL && rinfo->is_mobility) | if (rinfo->bios_seg == NULL && rinfo->is_mobility) |
radeon_map_ROM(rinfo, pdev); | radeon_map_ROM(rinfo, pdev); |
| |
|
/* Check BIOS Type */ |
|
radeon_detect_bios_type(rinfo); |
|
|
/* Get informations about the board's PLL */ | /* Get informations about the board's PLL */ |
radeon_get_pllinfo(rinfo); | radeon_get_pllinfo(rinfo); |
| |
|
|
| |
radeonfb_bl_exit(rinfo); | radeonfb_bl_exit(rinfo); |
| |
|
radeonfb_bl_exit(rinfo); |
|
|
iounmap(rinfo->mmio_base); | iounmap(rinfo->mmio_base); |
iounmap(rinfo->fb_base); | iounmap(rinfo->fb_base); |
| |
|
|
void __iomem *bios_seg; | void __iomem *bios_seg; |
int fp_bios_start; | int fp_bios_start; |
| |
|
int is_atom_bios; |
|
int atom_data_start; |
|
|
u32 pseudo_palette[17]; | u32 pseudo_palette[17]; |
struct { u8 red, green, blue, pad; } | struct { u8 red, green, blue, pad; } |
palette[256]; | palette[256]; |
|
|
| |
RTRACE("Starting monitor auto detection...\n"); | RTRACE("Starting monitor auto detection...\n"); |
| |
#if DEBUG && defined(CONFIG_FB_RADEON_I2C) |
|
{ |
|
u8 *EDIDs[4] = { NULL, NULL, NULL, NULL }; |
|
int mon_types[4] = {MT_NONE, MT_NONE, MT_NONE, MT_NONE}; |
|
int i; |
|
|
|
for (i = 0; i < 4; i++) |
|
mon_types[i] = radeon_probe_i2c_connector(rinfo, |
|
i+1, &EDIDs[i]); |
|
} |
|
#endif /* DEBUG */ |
|
/* | /* |
* Old single head cards | * Old single head cards |
*/ | */ |
|
|
if (!BIOS_IN8(tmp + i*2) && i > 1) | if (!BIOS_IN8(tmp + i*2) && i > 1) |
break; | break; |
tmp0 = BIOS_IN16(tmp + i*2); | tmp0 = BIOS_IN16(tmp + i*2); |
if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0x0f) == ddc_dvi)) { |
if ((!(tmp0 & 0x01)) && ((((tmp0 >> 8) & 0x0f) == ddc_dvi) || (((tmp0 >> 8) & 0x0f) == ddc_monid))) { |
rinfo->reversed_DAC = 1; | rinfo->reversed_DAC = 1; |
printk(KERN_INFO "radeonfb: Reversed DACs detected\n"); | printk(KERN_INFO "radeonfb: Reversed DACs detected\n"); |
} | } |
if ((((tmp0 >> 8) & 0x0f) == ddc_dvi) && ((tmp0 >> 4) & 0x01)) { |
if ((((tmp0 >> 8) & 0x0f) == ddc_dvi || (((tmp0 >> 8) & 0x0f) == ddc_monid)) && ((tmp0 >> 4) & 0x01)) { |
rinfo->reversed_TMDS = 1; | rinfo->reversed_TMDS = 1; |
printk(KERN_INFO "radeonfb: Reversed TMDS detected\n"); | printk(KERN_INFO "radeonfb: Reversed TMDS detected\n"); |
} | } |
|
|
#endif /* CONFIG_PPC_OF || CONFIG_SPARC */ | #endif /* CONFIG_PPC_OF || CONFIG_SPARC */ |
#ifdef CONFIG_FB_RADEON_I2C | #ifdef CONFIG_FB_RADEON_I2C |
if (rinfo->mon1_type == MT_NONE) | if (rinfo->mon1_type == MT_NONE) |
|
rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_monid, |
|
&rinfo->mon1_EDID); |
|
if (rinfo->mon1_type == MT_NONE) |
rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi, | rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi, |
&rinfo->mon1_EDID); | &rinfo->mon1_EDID); |
if (rinfo->mon1_type == MT_NONE) { | if (rinfo->mon1_type == MT_NONE) { |
|
|
| |
| |
/* | /* |
* This functions applyes any arch/model/machine specific fixups |
* This functions applies any arch/model/machine specific fixups |
* to the panel info. It may eventually alter EDID block as | * to the panel info. It may eventually alter EDID block as |
* well or whatever is specific to a given model and not probed | * well or whatever is specific to a given model and not probed |
* properly by the default code | * properly by the default code |