Commit ac89af1e authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms/atom: move dig phy init out of modesetting

It only needs to be called once at startup, not for every
modeset.
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent bb92091a
...@@ -923,6 +923,9 @@ int radeon_resume_kms(struct drm_device *dev) ...@@ -923,6 +923,9 @@ int radeon_resume_kms(struct drm_device *dev)
radeon_fbdev_set_suspend(rdev, 0); radeon_fbdev_set_suspend(rdev, 0);
console_unlock(); console_unlock();
/* init dig PHYs */
if (rdev->is_atom_bios)
radeon_atom_encoder_init(rdev);
/* reset hpd state */ /* reset hpd state */
radeon_hpd_init(rdev); radeon_hpd_init(rdev);
/* blat the mode back in */ /* blat the mode back in */
......
...@@ -1345,6 +1345,11 @@ int radeon_modeset_init(struct radeon_device *rdev) ...@@ -1345,6 +1345,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
if (!ret) { if (!ret) {
return ret; return ret;
} }
/* init dig PHYs */
if (rdev->is_atom_bios)
radeon_atom_encoder_init(rdev);
/* initialize hpd */ /* initialize hpd */
radeon_hpd_init(rdev); radeon_hpd_init(rdev);
......
...@@ -229,6 +229,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) ...@@ -229,6 +229,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
return NULL; return NULL;
} }
static struct drm_connector *
radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
radeon_connector = to_radeon_connector(connector);
if (radeon_encoder->devices & radeon_connector->devices)
return connector;
}
return NULL;
}
struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder) struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -928,7 +944,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t ...@@ -928,7 +944,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct drm_connector *connector;
union dig_transmitter_control args; union dig_transmitter_control args;
int index = 0; int index = 0;
uint8_t frev, crev; uint8_t frev, crev;
...@@ -939,6 +955,11 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t ...@@ -939,6 +955,11 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
int connector_object_id = 0; int connector_object_id = 0;
int igp_lane_info = 0; int igp_lane_info = 0;
if (action == ATOM_TRANSMITTER_ACTION_INIT)
connector = radeon_get_connector_for_encoder_init(encoder);
else
connector = radeon_get_connector_for_encoder(encoder);
if (connector) { if (connector) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector = struct radeon_connector_atom_dig *dig_connector =
...@@ -1180,7 +1201,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, ...@@ -1180,7 +1201,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
union external_encoder_control args; union external_encoder_control args;
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct drm_connector *connector;
int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
u8 frev, crev; u8 frev, crev;
int dp_clock = 0; int dp_clock = 0;
...@@ -1189,6 +1210,11 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, ...@@ -1189,6 +1210,11 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
int bpc = 8; int bpc = 8;
if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
connector = radeon_get_connector_for_encoder_init(encoder);
else
connector = radeon_get_connector_for_encoder(encoder);
if (connector) { if (connector) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector = struct radeon_connector_atom_dig *dig_connector =
...@@ -1771,6 +1797,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) ...@@ -1771,6 +1797,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
return 1; return 1;
} }
/* This only needs to be called once at startup */
void
radeon_atom_encoder_init(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct drm_encoder *encoder;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
break;
default:
break;
}
if (ext_encoder && ASIC_IS_DCE41(rdev))
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
}
}
static void static void
radeon_atom_encoder_mode_set(struct drm_encoder *encoder, radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode, struct drm_display_mode *mode,
...@@ -1807,8 +1861,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1807,8 +1861,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
/* setup and enable the encoder */ /* setup and enable the encoder */
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
/* init and enable the transmitter */ /* enable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
} else { } else {
/* disable the encoder and transmitter */ /* disable the encoder and transmitter */
...@@ -1817,7 +1870,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1817,7 +1870,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
/* setup and enable the encoder and transmitter */ /* setup and enable the encoder and transmitter */
atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
} }
...@@ -1842,12 +1894,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1842,12 +1894,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
} }
if (ext_encoder) { if (ext_encoder) {
if (ASIC_IS_DCE41(rdev)) { if (ASIC_IS_DCE41(rdev))
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
atombios_external_encoder_setup(encoder, ext_encoder, atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
} else else
atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
} }
......
...@@ -479,6 +479,7 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder, ...@@ -479,6 +479,7 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder,
extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode);
extern void radeon_atom_encoder_init(struct radeon_device *rdev);
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t lane_num, int action, uint8_t lane_num,
uint8_t lane_set); uint8_t lane_set);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment