radeon_hd: Begin improvement on crtc state control

* Try to not blank the crtc when it is alreay disabled
* Clean up wording, active now present on display info
* Don't lock crtc when doing normal dpms calls, crtc
  should only be locked during mode set / change
This commit is contained in:
Alexander von Gluck IV
2012-02-25 11:04:07 -06:00
parent a5e3ee78ee
commit 2399d174dc
5 changed files with 64 additions and 62 deletions
@@ -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;
+55 -14
View File
@@ -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)
{
@@ -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);
@@ -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;
+5 -46
View File
@@ -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