void dp_setup_connectors() { TRACE("%s\n", __func__); for (uint32 index = 0; index < ATOM_MAX_SUPPORTED_DEVICE; index++) { dp_info* dpInfo = &gConnector[index]->dpInfo; dpInfo->valid = false; if (gConnector[index]->valid == false) { dpInfo->config[0] = 0; continue; } if (connector_is_dp(index) == false) { dpInfo->config[0] = 0; continue; } TRACE("%s: found dp connector on index %" B_PRIu32 "\n", __func__, index); uint32 gpioID = gConnector[index]->gpioID; uint32 auxPin = gGPIOInfo[gpioID]->hwPin; dpInfo->auxPin = auxPin; uint8 auxMessage[25]; int result; result = dp_aux_read(auxPin, DP_DPCD_REV, auxMessage, 8, 0); if (result > 0) { dpInfo->valid = true; memcpy(dpInfo->config, auxMessage, 8); } } }
status_t pll_pick(uint32 connectorIndex) { pll_info* pll = &gConnector[connectorIndex]->encoder.pll; radeon_shared_info &info = *gInfo->shared_info; bool linkB = gConnector[connectorIndex]->encoder.linkEnumeration == GRAPH_OBJECT_ENUM_ID2 ? true : false; if (info.dceMajor == 6 && info.dceMinor == 1) { // DCE 6.1 APU if (gConnector[connectorIndex]->encoder.objectID == ENCODER_OBJECT_ID_INTERNAL_UNIPHY && !linkB) { pll->id = ATOM_PPLL2; return B_OK; } // TODO: check for used PLL1 and use PLL2? pll->id = ATOM_PPLL1; return B_OK; } else if (info.dceMajor >= 4) { if (connector_is_dp(connectorIndex)) { if (gInfo->dpExternalClock) { pll->id = ATOM_PPLL_INVALID; return B_OK; } else if (info.dceMajor >= 6) { pll->id = ATOM_PPLL1; return B_OK; } else if (info.dceMajor >= 5) { pll->id = ATOM_DCPLL; return B_OK; } } pll->id = ATOM_PPLL1; return B_OK; } // TODO: Should return the CRTCID here. pll->id = ATOM_PPLL1; 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; 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]->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; }