diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index aa6deb1480..61294c2fbd 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -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); } diff --git a/src/add-ons/accelerants/radeon_hd/encoder.cpp b/src/add-ons/accelerants/radeon_hd/encoder.cpp index de27f76cb5..6c91f2471b 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.cpp +++ b/src/add-ons/accelerants/radeon_hd/encoder.cpp @@ -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); } diff --git a/src/add-ons/accelerants/radeon_hd/encoder.h b/src/add-ons/accelerants/radeon_hd/encoder.h index 19f769d0c1..0ed892b798 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.h +++ b/src/add-ons/accelerants/radeon_hd/encoder.h @@ -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); diff --git a/src/add-ons/accelerants/radeon_hd/hooks.cpp b/src/add-ons/accelerants/radeon_hd/hooks.cpp index 63d6f54494..9be18755a3 100644 --- a/src/add-ons/accelerants/radeon_hd/hooks.cpp +++ b/src/add-ons/accelerants/radeon_hd/hooks.cpp @@ -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: diff --git a/src/add-ons/accelerants/radeon_hd/mode.cpp b/src/add-ons/accelerants/radeon_hd/mode.cpp index 8635e96087..3925a70d4f 100644 --- a/src/add-ons/accelerants/radeon_hd/mode.cpp +++ b/src/add-ons/accelerants/radeon_hd/mode.cpp @@ -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);