--- radeon_base.c.orig 2007-03-23 23:09:19.000000000 +0100 +++ radeon_base.c 2007-03-26 13:39:31.000000000 +0200 @@ -3,6 +3,7 @@ * * framebuffer driver for ATI Radeon chipset video boards * + * Copyright 2006 Solomon Peachy * Copyright 2003 Ben. Herrenschmidt * Copyright 2000 Ani Joshi * @@ -50,7 +51,7 @@ */ -#define RADEON_VERSION "0.2.0" +#define RADEON_VERSION "0.3.0" #include #include @@ -180,6 +181,7 @@ CHIP_DEF(PCI_CHIP_RV360_AR, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV350_AS, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV350_AT, RV350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV350_AU, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV350_AV, RV350, CHIP_HAS_CRTC2), /* 9800/Pro/FileGL X2 */ CHIP_DEF(PCI_CHIP_R350_AH, R350, CHIP_HAS_CRTC2), @@ -190,7 +192,7 @@ CHIP_DEF(PCI_CHIP_R350_NI, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R360_NJ, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R350_NK, R350, CHIP_HAS_CRTC2), - /* Newer stuff */ + /* X300/X600 */ CHIP_DEF(PCI_CHIP_RV380_3E50, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV380_3E54, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV380_3150, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), @@ -201,6 +203,19 @@ CHIP_DEF(PCI_CHIP_RV370_5B65, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV370_5460, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV370_5464, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + /* X700 */ + CHIP_DEF(PCI_CHIP_RV410_VJ, RV410, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV410_VK, RV410, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV410_VO, RV410, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV410_VR, RV410, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV410_VS, RV410, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV410_5E48, RV410, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV410_5E4A, RV410, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV410_5E4B, RV410, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV410_5E4C, RV410, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV410_5E4D, RV410, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV410_5E4F, RV410, CHIP_HAS_CRTC2), + /* X800/X850 */ CHIP_DEF(PCI_CHIP_R420_JH, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JI, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JJ, R420, CHIP_HAS_CRTC2), @@ -208,7 +223,9 @@ CHIP_DEF(PCI_CHIP_R420_JL, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JM, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JN, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_R420_JO, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JP, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R420_JT, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UH, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UI, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UJ, R420, CHIP_HAS_CRTC2), @@ -217,6 +234,25 @@ CHIP_DEF(PCI_CHIP_R423_UR, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UT, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_5D57, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_5F57, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UP, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_5D49, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_R423_5D4A, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_R423_5D48, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_R423_UO, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UM, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UN, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UL, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_5D4C, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_5D50, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_5D4E, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_5D4F, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_5D52, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_5D4D, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_KJ, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_KK, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_KI, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R480_KL, R420, CHIP_HAS_CRTC2), /* Original Radeon/7200 */ CHIP_DEF(PCI_CHIP_RADEON_QD, RADEON, 0), CHIP_DEF(PCI_CHIP_RADEON_QE, RADEON, 0), @@ -259,6 +295,7 @@ static int default_dynclk = -2; static int nomodeset = 0; static int ignore_edid = 0; +static int ignore_conntable = 0; static int mirror = 0; static int panel_yres = 0; static int force_dfp = 0; @@ -269,6 +306,12 @@ static int force_sleep; static int ignore_devlist; +#ifdef CONFIG_FB_RADEON_DEBUG +int radeonfb_debug = 1; +#else +int radeonfb_debug = 0; +#endif + /* * prototypes */ @@ -324,7 +367,7 @@ * to phase out Open Firmware images. * * Currently, we only look at the first PCI data, we could iteratre and deal with - * them all, and we should use fb_bios_start relative to start of image and not + * them all, and we should use fp_bios_start relative to start of image and not * relative start of ROM, but so far, I never found a dual-image ATI card * * typedef struct { @@ -410,7 +453,7 @@ * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device * tree. Hopefully, ATI OF driver is kind enough to fill these */ -static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo) +static int __devinit radeon_get_pll_info_openfirmware (struct radeonfb_info *rinfo) { struct device_node *dp = rinfo->of_node; const u32 *val; @@ -433,6 +476,7 @@ if (val && *val) rinfo->pll.mclk = (*val) / 10; + RTRACE("Retrieved PLL infos from Open Firmware\n"); return 0; } #endif /* CONFIG_PPC_OF */ @@ -575,10 +619,87 @@ return 0; } +static int __devinit radeon_get_pll_info_legacy(struct radeonfb_info *rinfo) +{ + u16 pll_info_block; + + if (!rinfo->bios_seg) + return -EINVAL; + + 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); + + RTRACE("Retrieved PLL infos from Legacy BIOS\n"); + return 0; +} + + +static int __devinit radeon_get_pll_info_atom(struct radeonfb_info *rinfo) +{ + u16 pll_info_block; + + if (!rinfo->bios_seg) + return -EINVAL; + + 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); + + RTRACE("Retrieved PLL infos from ATOM BIOS\n"); + return 0; +} + +static void radeon_detect_bios_type(struct radeonfb_info *rinfo) +{ +#ifdef CONFIG_PPC_OF + rinfo->is_atom_bios = 0; + rinfo->radeon_get_pll_info = radeon_get_pll_info_openfirmware; + rinfo->radeon_get_lvds_info = radeon_get_lvds_info_openfirmware; + rinfo->radeon_get_tmds_info = NULL; + rinfo->radeon_get_conn_info = radeon_get_conn_info_openfirmware; +#else + int tmp = rinfo->fp_bios_start + 4; + unsigned char sign[4]; + + sign[0] = BIOS_IN8(tmp); + sign[1] = BIOS_IN8(tmp + 1); + sign[2] = BIOS_IN8(tmp + 2); + sign[3] = BIOS_IN8(tmp + 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); + rinfo->radeon_get_pll_info = radeon_get_pll_info_atom; + rinfo->radeon_get_lvds_info = radeon_get_lvds_info_atom; + rinfo->radeon_get_conn_info = radeon_get_conn_info_atom; + rinfo->radeon_get_tmds_info = radeon_get_tmds_info_atom; + } else { + rinfo->is_atom_bios = 0; + rinfo->radeon_get_pll_info = radeon_get_pll_info_legacy; + rinfo->radeon_get_lvds_info = radeon_get_lvds_info_legacy; + rinfo->radeon_get_conn_info = radeon_get_conn_info_legacy; + rinfo->radeon_get_tmds_info = radeon_get_tmds_info_legacy; + } +#endif /* CONFIG_PPC_OF */ + +} + /* * Retrieve PLL infos by different means (BIOS, Open Firmware, register probing...) */ -static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo) +static void __devinit radeon_get_pll_info(struct radeonfb_info *rinfo) { /* * In the case nothing works, these are defaults; they are mostly @@ -630,46 +751,30 @@ case PCI_DEVICE_ID_ATI_RADEON_QF: case PCI_DEVICE_ID_ATI_RADEON_QG: default: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; + if (rinfo->family == CHIP_FAMILY_R420) { + rinfo->pll.ppll_max = 50000; + rinfo->pll.ppll_min = 20000; + } else { + rinfo->pll.ppll_max = 35000; + rinfo->pll.ppll_min = 12000; + } rinfo->pll.mclk = 16600; rinfo->pll.sclk = 16600; rinfo->pll.ref_clk = 2700; break; } - rinfo->pll.ref_div = INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK; - - -#ifdef CONFIG_PPC_OF - /* - * Retrieve PLL infos from Open Firmware first - */ - if (!force_measure_pll && radeon_read_xtal_OF(rinfo) == 0) { - printk(KERN_INFO "radeonfb: Retrieved PLL infos from Open Firmware\n"); - goto found; - } -#endif /* CONFIG_PPC_OF */ /* - * Check out if we have an X86 which gave us some PLL informations - * and if yes, retrieve them + * If we have a way to retrieve the PLL information, do so. */ - if (!force_measure_pll && rinfo->bios_seg) { - u16 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; + if (!force_measure_pll && rinfo->radeon_get_pll_info) { + if (!rinfo->radeon_get_pll_info(rinfo)) { + goto found; + } } /* - * We didn't get PLL parameters from either OF or BIOS, we try to + * If we don't get the PLL parameters handed to us, we try to * probe them */ if (radeon_probe_pll_params(rinfo) == 0) { @@ -683,6 +788,22 @@ printk(KERN_INFO "radeonfb: Used 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) { + 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 @@ -698,7 +819,7 @@ rinfo->pll.ref_div, rinfo->pll.mclk / 100, rinfo->pll.mclk % 100, rinfo->pll.sclk / 100, rinfo->pll.sclk % 100); - printk("radeonfb: PLL min %d max %d\n", rinfo->pll.ppll_min, rinfo->pll.ppll_max); + RTRACE("PLL min %d max %d\n", rinfo->pll.ppll_min, rinfo->pll.ppll_max); } static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info) @@ -839,7 +960,7 @@ if (rinfo->asleep) return 0; - radeon_fifo_wait(2); + radeon_engine_idle(); OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7); return 0; @@ -923,6 +1044,7 @@ u32 val; u32 tmp_pix_clks; int unblank = 0; + int i; if (rinfo->lock_blank) return 0; @@ -952,78 +1074,81 @@ } OUTREG(CRTC_EXT_CNTL, val); + for (i = 0 ; i < RADEON_MAX_CONNECTORS ; i++) { + if (rinfo->heads[i] == -1) + continue; - switch (rinfo->mon1_type) { - case MT_DFP: - if (unblank) - OUTREGP(FP_GEN_CNTL, (FP_FPON | FP_TMDS_EN), - ~(FP_FPON | FP_TMDS_EN)); - else { - if (mode_switch || blank == FB_BLANK_NORMAL) - break; - OUTREGP(FP_GEN_CNTL, 0, ~(FP_FPON | FP_TMDS_EN)); - } + switch (rinfo->connectors[rinfo->heads[i]].mon_type) { + case MT_DFP: + if (unblank) + OUTREGP(FP_GEN_CNTL, (FP_FPON | FP_TMDS_EN), + ~(FP_FPON | FP_TMDS_EN)); + else { + if (mode_switch || blank == FB_BLANK_NORMAL) + break; + OUTREGP(FP_GEN_CNTL, 0, ~(FP_FPON | FP_TMDS_EN)); + } break; - case MT_LCD: - del_timer_sync(&rinfo->lvds_timer); - val = INREG(LVDS_GEN_CNTL); - if (unblank) { - u32 target_val = (val & ~LVDS_DISPLAY_DIS) | LVDS_BLON | LVDS_ON - | LVDS_EN | (rinfo->init_state.lvds_gen_cntl - & (LVDS_DIGON | LVDS_BL_MOD_EN)); - if ((val ^ target_val) == LVDS_DISPLAY_DIS) - OUTREG(LVDS_GEN_CNTL, target_val); - else if ((val ^ target_val) != 0) { - OUTREG(LVDS_GEN_CNTL, target_val - & ~(LVDS_ON | LVDS_BL_MOD_EN)); - rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; - rinfo->init_state.lvds_gen_cntl |= - target_val & LVDS_STATE_MASK; - if (mode_switch) { - radeon_msleep(rinfo->panel_info.pwr_delay); + case MT_LCD: + del_timer_sync(&rinfo->lvds_timer); + val = INREG(LVDS_GEN_CNTL); + if (unblank) { + u32 target_val = (val & ~LVDS_DISPLAY_DIS) | LVDS_BLON | LVDS_ON + | LVDS_EN | (rinfo->init_state.lvds_gen_cntl + & (LVDS_DIGON | LVDS_BL_MOD_EN)); + if ((val ^ target_val) == LVDS_DISPLAY_DIS) OUTREG(LVDS_GEN_CNTL, target_val); + else if ((val ^ target_val) != 0) { + OUTREG(LVDS_GEN_CNTL, target_val + & ~(LVDS_ON | LVDS_BL_MOD_EN)); + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= + target_val & LVDS_STATE_MASK; + if (mode_switch) { + radeon_msleep(rinfo->panel_info.pwr_delay); + OUTREG(LVDS_GEN_CNTL, target_val); + } else { + rinfo->pending_lvds_gen_cntl = target_val; + mod_timer(&rinfo->lvds_timer, + jiffies + + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); + } } - else { - rinfo->pending_lvds_gen_cntl = target_val; - mod_timer(&rinfo->lvds_timer, - jiffies + - msecs_to_jiffies(rinfo->panel_info.pwr_delay)); - } + } else { + val |= LVDS_DISPLAY_DIS; + OUTREG(LVDS_GEN_CNTL, val); + + /* We don't do a full switch-off on a simple mode switch */ + if (mode_switch || blank == FB_BLANK_NORMAL) + break; + + /* Asic bug, when turning off LVDS_ON, we have to make sure + * RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off + */ + tmp_pix_clks = INPLL(PIXCLKS_CNTL); + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); + val &= ~(LVDS_BL_MOD_EN); + OUTREG(LVDS_GEN_CNTL, val); + udelay(100); + val &= ~(LVDS_ON | LVDS_EN); + OUTREG(LVDS_GEN_CNTL, val); + val &= ~LVDS_DIGON; + rinfo->pending_lvds_gen_cntl = val; + mod_timer(&rinfo->lvds_timer, + jiffies + + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK; + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLL(PIXCLKS_CNTL, tmp_pix_clks); } - } else { - val |= LVDS_DISPLAY_DIS; - OUTREG(LVDS_GEN_CNTL, val); - - /* We don't do a full switch-off on a simple mode switch */ - if (mode_switch || blank == FB_BLANK_NORMAL) - break; - - /* Asic bug, when turning off LVDS_ON, we have to make sure - * RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off - */ - tmp_pix_clks = INPLL(PIXCLKS_CNTL); - if (rinfo->is_mobility || rinfo->is_IGP) - OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); - val &= ~(LVDS_BL_MOD_EN); - OUTREG(LVDS_GEN_CNTL, val); - udelay(100); - val &= ~(LVDS_ON | LVDS_EN); - OUTREG(LVDS_GEN_CNTL, val); - val &= ~LVDS_DIGON; - rinfo->pending_lvds_gen_cntl = val; - mod_timer(&rinfo->lvds_timer, - jiffies + - msecs_to_jiffies(rinfo->panel_info.pwr_delay)); - rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; - rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK; - if (rinfo->is_mobility || rinfo->is_IGP) - OUTPLL(PIXCLKS_CNTL, tmp_pix_clks); + break; + case MT_CRT: + // todo: powerdown DAC + default: + break; } - break; - case MT_CRT: - // todo: powerdown DAC - default: - break; } /* let fbcon do a soft blank for us */ @@ -1274,10 +1399,7 @@ radeon_pll_errata_after_data(rinfo); /* Set PPLL ref. div */ - if (rinfo->family == CHIP_FAMILY_R300 || - rinfo->family == CHIP_FAMILY_RS300 || - rinfo->family == CHIP_FAMILY_R350 || - rinfo->family == CHIP_FAMILY_RV350) { + if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_RS300)) { if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { /* When restoring console mode, use saved PPLL_REF_DIV * setting. @@ -1374,6 +1496,7 @@ OUTREG(CRTC_OFFSET_CNTL, 0); OUTREG(CRTC_PITCH, mode->crtc_pitch); OUTREG(SURFACE_CNTL, mode->surface_cntl); + OUTREG(DISP_MERGE_CNTL, 0xffff0000); radeon_write_pll_regs(rinfo, mode); @@ -1884,7 +2007,7 @@ info->fix.ywrapstep = 0; info->fix.type_aux = 0; info->fix.mmio_start = rinfo->mmio_base_phys; - info->fix.mmio_len = RADEON_REGSIZE; + info->fix.mmio_len = pci_resource_len(rinfo->pdev, 2); info->fix.accel = FB_ACCEL_ATI_RADEON; fb_alloc_cmap(&info->cmap, 256, 0); @@ -1988,9 +2111,7 @@ u32 tmp; /* framebuffer size */ - if ((rinfo->family == CHIP_FAMILY_RS100) || - (rinfo->family == CHIP_FAMILY_RS200) || - (rinfo->family == CHIP_FAMILY_RS300)) { + if (rinfo->is_IGP) { u32 tom = INREG(NB_TOM); tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); @@ -2018,6 +2139,10 @@ /* mem size is bits [28:0], mask off the rest */ rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; + /* Limit memory to 128 megs for now */ + if (rinfo->video_ram > MAX_VRAM) + rinfo->video_ram = MAX_VRAM; + /* * Hack to get around some busted production M6's * reporting no ram @@ -2102,7 +2227,7 @@ struct fb_info *info = pci_get_drvdata(pdev); struct radeonfb_info *rinfo = info->par; - return radeon_show_one_edid(buf, off, count, rinfo->mon1_EDID); + return radeon_show_one_edid(buf, off, count, rinfo->connectors[rinfo->heads[0]].edid); } @@ -2113,7 +2238,27 @@ struct fb_info *info = pci_get_drvdata(pdev); struct radeonfb_info *rinfo = info->par; - return radeon_show_one_edid(buf, off, count, rinfo->mon2_EDID); + return radeon_show_one_edid(buf, off, count, rinfo->connectors[rinfo->heads[1]].edid); +} + +static ssize_t radeon_show_edid3(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct pci_dev *pdev = to_pci_dev(dev); + struct fb_info *info = pci_get_drvdata(pdev); + struct radeonfb_info *rinfo = info->par; + + return radeon_show_one_edid(buf, off, count, rinfo->connectors[rinfo->heads[2]].edid); +} + +static ssize_t radeon_show_edid4(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct pci_dev *pdev = to_pci_dev(dev); + struct fb_info *info = pci_get_drvdata(pdev); + struct radeonfb_info *rinfo = info->par; + + return radeon_show_one_edid(buf, off, count, rinfo->connectors[rinfo->heads[3]].edid); } static struct bin_attribute edid1_attr = { @@ -2136,6 +2281,25 @@ .read = radeon_show_edid2, }; +static struct bin_attribute edid3_attr = { + .attr = { + .name = "edid3", + .owner = THIS_MODULE, + .mode = 0444, + }, + .size = EDID_LENGTH, + .read = radeon_show_edid3, +}; + +static struct bin_attribute edid4_attr = { + .attr = { + .name = "edid4", + .owner = THIS_MODULE, + .mode = 0444, + }, + .size = EDID_LENGTH, + .read = radeon_show_edid4, +}; static int __devinit radeonfb_pci_register (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -2143,6 +2307,7 @@ struct fb_info *info; struct radeonfb_info *rinfo; int ret; + int i; RTRACE("radeonfb_pci_register BEGIN\n"); @@ -2199,7 +2364,8 @@ } /* map the regions */ - rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE); + rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, + pci_resource_len(rinfo->pdev, 2)); if (!rinfo->mmio_base) { printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n", pci_name(rinfo->pdev)); @@ -2284,6 +2450,7 @@ * We probably need to make sure this is the primary display, * but that is difficult without some arch support. */ + #ifdef CONFIG_X86 if (rinfo->bios_seg == NULL) radeon_find_mem_vbios(rinfo); @@ -2295,14 +2462,23 @@ 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); + radeon_get_pll_info(rinfo); + + /* Get informations about internal TMDS controller if any */ + radeon_get_tmds_info(rinfo); #ifdef CONFIG_FB_RADEON_I2C /* Register I2C bus */ radeon_create_i2c_busses(rinfo); #endif + /* Get infos about connectors -- need I2C here! */ + radeon_get_conn_info(rinfo, ignore_conntable); + /* set all the vital stuff */ radeon_set_fbinfo (rinfo); @@ -2313,10 +2489,15 @@ radeon_check_modes(rinfo, mode_option); /* Register some sysfs stuff (should be done better) */ - if (rinfo->mon1_EDID) + + if ((rinfo->heads[0] != -1) && rinfo->connectors[rinfo->heads[0]].edid) sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr); - if (rinfo->mon2_EDID) + if ((rinfo->heads[1] != -1) && rinfo->connectors[rinfo->heads[1]].edid) sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr); + if ((rinfo->heads[2] != -1) && rinfo->connectors[rinfo->heads[2]].edid) + sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid3_attr); + if ((rinfo->heads[3] != -1) && rinfo->connectors[rinfo->heads[3]].edid) + sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid4_attr); /* save current mode regs before we switch into the new one * so we can restore this upon __exit @@ -2361,10 +2542,12 @@ err_unmap_fb: iounmap(rinfo->fb_base); err_unmap_rom: - kfree(rinfo->mon1_EDID); - kfree(rinfo->mon2_EDID); - if (rinfo->mon1_modedb) - fb_destroy_modedb(rinfo->mon1_modedb); + for (i = 0 ; i < RADEON_MAX_CONNECTORS ; i++) { + kfree(rinfo->connectors[i].edid); + if (rinfo->connectors[i].modedb) + fb_destroy_modedb(rinfo->connectors[i].modedb); + } + fb_dealloc_cmap(&info->cmap); #ifdef CONFIG_FB_RADEON_I2C radeon_delete_i2c_busses(rinfo); @@ -2389,18 +2572,24 @@ { struct fb_info *info = pci_get_drvdata(pdev); struct radeonfb_info *rinfo = info->par; - + + int i; + if (!rinfo) return; radeonfb_bl_exit(rinfo); radeonfb_pm_exit(rinfo); - if (rinfo->mon1_EDID) + if ((rinfo->heads[0] != -1) && rinfo->connectors[rinfo->heads[0]].edid) sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr); - if (rinfo->mon2_EDID) + if ((rinfo->heads[1] != -1) && rinfo->connectors[rinfo->heads[1]].edid) sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr); - + if ((rinfo->heads[2] != -1) && rinfo->connectors[rinfo->heads[2]].edid) + sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid3_attr); + if ((rinfo->heads[3] != -1) && rinfo->connectors[rinfo->heads[3]].edid) + sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid4_attr); + #if 0 /* restore original state * @@ -2426,10 +2615,11 @@ pci_release_region(pdev, 2); pci_release_region(pdev, 0); - kfree(rinfo->mon1_EDID); - kfree(rinfo->mon2_EDID); - if (rinfo->mon1_modedb) - fb_destroy_modedb(rinfo->mon1_modedb); + for (i = 0 ; i < RADEON_MAX_CONNECTORS ; i++) { + kfree(rinfo->connectors[i].edid); + if (rinfo->connectors[i].modedb) + fb_destroy_modedb(rinfo->connectors[i].modedb); + } #ifdef CONFIG_FB_RADEON_I2C radeon_delete_i2c_busses(rinfo); #endif @@ -2479,12 +2669,18 @@ force_measure_pll = 1; } else if (!strncmp(this_opt, "ignore_edid", 11)) { ignore_edid = 1; + } else if (!strncmp(this_opt, "ignore_conntable", 16)) { + ignore_conntable = 1; + } else if (!strncmp( this_opt, "default_dynclk:", 15)) { + default_dynclk = simple_strtoul((this_opt+15), NULL, 10); #if defined(CONFIG_PM) && defined(CONFIG_X86) } else if (!strncmp(this_opt, "force_sleep", 11)) { force_sleep = 1; } else if (!strncmp(this_opt, "ignore_devlist", 14)) { ignore_devlist = 1; #endif + } else if (!strncmp(this_opt, "debug", 5)) { + radeonfb_debug = 1; } else mode_option = this_opt; } @@ -2528,6 +2724,8 @@ MODULE_PARM_DESC(force_dfp, "bool: force display to dfp"); module_param(ignore_edid, bool, 0); MODULE_PARM_DESC(ignore_edid, "bool: Ignore EDID data when doing DDC probe"); +module_param(ignore_conntable, bool, 0); +MODULE_PARM_DESC(ignore_conntable, "bool: Ignore BIOS Connector table"); module_param(monitor_layout, charp, 0); MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)"); module_param(force_measure_pll, bool, 0); @@ -2546,3 +2744,5 @@ module_param(ignore_devlist, bool, 0); MODULE_PARM_DESC(ignore_devlist, "bool: ignore workarounds for bugs in specific laptops"); #endif +module_param(radeonfb_debug, int, 0); +MODULE_PARM_DESC(radeonfb_debug, "Enable full debugging text");