From 96587f13569659fa59abde67e430da426bb0a1ac Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 13 Dec 2011 17:51:30 -0600 Subject: [PATCH] Introduce new displayport source file * Move existing displayport functions to new source file * Move was done due to large amount of DP code * Style fixes * Stub out new DP link training function --- src/add-ons/accelerants/radeon_hd/Jamfile | 1 + .../accelerants/radeon_hd/connector.cpp | 275 -------------- src/add-ons/accelerants/radeon_hd/connector.h | 30 -- .../accelerants/radeon_hd/displayport.cpp | 338 ++++++++++++++++++ .../accelerants/radeon_hd/displayport.h | 49 +++ src/add-ons/accelerants/radeon_hd/encoder.cpp | 15 +- src/add-ons/accelerants/radeon_hd/encoder.h | 1 - src/add-ons/accelerants/radeon_hd/pll.cpp | 4 +- 8 files changed, 393 insertions(+), 320 deletions(-) create mode 100644 src/add-ons/accelerants/radeon_hd/displayport.cpp create mode 100644 src/add-ons/accelerants/radeon_hd/displayport.h diff --git a/src/add-ons/accelerants/radeon_hd/Jamfile b/src/add-ons/accelerants/radeon_hd/Jamfile index 91a46e6092..39d08ebd3e 100644 --- a/src/add-ons/accelerants/radeon_hd/Jamfile +++ b/src/add-ons/accelerants/radeon_hd/Jamfile @@ -16,6 +16,7 @@ Addon radeon_hd.accelerant : connector.cpp create_display_modes.cpp display.cpp + displayport.cpp encoder.cpp engine.cpp gpu.cpp diff --git a/src/add-ons/accelerants/radeon_hd/connector.cpp b/src/add-ons/accelerants/radeon_hd/connector.cpp index 5293977179..fa513d0a6f 100644 --- a/src/add-ons/accelerants/radeon_hd/connector.cpp +++ b/src/add-ons/accelerants/radeon_hd/connector.cpp @@ -31,281 +31,6 @@ #define ERROR(x...) _sPrintf("radeon_hd: " x) -static int -dp_aux_speak(uint32 hwLine, uint8* send, int sendBytes, - uint8* recv, int recvBytes, uint8 delay, uint8* ack) -{ - if (hwLine == 0) { - ERROR("%s: cannot speak on invalid GPIO pin!\n", __func__); - return B_IO_ERROR; - } - - int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); - - // Build AtomBIOS Transaction - union auxChannelTransaction { - PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; - PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; - }; - union auxChannelTransaction args; - memset(&args, 0, sizeof(args)); - - args.v1.lpAuxRequest = 0; - args.v1.lpDataOut = 16; - args.v1.ucDataOutLen = 0; - args.v1.ucChannelID = hwLine; - args.v1.ucDelay = delay / 10; - - //if (ASIC_IS_DCE4(rdev)) - // args.v2.ucHPD_ID = chan->rec.hpd; - - unsigned char* base = (unsigned char*)gAtomContext->scratch; - memcpy(base, send, sendBytes); - - atom_execute_table(gAtomContext, index, (uint32*)&args); - - *ack = args.v1.ucReplyStatus; - - switch (args.v1.ucReplyStatus) { - case 1: - ERROR("%s: dp_aux_ch timeout!\n", __func__); - return B_TIMED_OUT; - case 2: - ERROR("%s: dp_aux_ch flags not zero!\n", __func__); - return B_BUSY; - case 3: - ERROR("%s: dp_aux_ch error!\n", __func__); - return B_IO_ERROR; - } - - int recvLength = args.v1.ucDataOutLen; - if (recvLength > recvBytes) - recvLength = recvBytes; - - if (recv && recvBytes) - memcpy(recv, base + 16, recvLength); - - return recvLength; -} - - -int -dp_aux_write(uint32 hwLine, uint16 address, - uint8* send, uint8 sendBytes, uint8 delay) -{ - uint8 auxMessage[20]; - int auxMessageBytes = sendBytes + 4; - - if (sendBytes > 16) - return -1; - - auxMessage[0] = address; - auxMessage[1] = address >> 8; - auxMessage[2] = AUX_NATIVE_WRITE << 4; - auxMessage[3] = (auxMessageBytes << 4) | (sendBytes - 1); - memcpy(&auxMessage[4], send, sendBytes); - - uint8 retry; - for (retry = 0; retry < 4; retry++) { - uint8 ack; - int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, - NULL, 0, delay, &ack); - - if (result == B_BUSY) - continue; - else if (result < B_OK) - return result; - - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - return sendBytes; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - snooze(400); - else - return B_IO_ERROR; - } - - return B_IO_ERROR; -} - - -int -dp_aux_read(uint32 hwLine, uint16 address, - uint8* recv, int recvBytes, uint8 delay) -{ - uint8 auxMessage[4]; - int auxMessageBytes = 4; - - auxMessage[0] = address; - auxMessage[1] = address >> 8; - auxMessage[2] = AUX_NATIVE_READ << 4; - auxMessage[3] = (auxMessageBytes << 4) | (recvBytes - 1); - - uint8 retry; - for (retry = 0; retry < 4; retry++) { - uint8 ack; - int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, - recv, recvBytes, delay, &ack); - - if (result == B_BUSY) - continue; - else if (result < B_OK) - return result; - - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - return result; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - snooze(400); - else - return B_IO_ERROR; - } - - return B_IO_ERROR; -} - - -status_t -dp_aux_get_i2c_byte(uint32 hwLine, uint16 address, uint8* data, bool end) -{ - uint8 auxMessage[5]; - int auxMessageBytes = 4; // 4 for read - - /* Set up the command byte */ - auxMessage[2] = AUX_I2C_READ << 4; - if (end == false) - auxMessage[2] |= AUX_I2C_MOT << 4; - - auxMessage[0] = address; - auxMessage[1] = address >> 8; - - auxMessage[3] = auxMessageBytes << 4; - - int retry; - for (retry = 0; retry < 4; retry++) { - uint8 ack; - uint8 reply[2]; - int replyBytes = 1; - - int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, - reply, replyBytes, 0, &ack); - if (result == B_BUSY) - continue; - else if (result < 0) { - ERROR("%s: aux_ch failed: %d\n", __func__, result); - return B_ERROR; - } - - switch (ack & AUX_NATIVE_REPLY_MASK) { - case AUX_NATIVE_REPLY_ACK: - // I2C-over-AUX Reply field is only valid for AUX_ACK - break; - case AUX_NATIVE_REPLY_NACK: - TRACE("%s: aux_ch native nack\n", __func__); - return B_IO_ERROR; - case AUX_NATIVE_REPLY_DEFER: - TRACE("%s: aux_ch native defer\n", __func__); - snooze(400); - continue; - default: - TRACE("%s: aux_ch invalid native reply: 0x%02x\n", - __func__, ack); - return B_ERROR; - } - - switch (ack & AUX_I2C_REPLY_MASK) { - case AUX_I2C_REPLY_ACK: - *data = reply[0]; - return B_OK; - case AUX_I2C_REPLY_NACK: - TRACE("%s: aux_i2c nack\n", __func__); - return B_IO_ERROR; - case AUX_I2C_REPLY_DEFER: - TRACE("%s: aux_i2c defer\n", __func__); - snooze(400); - break; - default: - TRACE("%s: aux_i2c invalid native reply: 0x%02x\n", - __func__, ack); - return B_ERROR; - } - } - - TRACE("%s: aux i2c too many retries, giving up.\n", __func__); - return B_ERROR; -} - - -status_t -dp_aux_set_i2c_byte(uint32 hwLine, uint16 address, uint8* data, bool end) -{ - uint8 auxMessage[5]; - int auxMessageBytes = 5; // 5 for write - - /* Set up the command byte */ - auxMessage[2] = AUX_I2C_WRITE << 4; - if (end == false) - auxMessage[2] |= AUX_I2C_MOT << 4; - - auxMessage[0] = address; - auxMessage[1] = address >> 8; - - auxMessage[3] = auxMessageBytes << 4; - auxMessage[4] = *data; - - int retry; - for (retry = 0; retry < 4; retry++) { - uint8 ack; - uint8 reply[2]; - int replyBytes = 1; - - int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, - reply, replyBytes, 0, &ack); - if (result == B_BUSY) - continue; - else if (result < 0) { - ERROR("%s: aux_ch failed: %d\n", __func__, result); - return B_ERROR; - } - - switch (ack & AUX_NATIVE_REPLY_MASK) { - case AUX_NATIVE_REPLY_ACK: - // I2C-over-AUX Reply field is only valid for AUX_ACK - break; - case AUX_NATIVE_REPLY_NACK: - TRACE("%s: aux_ch native nack\n", __func__); - return B_IO_ERROR; - case AUX_NATIVE_REPLY_DEFER: - TRACE("%s: aux_ch native defer\n", __func__); - snooze(400); - continue; - default: - TRACE("%s: aux_ch invalid native reply: 0x%02x\n", - __func__, ack); - return B_ERROR; - } - - switch (ack & AUX_I2C_REPLY_MASK) { - case AUX_I2C_REPLY_ACK: - // Success! - return B_OK; - case AUX_I2C_REPLY_NACK: - TRACE("%s: aux_i2c nack\n", __func__); - return B_IO_ERROR; - case AUX_I2C_REPLY_DEFER: - TRACE("%s: aux_i2c defer\n", __func__); - snooze(400); - break; - default: - TRACE("%s: aux_i2c invalid native reply: 0x%02x\n", - __func__, ack); - return B_ERROR; - } - } - - TRACE("%s: aux i2c too many retries, giving up.\n", __func__); - return B_OK; -} - - static void gpio_lock_i2c(void* cookie, bool lock) { diff --git a/src/add-ons/accelerants/radeon_hd/connector.h b/src/add-ons/accelerants/radeon_hd/connector.h index 123cbd5f5a..81b1de97bf 100644 --- a/src/add-ons/accelerants/radeon_hd/connector.h +++ b/src/add-ons/accelerants/radeon_hd/connector.h @@ -14,26 +14,6 @@ #include "accelerant.h" -// From the VESA DisplayPort spec -// TODO: may want to move these into common code -#define AUX_NATIVE_WRITE 0x8 -#define AUX_NATIVE_READ 0x9 -#define AUX_I2C_WRITE 0x0 -#define AUX_I2C_READ 0x1 -#define AUX_I2C_STATUS 0x2 -#define AUX_I2C_MOT 0x4 - -#define AUX_NATIVE_REPLY_ACK (0x0 << 4) -#define AUX_NATIVE_REPLY_NACK (0x1 << 4) -#define AUX_NATIVE_REPLY_DEFER (0x2 << 4) -#define AUX_NATIVE_REPLY_MASK (0x3 << 4) - -#define AUX_I2C_REPLY_ACK (0x0 << 6) -#define AUX_I2C_REPLY_NACK (0x1 << 6) -#define AUX_I2C_REPLY_DEFER (0x2 << 6) -#define AUX_I2C_REPLY_MASK (0x3 << 6) - - // convert radeon connector to common connector type const int kConnectorConvertLegacy[] = { VIDEO_CONNECTOR_UNKNOWN, @@ -80,16 +60,6 @@ const int kConnectorConvert[] = { }; -int dp_aux_write(uint32 hwLine, uint16 address, uint8* send, - uint8 sendBytes, uint8 delay); -int dp_aux_read(uint32 hwLine, uint16 address, uint8* recv, - int recvBytes, uint8 delay); -status_t dp_aux_set_i2c_byte(uint32 hwLine, uint16 address, - uint8* data, bool end); -status_t dp_aux_get_i2c_byte(uint32 hwLine, uint16 address, - uint8* data, bool end); - - status_t gpio_probe(); status_t connector_attach_gpio(uint32 id, uint8 hw_line); bool connector_read_edid(uint32 connector, edid1_info* edid); diff --git a/src/add-ons/accelerants/radeon_hd/displayport.cpp b/src/add-ons/accelerants/radeon_hd/displayport.cpp new file mode 100644 index 0000000000..be9d31e49f --- /dev/null +++ b/src/add-ons/accelerants/radeon_hd/displayport.cpp @@ -0,0 +1,338 @@ +/* + * Copyright 2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck IV, kallisti5@unixzen.com + */ + + +#include "displayport.h" + +#include + +#include "accelerant.h" +#include "accelerant_protos.h" + + +#undef TRACE + +#define TRACE_DP +#ifdef TRACE_DP +# define TRACE(x...) _sPrintf("radeon_hd: " x) +#else +# define TRACE(x...) ; +#endif + +#define ERROR(x...) _sPrintf("radeon_hd: " x) + + +static int +dp_aux_speak(uint32 hwLine, uint8* send, int sendBytes, + uint8* recv, int recvBytes, uint8 delay, uint8* ack) +{ + if (hwLine == 0) { + ERROR("%s: cannot speak on invalid GPIO pin!\n", __func__); + return B_IO_ERROR; + } + + int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); + + // Build AtomBIOS Transaction + union auxChannelTransaction { + PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; + PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; + }; + union auxChannelTransaction args; + memset(&args, 0, sizeof(args)); + + args.v1.lpAuxRequest = 0; + args.v1.lpDataOut = 16; + args.v1.ucDataOutLen = 0; + args.v1.ucChannelID = hwLine; + args.v1.ucDelay = delay / 10; + + //if (ASIC_IS_DCE4(rdev)) + // args.v2.ucHPD_ID = chan->rec.hpd; + + unsigned char* base = (unsigned char*)gAtomContext->scratch; + memcpy(base, send, sendBytes); + + atom_execute_table(gAtomContext, index, (uint32*)&args); + + *ack = args.v1.ucReplyStatus; + + switch (args.v1.ucReplyStatus) { + case 1: + ERROR("%s: dp_aux_ch timeout!\n", __func__); + return B_TIMED_OUT; + case 2: + ERROR("%s: dp_aux_ch flags not zero!\n", __func__); + return B_BUSY; + case 3: + ERROR("%s: dp_aux_ch error!\n", __func__); + return B_IO_ERROR; + } + + int recvLength = args.v1.ucDataOutLen; + if (recvLength > recvBytes) + recvLength = recvBytes; + + if (recv && recvBytes) + memcpy(recv, base + 16, recvLength); + + return recvLength; +} + + +int +dp_aux_write(uint32 hwLine, uint16 address, + uint8* send, uint8 sendBytes, uint8 delay) +{ + uint8 auxMessage[20]; + int auxMessageBytes = sendBytes + 4; + + if (sendBytes > 16) + return -1; + + auxMessage[0] = address; + auxMessage[1] = address >> 8; + auxMessage[2] = AUX_NATIVE_WRITE << 4; + auxMessage[3] = (auxMessageBytes << 4) | (sendBytes - 1); + memcpy(&auxMessage[4], send, sendBytes); + + uint8 retry; + for (retry = 0; retry < 4; retry++) { + uint8 ack; + int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, + NULL, 0, delay, &ack); + + if (result == B_BUSY) + continue; + else if (result < B_OK) + return result; + + if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) + return sendBytes; + else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) + snooze(400); + else + return B_IO_ERROR; + } + + return B_IO_ERROR; +} + + +int +dp_aux_read(uint32 hwLine, uint16 address, + uint8* recv, int recvBytes, uint8 delay) +{ + uint8 auxMessage[4]; + int auxMessageBytes = 4; + + auxMessage[0] = address; + auxMessage[1] = address >> 8; + auxMessage[2] = AUX_NATIVE_READ << 4; + auxMessage[3] = (auxMessageBytes << 4) | (recvBytes - 1); + + uint8 retry; + for (retry = 0; retry < 4; retry++) { + uint8 ack; + int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, + recv, recvBytes, delay, &ack); + + if (result == B_BUSY) + continue; + else if (result < B_OK) + return result; + + if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) + return result; + else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) + snooze(400); + else + return B_IO_ERROR; + } + + return B_IO_ERROR; +} + + +status_t +dp_aux_get_i2c_byte(uint32 hwLine, uint16 address, uint8* data, bool end) +{ + uint8 auxMessage[5]; + int auxMessageBytes = 4; // 4 for read + + /* Set up the command byte */ + auxMessage[2] = AUX_I2C_READ << 4; + if (end == false) + auxMessage[2] |= AUX_I2C_MOT << 4; + + auxMessage[0] = address; + auxMessage[1] = address >> 8; + + auxMessage[3] = auxMessageBytes << 4; + + int retry; + for (retry = 0; retry < 4; retry++) { + uint8 ack; + uint8 reply[2]; + int replyBytes = 1; + + int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, + reply, replyBytes, 0, &ack); + if (result == B_BUSY) + continue; + else if (result < 0) { + ERROR("%s: aux_ch failed: %d\n", __func__, result); + return B_ERROR; + } + + switch (ack & AUX_NATIVE_REPLY_MASK) { + case AUX_NATIVE_REPLY_ACK: + // I2C-over-AUX Reply field is only valid for AUX_ACK + break; + case AUX_NATIVE_REPLY_NACK: + TRACE("%s: aux_ch native nack\n", __func__); + return B_IO_ERROR; + case AUX_NATIVE_REPLY_DEFER: + TRACE("%s: aux_ch native defer\n", __func__); + snooze(400); + continue; + default: + TRACE("%s: aux_ch invalid native reply: 0x%02x\n", + __func__, ack); + return B_ERROR; + } + + switch (ack & AUX_I2C_REPLY_MASK) { + case AUX_I2C_REPLY_ACK: + *data = reply[0]; + return B_OK; + case AUX_I2C_REPLY_NACK: + TRACE("%s: aux_i2c nack\n", __func__); + return B_IO_ERROR; + case AUX_I2C_REPLY_DEFER: + TRACE("%s: aux_i2c defer\n", __func__); + snooze(400); + break; + default: + TRACE("%s: aux_i2c invalid native reply: 0x%02x\n", + __func__, ack); + return B_ERROR; + } + } + + TRACE("%s: aux i2c too many retries, giving up.\n", __func__); + return B_ERROR; +} + + +status_t +dp_aux_set_i2c_byte(uint32 hwLine, uint16 address, uint8* data, bool end) +{ + uint8 auxMessage[5]; + int auxMessageBytes = 5; // 5 for write + + /* Set up the command byte */ + auxMessage[2] = AUX_I2C_WRITE << 4; + if (end == false) + auxMessage[2] |= AUX_I2C_MOT << 4; + + auxMessage[0] = address; + auxMessage[1] = address >> 8; + + auxMessage[3] = auxMessageBytes << 4; + auxMessage[4] = *data; + + int retry; + for (retry = 0; retry < 4; retry++) { + uint8 ack; + uint8 reply[2]; + int replyBytes = 1; + + int result = dp_aux_speak(hwLine, auxMessage, auxMessageBytes, + reply, replyBytes, 0, &ack); + if (result == B_BUSY) + continue; + else if (result < 0) { + ERROR("%s: aux_ch failed: %d\n", __func__, result); + return B_ERROR; + } + + switch (ack & AUX_NATIVE_REPLY_MASK) { + case AUX_NATIVE_REPLY_ACK: + // I2C-over-AUX Reply field is only valid for AUX_ACK + break; + case AUX_NATIVE_REPLY_NACK: + TRACE("%s: aux_ch native nack\n", __func__); + return B_IO_ERROR; + case AUX_NATIVE_REPLY_DEFER: + TRACE("%s: aux_ch native defer\n", __func__); + snooze(400); + continue; + default: + TRACE("%s: aux_ch invalid native reply: 0x%02x\n", + __func__, ack); + return B_ERROR; + } + + switch (ack & AUX_I2C_REPLY_MASK) { + case AUX_I2C_REPLY_ACK: + // Success! + return B_OK; + case AUX_I2C_REPLY_NACK: + TRACE("%s: aux_i2c nack\n", __func__); + return B_IO_ERROR; + case AUX_I2C_REPLY_DEFER: + TRACE("%s: aux_i2c defer\n", __func__); + snooze(400); + break; + default: + TRACE("%s: aux_i2c invalid native reply: 0x%02x\n", + __func__, ack); + return B_ERROR; + } + } + + TRACE("%s: aux i2c too many retries, giving up.\n", __func__); + return B_OK; +} + + +uint32 +dp_get_link_clock(uint32 connectorIndex) +{ + uint16 encoderID = gConnector[connectorIndex]->encoder.objectID; + + if (encoderID == ENCODER_OBJECT_ID_NUTMEG) + return 270000; + + // TODO: calculate DisplayPort max pixel clock based on bpp and DP channels + return 162000; +} + + +status_t +dp_link_train(uint32 connectorIndex) +{ + TRACE("%s\n", __func__); + + int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); + // Table version + uint8 tableMajor; + uint8 tableMinor; + + bool useDpencoder = true; // ?? + if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor) + == B_OK) { + if (tableMinor > 1) { + useDpencoder = false; + } + } + + // TODO: perform displayport training + return B_ERROR; +} diff --git a/src/add-ons/accelerants/radeon_hd/displayport.h b/src/add-ons/accelerants/radeon_hd/displayport.h new file mode 100644 index 0000000000..914c2d055e --- /dev/null +++ b/src/add-ons/accelerants/radeon_hd/displayport.h @@ -0,0 +1,49 @@ +/* + * Copyright 2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck IV, kallisti5@unixzen.com + */ +#ifndef RADEON_HD_DISPLAYPORT_H +#define RADEON_HD_DISPLAYPORT_H + + +#include +#include + + +// From the VESA DisplayPort spec +// TODO: may want to move these into common code +#define AUX_NATIVE_WRITE 0x8 +#define AUX_NATIVE_READ 0x9 +#define AUX_I2C_WRITE 0x0 +#define AUX_I2C_READ 0x1 +#define AUX_I2C_STATUS 0x2 +#define AUX_I2C_MOT 0x4 + +#define AUX_NATIVE_REPLY_ACK (0x0 << 4) +#define AUX_NATIVE_REPLY_NACK (0x1 << 4) +#define AUX_NATIVE_REPLY_DEFER (0x2 << 4) +#define AUX_NATIVE_REPLY_MASK (0x3 << 4) + +#define AUX_I2C_REPLY_ACK (0x0 << 6) +#define AUX_I2C_REPLY_NACK (0x1 << 6) +#define AUX_I2C_REPLY_DEFER (0x2 << 6) +#define AUX_I2C_REPLY_MASK (0x3 << 6) + + +int dp_aux_write(uint32 hwLine, uint16 address, uint8* send, + uint8 sendBytes, uint8 delay); +int dp_aux_read(uint32 hwLine, uint16 address, uint8* recv, + int recvBytes, uint8 delay); +status_t dp_aux_set_i2c_byte(uint32 hwLine, uint16 address, + uint8* data, bool end); +status_t dp_aux_get_i2c_byte(uint32 hwLine, uint16 address, + uint8* data, bool end); + +uint32 dp_get_link_clock(uint32 connectorIndex); +status_t dp_link_train(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 d77facaaec..fe1968ac09 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.cpp +++ b/src/add-ons/accelerants/radeon_hd/encoder.cpp @@ -1361,7 +1361,8 @@ encoder_is_external(uint32 encoderID) bool -encoder_is_dp_bridge(uint32 encoderID) { +encoder_is_dp_bridge(uint32 encoderID) +{ switch (encoderID) { case ENCODER_OBJECT_ID_TRAVIS: case ENCODER_OBJECT_ID_NUTMEG: @@ -1369,15 +1370,3 @@ encoder_is_dp_bridge(uint32 encoderID) { } return false; } - - -uint32 -encoder_get_dp_link_clock(uint32 connectorIndex) { - uint16 encoderID = gConnector[connectorIndex]->encoder.objectID; - - if (encoderID == ENCODER_OBJECT_ID_NUTMEG) - return 270000; - - // TODO: calculate DisplayPort max pixel clock based on bpp and DP channels - return 162000; -} diff --git a/src/add-ons/accelerants/radeon_hd/encoder.h b/src/add-ons/accelerants/radeon_hd/encoder.h index 9f1eeeef7b..284eb5d5af 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.h +++ b/src/add-ons/accelerants/radeon_hd/encoder.h @@ -38,7 +38,6 @@ uint32 encoder_object_lookup(uint32 encoderFlags, uint8 dacID); uint32 encoder_type_lookup(uint32 encoderID, uint32 connectorFlags); bool encoder_is_external(uint32 encoderID); bool encoder_is_dp_bridge(uint32 encoderID); -uint32 encoder_get_dp_link_clock(uint32 connectorIndex); #endif /* RADEON_HD_ENCODER_H */ diff --git a/src/add-ons/accelerants/radeon_hd/pll.cpp b/src/add-ons/accelerants/radeon_hd/pll.cpp index 67242abc30..bcc1c3bf8e 100644 --- a/src/add-ons/accelerants/radeon_hd/pll.cpp +++ b/src/add-ons/accelerants/radeon_hd/pll.cpp @@ -18,9 +18,11 @@ #include "accelerant.h" #include "bios.h" #include "display.h" +#include "displayport.h" #include "encoder.h" #include "utility.h" + #define TRACE_PLL #ifdef TRACE_PLL extern "C" void _sPrintf(const char* format, ...); @@ -401,7 +403,7 @@ pll_adjust(pll_info* pll, uint8 crtcID) |= DISPPLL_CONFIG_COHERENT_MODE; /* 16200 or 27000 */ uint32 dpLinkSpeed - = encoder_get_dp_link_clock(connectorIndex); + = dp_get_link_clock(connectorIndex); args.v3.sInput.usPixelClock = B_LENDIAN_TO_HOST_INT16(dpLinkSpeed / 10); } else if ((encoderFlags & ATOM_DEVICE_DFP_SUPPORT)