drm/radeon/kms: DP fixes and cleanup from the ddx
- dpcp -> dpcd - fix up dig encoder routing - aux transaction table takes delay in 10 usec units Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
746c1aa4d1
commit
1a66c95a64
|
@ -34,7 +34,7 @@
|
||||||
#define DP_LINK_STATUS_SIZE 6
|
#define DP_LINK_STATUS_SIZE 6
|
||||||
|
|
||||||
bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
|
bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
|
||||||
int num_bytes, u8 *read_byte,
|
int num_bytes, u8 *read_byte,
|
||||||
u8 read_buf_len, u8 delay)
|
u8 read_buf_len, u8 delay)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = chan->dev;
|
struct drm_device *dev = chan->dev;
|
||||||
|
@ -42,9 +42,9 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
|
||||||
PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
|
PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
|
int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
|
||||||
unsigned char *base;
|
unsigned char *base;
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
base = (unsigned char *)rdev->mode_info.atom_context->scratch;
|
base = (unsigned char *)rdev->mode_info.atom_context->scratch;
|
||||||
|
|
||||||
memcpy(base, req_bytes, num_bytes);
|
memcpy(base, req_bytes, num_bytes);
|
||||||
|
@ -53,7 +53,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
|
||||||
args.lpDataOut = 16;
|
args.lpDataOut = 16;
|
||||||
args.ucDataOutLen = 0;
|
args.ucDataOutLen = 0;
|
||||||
args.ucChannelID = chan->i2c_id;
|
args.ucChannelID = chan->i2c_id;
|
||||||
args.ucDelay = delay;
|
args.ucDelay = delay / 10;
|
||||||
|
|
||||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||||
|
|
||||||
|
@ -158,24 +158,24 @@ bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void radeon_dp_getdpcp(struct radeon_connector *radeon_connector)
|
void radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
|
||||||
{
|
{
|
||||||
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
|
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
|
||||||
u8 msg[25];
|
u8 msg[25];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCP_REV, 0, 8, msg);
|
ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
memcpy(radeon_dig_connector->dpcp, msg, 8);
|
memcpy(radeon_dig_connector->dpcd, msg, 8);
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
printk("DPCP: ");
|
printk("DPCD: ");
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
printk("%02x ", msg[i]);
|
printk("%02x ", msg[i]);
|
||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
radeon_dig_connector->dpcp[0] = 0;
|
radeon_dig_connector->dpcd[0] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,8 +199,8 @@ static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
|
||||||
static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
|
static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
|
||||||
{
|
{
|
||||||
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
|
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
|
||||||
if (radeon_dig_connector->dpcp[0] >= 0x11) {
|
if (radeon_dig_connector->dpcd[0] >= 0x11) {
|
||||||
radeon_dp_aux_native_write(radeon_connector, 0x600, 1,
|
radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
|
||||||
&power_state);
|
&power_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -923,7 +923,7 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto
|
||||||
|
|
||||||
sink_type = radeon_dp_getsinktype(radeon_connector);
|
sink_type = radeon_dp_getsinktype(radeon_connector);
|
||||||
if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
|
if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
|
||||||
radeon_dp_getdpcp(radeon_connector);
|
radeon_dp_getdpcd(radeon_connector);
|
||||||
ret = connector_status_connected;
|
ret = connector_status_connected;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -605,6 +605,30 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DIG Encoder/Transmitter Setup
|
||||||
|
*
|
||||||
|
* DCE 3.0/3.1
|
||||||
|
* - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
|
||||||
|
* Supports up to 3 digital outputs
|
||||||
|
* - 2 DIG encoder blocks.
|
||||||
|
* DIG1 can drive UNIPHY link A or link B
|
||||||
|
* DIG2 can drive UNIPHY link B or LVTMA
|
||||||
|
*
|
||||||
|
* DCE 3.2
|
||||||
|
* - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
|
||||||
|
* Supports up to 5 digital outputs
|
||||||
|
* - 2 DIG encoder blocks.
|
||||||
|
* DIG1/2 can drive UNIPHY0/1/2 link A or link B
|
||||||
|
*
|
||||||
|
* Routing
|
||||||
|
* crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
|
||||||
|
* Examples:
|
||||||
|
* crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI
|
||||||
|
* crtc1 -> dig1 -> UNIPHY0 link B -> DP
|
||||||
|
* crtc0 -> dig1 -> UNIPHY2 link A -> LVDS
|
||||||
|
* crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
|
atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
|
||||||
{
|
{
|
||||||
|
@ -646,10 +670,17 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
|
||||||
} else {
|
} else {
|
||||||
switch (radeon_encoder->encoder_id) {
|
switch (radeon_encoder->encoder_id) {
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
|
/* XXX doesn't really matter which dig encoder we pick as long as it's
|
||||||
|
* not already in use
|
||||||
|
*/
|
||||||
|
if (dig_connector->linkb)
|
||||||
|
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
|
||||||
|
else
|
||||||
|
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
|
||||||
num = 1;
|
num = 1;
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
|
/* Only dig2 encoder can drive LVTMA */
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
|
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
|
||||||
num = 2;
|
num = 2;
|
||||||
break;
|
break;
|
||||||
|
@ -684,16 +715,15 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radeon_encoder->pixel_clock > 165000) {
|
if (radeon_encoder->pixel_clock > 165000)
|
||||||
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
|
|
||||||
args.ucLaneNum = 8;
|
args.ucLaneNum = 8;
|
||||||
} else {
|
else
|
||||||
if (dig_connector->linkb)
|
|
||||||
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
|
|
||||||
else
|
|
||||||
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
|
|
||||||
args.ucLaneNum = 4;
|
args.ucLaneNum = 4;
|
||||||
}
|
|
||||||
|
if (dig_connector->linkb)
|
||||||
|
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
|
||||||
|
else
|
||||||
|
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
|
||||||
|
|
||||||
args.ucEncoderMode = atombios_get_encoder_mode(encoder);
|
args.ucEncoderMode = atombios_get_encoder_mode(encoder);
|
||||||
|
|
||||||
|
@ -707,7 +737,7 @@ union dig_transmitter_control {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
|
atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = encoder->dev;
|
struct drm_device *dev = encoder->dev;
|
||||||
struct radeon_device *rdev = dev->dev_private;
|
struct radeon_device *rdev = dev->dev_private;
|
||||||
|
@ -756,6 +786,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
|
||||||
args.v1.ucAction = action;
|
args.v1.ucAction = action;
|
||||||
if (action == ATOM_TRANSMITTER_ACTION_INIT) {
|
if (action == ATOM_TRANSMITTER_ACTION_INIT) {
|
||||||
args.v1.usInitInfo = radeon_connector->connector_object_id;
|
args.v1.usInitInfo = radeon_connector->connector_object_id;
|
||||||
|
} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
|
||||||
|
args.v1.asMode.ucLaneSel = lane_num;
|
||||||
|
args.v1.asMode.ucLaneSet = lane_set;
|
||||||
} else {
|
} else {
|
||||||
if (radeon_encoder->pixel_clock > 165000)
|
if (radeon_encoder->pixel_clock > 165000)
|
||||||
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
||||||
|
@ -767,6 +800,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
|
||||||
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
||||||
if (dig->dig_block)
|
if (dig->dig_block)
|
||||||
args.v2.acConfig.ucEncoderSel = 1;
|
args.v2.acConfig.ucEncoderSel = 1;
|
||||||
|
if (dig_connector->linkb)
|
||||||
|
args.v2.acConfig.ucLinkSel = 1;
|
||||||
|
|
||||||
switch (radeon_encoder->encoder_id) {
|
switch (radeon_encoder->encoder_id) {
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||||
|
@ -792,17 +827,20 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
|
||||||
|
|
||||||
switch (radeon_encoder->encoder_id) {
|
switch (radeon_encoder->encoder_id) {
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
|
/* XXX doesn't really matter which dig encoder we pick as long as it's
|
||||||
|
* not already in use
|
||||||
|
*/
|
||||||
|
if (dig_connector->linkb)
|
||||||
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
|
||||||
|
else
|
||||||
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
|
||||||
if (rdev->flags & RADEON_IS_IGP) {
|
if (rdev->flags & RADEON_IS_IGP) {
|
||||||
if (radeon_encoder->pixel_clock > 165000) {
|
if (radeon_encoder->pixel_clock > 165000) {
|
||||||
args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
|
|
||||||
ATOM_TRANSMITTER_CONFIG_LINKA_B);
|
|
||||||
if (dig_connector->igp_lane_info & 0x3)
|
if (dig_connector->igp_lane_info & 0x3)
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
|
||||||
else if (dig_connector->igp_lane_info & 0xc)
|
else if (dig_connector->igp_lane_info & 0xc)
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
|
||||||
} else {
|
} else {
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
|
|
||||||
if (dig_connector->igp_lane_info & 0x1)
|
if (dig_connector->igp_lane_info & 0x1)
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
||||||
else if (dig_connector->igp_lane_info & 0x2)
|
else if (dig_connector->igp_lane_info & 0x2)
|
||||||
|
@ -812,34 +850,22 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
|
||||||
else if (dig_connector->igp_lane_info & 0x8)
|
else if (dig_connector->igp_lane_info & 0x8)
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (radeon_encoder->pixel_clock > 165000)
|
|
||||||
args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
|
|
||||||
ATOM_TRANSMITTER_CONFIG_LINKA_B |
|
|
||||||
ATOM_TRANSMITTER_CONFIG_LANE_0_7);
|
|
||||||
else {
|
|
||||||
if (dig_connector->linkb)
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
|
||||||
else
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
|
/* Only dig2 encoder can drive LVTMA */
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
|
||||||
if (radeon_encoder->pixel_clock > 165000)
|
|
||||||
args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
|
|
||||||
ATOM_TRANSMITTER_CONFIG_LINKA_B |
|
|
||||||
ATOM_TRANSMITTER_CONFIG_LANE_0_7);
|
|
||||||
else {
|
|
||||||
if (dig_connector->linkb)
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
|
||||||
else
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (radeon_encoder->pixel_clock > 165000)
|
||||||
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
|
||||||
|
|
||||||
|
if (dig_connector->linkb)
|
||||||
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
|
||||||
|
else
|
||||||
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
|
||||||
|
|
||||||
if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
||||||
if (dig->coherent_mode)
|
if (dig->coherent_mode)
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
|
||||||
|
@ -850,99 +876,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
atombios_dig_transmitter_setup_vsemph(struct drm_encoder *encoder, u8 lane_num,
|
|
||||||
u8 lane_set)
|
|
||||||
{
|
|
||||||
struct drm_device *dev = encoder->dev;
|
|
||||||
struct radeon_device *rdev = dev->dev_private;
|
|
||||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
|
||||||
union dig_transmitter_control args;
|
|
||||||
int index = 0, num = 0;
|
|
||||||
uint8_t frev, crev;
|
|
||||||
struct radeon_encoder_atom_dig *dig;
|
|
||||||
struct drm_connector *connector;
|
|
||||||
struct radeon_connector *radeon_connector;
|
|
||||||
struct radeon_connector_atom_dig *dig_connector;
|
|
||||||
|
|
||||||
connector = radeon_get_connector_for_encoder(encoder);
|
|
||||||
if (!connector)
|
|
||||||
return;
|
|
||||||
|
|
||||||
radeon_connector = to_radeon_connector(connector);
|
|
||||||
|
|
||||||
if (!radeon_encoder->enc_priv)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dig = radeon_encoder->enc_priv;
|
|
||||||
|
|
||||||
if (!radeon_connector->con_priv)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dig_connector = radeon_connector->con_priv;
|
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
|
||||||
|
|
||||||
if (ASIC_IS_DCE32(rdev))
|
|
||||||
index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
|
|
||||||
else {
|
|
||||||
switch (radeon_encoder->encoder_id) {
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
|
||||||
|
|
||||||
args.v1.ucAction = ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH;
|
|
||||||
args.v1.asMode.ucLaneSel = lane_num;
|
|
||||||
args.v1.asMode.ucLaneSet = lane_set;
|
|
||||||
|
|
||||||
if (ASIC_IS_DCE32(rdev)) {
|
|
||||||
args.v2.acConfig.fDPConnector = 1;
|
|
||||||
|
|
||||||
if (dig->dig_block)
|
|
||||||
args.v2.acConfig.ucEncoderSel = 1;
|
|
||||||
|
|
||||||
switch (radeon_encoder->encoder_id) {
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
|
||||||
args.v2.acConfig.ucTransmitterSel = 0;
|
|
||||||
num = 0;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
|
||||||
args.v2.acConfig.ucTransmitterSel = 1;
|
|
||||||
num = 1;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
|
||||||
args.v2.acConfig.ucTransmitterSel = 2;
|
|
||||||
num = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
|
|
||||||
|
|
||||||
switch (radeon_encoder->encoder_id) {
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
|
|
||||||
if (dig_connector->linkb)
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
|
||||||
else
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
|
||||||
|
|
||||||
if (ASIC_IS_DCE32(rdev))
|
|
||||||
DRM_INFO("Output UNIPHY%d transmitter VSEMPH setup success\n", num);
|
|
||||||
else
|
|
||||||
DRM_INFO("Output DIG%d transmitter VSEMPH setup success\n", num);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
|
atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
|
||||||
{
|
{
|
||||||
|
@ -1150,13 +1083,33 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
||||||
else
|
else
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
||||||
} else
|
} else {
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
struct drm_connector *connector;
|
||||||
|
struct radeon_connector *radeon_connector;
|
||||||
|
struct radeon_connector_atom_dig *dig_connector;
|
||||||
|
|
||||||
|
connector = radeon_get_connector_for_encoder(encoder);
|
||||||
|
if (!connector)
|
||||||
|
return;
|
||||||
|
radeon_connector = to_radeon_connector(connector);
|
||||||
|
if (!radeon_connector->con_priv)
|
||||||
|
return;
|
||||||
|
dig_connector = radeon_connector->con_priv;
|
||||||
|
|
||||||
|
/* XXX doesn't really matter which dig encoder we pick as long as it's
|
||||||
|
* not already in use
|
||||||
|
*/
|
||||||
|
if (dig_connector->linkb)
|
||||||
|
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
||||||
|
else
|
||||||
|
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||||
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
|
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
|
/* Only dig2 encoder can drive LVTMA */
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||||
|
@ -1259,14 +1212,14 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
/* disable the encoder and transmitter */
|
/* disable the encoder and transmitter */
|
||||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
|
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
|
||||||
atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
|
atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
|
||||||
|
|
||||||
/* setup and enable the encoder and transmitter */
|
/* setup and enable the encoder and transmitter */
|
||||||
atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
|
atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
|
||||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT);
|
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
|
||||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
|
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
|
||||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
|
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_DDI:
|
case ENCODER_OBJECT_ID_INTERNAL_DDI:
|
||||||
atombios_ddia_setup(encoder, ATOM_ENABLE);
|
atombios_ddia_setup(encoder, ATOM_ENABLE);
|
||||||
|
|
|
@ -335,7 +335,7 @@ struct radeon_connector_atom_dig {
|
||||||
bool linkb;
|
bool linkb;
|
||||||
uint16_t uc_i2c_id;
|
uint16_t uc_i2c_id;
|
||||||
struct radeon_i2c_chan *dp_i2c_bus;
|
struct radeon_i2c_chan *dp_i2c_bus;
|
||||||
u8 dpcp[8];
|
u8 dpcd[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radeon_connector {
|
struct radeon_connector {
|
||||||
|
@ -362,7 +362,7 @@ struct radeon_framebuffer {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
|
extern int radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
|
||||||
extern void radeon_dp_getdpcp(struct radeon_connector *connector);
|
extern void radeon_dp_getdpcd(struct radeon_connector *connector);
|
||||||
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
||||||
uint8_t write_byte, uint8_t *read_byte);
|
uint8_t write_byte, uint8_t *read_byte);
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#define AUX_I2C_REPLY_MASK (0x3 << 6)
|
#define AUX_I2C_REPLY_MASK (0x3 << 6)
|
||||||
|
|
||||||
/* AUX CH addresses */
|
/* AUX CH addresses */
|
||||||
#define DP_DPCP_REV 0x0
|
#define DP_DPCD_REV 0x0
|
||||||
|
|
||||||
#define DP_LINK_BW_SET 0x100
|
#define DP_LINK_BW_SET 0x100
|
||||||
# define DP_LINK_BW_1_62 0x06
|
# define DP_LINK_BW_1_62 0x06
|
||||||
|
@ -132,6 +132,8 @@
|
||||||
#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0
|
#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0
|
||||||
#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6
|
#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6
|
||||||
|
|
||||||
|
#define DP_SET_POWER 0x600
|
||||||
|
|
||||||
#define MODE_I2C_START 1
|
#define MODE_I2C_START 1
|
||||||
#define MODE_I2C_WRITE 2
|
#define MODE_I2C_WRITE 2
|
||||||
#define MODE_I2C_READ 4
|
#define MODE_I2C_READ 4
|
||||||
|
|
Loading…
Reference in New Issue