diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index db8e5b057e..ac71a183f0 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -161,7 +161,8 @@ typedef struct { typedef struct { - bool active; + bool attached; + bool powered; uint32 connectorIndex; // matches connector id in connector_info register_info* regs; bool found_ranges; diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index 0b790264f5..9a359880e6 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -245,7 +245,8 @@ detect_displays() { // reset known displays for (uint32 id = 0; id < MAX_DISPLAY; id++) { - gDisplay[id]->active = false; + gDisplay[id]->attached = false; + gDisplay[id]->powered = false; gDisplay[id]->found_ranges = false; } @@ -269,16 +270,16 @@ detect_displays() if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) { // If plain (non-DP) laptop LVDS, read mode info from AtomBIOS //TRACE("%s: non-DP laptop LVDS detected\n", __func__); - gDisplay[displayIndex]->active + gDisplay[displayIndex]->attached = connector_read_mode_lvds(id, &gDisplay[displayIndex]->preferredMode); } - if (gDisplay[displayIndex]->active == false) { + if (gDisplay[displayIndex]->attached == false) { TRACE("%s: bit-banging ddc for edid on connector %" B_PRIu32 "\n", __func__, id); // Lets try bit-banging edid from connector - gDisplay[displayIndex]->active = + gDisplay[displayIndex]->attached = connector_read_edid(id, &gDisplay[displayIndex]->edid_info); if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC @@ -288,17 +289,17 @@ detect_displays() if (encoder_analog_load_detect(id) != true) { TRACE("%s: no analog load on EDID valid connector " "#%" B_PRIu32 "\n", __func__, id); - gDisplay[displayIndex]->active = false; + gDisplay[displayIndex]->attached = false; } } } - if (gDisplay[displayIndex]->active != true) { + if (gDisplay[displayIndex]->attached != true) { // Nothing interesting here, move along continue; } - // We found a valid / active display + // We found a valid / attached display gDisplay[displayIndex]->connectorIndex = id; // Populate physical connector index from gConnector @@ -317,7 +318,7 @@ detect_displays() displayIndex++; } - // fallback if no active monitors were found + // fallback if no attached monitors were found if (displayIndex == 0) { ERROR("%s: ERROR: 0 attached monitors were found on display connectors." " Injecting first connector as a last resort.\n", __func__); @@ -325,7 +326,7 @@ detect_displays() // skip TV DAC connectors as likely fallback isn't for TV if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC) continue; - gDisplay[0]->active = true; + gDisplay[0]->attached = true; gDisplay[0]->connectorIndex = id; init_registers(gDisplay[0]->regs, 0); if (detect_crt_ranges(0) == B_OK) @@ -334,6 +335,12 @@ detect_displays() } } + // Initial boot state is the first two crtc's powered + if (gDisplay[0]->attached == true) + gDisplay[0]->powered = true; + if (gDisplay[1]->attached == true) + gDisplay[1]->powered = true; + return B_OK; } @@ -343,12 +350,12 @@ debug_displays() { TRACE("Currently detected monitors===============\n"); for (uint32 id = 0; id < MAX_DISPLAY; id++) { - ERROR("Display #%" B_PRIu32 " active = %s\n", - id, gDisplay[id]->active ? "true" : "false"); + ERROR("Display #%" B_PRIu32 " attached = %s\n", + id, gDisplay[id]->attached ? "true" : "false"); uint32 connectorIndex = gDisplay[id]->connectorIndex; - if (gDisplay[id]->active) { + if (gDisplay[id]->attached) { uint32 connectorType = gConnector[connectorIndex]->type; uint32 encoderType = gConnector[connectorIndex]->encoder.type; ERROR(" + connector ID: %" B_PRIu32 "\n", connectorIndex); @@ -412,6 +419,7 @@ void display_crtc_lock(uint8 crtcID, int command) { TRACE("%s\n", __func__); + ENABLE_CRTC_PS_ALLOCATION args; int index = GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters); @@ -429,6 +437,7 @@ void display_crtc_blank(uint8 crtcID, int command) { TRACE("%s\n", __func__); + BLANK_CRTC_PS_ALLOCATION args; int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC); @@ -437,8 +446,7 @@ display_crtc_blank(uint8 crtcID, int command) args.ucCRTC = crtcID; args.ucBlanking = command; - // DEBUG: Radeon red to know when we are blanked :) - args.usBlackColorRCr = 255; + args.usBlackColorRCr = 0; args.usBlackColorGY = 0; args.usBlackColorBCb = 0; @@ -462,6 +470,39 @@ display_crtc_scale(uint8 crtcID, display_mode* mode) } +void +display_crtc_dpms(uint8 crtcID, int mode) +{ + + radeon_shared_info &info = *gInfo->shared_info; + + switch (mode) { + case B_DPMS_ON: + TRACE("%s: crtc %" B_PRIu8 " dpms powerup\n", __func__, crtcID); + if (gDisplay[crtcID]->attached == false) + return; + gDisplay[crtcID]->powered = true; + display_crtc_power(crtcID, ATOM_ENABLE); + if (info.dceMajor >= 3) + display_crtc_memreq(crtcID, ATOM_ENABLE); + display_crtc_blank(crtcID, ATOM_BLANKING_OFF); + break; + case B_DPMS_STAND_BY: + case B_DPMS_SUSPEND: + case B_DPMS_OFF: + TRACE("%s: crtc %" B_PRIu8 " dpms powerdown\n", __func__, crtcID); + if (gDisplay[crtcID]->attached == false) + return; + if (gDisplay[crtcID]->powered == true) + display_crtc_blank(crtcID, ATOM_BLANKING); + if (info.dceMajor >= 3) + display_crtc_memreq(crtcID, ATOM_DISABLE); + display_crtc_power(crtcID, ATOM_DISABLE); + gDisplay[crtcID]->powered = false; + } +} + + void display_crtc_fb_set(uint8 crtcID, display_mode* mode) { diff --git a/src/add-ons/accelerants/radeon_hd/display.h b/src/add-ons/accelerants/radeon_hd/display.h index b77ce8ab36..a132647104 100644 --- a/src/add-ons/accelerants/radeon_hd/display.h +++ b/src/add-ons/accelerants/radeon_hd/display.h @@ -22,6 +22,7 @@ void debug_displays(); uint32 display_get_encoder_mode(uint32 connectorIndex); void display_crtc_lock(uint8 crtcID, int command); void display_crtc_blank(uint8 crtcID, int command); +void display_crtc_dpms(uint8 crtcID, int mode); void display_crtc_scale(uint8 crtcID, display_mode* mode); void display_crtc_fb_set(uint8 crtcID, display_mode* mode); void display_crtc_set(uint8 crtcID, display_mode* mode); diff --git a/src/add-ons/accelerants/radeon_hd/encoder.cpp b/src/add-ons/accelerants/radeon_hd/encoder.cpp index 0a88ca7e35..0618d27c6d 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.cpp +++ b/src/add-ons/accelerants/radeon_hd/encoder.cpp @@ -190,7 +190,7 @@ encoder_pick_dig(uint32 connectorIndex) // obtain assigned CRT uint32 crtcID; for (crtcID = 0; crtcID < MAX_DISPLAY; crtcID++) { - if (gDisplay[crtcID]->active != true) + if (gDisplay[crtcID]->attached != true) continue; if (gDisplay[crtcID]->connectorIndex == connectorIndex) break; diff --git a/src/add-ons/accelerants/radeon_hd/mode.cpp b/src/add-ons/accelerants/radeon_hd/mode.cpp index beb2f8875c..8fd3a610ce 100644 --- a/src/add-ons/accelerants/radeon_hd/mode.cpp +++ b/src/add-ons/accelerants/radeon_hd/mode.cpp @@ -147,44 +147,9 @@ radeon_dpms_mode(void) void radeon_dpms_set(int mode) { - radeon_shared_info &info = *gInfo->shared_info; + for (uint8 id = 0; id < MAX_DISPLAY; id++) + display_crtc_dpms(id, mode); - switch (mode) { - case B_DPMS_ON: - TRACE("%s: ON\n", __func__); - for (uint8 id = 0; id < MAX_DISPLAY; id++) { - if (gDisplay[id]->active == false) - continue; - encoder_output_lock(true); - encoder_dpms_set(id, mode); - encoder_output_lock(false); - display_crtc_lock(id, ATOM_ENABLE); - 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); - } - break; - case B_DPMS_STAND_BY: - case B_DPMS_SUSPEND: - case B_DPMS_OFF: - TRACE("%s: OFF\n", __func__); - for (uint8 id = 0; id < MAX_DISPLAY; id++) { - if (gDisplay[id]->active == false) - continue; - 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); - display_crtc_lock(id, ATOM_DISABLE); - encoder_output_lock(true); - encoder_dpms_set(id, mode); - encoder_output_lock(false); - } - break; - } gInfo->dpms_mode = mode; } @@ -196,7 +161,7 @@ radeon_set_display_mode(display_mode* mode) // Set mode on each display for (uint8 id = 0; id < MAX_DISPLAY; id++) { - if (gDisplay[id]->active == false) + if (gDisplay[id]->attached == false) continue; uint16 connectorIndex = gDisplay[id]->connectorIndex; @@ -213,10 +178,7 @@ radeon_set_display_mode(display_mode* mode) // *** 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); + display_crtc_dpms(id, B_DPMS_OFF); // *** CRT controler mode set // TODO: program SS @@ -232,10 +194,7 @@ radeon_set_display_mode(display_mode* mode) 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_dpms(id, B_DPMS_ON); display_crtc_lock(id, ATOM_DISABLE); // *** encoder commit