* 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:
@@ -431,6 +431,7 @@ detect_connectors()
|
|||||||
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
|
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
|
||||||
if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
|
if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
|
||||||
// Found an encoder
|
// Found an encoder
|
||||||
|
// TODO : it may be possible to have more then one encoder
|
||||||
int32 k;
|
int32 k;
|
||||||
for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
|
for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
|
||||||
uint16 encoder_obj
|
uint16 encoder_obj
|
||||||
@@ -526,7 +527,6 @@ detect_connectors()
|
|||||||
// drm_encoder_helper_add
|
// drm_encoder_helper_add
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//encoder_object_id = grph_obj_id;
|
|
||||||
encoder_object_id = encoder_id;
|
encoder_object_id = encoder_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1076,17 +1076,30 @@ display_crtc_set_dtd(uint8 crtc_id, display_mode *mode)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
display_crtc_power(uint8 crt_id, int command)
|
display_crtc_power(uint8 crtc_id, int command)
|
||||||
{
|
{
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
|
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
|
||||||
ENABLE_CRTC_PS_ALLOCATION args;
|
ENABLE_CRTC_PS_ALLOCATION args;
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
args.ucCRTC = crt_id;
|
args.ucCRTC = crtc_id;
|
||||||
args.ucEnable = command;
|
args.ucEnable = command;
|
||||||
|
|
||||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
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_fb_set_dce1(uint8 crtc_id, display_mode *mode);
|
||||||
void display_crtc_set(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_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 */
|
#endif /* RADEON_HD_DISPLAY_H */
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ union crtc_source_param {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
encoder_assign_crtc(uint8 crtc_id)
|
encoder_assign_crtc(uint8 id)
|
||||||
{
|
{
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
||||||
union crtc_source_param args;
|
union crtc_source_param args;
|
||||||
@@ -50,7 +50,7 @@ encoder_assign_crtc(uint8 crtc_id)
|
|||||||
!= B_OK)
|
!= B_OK)
|
||||||
return;
|
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;
|
uint16 encoder_id = gConnector[connector_index]->encoder_object_id;
|
||||||
|
|
||||||
switch (frev) {
|
switch (frev) {
|
||||||
@@ -58,7 +58,7 @@ encoder_assign_crtc(uint8 crtc_id)
|
|||||||
switch (crev) {
|
switch (crev) {
|
||||||
case 1:
|
case 1:
|
||||||
default:
|
default:
|
||||||
args.v1.ucCRTC = crtc_id;
|
args.v1.ucCRTC = id;
|
||||||
switch (encoder_id) {
|
switch (encoder_id) {
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||||
@@ -102,7 +102,7 @@ encoder_assign_crtc(uint8 crtc_id)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
args.v2.ucCRTC = crtc_id;
|
args.v2.ucCRTC = id;
|
||||||
args.v2.ucEncodeMode
|
args.v2.ucEncodeMode
|
||||||
= display_get_encoder_mode(connector_index);
|
= display_get_encoder_mode(connector_index);
|
||||||
switch (encoder_id) {
|
switch (encoder_id) {
|
||||||
@@ -170,3 +170,90 @@ encoder_assign_crtc(uint8 crtc_id)
|
|||||||
|
|
||||||
// TODO : encoder_crtc_scratch_regs?
|
// 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_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 */
|
#endif /* RADEON_HD_ENCODER_H */
|
||||||
|
|||||||
@@ -34,6 +34,16 @@ get_accelerant_hook(uint32 feature, void *data)
|
|||||||
return (void*)radeon_accelerant_retrace_semaphore;
|
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 */
|
/* mode configuration */
|
||||||
case B_ACCELERANT_MODE_COUNT:
|
case B_ACCELERANT_MODE_COUNT:
|
||||||
return (void*)radeon_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
|
status_t
|
||||||
radeon_set_display_mode(display_mode *mode)
|
radeon_set_display_mode(display_mode *mode)
|
||||||
{
|
{
|
||||||
// TODO : multi-monitor? for now we use VESA and not gDisplay edid
|
// TODO : multi-monitor? for now we use VESA and not gDisplay edid
|
||||||
|
radeon_dpms_set(B_DPMS_OFF);
|
||||||
|
|
||||||
// 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++) {
|
||||||
display_crtc_lock(id, ATOM_ENABLE);
|
if (gDisplay[id]->active == false)
|
||||||
// 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);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// uint32 connector_index = gDisplay[id]->connector_index;
|
// *** encoder prep
|
||||||
// uint32 connector_type = gConnector[connector_index]->connector_type;
|
encoder_output_lock(true);
|
||||||
// uint32 encoder_type = gConnector[connector_index]->encoder_type;
|
// 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);
|
display_crtc_set_dtd(id, mode);
|
||||||
|
|
||||||
|
// TODO : vvvv : atombios_crtc_set_base
|
||||||
display_crtc_fb_set_dce1(id, mode);
|
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);
|
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);
|
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);
|
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
|
||||||
TRACE("CRT0 Status: 0x%X\n", crtstatus);
|
TRACE("CRT0 Status: 0x%X\n", crtstatus);
|
||||||
crtstatus = Read32(CRT, D2CRTC_STATUS);
|
crtstatus = Read32(CRT, D2CRTC_STATUS);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
status_t create_mode_list(void);
|
status_t create_mode_list(void);
|
||||||
bool is_mode_supported(display_mode* mode);
|
bool is_mode_supported(display_mode* mode);
|
||||||
status_t is_mode_sane(display_mode *mode);
|
status_t is_mode_sane(display_mode *mode);
|
||||||
|
void radeon_dpms_set(int mode);
|
||||||
|
|
||||||
|
|
||||||
#endif /*RADEON_HD_MODE_H*/
|
#endif /*RADEON_HD_MODE_H*/
|
||||||
|
|||||||
Reference in New Issue
Block a user