* add encoder code to handle setting up and adjusting encoders

* reorganize mode set code to match layout of linux DRM driver
* add initial DPMS code
* add lots of TODOs


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42801 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV 2011-10-05 04:25:50 +00:00
parent e3e636ae3a
commit b54c811990
7 changed files with 178 additions and 29 deletions

View File

@ -431,6 +431,7 @@ detect_connectors()
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
// Found an encoder
// TODO : it may be possible to have more then one encoder
int32 k;
for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
uint16 encoder_obj
@ -526,7 +527,6 @@ detect_connectors()
// drm_encoder_helper_add
break;
}
//encoder_object_id = grph_obj_id;
encoder_object_id = encoder_id;
}
}
@ -1076,17 +1076,30 @@ display_crtc_set_dtd(uint8 crtc_id, display_mode *mode)
void
display_crtc_power(uint8 crt_id, int command)
display_crtc_power(uint8 crtc_id, int command)
{
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
ENABLE_CRTC_PS_ALLOCATION args;
memset(&args, 0, sizeof(args));
args.ucCRTC = crt_id;
args.ucCRTC = crtc_id;
args.ucEnable = command;
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
void
display_crtc_memreq(uint8 crtc_id, int command)
{
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
ENABLE_CRTC_PS_ALLOCATION args;
memset(&args, 0, sizeof(args));
args.ucCRTC = crtc_id;
args.ucEnable = command;
atom_execute_table(gAtomContext, index, (uint32*)&args);
}

View File

@ -73,7 +73,8 @@ void display_crtc_fb_set_legacy(uint8 crtc_id, display_mode *mode);
void display_crtc_fb_set_dce1(uint8 crtc_id, display_mode *mode);
void display_crtc_set(uint8 crtc_id, display_mode *mode);
void display_crtc_set_dtd(uint8 crtc_id, display_mode *mode);
void display_crtc_power(uint8 crt_id, int command);
void display_crtc_power(uint8 crtc_id, int command);
void display_crtc_memreq(uint8 crtc_id, int command);
#endif /* RADEON_HD_DISPLAY_H */

View File

@ -37,7 +37,7 @@ union crtc_source_param {
void
encoder_assign_crtc(uint8 crtc_id)
encoder_assign_crtc(uint8 id)
{
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
union crtc_source_param args;
@ -50,7 +50,7 @@ encoder_assign_crtc(uint8 crtc_id)
!= B_OK)
return;
uint16 connector_index = gDisplay[crtc_id]->connector_index;
uint16 connector_index = gDisplay[id]->connector_index;
uint16 encoder_id = gConnector[connector_index]->encoder_object_id;
switch (frev) {
@ -58,7 +58,7 @@ encoder_assign_crtc(uint8 crtc_id)
switch (crev) {
case 1:
default:
args.v1.ucCRTC = crtc_id;
args.v1.ucCRTC = id;
switch (encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@ -102,7 +102,7 @@ encoder_assign_crtc(uint8 crtc_id)
}
break;
case 2:
args.v2.ucCRTC = crtc_id;
args.v2.ucCRTC = id;
args.v2.ucEncodeMode
= display_get_encoder_mode(connector_index);
switch (encoder_id) {
@ -170,3 +170,90 @@ encoder_assign_crtc(uint8 crtc_id)
// TODO : encoder_crtc_scratch_regs?
}
void
encoder_mode_set(uint8 id, uint32 pixelClock)
{
uint32 connector_index = gDisplay[id]->connector_index;
switch (gConnector[connector_index]->encoder_object_id) {
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
encoder_analog_setup(id, pixelClock, ATOM_ENABLE);
break;
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
TRACE("%s: TODO for digital encoder setup\n", __func__);
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:
TRACE("%s: TODO for DIG encoder setup\n", __func__);
break;
case ENCODER_OBJECT_ID_INTERNAL_DDI:
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
TRACE("%s: TODO for DVO encoder setup\n", __func__);
break;
default:
TRACE("%s: TODO for unknown encoder setup!\n", __func__);
}
}
void
encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
{
TRACE("%s\n", __func__);
uint32 connector_index = gDisplay[id]->connector_index;
int index = 0;
DAC_ENCODER_CONTROL_PS_ALLOCATION args;
memset(&args, 0, sizeof(args));
switch (gConnector[connector_index]->encoder_object_id) {
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
break;
}
args.ucAction = command;
args.ucDacStandard = ATOM_DAC1_PS2;
// TODO : or ATOM_DAC1_CV if ATOM_DEVICE_CV_SUPPORT
// TODO : or ATOM_DAC1_PAL or ATOM_DAC1_NTSC if else
args.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
void
encoder_output_lock(bool lock)
{
TRACE("%s: %s\n", __func__, lock ? "true" : "false");
uint32 bios_6_scratch = Read32(OUT, R600_BIOS_6_SCRATCH);
if (lock) {
bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
bios_6_scratch &= ~ATOM_S6_ACC_MODE;
} else {
bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
bios_6_scratch |= ATOM_S6_ACC_MODE;
}
Write32(OUT, R600_BIOS_6_SCRATCH, bios_6_scratch);
}

View File

@ -10,6 +10,9 @@
void encoder_assign_crtc(uint8 crt_id);
void encoder_mode_set(uint8 id, uint32 pixelClock);
void encoder_analog_setup(uint8 id, uint32 pixelClock, int command);
void encoder_output_lock(bool lock);
#endif /* RADEON_HD_ENCODER_H */

View File

@ -34,6 +34,16 @@ get_accelerant_hook(uint32 feature, void *data)
return (void*)radeon_accelerant_retrace_semaphore;
*/
/* DPMS */
/*
case B_DPMS_CAPABILITIES:
return (void*)radeon_dpms_capabilities;
case B_DPMS_MODE:
return (void*)radeon_dpms_mode;
case B_SET_DPMS_MODE:
return (void*)radeon_dpms_set;
*/
/* mode configuration */
case B_ACCELERANT_MODE_COUNT:
return (void*)radeon_accelerant_mode_count;

View File

@ -97,48 +97,82 @@ radeon_get_edid_info(void* info, size_t size, uint32* edid_version)
}
void
radeon_dpms_set(int mode)
{
switch(mode) {
case B_DPMS_ON:
for (uint8 id = 0; id < MAX_DISPLAY; id++) {
if (gDisplay[id]->active == false)
continue;
display_crtc_power(id, ATOM_ENABLE);
display_crtc_memreq(id, ATOM_ENABLE);
display_crtc_blank(id, ATOM_DISABLE);
}
break;
case B_DPMS_STAND_BY:
case B_DPMS_SUSPEND:
case B_DPMS_OFF:
for (uint8 id = 0; id < MAX_DISPLAY; id++) {
if (gDisplay[id]->active == false)
continue;
display_crtc_blank(id, ATOM_ENABLE);
display_crtc_memreq(id, ATOM_DISABLE);
display_crtc_power(id, ATOM_DISABLE);
}
break;
}
}
status_t
radeon_set_display_mode(display_mode *mode)
{
// TODO : multi-monitor? for now we use VESA and not gDisplay edid
radeon_dpms_set(B_DPMS_OFF);
// Set mode on each display
for (uint8 id = 0; id < MAX_DISPLAY; id++) {
display_crtc_lock(id, ATOM_ENABLE);
// Skip if display is inactive
if (gDisplay[id]->active == false) {
display_crtc_blank(id, ATOM_ENABLE);
display_crtc_power(id, ATOM_DISABLE);
display_crtc_lock(id, ATOM_DISABLE);
if (gDisplay[id]->active == false)
continue;
}
// uint32 connector_index = gDisplay[id]->connector_index;
// uint32 connector_type = gConnector[connector_index]->connector_type;
// uint32 encoder_type = gConnector[connector_index]->encoder_type;
// *** encoder prep
encoder_output_lock(true);
// encoder DPMS OFF
encoder_assign_crtc(id);
// *** CRT controler prep
display_crtc_lock(id, ATOM_ENABLE);
// TODO : the first id is the pll we use... this won't work for
// more then two monitors
pll_set(id, mode->timing.pixel_clock, id);
// Program CRT Controller
// *** CRT controler mode set
// TODO program SS
pll_set(0, mode->timing.pixel_clock, id);
// TODO : check if pll 0 is used and use pll 1 if so
display_crtc_set_dtd(id, mode);
// TODO : vvvv : atombios_crtc_set_base
display_crtc_fb_set_dce1(id, mode);
//display_crtc_fb_set_legacy(id, mode);
// display_crtc_fb_set_legacy(id, mode);
// atombios_overscan_setup
display_crtc_scale(id, mode);
// Power CRT Controller
display_crtc_blank(id, ATOM_DISABLE);
display_crtc_power(id, ATOM_ENABLE);
//PLLPower(gDisplay[id]->connection_id, RHD_POWER_ON);
// *** encoder mode set
encoder_mode_set(id, mode->timing.pixel_clock);
encoder_assign_crtc(id);
// *** CRT controler commit
display_crtc_lock(id, ATOM_DISABLE);
// commit
// *** encoder commit
// encoder DPMS OFF
encoder_output_lock(false);
}
radeon_dpms_set(B_DPMS_ON);
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
TRACE("CRT0 Status: 0x%X\n", crtstatus);
crtstatus = Read32(CRT, D2CRTC_STATUS);

View File

@ -29,6 +29,7 @@
status_t create_mode_list(void);
bool is_mode_supported(display_mode* mode);
status_t is_mode_sane(display_mode *mode);
void radeon_dpms_set(int mode);
#endif /*RADEON_HD_MODE_H*/