Author: kallisti5 Date: 2011-10-21 16:53:40 +0200 (Fri, 21 Oct 2011) New Revision: 42892 Changeset: https://dev.haiku-os.org/changeset/42892 Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp Log: * stub out dig encoder setup * adjust pll post divider calculation * fix digital encoder setup action * don't run memreq on DCE < 3, should solve some AtomBIOS failure loops Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp 2011-10-21 14:32:01 UTC (rev 42891) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp 2011-10-21 14:53:40 UTC (rev 42892) @@ -176,6 +176,7 @@ void encoder_mode_set(uint8 id, uint32 pixelClock) { + radeon_shared_info &info = *gInfo->shared_info; uint32 connectorIndex = gDisplay[id]->connectorIndex; switch (gConnector[connectorIndex]->encoder.objectID) { @@ -189,12 +190,40 @@ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: case ENCODER_OBJECT_ID_INTERNAL_LVDS: case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - encoder_digital_setup(id, pixelClock, ATOM_ENABLE); + encoder_digital_setup(id, pixelClock, PANEL_ENCODER_ACTION_ENABLE); break; case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + if (info.dceMajor >= 4) { + //atombios_dig_transmitter_setup(encoder, + // ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + // TODO: Disable the dig transmitter + encoder_dig_setup(id, pixelClock, ATOM_ENCODER_CMD_SETUP); + // Setup and enable the dig encoder + + //atombios_dig_transmitter_setup(encoder, + // ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + // TODO: Enable the dig transmitter + } else { + //atombios_dig_transmitter_setup(encoder, + // ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + // Disable the dig transmitter + encoder_dig_setup(id, pixelClock, ATOM_DISABLE); + // Disable the dig encoder + + /* setup and enable the encoder and transmitter */ + encoder_dig_setup(id, pixelClock, ATOM_ENABLE); + // Setup and enable the dig encoder + + //atombios_dig_transmitter_setup(encoder, + // ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); + //atombios_dig_transmitter_setup(encoder, + // ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + // TODO: Setup and Enable the dig transmitter + } + TRACE("%s: TODO for DIG encoder setup\n", __func__); break; case ENCODER_OBJECT_ID_INTERNAL_DDI: @@ -337,7 +366,24 @@ } +union dig_encoder_control { + DIG_ENCODER_CONTROL_PS_ALLOCATION v1; + DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; + DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; + DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; +}; + + status_t +encoder_dig_setup(uint8 id, uint32 pixelClock, int command) +{ + TRACE("%s: TODO\n", __func__); + + return B_OK; +} + + +status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command) { TRACE("%s\n", __func__); Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h 2011-10-21 14:32:01 UTC (rev 42891) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h 2011-10-21 14:53:40 UTC (rev 42892) @@ -13,6 +13,7 @@ void encoder_mode_set(uint8 id, uint32 pixelClock); status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command); status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command); +status_t encoder_dig_setup(uint8 id, uint32 pixelClock, int command); bool encoder_analog_load_detect(uint8 connectorIndex); void encoder_output_lock(bool lock); void encoder_crtc_scratch(uint8 crtcID); Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp 2011-10-21 14:32:01 UTC (rev 42891) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp 2011-10-21 14:53:40 UTC (rev 42892) @@ -117,6 +117,8 @@ void radeon_dpms_set(int mode) { + radeon_shared_info &info = *gInfo->shared_info; + switch(mode) { case B_DPMS_ON: TRACE("%s: ON\n", __func__); @@ -125,7 +127,8 @@ continue; display_crtc_lock(id, ATOM_ENABLE); display_crtc_power(id, ATOM_ENABLE); - display_crtc_memreq(id, ATOM_ENABLE); + if (info.dceMajor >= 3) + display_crtc_memreq(id, ATOM_ENABLE); display_crtc_blank(id, ATOM_DISABLE); display_crtc_lock(id, ATOM_DISABLE); } @@ -139,7 +142,8 @@ continue; display_crtc_lock(id, ATOM_ENABLE); display_crtc_blank(id, ATOM_ENABLE); - display_crtc_memreq(id, ATOM_DISABLE); + if (info.dceMajor >= 3) + display_crtc_memreq(id, ATOM_DISABLE); display_crtc_power(id, ATOM_DISABLE); display_crtc_lock(id, ATOM_DISABLE); } @@ -152,6 +156,8 @@ status_t radeon_set_display_mode(display_mode *mode) { + radeon_shared_info &info = *gInfo->shared_info; + // TODO: multi-monitor? for now we use VESA and not gDisplay edid // Set mode on each display for (uint8 id = 0; id < MAX_DISPLAY; id++) { @@ -169,7 +175,8 @@ // *** CRT controler prep display_crtc_lock(id, ATOM_ENABLE); display_crtc_blank(id, ATOM_ENABLE); - display_crtc_memreq(id, ATOM_DISABLE); + if (info.dceMajor >= 3) + display_crtc_memreq(id, ATOM_DISABLE); display_crtc_power(id, ATOM_DISABLE); // *** CRT controler mode set @@ -187,7 +194,8 @@ // *** CRT controler commit display_crtc_power(id, ATOM_ENABLE); - display_crtc_memreq(id, ATOM_ENABLE); + if (info.dceMajor >= 3) + display_crtc_memreq(id, ATOM_ENABLE); display_crtc_blank(id, ATOM_DISABLE); display_crtc_lock(id, ATOM_DISABLE); Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp 2011-10-21 14:32:01 UTC (rev 42891) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp 2011-10-21 14:53:40 UTC (rev 42892) @@ -125,15 +125,13 @@ void pll_compute_post_divider(pll_info *pll) { - radeon_shared_info &info = *gInfo->shared_info; - if ((pll->flags & PLL_USE_POST_DIV) != 0) { TRACE("%s: using AtomBIOS post divider\n", __func__); return; } uint32 vco; - if (info.device_chipset < (RADEON_R700 | 0x70)) { + if ((pll->flags & PLL_PREFER_MINM_OVER_MAXP) != 0) { if ((pll->flags & PLL_IS_LCD) != 0) vco = pll->lcdPllOutMin; else @@ -150,7 +148,7 @@ uint32 postDivider = vco / pll->pixelClock; uint32 tmp = vco % pll->pixelClock; - if (info.device_chipset < (RADEON_R700 | 0x70)) { + if ((pll->flags & PLL_PREFER_MINM_OVER_MAXP) != 0) { if (tmp) postDivider++; } else { @@ -294,11 +292,21 @@ void pll_setup_flags(pll_info *pll, uint8 crtcID) { + radeon_shared_info &info = *gInfo->shared_info; uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; uint32 encoderFlags = gConnector[connectorIndex]->encoder.flags; - pll->flags |= PLL_PREFER_LOW_REF_DIV; + if ((info.dceMajor >= 3 && info.dceMinor >= 2) + && pll->pixelClock > 200000) { + pll->flags |= PLL_PREFER_HIGH_FB_DIV; + } else + pll->flags |= PLL_PREFER_LOW_REF_DIV; + + if (info.device_chipset < (RADEON_R700 | 0x70)) + pll->flags |= PLL_PREFER_MINM_OVER_MAXP; + + if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) { pll->flags |= PLL_IS_LCD;