diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_display.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 113 |
1 files changed, 93 insertions, 20 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0a1d4bd65ed..64a008d1449 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -573,24 +573,6 @@ static const char *encoder_names[37] = { "INTERNAL_VCE" }; -static const char *connector_names[15] = { - "Unknown", - "VGA", - "DVI-I", - "DVI-D", - "DVI-A", - "Composite", - "S-video", - "LVDS", - "Component", - "DIN", - "DisplayPort", - "HDMI-A", - "HDMI-B", - "TV", - "eDP", -}; - static const char *hpd_names[6] = { "HPD1", "HPD2", @@ -613,7 +595,7 @@ static void radeon_print_display_setup(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { radeon_connector = to_radeon_connector(connector); DRM_INFO("Connector %d:\n", i); - DRM_INFO(" %s\n", connector_names[connector->connector_type]); + DRM_INFO(" %s\n", drm_get_connector_name(connector)); if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); if (radeon_connector->ddc_bus) { @@ -1243,6 +1225,93 @@ void radeon_update_display_priority(struct radeon_device *rdev) } +/* + * Allocate hdmi structs and determine register offsets + */ +static void radeon_afmt_init(struct radeon_device *rdev) +{ + int i; + + for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++) + rdev->mode_info.afmt[i] = NULL; + + if (ASIC_IS_DCE6(rdev)) { + /* todo */ + } else if (ASIC_IS_DCE4(rdev)) { + /* DCE4/5 has 6 audio blocks tied to DIG encoders */ + /* DCE4.1 has 2 audio blocks tied to DIG encoders */ + rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[0]) { + rdev->mode_info.afmt[0]->offset = EVERGREEN_CRTC0_REGISTER_OFFSET; + rdev->mode_info.afmt[0]->id = 0; + } + rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[1]) { + rdev->mode_info.afmt[1]->offset = EVERGREEN_CRTC1_REGISTER_OFFSET; + rdev->mode_info.afmt[1]->id = 1; + } + if (!ASIC_IS_DCE41(rdev)) { + rdev->mode_info.afmt[2] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[2]) { + rdev->mode_info.afmt[2]->offset = EVERGREEN_CRTC2_REGISTER_OFFSET; + rdev->mode_info.afmt[2]->id = 2; + } + rdev->mode_info.afmt[3] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[3]) { + rdev->mode_info.afmt[3]->offset = EVERGREEN_CRTC3_REGISTER_OFFSET; + rdev->mode_info.afmt[3]->id = 3; + } + rdev->mode_info.afmt[4] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[4]) { + rdev->mode_info.afmt[4]->offset = EVERGREEN_CRTC4_REGISTER_OFFSET; + rdev->mode_info.afmt[4]->id = 4; + } + rdev->mode_info.afmt[5] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[5]) { + rdev->mode_info.afmt[5]->offset = EVERGREEN_CRTC5_REGISTER_OFFSET; + rdev->mode_info.afmt[5]->id = 5; + } + } + } else if (ASIC_IS_DCE3(rdev)) { + /* DCE3.x has 2 audio blocks tied to DIG encoders */ + rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[0]) { + rdev->mode_info.afmt[0]->offset = DCE3_HDMI_OFFSET0; + rdev->mode_info.afmt[0]->id = 0; + } + rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[1]) { + rdev->mode_info.afmt[1]->offset = DCE3_HDMI_OFFSET1; + rdev->mode_info.afmt[1]->id = 1; + } + } else if (ASIC_IS_DCE2(rdev)) { + /* DCE2 has at least 1 routable audio block */ + rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[0]) { + rdev->mode_info.afmt[0]->offset = DCE2_HDMI_OFFSET0; + rdev->mode_info.afmt[0]->id = 0; + } + /* r6xx has 2 routable audio blocks */ + if (rdev->family >= CHIP_R600) { + rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + if (rdev->mode_info.afmt[1]) { + rdev->mode_info.afmt[1]->offset = DCE2_HDMI_OFFSET1; + rdev->mode_info.afmt[1]->id = 1; + } + } + } +} + +static void radeon_afmt_fini(struct radeon_device *rdev) +{ + int i; + + for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++) { + kfree(rdev->mode_info.afmt[i]); + rdev->mode_info.afmt[i] = NULL; + } +} + int radeon_modeset_init(struct radeon_device *rdev) { int i; @@ -1251,7 +1320,7 @@ int radeon_modeset_init(struct radeon_device *rdev) drm_mode_config_init(rdev->ddev); rdev->mode_info.mode_config_initialized = true; - rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs; + rdev->ddev->mode_config.funcs = &radeon_mode_funcs; if (ASIC_IS_DCE5(rdev)) { rdev->ddev->mode_config.max_width = 16384; @@ -1303,6 +1372,9 @@ int radeon_modeset_init(struct radeon_device *rdev) /* initialize hpd */ radeon_hpd_init(rdev); + /* setup afmt */ + radeon_afmt_init(rdev); + /* Initialize power management */ radeon_pm_init(rdev); @@ -1319,6 +1391,7 @@ void radeon_modeset_fini(struct radeon_device *rdev) radeon_pm_fini(rdev); if (rdev->mode_info.mode_config_initialized) { + radeon_afmt_fini(rdev); drm_kms_helper_poll_fini(rdev->ddev); radeon_hpd_fini(rdev); drm_mode_config_cleanup(rdev->ddev); |