diff options
-rw-r--r-- | src/atombios_output.c | 50 | ||||
-rw-r--r-- | src/legacy_output.c | 106 | ||||
-rw-r--r-- | src/radeon_atombios.c | 1 | ||||
-rw-r--r-- | src/radeon_probe.h | 1 |
4 files changed, 66 insertions, 92 deletions
diff --git a/src/atombios_output.c b/src/atombios_output.c index a39c6e47..636373d6 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -819,6 +819,7 @@ atombios_output_dpms(xf86OutputPtr output, int mode) AtomBiosArgRec data; unsigned char *space; int index = 0; + Bool is_dig = FALSE; if (radeon_encoder == NULL) return; @@ -831,8 +832,8 @@ atombios_output_dpms(xf86OutputPtr output, int mode) case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - (void)atombios_dig_dpms(output, mode); - return; + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + is_dig = TRUE; break; case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DDI: @@ -843,7 +844,6 @@ atombios_output_dpms(xf86OutputPtr output, int mode) index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); break; case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); else @@ -871,24 +871,44 @@ atombios_output_dpms(xf86OutputPtr output, int mode) switch (mode) { case DPMSModeOn: - disp_data.ucAction = ATOM_ENABLE; + if (is_dig) + (void)atombios_dig_dpms(output, mode); + else { + disp_data.ucAction = ATOM_ENABLE; + data.exec.index = index; + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &disp_data; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) + ErrorF("Output %d enable success\n", index); + else + ErrorF("Output %d enable failed\n", index); + } + radeon_encoder->use_count++; break; case DPMSModeStandby: case DPMSModeSuspend: case DPMSModeOff: - disp_data.ucAction = ATOM_DISABLE; + if (radeon_encoder->use_count < 2) { + if (is_dig) + (void)atombios_dig_dpms(output, mode); + else { + disp_data.ucAction = ATOM_DISABLE; + data.exec.index = index; + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &disp_data; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) + == ATOM_SUCCESS) + ErrorF("Output %d disable success\n", index); + else + ErrorF("Output %d disable failed\n", index); + } + } + if (radeon_encoder->use_count > 0) + radeon_encoder->use_count--; break; } - - data.exec.index = index; - data.exec.dataSpace = (void *)&space; - data.exec.pspace = &disp_data; - - if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Output %d %s success\n", index, disp_data.ucAction? "enable":"disable"); - } - - ErrorF("Output %d %s failed\n", index, disp_data.ucAction? "enable":"disable"); } static void diff --git a/src/legacy_output.c b/src/legacy_output.c index 1b58c324..e4e81d0f 100644 --- a/src/legacy_output.c +++ b/src/legacy_output.c @@ -689,9 +689,8 @@ RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) } } -/* This is to be used enable/disable displays dynamically */ -static void -RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) +void +legacy_output_dpms(xf86OutputPtr output, int mode) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); @@ -699,26 +698,17 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) unsigned char * RADEONMMIO = info->MMIO; unsigned long tmp; RADEONOutputPrivatePtr radeon_output; - int tv_dac_change = 0, o; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); if (radeon_encoder == NULL) return; - radeon_output = output->driver_private; - for (o = 0; o < xf86_config->num_output; o++) { - if (output == xf86_config->output[o]) { - break; - } - } - - if (bEnable) { - /*ErrorF("enable montype: %d\n", radeon_output->MonType);*/ + switch(mode) { + case DPMSModeOn: switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_LVDS: ErrorF("enable LVDS\n"); - info->output_lcd1 |= (1 << o); tmp = INREG(RADEON_LVDS_GEN_CNTL); tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); tmp &= ~(RADEON_LVDS_DISPLAY_DIS); @@ -729,7 +719,6 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) break; case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ErrorF("enable FP1\n"); - info->output_dfp1 |= (1 << o); tmp = INREG(RADEON_FP_GEN_CNTL); tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); @@ -745,7 +734,6 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) break; case ENCODER_OBJECT_ID_INTERNAL_DVO1: ErrorF("enable FP2\n"); - info->output_dfp2 |= (1 << o); tmp = INREG(RADEON_FP2_GEN_CNTL); tmp &= ~RADEON_FP2_BLANK_EN; tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -764,28 +752,23 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) break; case ENCODER_OBJECT_ID_INTERNAL_DAC1: ErrorF("enable primary dac\n"); - info->output_crt1 |= (1 << o); tmp = INREG(RADEON_CRTC_EXT_CNTL); tmp |= RADEON_CRTC_CRT_ON; OUTREG(RADEON_CRTC_EXT_CNTL, tmp); save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; - RADEONDacPowerSet(pScrn, bEnable, TRUE); + RADEONDacPowerSet(pScrn, TRUE, TRUE); break; case ENCODER_OBJECT_ID_INTERNAL_DAC2: if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { ErrorF("enable TV\n"); - info->output_tv1 |= (1 << o); tmp = INREG(RADEON_TV_MASTER_CNTL); tmp |= RADEON_TV_ON; OUTREG(RADEON_TV_MASTER_CNTL, tmp); - tv_dac_change = 2; - radeon_output->tv_on = TRUE; } else { ErrorF("enable TVDAC\n"); - info->output_crt2 |= (1 << o); if (info->ChipFamily == CHIP_FAMILY_R200) { tmp = INREG(RADEON_FP2_GEN_CNTL); - tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); + tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); OUTREG(RADEON_FP2_GEN_CNTL, tmp); save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); } else { @@ -794,18 +777,20 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) OUTREG(RADEON_CRTC2_GEN_CNTL, tmp); save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; } - tv_dac_change = 1; } + RADEONDacPowerSet(pScrn, TRUE, FALSE); break; } - } else { - /*ErrorF("disable montype: %d\n", radeon_output->MonType);*/ + radeon_encoder->use_count++; + break; + case DPMSModeOff: + case DPMSModeSuspend: + case DPMSModeStandby: switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_LVDS: - ErrorF("disable LVDS\n"); - info->output_lcd1 &= ~(1 << o); - if (!info->output_lcd1) { + if (radeon_encoder->use_count < 2) { unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + ErrorF("disable LVDS\n"); if (info->IsMobility || info->IsIGP) { /* Asic bug, when turning off LVDS_ON, we have to make sure RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off @@ -824,9 +809,8 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) } break; case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - ErrorF("disable FP1\n"); - info->output_dfp1 &= ~(1 << o); - if (!info->output_dfp1) { + if (radeon_encoder->use_count < 2) { + ErrorF("disable FP1\n"); tmp = INREG(RADEON_FP_GEN_CNTL); tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); @@ -842,9 +826,8 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) } break; case ENCODER_OBJECT_ID_INTERNAL_DVO1: - ErrorF("disable FP2\n"); - info->output_dfp2 &= ~(1 << o); - if (!info->output_dfp2) { + if (radeon_encoder->use_count < 2) { + ErrorF("disable FP2\n"); tmp = INREG(RADEON_FP2_GEN_CNTL); tmp |= RADEON_FP2_BLANK_EN; tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -863,32 +846,25 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) } break; case ENCODER_OBJECT_ID_INTERNAL_DAC1: - ErrorF("disable primary dac\n"); - info->output_crt1 &= ~(1 << o); - if (!info->output_crt1) { + if (radeon_encoder->use_count < 2) { + ErrorF("disable primary dac\n"); tmp = INREG(RADEON_CRTC_EXT_CNTL); tmp &= ~RADEON_CRTC_CRT_ON; OUTREG(RADEON_CRTC_EXT_CNTL, tmp); save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; - RADEONDacPowerSet(pScrn, bEnable, TRUE); + RADEONDacPowerSet(pScrn, FALSE, TRUE); } break; case ENCODER_OBJECT_ID_INTERNAL_DAC2: - if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { - ErrorF("disable TV\n"); - info->output_tv1 &= ~(1 << o); - tv_dac_change = 2; - if (!info->output_tv1) { + if (radeon_encoder->use_count < 2) { + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { + ErrorF("disable TV\n"); tmp = INREG(RADEON_TV_MASTER_CNTL); tmp &= ~RADEON_TV_ON; OUTREG(RADEON_TV_MASTER_CNTL, tmp); radeon_output->tv_on = FALSE; - } - } else { - ErrorF("disable TVDAC\n"); - info->output_crt2 &= ~(1 << o); - tv_dac_change = 1; - if (!info->output_crt2) { + } else { + ErrorF("disable TVDAC\n"); if (info->ChipFamily == CHIP_FAMILY_R200) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -901,36 +877,12 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; } } + RADEONDacPowerSet(pScrn, FALSE, FALSE); } break; } - } - - if (tv_dac_change) { - if (bEnable) - info->tv_dac_enable_mask |= tv_dac_change; - else - info->tv_dac_enable_mask &= ~tv_dac_change; - - if (bEnable && info->tv_dac_enable_mask) - RADEONDacPowerSet(pScrn, bEnable, FALSE); - else if (!bEnable && info->tv_dac_enable_mask == 0) - RADEONDacPowerSet(pScrn, bEnable, FALSE); - - } -} - -void -legacy_output_dpms(xf86OutputPtr output, int mode) -{ - switch(mode) { - case DPMSModeOn: - RADEONEnableDisplay(output, TRUE); - break; - case DPMSModeOff: - case DPMSModeSuspend: - case DPMSModeStandby: - RADEONEnableDisplay(output, FALSE); + if (radeon_encoder->use_count > 0) + radeon_encoder->use_count--; break; } } diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index 26dae63c..68adb0de 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -1619,6 +1619,7 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo info->encoders[device_index] = (radeon_encoder_ptr)xcalloc(1,sizeof(radeon_encoder_rec)); if (info->encoders[device_index] != NULL) { info->encoders[device_index]->encoder_id = encoder_id; + info->encoders[device_index]->use_count = 0; // add dev_priv stuff return TRUE; } else { diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 2914e04c..7b52c4e1 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -182,6 +182,7 @@ typedef struct _RADEONCrtcPrivateRec { typedef struct _radeon_encoder { uint16_t encoder_id; + int use_count; void *dev_priv; } radeon_encoder_rec, *radeon_encoder_ptr; |