* 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:
parent
e3e636ae3a
commit
b54c811990
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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*/
|
||||
|
|
Loading…
Reference in New Issue