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 {
|
typedef struct {
|
||||||
bool active;
|
bool attached;
|
||||||
|
bool powered;
|
||||||
uint32 connectorIndex; // matches connector id in connector_info
|
uint32 connectorIndex; // matches connector id in connector_info
|
||||||
register_info* regs;
|
register_info* regs;
|
||||||
bool found_ranges;
|
bool found_ranges;
|
||||||
|
|||||||
@@ -245,7 +245,8 @@ detect_displays()
|
|||||||
{
|
{
|
||||||
// reset known displays
|
// reset known displays
|
||||||
for (uint32 id = 0; id < MAX_DISPLAY; id++) {
|
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;
|
gDisplay[id]->found_ranges = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,16 +270,16 @@ detect_displays()
|
|||||||
if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
|
if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
|
||||||
// If plain (non-DP) laptop LVDS, read mode info from AtomBIOS
|
// If plain (non-DP) laptop LVDS, read mode info from AtomBIOS
|
||||||
//TRACE("%s: non-DP laptop LVDS detected\n", __func__);
|
//TRACE("%s: non-DP laptop LVDS detected\n", __func__);
|
||||||
gDisplay[displayIndex]->active
|
gDisplay[displayIndex]->attached
|
||||||
= connector_read_mode_lvds(id,
|
= connector_read_mode_lvds(id,
|
||||||
&gDisplay[displayIndex]->preferredMode);
|
&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",
|
TRACE("%s: bit-banging ddc for edid on connector %" B_PRIu32 "\n",
|
||||||
__func__, id);
|
__func__, id);
|
||||||
// Lets try bit-banging edid from connector
|
// Lets try bit-banging edid from connector
|
||||||
gDisplay[displayIndex]->active =
|
gDisplay[displayIndex]->attached =
|
||||||
connector_read_edid(id, &gDisplay[displayIndex]->edid_info);
|
connector_read_edid(id, &gDisplay[displayIndex]->edid_info);
|
||||||
|
|
||||||
if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC
|
if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC
|
||||||
@@ -288,17 +289,17 @@ detect_displays()
|
|||||||
if (encoder_analog_load_detect(id) != true) {
|
if (encoder_analog_load_detect(id) != true) {
|
||||||
TRACE("%s: no analog load on EDID valid connector "
|
TRACE("%s: no analog load on EDID valid connector "
|
||||||
"#%" B_PRIu32 "\n", __func__, id);
|
"#%" 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
|
// Nothing interesting here, move along
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We found a valid / active display
|
// We found a valid / attached display
|
||||||
|
|
||||||
gDisplay[displayIndex]->connectorIndex = id;
|
gDisplay[displayIndex]->connectorIndex = id;
|
||||||
// Populate physical connector index from gConnector
|
// Populate physical connector index from gConnector
|
||||||
@@ -317,7 +318,7 @@ detect_displays()
|
|||||||
displayIndex++;
|
displayIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fallback if no active monitors were found
|
// fallback if no attached monitors were found
|
||||||
if (displayIndex == 0) {
|
if (displayIndex == 0) {
|
||||||
ERROR("%s: ERROR: 0 attached monitors were found on display connectors."
|
ERROR("%s: ERROR: 0 attached monitors were found on display connectors."
|
||||||
" Injecting first connector as a last resort.\n", __func__);
|
" 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
|
// skip TV DAC connectors as likely fallback isn't for TV
|
||||||
if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC)
|
if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC)
|
||||||
continue;
|
continue;
|
||||||
gDisplay[0]->active = true;
|
gDisplay[0]->attached = true;
|
||||||
gDisplay[0]->connectorIndex = id;
|
gDisplay[0]->connectorIndex = id;
|
||||||
init_registers(gDisplay[0]->regs, 0);
|
init_registers(gDisplay[0]->regs, 0);
|
||||||
if (detect_crt_ranges(0) == B_OK)
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,12 +350,12 @@ debug_displays()
|
|||||||
{
|
{
|
||||||
TRACE("Currently detected monitors===============\n");
|
TRACE("Currently detected monitors===============\n");
|
||||||
for (uint32 id = 0; id < MAX_DISPLAY; id++) {
|
for (uint32 id = 0; id < MAX_DISPLAY; id++) {
|
||||||
ERROR("Display #%" B_PRIu32 " active = %s\n",
|
ERROR("Display #%" B_PRIu32 " attached = %s\n",
|
||||||
id, gDisplay[id]->active ? "true" : "false");
|
id, gDisplay[id]->attached ? "true" : "false");
|
||||||
|
|
||||||
uint32 connectorIndex = gDisplay[id]->connectorIndex;
|
uint32 connectorIndex = gDisplay[id]->connectorIndex;
|
||||||
|
|
||||||
if (gDisplay[id]->active) {
|
if (gDisplay[id]->attached) {
|
||||||
uint32 connectorType = gConnector[connectorIndex]->type;
|
uint32 connectorType = gConnector[connectorIndex]->type;
|
||||||
uint32 encoderType = gConnector[connectorIndex]->encoder.type;
|
uint32 encoderType = gConnector[connectorIndex]->encoder.type;
|
||||||
ERROR(" + connector ID: %" B_PRIu32 "\n", connectorIndex);
|
ERROR(" + connector ID: %" B_PRIu32 "\n", connectorIndex);
|
||||||
@@ -412,6 +419,7 @@ void
|
|||||||
display_crtc_lock(uint8 crtcID, int command)
|
display_crtc_lock(uint8 crtcID, int command)
|
||||||
{
|
{
|
||||||
TRACE("%s\n", __func__);
|
TRACE("%s\n", __func__);
|
||||||
|
|
||||||
ENABLE_CRTC_PS_ALLOCATION args;
|
ENABLE_CRTC_PS_ALLOCATION args;
|
||||||
int index
|
int index
|
||||||
= GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
|
= GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
|
||||||
@@ -429,6 +437,7 @@ void
|
|||||||
display_crtc_blank(uint8 crtcID, int command)
|
display_crtc_blank(uint8 crtcID, int command)
|
||||||
{
|
{
|
||||||
TRACE("%s\n", __func__);
|
TRACE("%s\n", __func__);
|
||||||
|
|
||||||
BLANK_CRTC_PS_ALLOCATION args;
|
BLANK_CRTC_PS_ALLOCATION args;
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
|
int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
|
||||||
|
|
||||||
@@ -437,8 +446,7 @@ display_crtc_blank(uint8 crtcID, int command)
|
|||||||
args.ucCRTC = crtcID;
|
args.ucCRTC = crtcID;
|
||||||
args.ucBlanking = command;
|
args.ucBlanking = command;
|
||||||
|
|
||||||
// DEBUG: Radeon red to know when we are blanked :)
|
args.usBlackColorRCr = 0;
|
||||||
args.usBlackColorRCr = 255;
|
|
||||||
args.usBlackColorGY = 0;
|
args.usBlackColorGY = 0;
|
||||||
args.usBlackColorBCb = 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
|
void
|
||||||
display_crtc_fb_set(uint8 crtcID, display_mode* mode)
|
display_crtc_fb_set(uint8 crtcID, display_mode* mode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ void debug_displays();
|
|||||||
uint32 display_get_encoder_mode(uint32 connectorIndex);
|
uint32 display_get_encoder_mode(uint32 connectorIndex);
|
||||||
void display_crtc_lock(uint8 crtcID, int command);
|
void display_crtc_lock(uint8 crtcID, int command);
|
||||||
void display_crtc_blank(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_scale(uint8 crtcID, display_mode* mode);
|
||||||
void display_crtc_fb_set(uint8 crtcID, display_mode* mode);
|
void display_crtc_fb_set(uint8 crtcID, display_mode* mode);
|
||||||
void display_crtc_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
|
// obtain assigned CRT
|
||||||
uint32 crtcID;
|
uint32 crtcID;
|
||||||
for (crtcID = 0; crtcID < MAX_DISPLAY; crtcID++) {
|
for (crtcID = 0; crtcID < MAX_DISPLAY; crtcID++) {
|
||||||
if (gDisplay[crtcID]->active != true)
|
if (gDisplay[crtcID]->attached != true)
|
||||||
continue;
|
continue;
|
||||||
if (gDisplay[crtcID]->connectorIndex == connectorIndex)
|
if (gDisplay[crtcID]->connectorIndex == connectorIndex)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -147,44 +147,9 @@ radeon_dpms_mode(void)
|
|||||||
void
|
void
|
||||||
radeon_dpms_set(int mode)
|
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;
|
gInfo->dpms_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +161,7 @@ radeon_set_display_mode(display_mode* mode)
|
|||||||
|
|
||||||
// Set mode on each display
|
// Set mode on each display
|
||||||
for (uint8 id = 0; id < MAX_DISPLAY; id++) {
|
for (uint8 id = 0; id < MAX_DISPLAY; id++) {
|
||||||
if (gDisplay[id]->active == false)
|
if (gDisplay[id]->attached == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint16 connectorIndex = gDisplay[id]->connectorIndex;
|
uint16 connectorIndex = gDisplay[id]->connectorIndex;
|
||||||
@@ -213,10 +178,7 @@ radeon_set_display_mode(display_mode* mode)
|
|||||||
|
|
||||||
// *** CRT controler prep
|
// *** CRT controler prep
|
||||||
display_crtc_lock(id, ATOM_ENABLE);
|
display_crtc_lock(id, ATOM_ENABLE);
|
||||||
display_crtc_blank(id, ATOM_BLANKING);
|
display_crtc_dpms(id, B_DPMS_OFF);
|
||||||
if (info.dceMajor >= 3)
|
|
||||||
display_crtc_memreq(id, ATOM_DISABLE);
|
|
||||||
display_crtc_power(id, ATOM_DISABLE);
|
|
||||||
|
|
||||||
// *** CRT controler mode set
|
// *** CRT controler mode set
|
||||||
// TODO: program SS
|
// TODO: program SS
|
||||||
@@ -232,10 +194,7 @@ radeon_set_display_mode(display_mode* mode)
|
|||||||
encoder_mode_set(id, mode->timing.pixel_clock);
|
encoder_mode_set(id, mode->timing.pixel_clock);
|
||||||
|
|
||||||
// *** CRT controler commit
|
// *** CRT controler commit
|
||||||
display_crtc_power(id, ATOM_ENABLE);
|
display_crtc_dpms(id, B_DPMS_ON);
|
||||||
if (info.dceMajor >= 3)
|
|
||||||
display_crtc_memreq(id, ATOM_ENABLE);
|
|
||||||
display_crtc_blank(id, ATOM_BLANKING_OFF);
|
|
||||||
display_crtc_lock(id, ATOM_DISABLE);
|
display_crtc_lock(id, ATOM_DISABLE);
|
||||||
|
|
||||||
// *** encoder commit
|
// *** encoder commit
|
||||||
|
|||||||
Reference in New Issue
Block a user