hrev43959 adds 1 changeset to branch 'master' old head: 33629ffdd3e46a276b307df9484d8fae1cf05b37 new head: 0de9d6cdeffaa5525911a1ecf1bcb3afb1862efb ---------------------------------------------------------------------------- 0de9d6c: radeon_hd: Move out some DisplayPort common code * General DisplayPort functions in common dp.cpp * DP port information struct in common header * Please don't use this private accelerant common DP code just yet as it is very early. [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev43959 Commit: 0de9d6cdeffaa5525911a1ecf1bcb3afb1862efb URL: http://cgit.haiku-os.org/haiku/commit/?id=0de9d6c Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> Date: Fri Apr 6 18:34:03 2012 UTC ---------------------------------------------------------------------------- 9 files changed, 187 insertions(+), 123 deletions(-) headers/private/graphics/common/dp.h | 46 ++++++++ src/add-ons/accelerants/common/Jamfile | 1 + src/add-ons/accelerants/common/dp.cpp | 93 ++++++++++++++++ src/add-ons/accelerants/radeon_hd/accelerant.cpp | 11 -- src/add-ons/accelerants/radeon_hd/accelerant.h | 26 +---- src/add-ons/accelerants/radeon_hd/displayport.cpp | 96 +++++------------ src/add-ons/accelerants/radeon_hd/displayport.h | 8 +- src/add-ons/accelerants/radeon_hd/encoder.cpp | 23 +++-- src/add-ons/accelerants/radeon_hd/mode.cpp | 6 +- ---------------------------------------------------------------------------- diff --git a/headers/private/graphics/common/dp.h b/headers/private/graphics/common/dp.h new file mode 100644 index 0000000..e9d2396 --- /dev/null +++ b/headers/private/graphics/common/dp.h @@ -0,0 +1,46 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@xxxxxxxxxxx + */ +#ifndef _DP_H +#define _DP_H + + +#include <Accelerant.h> +#include "dp_raw.h" +#include <GraphicsDefs.h> +#include <OS.h> + + +typedef struct { + // Required configuration + bool valid; // Is valid DP information + uint32 auxPin; // Normally GPIO pin on GPU + + uint8 config[8]; // DP Configuration Data + int laneCount; + + uint32 linkRate; // DP Link Speed 162000, 270000, 540000 + + // Internal State information + uint8 linkStatus[DP_LINK_STATUS_SIZE]; + + bool trainingUseEncoder; + + uint8 trainingAttempts; + uint8 trainingSet[4]; + int trainingReadInterval; + +} dp_info; + + +uint32 dp_encode_link_rate(uint32 linkRate); +uint32 dp_decode_link_rate(uint32 rawLinkRate); + +uint32 dp_get_lane_count(dp_info* dpInfo, display_mode* mode); + + +#endif /* _DP_H */ diff --git a/src/add-ons/accelerants/common/Jamfile b/src/add-ons/accelerants/common/Jamfile index 6642a23..14d0b26 100644 --- a/src/add-ons/accelerants/common/Jamfile +++ b/src/add-ons/accelerants/common/Jamfile @@ -12,6 +12,7 @@ StaticLibrary libaccelerantscommon.a : create_display_modes.cpp ddc.c decode_edid.c + dp.cpp dump_edid.c i2c.c validate_display_mode.cpp diff --git a/src/add-ons/accelerants/common/dp.cpp b/src/add-ons/accelerants/common/dp.cpp new file mode 100644 index 0000000..a6a7adc --- /dev/null +++ b/src/add-ons/accelerants/common/dp.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@xxxxxxxxxxx + */ + + +#include "dp.h" + + +#define TRACE_DISPLAY +#ifdef TRACE_DISPLAY +extern "C" void _sPrintf(const char* format, ...); +# define TRACE(x...) _sPrintf("radeon_hd: " x) +#else +# define TRACE(x...) ; +#endif + +#define ERROR(x...) _sPrintf("radeon_hd: " x) + + +uint32 +dp_encode_link_rate(uint32 linkRate) +{ + switch (linkRate) { + case 162000: + // 1.62 Ghz + return DP_LINK_RATE_162; + case 270000: + // 2.7 Ghz + return DP_LINK_RATE_270; + case 540000: + // 5.4 Ghz + return DP_LINK_RATE_540; + } + + ERROR("%s: Unknown DisplayPort Link Rate!\n", + __func__); + return DP_LINK_RATE_162; +} + + +uint32 +dp_decode_link_rate(uint32 rawLinkRate) +{ + switch (rawLinkRate) { + case DP_LINK_RATE_162: + return 162000; + case DP_LINK_RATE_270: + return 270000; + case DP_LINK_RATE_540: + return 540000; + } + ERROR("%s: Unknown DisplayPort Link Rate!\n", + __func__); + return 162000; +} + + +uint32 +dp_get_lane_count(dp_info* dpInfo, display_mode* mode) +{ + // TODO: Really need a function in GraphicDefs.h for this + uint32 bitsPerPixel; + switch (mode->space) { + case B_CMAP8: + bitsPerPixel = 8; + case B_RGB15_LITTLE: + bitsPerPixel = 15; + case B_RGB16_LITTLE: + bitsPerPixel = 16; + case B_RGB24_LITTLE: + case B_RGB32_LITTLE: + bitsPerPixel = 32; + } + + uint32 maxLaneCount = dpInfo->config[DP_MAX_LANE_COUNT] + & DP_MAX_LANE_COUNT_MASK; + uint32 maxLinkRate = dp_decode_link_rate(dpInfo->config[DP_MAX_LINK_RATE]); + + uint32 lane; + for (lane = 1; lane < maxLaneCount; lane <<= 1) { + uint32 maxDPPixelClock = (maxLinkRate * lane * 8) / bitsPerPixel; + if (mode->timing.pixel_clock <= maxDPPixelClock) + break; + } + + TRACE("%s: Lanes: %" B_PRIu32 "\n", __func__, lane); + + return lane; +} diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.cpp b/src/add-ons/accelerants/radeon_hd/accelerant.cpp index c2f937a..7753c68 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.cpp +++ b/src/add-ons/accelerants/radeon_hd/accelerant.cpp @@ -44,7 +44,6 @@ struct accelerant_info* gInfo; display_info* gDisplay[MAX_DISPLAY]; connector_info* gConnector[ATOM_MAX_SUPPORTED_DEVICE]; gpio_info* gGPIOInfo[ATOM_MAX_SUPPORTED_DEVICE]; -dp_info* gDPInfo[ATOM_MAX_SUPPORTED_DEVICE]; class AreaCloner { @@ -143,16 +142,6 @@ init_common(int device, bool isClone) memset(gGPIOInfo[id], 0, sizeof(gpio_info)); } - // malloc for card DP information - for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) { - gDPInfo[id] = (dp_info*)malloc(sizeof(dp_info)); - - if (gDPInfo[id] == NULL) - return B_NO_MEMORY; - memset(gDPInfo[id], 0, sizeof(dp_info)); - gDPInfo[id]->valid = false; - } - gInfo->is_clone = isClone; gInfo->device = device; diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index 8da527d..fdca834 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -14,7 +14,7 @@ #include <edid.h> #include "atom.h" -#include "dp_raw.h" +#include "dp.h" #include "encoder.h" #include "mode.h" #include "pll.h" @@ -125,28 +125,6 @@ typedef struct { } gpio_info; -typedef struct { - bool valid; - uint32 connectorIndex; - - uint32 auxPin; // normally GPIO pin on GPU - - uint8 config[8]; // DP configuration data - uint8 sinkType; - uint8 clock; - int laneCount; - - bool trainingUseEncoder; - - uint8 trainingAttempts; - uint8 trainingSet[4]; - int trainingReadInterval; - uint8 linkStatus[DP_LINK_STATUS_SIZE]; - - bool eDPOn; -} dp_info; - - struct encoder_info { bool valid; uint16 objectID; @@ -169,6 +147,7 @@ typedef struct { struct encoder_info encoder; struct encoder_info encoderExternal; // TODO struct radeon_hpd hpd; + dp_info dpInfo; } connector_info; @@ -200,7 +179,6 @@ extern atom_context* gAtomContext; extern display_info* gDisplay[MAX_DISPLAY]; extern connector_info* gConnector[ATOM_MAX_SUPPORTED_DEVICE]; extern gpio_info* gGPIOInfo[ATOM_MAX_SUPPORTED_DEVICE]; -extern dp_info* gDPInfo[ATOM_MAX_SUPPORTED_DEVICE]; // register access diff --git a/src/add-ons/accelerants/radeon_hd/displayport.cpp b/src/add-ons/accelerants/radeon_hd/displayport.cpp index e114818..ec3bb93 100644 --- a/src/add-ons/accelerants/radeon_hd/displayport.cpp +++ b/src/add-ons/accelerants/radeon_hd/displayport.cpp @@ -333,90 +333,39 @@ dp_get_link_clock(uint32 connectorIndex) } -uint32 -dp_get_link_clock_encode(uint32 dpLinkClock) -{ - switch (dpLinkClock) { - case 270000: - return DP_LINK_RATE_270; - case 540000: - return DP_LINK_RATE_540; - } - - return DP_LINK_RATE_162; -} - - -uint32 -dp_get_link_clock_decode(uint32 dpLinkClock) -{ - switch (dpLinkClock) { - case DP_LINK_RATE_270: - return 270000; - case DP_LINK_RATE_540: - return 540000; - } - return 162000; -} - - -uint32 -dp_get_lane_count(uint32 connectorIndex, display_mode* mode) -{ - uint32 bitsPerPixel = get_mode_bpp(mode); - - uint32 maxLaneCount = gDPInfo[connectorIndex]->config[DP_MAX_LANE_COUNT] - & DP_MAX_LANE_COUNT_MASK; - - uint32 maxLinkRate = dp_get_link_clock_decode( - gDPInfo[connectorIndex]->config[DP_MAX_LINK_RATE]); - - uint32 lane; - for (lane = 1; lane < maxLaneCount; lane <<= 1) { - uint32 maxDPPixelClock = (maxLinkRate * lane * 8) / bitsPerPixel; - if (mode->timing.pixel_clock <= maxDPPixelClock) - break; - } - TRACE("%s: connector: %" B_PRIu32 ", lanes: %" B_PRIu32 "\n", __func__, - connectorIndex, lane); - - return lane; -} - - void dp_setup_connectors() { TRACE("%s\n", __func__); for (uint32 index = 0; index < ATOM_MAX_SUPPORTED_DEVICE; index++) { - gDPInfo[index]->valid = false; + dp_info* dpInfo = &gConnector[index]->dpInfo; + dpInfo->valid = false; if (gConnector[index]->valid == false) { - gDPInfo[index]->config[0] = 0; + dpInfo->config[0] = 0; continue; } if (connector_is_dp(index) == false) { - gDPInfo[index]->config[0] = 0; + dpInfo->config[0] = 0; continue; } uint32 gpioID = gConnector[index]->gpioID; uint32 auxPin = gGPIOInfo[gpioID]->hwPin; - gDPInfo[index]->auxPin = auxPin; - gDPInfo[index]->connectorIndex = index; + dpInfo->auxPin = auxPin; uint8 auxMessage[25]; int result; result = dp_aux_read(auxPin, DP_DPCD_REV, auxMessage, 8, 0); if (result > 0) { - gDPInfo[index]->valid = true; - memcpy(gDPInfo[index]->config, auxMessage, 8); + dpInfo->valid = true; + memcpy(dpInfo->config, auxMessage, 8); } - gDPInfo[index]->clock = dp_get_link_clock(index); + dpInfo->linkRate = dp_get_link_clock(index); } } @@ -462,11 +411,13 @@ dp_clock_recovery_ok(dp_info* dp) static void -dp_update_vs_emph(dp_info* dp) +dp_update_vs_emph(uint32 connectorIndex) { + dp_info* dp = &gConnector[connectorIndex]->dpInfo; + // Set initial vs and emph on source - transmitter_dig_setup(dp->connectorIndex, dp->clock, 0, dp->trainingSet[0], - ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH); + transmitter_dig_setup(connectorIndex, dp->linkRate, 0, + dp->trainingSet[0], ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH); // Set vs and emph on the sink dp_aux_write(dp->auxPin, DP_TRAIN_LANE0, @@ -543,11 +494,12 @@ dp_get_adjust_train(dp_info* dp) static void -dp_set_tp(dp_info* dp, int trainingPattern) +dp_set_tp(uint32 connectorIndex, int trainingPattern) { TRACE("%s\n", __func__); radeon_shared_info &info = *gInfo->shared_info; + dp_info* dp = &gConnector[connectorIndex]->dpInfo; int rawTrainingPattern = 0; @@ -565,7 +517,7 @@ dp_set_tp(dp_info* dp, int trainingPattern) break; } // TODO: PixelClock 0 ok? - encoder_dig_setup(dp->connectorIndex, 0, rawTrainingPattern); + encoder_dig_setup(connectorIndex, 0, rawTrainingPattern); } else { ERROR("%s: TODO: dp_encoder_service\n", __func__); return; @@ -590,19 +542,21 @@ dp_set_tp(dp_info* dp, int trainingPattern) status_t -dp_link_train_cr(dp_info* dp) +dp_link_train_cr(uint32 connectorIndex) { TRACE("%s\n", __func__); + dp_info* dp = &gConnector[connectorIndex]->dpInfo; + // Display Port Clock Recovery Training bool clockRecovery = false; uint8 voltage = 0xff; int lane; - dp_set_tp(dp, DP_TRAIN_PATTERN_1); + dp_set_tp(connectorIndex, DP_TRAIN_PATTERN_1); memset(dp->trainingSet, 0, 4); - dp_update_vs_emph(dp); + dp_update_vs_emph(connectorIndex); while (1) { if (dp->trainingReadInterval == 0) @@ -642,7 +596,7 @@ dp_link_train_cr(dp_info* dp) // Compute new trainingSet as requested by sink dp_get_adjust_train(dp); - dp_update_vs_emph(dp); + dp_update_vs_emph(connectorIndex); } if (!clockRecovery) { @@ -664,7 +618,7 @@ dp_link_train(uint8 crtcID, display_mode* mode) TRACE("%s\n", __func__); uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; - dp_info* dp = gDPInfo[connectorIndex]; + dp_info* dp = &gConnector[connectorIndex]->dpInfo; if (dp->valid != true) { ERROR("%s: started on invalid DisplayPort connector #%" B_PRIu32 "\n", @@ -732,7 +686,7 @@ dp_link_train(uint8 crtcID, display_mode* mode) dpcd_reg_write(hwPin, DP_LANE_COUNT, sandbox); // Set the link rate on the DP sink - sandbox = dp_get_link_clock_encode(dp->clock); + sandbox = dp_encode_link_rate(dp->linkRate); dpcd_reg_write(hwPin, DP_LINK_RATE, sandbox); // Start link training on source @@ -747,7 +701,7 @@ dp_link_train(uint8 crtcID, display_mode* mode) // Disable the training pattern on the sink dpcd_reg_write(hwPin, DP_TRAIN, DP_TRAIN_PATTERN_DISABLED); - dp_link_train_cr(dp); + dp_link_train_cr(connectorIndex); // TODO: dp_link_train_ce diff --git a/src/add-ons/accelerants/radeon_hd/displayport.h b/src/add-ons/accelerants/radeon_hd/displayport.h index 4cfd3e8..ebf06fb 100644 --- a/src/add-ons/accelerants/radeon_hd/displayport.h +++ b/src/add-ons/accelerants/radeon_hd/displayport.h @@ -14,7 +14,7 @@ #include <SupportDefs.h> #include "accelerant.h" -#include "dp_raw.h" +#include "dp.h" // Radeon HD specific DisplayPort Configuration Data @@ -31,14 +31,12 @@ status_t dp_aux_set_i2c_byte(uint32 hwPin, uint16 address, status_t dp_aux_get_i2c_byte(uint32 hwPin, uint16 address, uint8* data, bool end); -uint32 dp_get_lane_count(uint32 connectorIndex, display_mode* mode); uint32 dp_get_link_clock(uint32 connectorIndex); -uint32 dp_get_link_clock_encode(uint32 dpLinkClock); -uint32 dp_get_link_clock_decode(uint32 dpLinkClock); void dp_setup_connectors(); + status_t dp_link_train(uint8 crtcID, display_mode* mode); -status_t dp_link_train_cr(dp_info* dp); +status_t dp_link_train_cr(uint32 connectorIndex); #endif /* RADEON_HD_DISPLAYPORT_H */ diff --git a/src/add-ons/accelerants/radeon_hd/encoder.cpp b/src/add-ons/accelerants/radeon_hd/encoder.cpp index d4fe6ea..57a8fdf 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.cpp +++ b/src/add-ons/accelerants/radeon_hd/encoder.cpp @@ -602,6 +602,7 @@ encoder_dig_setup(uint32 connectorIndex, uint32 pixelClock, int command) TRACE("%s: table %" B_PRIu8 ".%" B_PRIu8 "\n", __func__, tableMajor, tableMinor); + dp_info* dpInfo = &gConnector[connectorIndex]->dpInfo; uint32 dpClock = dp_get_link_clock(connectorIndex); switch (tableMinor) { case 1: @@ -653,7 +654,7 @@ encoder_dig_setup(uint32 connectorIndex, uint32 pixelClock, int command) if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP || args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST) { - args.v1.ucLaneNum = gDPInfo[connectorIndex]->laneCount; + args.v1.ucLaneNum = dpInfo->laneCount; } else if (pixelClock > 165000) args.v1.ucLaneNum = 8; else @@ -718,6 +719,8 @@ encoder_external_setup(uint32 connectorIndex, uint32 pixelClock, int command) encoder_info* encoder = &gConnector[connectorIndex]->encoderExternal; + dp_info* dpInfo + = &gConnector[connectorIndex]->dpInfo; if (encoder->valid != true) { ERROR("%s: connector %" B_PRIu32 " doesn't have a valid " @@ -764,12 +767,12 @@ encoder_external_setup(uint32 connectorIndex, uint32 pixelClock, int command) = display_get_encoder_mode(connectorIndex); if (connector_is_dp(connectorIndex)) { - if (gDPInfo[connectorIndex]->clock == 270000) { + if (dpInfo->linkRate == 270000) { args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; } args.v1.sDigEncoder.ucLaneNum - = gDPInfo[connectorIndex]->laneCount; + = dpInfo->laneCount; } else if (pixelClock > 165000) { args.v1.sDigEncoder.ucLaneNum = 8; } else { @@ -791,15 +794,15 @@ encoder_external_setup(uint32 connectorIndex, uint32 pixelClock, int command) = display_get_encoder_mode(connectorIndex); if (connector_is_dp(connectorIndex)) { - if (gDPInfo[connectorIndex]->clock == 270000) { + if (dpInfo->linkRate == 270000) { args.v3.sExtEncoder.ucConfig |=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; - } else if (gDPInfo[connectorIndex]->clock == 540000) { + } else if (dpInfo->linkRate == 540000) { args.v3.sExtEncoder.ucConfig |=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; } args.v1.sDigEncoder.ucLaneNum - = gDPInfo[connectorIndex]->laneCount; + = dpInfo->laneCount; } else if (pixelClock > 165000) { args.v3.sExtEncoder.ucLaneNum = 8; } else { @@ -1129,11 +1132,13 @@ transmitter_dig_setup(uint32 connectorIndex, uint32 pixelClock, bool linkB = gConnector[connectorIndex]->encoderExternal.linkEnumeration == GRAPH_OBJECT_ENUM_ID2 ? true : false; + dp_info* dpInfo = &gConnector[connectorIndex]->dpInfo; + uint8 dpClock = 0; int dpLaneCount = 0; - if (gDPInfo[connectorIndex]->valid == true) { - dpClock = gDPInfo[connectorIndex]->clock; - dpLaneCount = gDPInfo[connectorIndex]->laneCount; + if (dpInfo->valid == true) { + dpClock = dpInfo->linkRate; + dpLaneCount = dpInfo->laneCount; } switch (tableMajor) { diff --git a/src/add-ons/accelerants/radeon_hd/mode.cpp b/src/add-ons/accelerants/radeon_hd/mode.cpp index e79d3a4..381878d 100644 --- a/src/add-ons/accelerants/radeon_hd/mode.cpp +++ b/src/add-ons/accelerants/radeon_hd/mode.cpp @@ -166,12 +166,12 @@ radeon_set_display_mode(display_mode* mode) if (gDisplay[id]->attached == false) continue; - uint16 connectorIndex = gDisplay[id]->connectorIndex; + uint32 connectorIndex = gDisplay[id]->connectorIndex; + dp_info *dpInfo = &gConnector[connectorIndex]->dpInfo; // Determine DP lanes if DP if (connector_is_dp(connectorIndex)) - gDPInfo[connectorIndex]->laneCount - = dp_get_lane_count(connectorIndex, mode); + dpInfo->laneCount = dp_get_lane_count(dpInfo, mode); // *** encoder prep encoder_output_lock(true);