--- radeon_accel.c.ori 2007-05-09 17:09:00.000000000 +0200 +++ radeon_accel.c 2007-05-09 18:59:25.000000000 +0200 @@ -203,9 +203,7 @@ host_path_cntl = INREG(HOST_PATH_CNTL); rbbm_soft_reset = INREG(RBBM_SOFT_RESET); - if (rinfo->family == CHIP_FAMILY_R300 || - rinfo->family == CHIP_FAMILY_R350 || - rinfo->family == CHIP_FAMILY_RV350) { + if (IS_R300_VARIANT(rinfo)) { u32 tmp; OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset | @@ -241,9 +239,7 @@ INREG(HOST_PATH_CNTL); OUTREG(HOST_PATH_CNTL, host_path_cntl); - if (rinfo->family != CHIP_FAMILY_R300 || - rinfo->family != CHIP_FAMILY_R350 || - rinfo->family != CHIP_FAMILY_RV350) + if (IS_R300_VARIANT(rinfo)) OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); @@ -254,16 +250,15 @@ { unsigned long temp; - /* disable 3D engine */ - OUTREG(RB3D_CNTL, 0); - radeonfb_engine_reset(rinfo); radeon_fifo_wait (1); - if ((rinfo->family != CHIP_FAMILY_R300) && - (rinfo->family != CHIP_FAMILY_R350) && - (rinfo->family != CHIP_FAMILY_RV350)) + if (IS_R300_VARIANT(rinfo)) { + temp = INREG(RB2D_DSTCACHE_MODE); + OUTREG(RB2D_DSTCACHE_MODE, temp | (1<<17)); /* FIXME */ + } else { OUTREG(RB2D_DSTCACHE_MODE, 0); + } radeon_fifo_wait (3); /* We re-read MC_FB_LOCATION from card as it can have been --- radeon_base.c.ori 2007-05-09 17:09:00.000000000 +0200 +++ radeon_base.c 2007-05-09 19:07:19.000000000 +0200 @@ -582,6 +582,32 @@ 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...) */ @@ -658,20 +684,38 @@ #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 */ + 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); - 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); + if(rinfo->is_atom_bios) { + pll_info_block = BIOS_IN16(rinfo->atom_data_start + 12); + 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"); + goto found; } @@ -687,18 +731,38 @@ /* * 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: + /* 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 - * 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... */ - 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; - 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; + } 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, @@ -2302,6 +2366,9 @@ if (rinfo->bios_seg == NULL && rinfo->is_mobility) radeon_map_ROM(rinfo, pdev); + /* Check BIOS Type */ + radeon_detect_bios_type(rinfo); + /* Get informations about the board's PLL */ radeon_get_pllinfo(rinfo); @@ -2429,6 +2496,8 @@ radeonfb_bl_exit(rinfo); + radeonfb_bl_exit(rinfo); + iounmap(rinfo->mmio_base); iounmap(rinfo->fb_base); --- radeonfb.h.ori 2007-05-09 17:09:00.000000000 +0200 +++ radeonfb.h 2007-05-09 19:17:11.000000000 +0200 @@ -301,6 +301,9 @@ void __iomem *bios_seg; int fp_bios_start; + int is_atom_bios; + int atom_data_start; + u32 pseudo_palette[17]; struct { u8 red, green, blue, pad; } palette[256]; --- radeon_monitor.c.ori 2007-05-09 18:56:37.000000000 +0200 +++ radeon_monitor.c 2007-05-09 19:18:14.000000000 +0200 @@ -481,17 +481,6 @@ 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 */ @@ -531,11 +520,11 @@ if (!BIOS_IN8(tmp + i*2) && i > 1) break; 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; 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; printk(KERN_INFO "radeonfb: Reversed TMDS detected\n"); } @@ -552,6 +541,9 @@ #endif /* CONFIG_PPC_OF || CONFIG_SPARC */ #ifdef CONFIG_FB_RADEON_I2C 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_EDID); if (rinfo->mon1_type == MT_NONE) { @@ -643,7 +635,7 @@ /* - * 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 * well or whatever is specific to a given model and not probed * properly by the default code