status_t radeon_set_display_mode(display_mode* mode) { radeon_shared_info &info = *gInfo->shared_info; // Set mode on each display for (uint8 id = 0; id < MAX_DISPLAY; id++) { if (gDisplay[id]->attached == false) continue; uint32 connectorIndex = gDisplay[id]->connectorIndex; dp_info *dpInfo = &gConnector[connectorIndex]->dpInfo; // Determine DP lanes if DP if (connector_is_dp(connectorIndex)) dpInfo->laneCount = dp_get_lane_count(dpInfo, mode); // *** crtc and encoder prep encoder_output_lock(true); encoder_dpms_set(id, B_DPMS_OFF); display_crtc_lock(id, ATOM_ENABLE); display_crtc_dpms(id, B_DPMS_OFF); // *** Set up encoder -> crtc routing encoder_assign_crtc(id); // *** CRT controler mode set // TODO: program SS pll_set(ATOM_PPLL1, mode->timing.pixel_clock, id); // TODO: check if ATOM_PPLL1 is used and use ATOM_PPLL2 if so display_crtc_set_dtd(id, mode); display_crtc_fb_set(id, mode); // atombios_overscan_setup display_crtc_scale(id, mode); // *** encoder mode set encoder_mode_set(id); // *** CRT controler commit display_crtc_dpms(id, B_DPMS_ON); display_crtc_lock(id, ATOM_DISABLE); // *** encoder commit // handle DisplayPort link training if (connector_is_dp(connectorIndex)) { if (info.dceMajor >= 4) encoder_dig_setup(connectorIndex, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); dp_link_train(id, mode); if (info.dceMajor >= 4) encoder_dig_setup(connectorIndex, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); } encoder_dpms_set(id, B_DPMS_ON); encoder_output_lock(false); } // for debugging TRACE("D1CRTC_STATUS Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_STATUS)); TRACE("D2CRTC_STATUS Value: 0x%X\n", Read32(CRT, AVIVO_D2CRTC_STATUS)); TRACE("D1CRTC_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_CONTROL)); TRACE("D2CRTC_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D2CRTC_CONTROL)); TRACE("D1GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1GRPH_ENABLE)); TRACE("D2GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2GRPH_ENABLE)); TRACE("D1SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1SCL_SCALER_ENABLE)); TRACE("D2SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2SCL_SCALER_ENABLE)); TRACE("D1CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); TRACE("D2CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); return B_OK; }
status_t radeon_set_display_mode(display_mode* mode) { // TODO: multi-monitor? For now we set the mode on // all displays (this is very incorrect). This also // causes a lot of problems on DisplayPort devices // Set mode on each display for (uint8 id = 0; id < MAX_DISPLAY; id++) { if (gDisplay[id]->attached == false) continue; // Copy this display mode into the "current mode" for the display memcpy(&gDisplay[id]->currentMode, mode, sizeof(display_mode)); uint32 connectorIndex = gDisplay[id]->connectorIndex; // Determine DP lanes if DP if (connector_is_dp(connectorIndex)) { dp_info *dpInfo = &gConnector[connectorIndex]->dpInfo; dpInfo->laneCount = dp_get_lane_count(connectorIndex, mode); dpInfo->linkRate = dp_get_link_rate(connectorIndex, mode); } // *** crtc and encoder prep encoder_output_lock(true); display_crtc_lock(id, ATOM_ENABLE); radeon_dpms_set(id, B_DPMS_OFF); // *** Set up encoder -> crtc routing encoder_assign_crtc(id); // *** CRT controler mode set // Set up PLL for connector pll_pick(connectorIndex); pll_info* pll = &gConnector[connectorIndex]->encoder.pll; TRACE("%s: pll %d selected for connector %" B_PRIu32 "\n", __func__, pll->id, connectorIndex); pll_set(mode, id); display_crtc_set_dtd(id, mode); display_crtc_fb_set(id, mode); // atombios_overscan_setup display_crtc_scale(id, mode); // *** encoder mode set encoder_mode_set(id); // *** encoder and CRT controller commit radeon_dpms_set(id, B_DPMS_ON); display_crtc_lock(id, ATOM_DISABLE); encoder_output_lock(false); } #ifdef TRACE_MODE // for debugging debug_dp_info(); TRACE("D1CRTC_STATUS Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_STATUS)); TRACE("D2CRTC_STATUS Value: 0x%X\n", Read32(CRT, AVIVO_D2CRTC_STATUS)); TRACE("D1CRTC_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_CONTROL)); TRACE("D2CRTC_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D2CRTC_CONTROL)); TRACE("D1GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1GRPH_ENABLE)); TRACE("D2GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2GRPH_ENABLE)); TRACE("D1SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1SCL_SCALER_ENABLE)); TRACE("D2SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2SCL_SCALER_ENABLE)); TRACE("D1CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); TRACE("D2CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); #endif return B_OK; }
status_t radeon_set_display_mode(display_mode *mode) { radeon_shared_info &info = *gInfo->shared_info; // Set mode on each display for (uint8 id = 0; id < MAX_DISPLAY; id++) { if (gDisplay[id]->active == false) continue; uint16 connectorIndex = gDisplay[id]->connectorIndex; // *** encoder prep encoder_output_lock(true); encoder_dpms_set(id, gConnector[connectorIndex]->encoder.objectID, B_DPMS_OFF); encoder_assign_crtc(id); // *** CRT controler prep display_crtc_lock(id, ATOM_ENABLE); display_crtc_blank(id, ATOM_BLANKING); if (info.dceMajor >= 3) display_crtc_memreq(id, ATOM_DISABLE); display_crtc_power(id, ATOM_DISABLE); // *** CRT controler mode set // TODO: program SS pll_set(ATOM_PPLL1, mode->timing.pixel_clock, id); // TODO: check if ATOM_PPLL1 is used and use ATOM_PPLL2 if so display_crtc_set_dtd(id, mode); display_crtc_fb_set(id, mode); // atombios_overscan_setup display_crtc_scale(id, mode); // *** encoder mode set encoder_mode_set(id, mode->timing.pixel_clock); // *** CRT controler commit display_crtc_power(id, ATOM_ENABLE); if (info.dceMajor >= 3) display_crtc_memreq(id, ATOM_ENABLE); display_crtc_blank(id, ATOM_BLANKING_OFF); display_crtc_lock(id, ATOM_DISABLE); // *** encoder commit encoder_dpms_set(id, gConnector[connectorIndex]->encoder.objectID, B_DPMS_ON); encoder_output_lock(false); } // for debugging TRACE("D1CRTC_STATUS Value: 0x%X\n", Read32(CRT, D1CRTC_STATUS)); TRACE("D2CRTC_STATUS Value: 0x%X\n", Read32(CRT, D2CRTC_STATUS)); TRACE("D1CRTC_CONTROL Value: 0x%X\n", Read32(CRT, D1CRTC_CONTROL)); TRACE("D2CRTC_CONTROL Value: 0x%X\n", Read32(CRT, D2CRTC_CONTROL)); TRACE("D1GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1GRPH_ENABLE)); TRACE("D2GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2GRPH_ENABLE)); TRACE("D1SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1SCL_SCALER_ENABLE)); TRACE("D2SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2SCL_SCALER_ENABLE)); TRACE("D1CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); TRACE("D2CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); return B_OK; }
status_t radeon_set_display_mode(display_mode* mode) { radeon_shared_info &info = *gInfo->shared_info; // Set mode on each display for (uint8 id = 0; id < MAX_DISPLAY; id++) { if (gDisplay[id]->attached == false) continue; uint32 connectorIndex = gDisplay[id]->connectorIndex; // Determine DP lanes if DP if (connector_is_dp(connectorIndex)) { dp_info *dpInfo = &gConnector[connectorIndex]->dpInfo; dpInfo->laneCount = dp_get_lane_count(connectorIndex, mode); dpInfo->linkRate = dp_get_link_rate(connectorIndex, mode); } // *** crtc and encoder prep encoder_output_lock(true); encoder_dpms_set(id, B_DPMS_OFF); display_crtc_lock(id, ATOM_ENABLE); display_crtc_dpms(id, B_DPMS_OFF); // *** Set up encoder -> crtc routing encoder_assign_crtc(id); // *** CRT controler mode set // Set up PLL for connector pll_pick(connectorIndex); pll_info* pll = &gConnector[connectorIndex]->encoder.pll; TRACE("%s: pll %d selected for connector %" B_PRIu32 "\n", __func__, pll->id, connectorIndex); pll_set(mode, id); display_crtc_set_dtd(id, mode); display_crtc_fb_set(id, mode); // atombios_overscan_setup display_crtc_scale(id, mode); // *** encoder mode set encoder_mode_set(id); // *** CRT controler commit display_crtc_dpms(id, B_DPMS_ON); display_crtc_lock(id, ATOM_DISABLE); // *** encoder commit // handle DisplayPort link training if (connector_is_dp(connectorIndex)) { if (info.dceMajor >= 4) encoder_dig_setup(connectorIndex, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); dp_link_train(connectorIndex, mode); if (info.dceMajor >= 4) encoder_dig_setup(connectorIndex, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); } encoder_dpms_set(id, B_DPMS_ON); encoder_output_lock(false); } // for debugging // debug_dp_info(); TRACE("D1CRTC_STATUS Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_STATUS)); TRACE("D2CRTC_STATUS Value: 0x%X\n", Read32(CRT, AVIVO_D2CRTC_STATUS)); TRACE("D1CRTC_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_CONTROL)); TRACE("D2CRTC_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D2CRTC_CONTROL)); TRACE("D1GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1GRPH_ENABLE)); TRACE("D2GRPH_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2GRPH_ENABLE)); TRACE("D1SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D1SCL_SCALER_ENABLE)); TRACE("D2SCL_ENABLE Value: 0x%X\n", Read32(CRT, AVIVO_D2SCL_SCALER_ENABLE)); TRACE("D1CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); TRACE("D2CRTC_BLANK_CONTROL Value: 0x%X\n", Read32(CRT, AVIVO_D1CRTC_BLANK_CONTROL)); return B_OK; }