* add digital encoder setup code

* make encoder setup functions return status_t
* really need a struct to hold encoder info


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42814 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV 2011-10-09 19:10:56 +00:00
parent f6e59c500a
commit 17b66d8250
5 changed files with 134 additions and 14 deletions

View File

@ -477,7 +477,6 @@ detect_connectors()
encoder_type = VIDEO_ENCODER_TMDS;
// radeon_atombios_set_dig_info
}
// drm_encoder_helper_add
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
encoder_type = VIDEO_ENCODER_DAC;
@ -486,7 +485,6 @@ detect_connectors()
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
encoder_type = VIDEO_ENCODER_TVDAC;
// drm_encoder_helper_add
break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
@ -769,7 +767,7 @@ display_crtc_lock(uint8 crtc_id, int command)
args.ucCRTC = crtc_id;
args.ucEnable = command;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
atom_execute_table(gAtomContext, index, (uint32*)&args);
}

View File

@ -188,7 +188,7 @@ encoder_mode_set(uint8 id, uint32 pixelClock)
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__);
encoder_digital_setup(id, pixelClock, ATOM_ENABLE);
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
@ -208,7 +208,131 @@ encoder_mode_set(uint8 id, uint32 pixelClock)
}
void
union lvds_encoder_control {
LVDS_ENCODER_CONTROL_PS_ALLOCATION v1;
LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
};
status_t
encoder_digital_setup(uint8 id, uint32 pixelClock, int command)
{
TRACE("%s\n", __func__);
uint32 connector_index = gDisplay[id]->connector_index;
union lvds_encoder_control args;
memset(&args, 0, sizeof(args));
int index = 0;
uint16 connector_flags = gConnector[connector_index]->connector_flags;
switch (gConnector[connector_index]->encoder_object_id) {
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
if (connector_flags & ATOM_DEVICE_LCD_SUPPORT)
index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
else
index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
break;
}
uint8 frev;
uint8 crev;
if (atom_parse_cmd_header(gAtomContext, index, &frev, &crev) != B_OK)
return B_ERROR;
switch (frev) {
case 1:
case 2:
switch (crev) {
case 1:
args.v1.ucMisc = 0;
args.v1.ucAction = command;
if (0) // TODO : HDMI?
args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
if (connector_flags & (ATOM_DEVICE_LCD_SUPPORT)) {
// TODO : laptop display support
//if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
// args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
//if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
// args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
} else {
//if (dig->linkb)
// args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
if (pixelClock > 165000)
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
/*if (pScrn->rgbBits == 8) */
args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
}
break;
case 2:
case 3:
args.v2.ucMisc = 0;
args.v2.ucAction = command;
if (crev == 3) {
//if (dig->coherent_mode)
// args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
}
if (0) // TODO : HDMI?
args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v2.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
args.v2.ucTruncate = 0;
args.v2.ucSpatial = 0;
args.v2.ucTemporal = 0;
args.v2.ucFRC = 0;
if (connector_flags & ATOM_DEVICE_LCD_SUPPORT) {
// TODO : laptop display support
//if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
// args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
//if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) {
args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
//if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
// args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
//}
//if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) {
// args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
// if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) {
// args.v2.ucTemporal
// |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
// }
// if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT)
// & 0x3) == 2) {
// args.v2.ucTemporal
// |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
// }
//}
} else {
//if (dig->linkb)
// args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
if (pixelClock > 165000)
args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
}
break;
default:
ERROR("%s: Unknown minor table version: %d.%d\n", __func__,
frev, crev);
return B_ERROR;
}
break;
default:
ERROR("%s: Unknown major table version: %d.%d\n", __func__,
frev, crev);
return B_ERROR;
}
return atom_execute_table(gAtomContext, index, (uint32*)&args);
}
status_t
encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
{
TRACE("%s\n", __func__);
@ -237,7 +361,7 @@ encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
args.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
atom_execute_table(gAtomContext, index, (uint32*)&args);
return atom_execute_table(gAtomContext, index, (uint32*)&args);
}

View File

@ -11,7 +11,8 @@
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);
status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command);
status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command);
void encoder_output_lock(bool lock);
void encoder_dpms_set(uint8 encoder_id, int mode);

View File

@ -40,9 +40,9 @@ get_accelerant_hook(uint32 feature, void *data)
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:

View File

@ -137,17 +137,18 @@ radeon_set_display_mode(display_mode *mode)
continue;
uint16 connector_index = gDisplay[id]->connector_index;
// *** encoder prep
encoder_output_lock(true);
encoder_dpms_set(gConnector[connector_index]->encoder_object_id,
B_DPMS_OFF);
encoder_assign_crtc(id);
// *** CRT controler prep
display_crtc_lock(id, ATOM_ENABLE);
// *** CRT controler mode set
// TODO program SS
// 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);
@ -158,16 +159,12 @@ radeon_set_display_mode(display_mode *mode)
// atombios_overscan_setup
display_crtc_scale(id, mode);
// *** encoder mode set
encoder_mode_set(id, mode->timing.pixel_clock);
encoder_assign_crtc(id);
// *** CRT controler commit
display_crtc_lock(id, ATOM_DISABLE);
// *** encoder commit
encoder_dpms_set(gConnector[connector_index]->encoder_object_id,
B_DPMS_ON);