Skip to content

Commit

Permalink
drm/radeon/kms/atom: move dig phy init out of modesetting
Browse files Browse the repository at this point in the history
It only needs to be called once at startup, not for every
modeset.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Alex Deucher authored and Dave Airlie committed May 23, 2011
1 parent bb92091 commit ac89af1
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/radeon/radeon_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,9 @@ int radeon_resume_kms(struct drm_device *dev)
radeon_fbdev_set_suspend(rdev, 0);
console_unlock();

/* init dig PHYs */
if (rdev->is_atom_bios)
radeon_atom_encoder_init(rdev);
/* reset hpd state */
radeon_hpd_init(rdev);
/* blat the mode back in */
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/radeon/radeon_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
if (!ret) {
return ret;
}

/* init dig PHYs */
if (rdev->is_atom_bios)
radeon_atom_encoder_init(rdev);

/* initialize hpd */
radeon_hpd_init(rdev);

Expand Down
68 changes: 59 additions & 9 deletions drivers/gpu/drm/radeon/radeon_encoders.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
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_device *dev = encoder->dev;
Expand Down Expand Up @@ -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_encoder *radeon_encoder = to_radeon_encoder(encoder);
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;
int index = 0;
uint8_t frev, crev;
Expand All @@ -939,6 +955,11 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
int connector_object_id = 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) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector =
Expand Down Expand Up @@ -1180,7 +1201,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
union external_encoder_control args;
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
struct drm_connector *connector;
int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
u8 frev, crev;
int dp_clock = 0;
Expand All @@ -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;
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) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector =
Expand Down Expand Up @@ -1771,6 +1797,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
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
radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
Expand Down Expand Up @@ -1807,8 +1861,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
/* setup and enable the encoder */
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);

/* init and enable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
/* enable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
} else {
/* disable the encoder and transmitter */
Expand All @@ -1817,7 +1870,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,

/* setup and enable the encoder and transmitter */
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_ENABLE, 0, 0);
}
Expand All @@ -1842,12 +1894,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
}

if (ext_encoder) {
if (ASIC_IS_DCE41(rdev)) {
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
if (ASIC_IS_DCE41(rdev))
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
} else
else
atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/radeon_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 radeon_atom_encoder_init(struct radeon_device *rdev);
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t lane_num,
uint8_t lane_set);
Expand Down

0 comments on commit ac89af1

Please sign in to comment.