diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-09-30 12:54:27 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-09-30 12:54:27 -0700 |
commit | 1eb46d055b147941fa529ac582c336a114f47892 (patch) | |
tree | 21dab3fcfe9b95e4f99322029bb76a99b303f3f9 | |
parent | 8408995ffbf705aa0bc09ab72c58c2e31a4b70c3 (diff) | |
parent | 497b7420c4a76df553ed53322a390a1c754ce30c (diff) |
Merge branch 'master' into xf86-video-intel-2.5-branch
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | man/intel.man | 8 | ||||
-rw-r--r-- | src/bios_reader/bios_reader.c | 157 | ||||
-rw-r--r-- | src/i810_reg.h | 3 | ||||
-rw-r--r-- | src/i830.h | 4 | ||||
-rw-r--r-- | src/i830_bios.c | 13 | ||||
-rw-r--r-- | src/i830_crt.c | 11 | ||||
-rw-r--r-- | src/i830_display.c | 48 | ||||
-rw-r--r-- | src/i830_driver.c | 34 | ||||
-rw-r--r-- | src/i830_video.c | 2 | ||||
-rw-r--r-- | uxa/uxa-glyphs.c | 4 |
11 files changed, 208 insertions, 78 deletions
diff --git a/configure.ac b/configure.ac index 86bb80fd..1aa44f55 100644 --- a/configure.ac +++ b/configure.ac @@ -203,7 +203,7 @@ dnl Use lots of warning flags with GCC WARN_CFLAGS="" if test "x$GCC" = "xyes"; then - WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ + WARN_CFLAGS="-Wall -Werror -Wpointer-arith -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ -Wnested-externs -fno-strict-aliasing" fi diff --git a/man/intel.man b/man/intel.man index 6969a159..115b35ac 100644 --- a/man/intel.man +++ b/man/intel.man @@ -25,7 +25,7 @@ the 830M and later. .B intel supports the i810, i810-DC100, i810e, i815, i830M, 845G, 852GM, 855GM, 865G, 915G, 915GM, 945G, 945GM, 965G, 965Q, 946GZ, 965GM, 945GME, -G33, Q33, and Q35 chipsets. +G33, Q33, Q35, G35, GM45, G45, Q45, G43 and G41 chipsets. .SH CONFIGURATION DETAILS Please refer to __xconfigfile__(__filemansuffix__) for general configuration @@ -222,6 +222,12 @@ information. Enable XvMC driver. Current support MPEG2 MC on 915/945 and G33 series. User should provide absolute path to libIntelXvMC.so in XvMCConfig file. Default: Disabled. +.TP +.BI "Option \*qForceSDVODetect\*q \*q" boolean \*q +Instead of depending on SDVO detect status bit to initialize SDVO outputs, +this option trys to ignore that status bit and try to probe on all SDVO +ports anyway. Try this if some output is not detected on your ADD2 card. +Use of this option will slow down your startup time. Default: Disabled. .SH OUTPUT CONFIGURATION On 830M and better chipsets, the driver supports runtime configuration of diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c index 9e053170..29c3edb0 100644 --- a/src/bios_reader/bios_reader.c +++ b/src/bios_reader/bios_reader.c @@ -59,42 +59,66 @@ struct _fake_i830 *pI830 = &I830; #define YESNO(val) ((val) ? "yes" : "no") +struct bdb_block { + uint8_t id; + uint16_t size; + void *data; +}; + +struct bdb_header *bdb; static int tv_present; static int lvds_present; static int panel_type; -static void *find_section(struct bdb_header *bdb, int section_id) +static struct bdb_block *find_section(int section_id) { - unsigned char *base = (unsigned char *)bdb; - int index = 0; - uint16_t total, current_size; - unsigned char current_id; - - /* skip to first section */ - index += bdb->header_size; - total = bdb->bdb_size; - - /* walk the sections looking for section_id */ - while (index < total) { - current_id = *(base + index); - index++; - current_size = *((uint16_t *)(base + index)); - index += 2; - if (current_id == section_id) - return base + index; - index += current_size; + struct bdb_block *block; + unsigned char *base = (unsigned char *)bdb; + int index = 0; + uint16_t total, current_size; + unsigned char current_id; + + /* skip to first section */ + index += bdb->header_size; + total = bdb->bdb_size; + + block = malloc(sizeof(*block)); + if (!block) { + fprintf(stderr, "out of memory\n"); + exit(-1); + } + + /* walk the sections looking for section_id */ + while (index < total) { + current_id = *(base + index); + index++; + current_size = *((uint16_t *)(base + index)); + index += 2; + if (current_id == section_id) { + block->id = current_id; + block->size = current_size; + block->data = base + index; + return block; } + index += current_size; + } - return NULL; + free(block); + return NULL; } -static void dump_general_features(void *data) +static void dump_general_features(void) { - struct bdb_general_features *features = data; + struct bdb_general_features *features; + struct bdb_block *block; + + block = find_section(BDB_GENERAL_FEATURES); - if (!data) + if (!block) return; + features = block->data; + printf("General features block:\n"); printf("\tPanel fitting: "); @@ -133,16 +157,24 @@ static void dump_general_features(void *data) tv_present = 1; /* should be based on whether TV DAC exists */ lvds_present = 1; /* should be based on IS_MOBILE() */ + + free(block); } -static void dump_general_definitions(void *data) +static void dump_general_definitions(void) { - struct bdb_general_definitions *defs = data; - unsigned char *lvds_data = defs->tv_or_lvds_info; + struct bdb_block *block; + struct bdb_general_definitions *defs; + unsigned char *lvds_data; + + block = find_section(BDB_GENERAL_DEFINITIONS); - if (!data) + if (!block) return; + defs = block->data; + lvds_data = defs->tv_or_lvds_info; + printf("General definitions block:\n"); printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin); @@ -157,15 +189,22 @@ static void dump_general_definitions(void *data) lvds_data += 33; if (lvds_present) printf("\tLFP DDC GMBUS addr: 0x%02x\n", lvds_data[19]); + + free(block); } -static void dump_lvds_options(void *data) +static void dump_lvds_options(void) { - struct bdb_lvds_options *options = data; + struct bdb_block *block; + struct bdb_lvds_options *options; + + block = find_section(BDB_LVDS_OPTIONS); - if (!data) + if (!block) return; + options = block->data; + printf("LVDS options block:\n"); panel_type = options->panel_type; @@ -178,19 +217,51 @@ static void dump_lvds_options(void *data) printf("\tPFIT enhanced text mode: %s\n", YESNO(options->pfit_text_mode_enhanced)); printf("\tPFIT mode: %d\n", options->pfit_mode); + + free(block); } -static void dump_lvds_data(void *data, unsigned char *base) +static void dump_lvds_ptr_data(void) { - struct bdb_lvds_lfp_data *lvds_data = data; + struct bdb_block *block; + struct bdb_lvds_lfp_data_ptrs *ptrs; + struct lvds_fp_timing *fp_timing; + + block = find_section(BDB_LVDS_LFP_DATA_PTRS); + if (!block) + return; + + ptrs = block->data; + fp_timing = (struct lvds_fp_timing *)((uint8_t *)bdb + + ptrs->ptr[panel_type].fp_timing_offset); + + printf("LVDS timing pointer data:\n"); + printf(" Number of entries: %d\n", ptrs->lvds_entries); + + printf("\tpanel type %02i: %dx%d\n", panel_type, fp_timing->x_res, + fp_timing->y_res); + + free(block); +} + +static void dump_lvds_data(void) +{ + struct bdb_block *block; + struct bdb_lvds_lfp_data *lvds_data; + int num_entries; int i; - if (!data) + block = find_section(BDB_LVDS_LFP_DATA); + if (!block) return; + lvds_data = block->data; + num_entries = block->size / sizeof(struct bdb_lvds_lfp_data_entry); + printf("LVDS panel data block (preferred block marked with '*'):\n"); + printf(" Number of entries: %d\n", num_entries); - for (i = 0; i < 16; i++) { + for (i = 0; i < num_entries; i++) { struct bdb_lvds_lfp_data_entry *lfp_data = &lvds_data->data[i]; uint8_t *timing_data = (uint8_t *)&lfp_data->dvo_timing; char marker; @@ -198,13 +269,13 @@ static void dump_lvds_data(void *data, unsigned char *base) if (i == panel_type) marker = '*'; else - continue; + marker = ' '; printf("%c\tpanel type %02i: %dx%d clock %d\n", marker, i, lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res, _PIXEL_CLOCK(timing_data)); printf("\t\tinfo:\n"); - printf("\t\t LVDS: 0x%08lx\n", + printf("\t\t LVDS: 0x%08lx\n", (unsigned long)lfp_data->fp_timing.lvds_reg_val); printf("\t\t PP_ON_DELAYS: 0x%08lx\n", (unsigned long)lfp_data->fp_timing.pp_on_reg_val); @@ -224,14 +295,13 @@ static void dump_lvds_data(void *data, unsigned char *base) _V_SYNC_OFF(timing_data), _V_SYNC_WIDTH(timing_data)); } - + free(block); } int main(int argc, char **argv) { int fd; struct vbt_header *vbt = NULL; - struct bdb_header *bdb; int vbt_off, bdb_off, i; char *filename = "bios"; struct stat finfo; @@ -240,7 +310,7 @@ int main(int argc, char **argv) printf("usage: %s <rom file>\n", argv[0]); return 1; } - + filename = argv[1]; fd = open(filename, O_RDONLY); @@ -281,10 +351,11 @@ int main(int argc, char **argv) printf("BDB sig: %16s\n", bdb->signature); printf("BDB vers: %d.%d\n", bdb->version / 100, bdb->version % 100); - dump_general_features(find_section(bdb, BDB_GENERAL_FEATURES)); - dump_general_definitions(find_section(bdb, BDB_GENERAL_DEFINITIONS)); - dump_lvds_options(find_section(bdb, BDB_LVDS_OPTIONS)); - dump_lvds_data(find_section(bdb, BDB_LVDS_LFP_DATA), (unsigned char *)bdb); + dump_general_features(); + dump_general_definitions(); + dump_lvds_options(); + dump_lvds_data(); + dump_lvds_ptr_data(); return 0; } diff --git a/src/i810_reg.h b/src/i810_reg.h index 5b90e12e..6458008c 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -1167,6 +1167,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define I965_DM_CLOCK_GATE_DISABLE (1 << 0) #define RENCLK_GATE_D2 0x6208 +#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) +#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) +#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) #define RAMCLK_GATE_D 0x6210 /* CRL only */ #define DEUC 0x6214 /* CRL only */ @@ -714,6 +714,10 @@ typedef struct _I830Rec { /** Enables logging of debug output related to mode switching. */ Bool debug_modes; unsigned int quirk_flag; + + /* User option to ignore SDVO detect bit status, in case some outputs + not detected on SDVO, so let driver try its best. */ + Bool force_sdvo_detect; } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) diff --git a/src/i830_bios.c b/src/i830_bios.c index ff49025d..2cb0b07b 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -88,8 +88,8 @@ static void parse_panel_data(I830Ptr pI830, struct bdb_header *bdb) { struct bdb_lvds_options *lvds_options; - struct bdb_lvds_lfp_data *lvds_lfp_data; - struct bdb_lvds_lfp_data_entry *entry; + struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; + int timing_offset; DisplayModePtr fixed_mode; unsigned char *timing_ptr; @@ -104,12 +104,13 @@ parse_panel_data(I830Ptr pI830, struct bdb_header *bdb) if (lvds_options->panel_type == 0xff) return; - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); - if (!lvds_lfp_data) + lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); + if (!lvds_lfp_data_ptrs) return; - entry = &lvds_lfp_data->data[lvds_options->panel_type]; - timing_ptr = (unsigned char *)&entry->dvo_timing; + timing_offset = + lvds_lfp_data_ptrs->ptr[lvds_options->panel_type].dvo_timing_offset; + timing_ptr = (unsigned char *)bdb + timing_offset; fixed_mode = xnfalloc(sizeof(DisplayModeRec)); memset(fixed_mode, 0, sizeof(*fixed_mode)); diff --git a/src/i830_crt.c b/src/i830_crt.c index 5812e2b7..2e70eb8d 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -161,6 +161,14 @@ i830_crt_detect_hotplug(xf86OutputPtr output) uint32_t temp; const int timeout_ms = 1000; int starttime, curtime; + int tries = 1; + + /* On 4 series, CRT detect sequence need to be done twice for safe. */ + if (IS_G4X(pI830)) + tries = 2; + +retry: + tries--; temp = INREG(PORT_HOTPLUG_EN); @@ -173,6 +181,9 @@ i830_crt_detect_hotplug(xf86OutputPtr output) break; } + if (tries > 0) + goto retry; + if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) == CRT_HOTPLUG_MONITOR_COLOR) { diff --git a/src/i830_display.c b/src/i830_display.c index ed49fb0e..0632f3a3 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -857,27 +857,31 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) /* Give the overlay scaler a chance to disable if it's on this pipe */ i830_crtc_dpms_video(crtc, FALSE); - /* Disable the VGA plane that we never use */ - OUTREG(VGACNTRL, VGA_DISP_DISABLE); + /* + * The documentation says : + * - Disable planes (VGA or hires) + * - Disable pipe + * - Disable VGA display + */ - /* May need to leave pipe A on */ - if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE)) + /* Disable display plane */ + temp = INREG(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - /* Disable display plane */ - temp = INREG(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) - { - OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - POSTING_READ(dspbase_reg); - } + OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + OUTREG(dspbase_reg, INREG(dspbase_reg)); + POSTING_READ(dspbase_reg); + } - if (!IS_I9XX(pI830)) { - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } + if (!IS_I9XX(pI830)) { + /* Wait for vblank for the disable to take effect */ + i830WaitForVblank(pScrn); + } + /* May need to leave pipe A on */ + if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE)) + { /* Next, disable display pipes */ temp = INREG(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { @@ -893,9 +897,15 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); POSTING_READ(dpll_reg); } + + /* Wait for the clocks to turn off. */ + usleep(150); } - /* Wait for the clocks to turn off. */ - usleep(150); + + /* Disable the VGA plane that we never use. */ + OUTREG(VGACNTRL, VGA_DISP_DISABLE); + i830WaitForVblank(pScrn); + break; } diff --git a/src/i830_driver.c b/src/i830_driver.c index 9bf0a64f..53219c39 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -316,6 +316,7 @@ typedef enum { #ifdef INTEL_XVMC OPTION_XVMC, #endif + OPTION_FORCE_SDVO_DETECT, } I830Opts; static OptionInfoRec I830Options[] = { @@ -342,6 +343,7 @@ static OptionInfoRec I830Options[] = { #ifdef INTEL_XVMC {OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, TRUE}, #endif + {OPTION_FORCE_SDVO_DETECT, "ForceSDVODetect", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; /* *INDENT-ON* */ @@ -915,14 +917,14 @@ I830SetupOutputs(ScrnInfoPtr pScrn) i830_lvds_init(pScrn); if (IS_I9XX(pI830)) { - if (INREG(SDVOB) & SDVO_DETECTED) { + if ((INREG(SDVOB) & SDVO_DETECTED) || pI830->force_sdvo_detect) { Bool found = i830_sdvo_init(pScrn, SDVOB); if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) i830_hdmi_init(pScrn, SDVOB); } - if (INREG(SDVOC) & SDVO_DETECTED) { + if ((INREG(SDVOC) & SDVO_DETECTED) || pI830->force_sdvo_detect) { Bool found = i830_sdvo_init(pScrn, SDVOC); if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) @@ -965,12 +967,18 @@ i830_init_clock_gating(ScrnInfoPtr pScrn) /* Disable clock gating reported to work incorrectly according to the specs. */ if (IS_GM45(pI830) || IS_G4X(pI830)) { + uint32_t dspclk_gate; OUTREG(RENCLK_GATE_D1, 0); - OUTREG(RENCLK_GATE_D2, 0); + OUTREG(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | + GS_UNIT_CLOCK_GATE_DISABLE | + CL_UNIT_CLOCK_GATE_DISABLE); OUTREG(RAMCLK_GATE_D, 0); - OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE | - OVRUNIT_CLOCK_GATE_DISABLE | - OVCUNIT_CLOCK_GATE_DISABLE); + dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | + OVRUNIT_CLOCK_GATE_DISABLE | + OVCUNIT_CLOCK_GATE_DISABLE; + if (IS_GM45(pI830)) + dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; + OUTREG(DSPCLK_GATE_D, dspclk_gate); } else if (IS_I965GM(pI830)) { OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); OUTREG(RENCLK_GATE_D2, 0); @@ -1458,6 +1466,12 @@ I830GetEarlyOptions(ScrnInfoPtr pScrn) if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) pI830->quirk_flag |= QUIRK_PIPEA_FORCE; + if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCE_SDVO_DETECT, FALSE)) { + pI830->force_sdvo_detect = TRUE; + } else { + pI830->force_sdvo_detect = FALSE; + } + return TRUE; } @@ -2359,12 +2373,15 @@ RestoreHWState(ScrnInfoPtr pScrn) /* If the pipe A PLL is active, we can restore the pipe & plane config */ if (pI830->saveDPLL_A & DPLL_VCO_ENABLE) { + OUTREG(FPA0, pI830->saveFPA0); OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE); + POSTING_READ(DPLL_A); usleep(150); } OUTREG(FPA0, pI830->saveFPA0); OUTREG(FPA1, pI830->saveFPA1); OUTREG(DPLL_A, pI830->saveDPLL_A); + POSTING_READ(DPLL_A); i830_dpll_settle(); if (IS_I965G(pI830)) OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD); @@ -2420,12 +2437,15 @@ RestoreHWState(ScrnInfoPtr pScrn) /* If the pipe B PLL is active, we can restore the pipe & plane config */ if (pI830->saveDPLL_B & DPLL_VCO_ENABLE) { + OUTREG(FPB0, pI830->saveFPB0); OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE); + POSTING_READ(DPLL_B); usleep(150); } OUTREG(FPB0, pI830->saveFPB0); OUTREG(FPB1, pI830->saveFPB1); OUTREG(DPLL_B, pI830->saveDPLL_B); + POSTING_READ(DPLL_B); i830_dpll_settle(); if (IS_I965G(pI830)) OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD); @@ -3038,7 +3058,7 @@ static Bool I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn; - vgaHWPtr hwp; + vgaHWPtr hwp = NULL; I830Ptr pI830; VisualPtr visual; I830Ptr pI8301 = NULL; diff --git a/src/i830_video.c b/src/i830_video.c index 6645daae..316bc61e 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2398,7 +2398,7 @@ I830PutImage(ScrnInfoPtr pScrn, /* fixup pointers */ #ifdef INTEL_XVMC if (id == FOURCC_XVMC && IS_I915(pI830)) { - pPriv->YBuf0offset = (uint32_t)((uint64_t)buf); + pPriv->YBuf0offset = (uint32_t)((uintptr_t)buf); pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); destId = FOURCC_YV12; diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c index 364fcfbc..dc518568 100644 --- a/uxa/uxa-glyphs.c +++ b/uxa/uxa-glyphs.c @@ -668,6 +668,10 @@ uxa_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) x = 0; y = 0; + extents.x1 = 0; + extents.y1 = 0; + extents.x2 = 0; + extents.y2 = 0; while (nlist--) { x += list->xOff; y += list->yOff; |