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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user