From 16613743adaf7989151da2e58fef2a71624875ab Mon Sep 17 00:00:00 2001 From: Glenn Kennard Date: Sat, 13 Dec 2014 03:32:37 +0100 Subject: drm/radeon: evergreen/cayman indirect draw support (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the necessary set of commands to support OpenGL indirect draw calls on evergreen/cayman devices that do not have VM. v2: agd5f: fix warning on 32-bit Reviewed-by: Marek Olšák Signed-off-by: Glenn Kennard Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_cs.c | 76 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_drv.c | 3 +- 2 files changed, 78 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 924b1b7ab455..c9e0fbbf76a3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -83,6 +83,7 @@ struct evergreen_cs_track { u32 htile_offset; u32 htile_surface; struct radeon_bo *htile_bo; + unsigned long indirect_draw_buffer_size; }; static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) @@ -1896,6 +1897,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, } break; } + case PACKET3_INDEX_BUFFER_SIZE: + { + if (pkt->count != 0) { + DRM_ERROR("bad INDEX_BUFFER_SIZE\n"); + return -EINVAL; + } + break; + } case PACKET3_DRAW_INDEX: { uint64_t offset; @@ -2006,6 +2015,67 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, return r; } break; + case PACKET3_SET_BASE: + { + /* + DW 1 HEADER Header of the packet. Shader_Type in bit 1 of the Header will correspond to the shader type of the Load, see Type-3 Packet. + 2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies which base address is specified in the last two DWs. + 0001: DX11 Draw_Index_Indirect Patch Table Base: Base address for Draw_Index_Indirect data. + 3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned Address. Bits [2:0] - Reserved + 4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits of Address [47:32] + */ + if (pkt->count != 2) { + DRM_ERROR("bad SET_BASE\n"); + return -EINVAL; + } + + /* currently only supporting setting indirect draw buffer base address */ + if (idx_value != 1) { + DRM_ERROR("bad SET_BASE\n"); + return -EINVAL; + } + + r = radeon_cs_packet_next_reloc(p, &reloc, 0); + if (r) { + DRM_ERROR("bad SET_BASE\n"); + return -EINVAL; + } + + track->indirect_draw_buffer_size = radeon_bo_size(reloc->robj); + + ib[idx+1] = reloc->gpu_offset; + ib[idx+2] = upper_32_bits(reloc->gpu_offset) & 0xff; + + break; + } + case PACKET3_DRAW_INDIRECT: + case PACKET3_DRAW_INDEX_INDIRECT: + { + u64 size = pkt->opcode == PACKET3_DRAW_INDIRECT ? 16 : 20; + + /* + DW 1 HEADER + 2 DATA_OFFSET Bits [31:0] + byte aligned offset where the required data structure starts. Bits 1:0 are zero + 3 DRAW_INITIATOR Draw Initiator Register. Written to the VGT_DRAW_INITIATOR register for the assigned context + */ + if (pkt->count != 1) { + DRM_ERROR("bad DRAW_INDIRECT\n"); + return -EINVAL; + } + + if (idx_value + size > track->indirect_draw_buffer_size) { + dev_warn(p->dev, "DRAW_INDIRECT buffer too small %u + %llu > %lu\n", + idx_value, size, track->indirect_draw_buffer_size); + return -EINVAL; + } + + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + } case PACKET3_DISPATCH_DIRECT: if (pkt->count != 3) { DRM_ERROR("bad DISPATCH_DIRECT\n"); @@ -3243,7 +3313,13 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev, switch (pkt->opcode) { case PACKET3_NOP: + break; case PACKET3_SET_BASE: + if (idx_value != 1) { + DRM_ERROR("bad SET_BASE"); + return -EINVAL; + } + break; case PACKET3_CLEAR_STATE: case PACKET3_INDEX_BUFFER_SIZE: case PACKET3_DISPATCH_DIRECT: diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4f50fb0e3d93..5d684beb48d3 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -88,9 +88,10 @@ * 2.39.0 - Add INFO query for number of active CUs * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting * CS to GPU on >= r600 + * 2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing support */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 40 +#define KMS_DRIVER_MINOR 41 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- cgit v1.2.3 From a35a4b2b1818239b54e12b60b6534d5d523eebfc Mon Sep 17 00:00:00 2001 From: Oleg Chernovskiy Date: Mon, 8 Dec 2014 00:10:44 +0300 Subject: add common fan control asic callbacks Adds 4 callbacks for managing fan state/speed * fan_ctrl_set_mode - manages fan control mode (nonzero == manual) * fan_ctrl_get_mode - queries fan control mode * set_fan_speed_percent - manages fan speed as percentage value * get_fan_speed_percent - queries fan speed as percentage value Signed-off-by: Oleg Chernovskiy Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 54529b837afa..4195e6cc4e52 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1967,6 +1967,10 @@ struct radeon_asic { bool (*vblank_too_short)(struct radeon_device *rdev); void (*powergate_uvd)(struct radeon_device *rdev, bool gate); void (*enable_bapm)(struct radeon_device *rdev, bool enable); + void (*fan_ctrl_set_mode)(struct radeon_device *rdev, u32 mode); + u32 (*fan_ctrl_get_mode)(struct radeon_device *rdev); + int (*set_fan_speed_percent)(struct radeon_device *rdev, u32 speed); + int (*get_fan_speed_percent)(struct radeon_device *rdev, u32 *speed); } dpm; /* pageflipping */ struct { -- cgit v1.2.3 From 99736703a9beedcb9afc69cde8e13846c713a4a3 Mon Sep 17 00:00:00 2001 From: Oleg Chernovskiy Date: Mon, 8 Dec 2014 00:10:45 +0300 Subject: drm/radeon: add hwmon interface for managing fan pwm (v2) This adds percent-based fan control. Attributes (I hope) follow the sysfs-interface specification: * pwm1 - fan speed query/manage * pwm1_max, pwm1_min - min/max values for fan pwm (constant) * pwm1_enable - fan control query/manage (enable/disable) (There is no rpm-based control for now) v2: agd5f: fix formatting Signed-off-by: Oleg Chernovskiy Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_pm.c | 131 ++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f7da8fe96a66..91e1bd246cad 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -24,6 +24,7 @@ #include "radeon.h" #include "avivod.h" #include "atom.h" +#include "r600_dpm.h" #include #include #include @@ -554,6 +555,96 @@ fail: return count; } +static ssize_t radeon_hwmon_get_pwm1_enable(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct radeon_device *rdev = dev_get_drvdata(dev); + u32 pwm_mode = 0; + + if (rdev->asic->dpm.fan_ctrl_get_mode) + pwm_mode = rdev->asic->dpm.fan_ctrl_get_mode(rdev); + + /* never 0 (full-speed), fuse or smc-controlled always */ + return sprintf(buf, "%i\n", pwm_mode == FDO_PWM_MODE_STATIC ? 1 : 2); +} + +static ssize_t radeon_hwmon_set_pwm1_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct radeon_device *rdev = dev_get_drvdata(dev); + int err; + int value; + + if(!rdev->asic->dpm.fan_ctrl_set_mode) + return -EINVAL; + + err = kstrtoint(buf, 10, &value); + if (err) + return err; + + switch(value) { + case 1: /* manual, percent-based */ + rdev->asic->dpm.fan_ctrl_set_mode(rdev, FDO_PWM_MODE_STATIC); + break; + default: /* disable */ + rdev->asic->dpm.fan_ctrl_set_mode(rdev, 0); + break; + } + + return count; +} + +static ssize_t radeon_hwmon_get_pwm1_min(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%i\n", 0); +} + +static ssize_t radeon_hwmon_get_pwm1_max(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%i\n", 100); /* pwm uses percent-based fan-control */ +} + +static ssize_t radeon_hwmon_set_pwm1(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct radeon_device *rdev = dev_get_drvdata(dev); + int err; + u32 value; + + err = kstrtou32(buf, 10, &value); + if (err) + return err; + + err = rdev->asic->dpm.set_fan_speed_percent(rdev, value); + if (err) + return err; + + return count; +} + +static ssize_t radeon_hwmon_get_pwm1(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct radeon_device *rdev = dev_get_drvdata(dev); + int err; + u32 speed; + + err = rdev->asic->dpm.get_fan_speed_percent(rdev, &speed); + if (err) + return err; + + return sprintf(buf, "%i\n", speed); +} + static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, radeon_get_dpm_state, radeon_set_dpm_state); @@ -601,11 +692,20 @@ static ssize_t radeon_hwmon_show_temp_thresh(struct device *dev, static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 1); +static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, radeon_hwmon_get_pwm1, radeon_hwmon_set_pwm1, 0); +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, radeon_hwmon_get_pwm1_enable, radeon_hwmon_set_pwm1_enable, 0); +static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO, radeon_hwmon_get_pwm1_min, NULL, 0); +static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO, radeon_hwmon_get_pwm1_max, NULL, 0); + static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_min.dev_attr.attr, + &sensor_dev_attr_pwm1_max.dev_attr.attr, NULL }; @@ -614,6 +714,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, { struct device *dev = container_of(kobj, struct device, kobj); struct radeon_device *rdev = dev_get_drvdata(dev); + umode_t effective_mode = attr->mode; /* Skip limit attributes if DPM is not enabled */ if (rdev->pm.pm_method != PM_METHOD_DPM && @@ -621,7 +722,35 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr)) return 0; - return attr->mode; + /* Skip fan attributes if fan is not present */ + if (rdev->pm.no_fan && + (attr == &sensor_dev_attr_pwm1.dev_attr.attr || + attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr || + attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || + attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) + return 0; + + /* mask fan attributes if we have no bindings for this asic to expose */ + if ((!rdev->asic->dpm.get_fan_speed_percent && + attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't query fan */ + (!rdev->asic->dpm.fan_ctrl_get_mode && + attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't query state */ + effective_mode &= ~S_IRUGO; + + if ((!rdev->asic->dpm.set_fan_speed_percent && + attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't manage fan */ + (!rdev->asic->dpm.fan_ctrl_set_mode && + attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */ + effective_mode &= ~S_IWUSR; + + /* hide max/min values if we can't both query and manage the fan */ + if ((!rdev->asic->dpm.set_fan_speed_percent && + !rdev->asic->dpm.get_fan_speed_percent) && + (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || + attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) + return 0; + + return effective_mode; } static const struct attribute_group hwmon_attrgroup = { -- cgit v1.2.3 From 36689e57502bd4de86abe5e55fff60b974416a52 Mon Sep 17 00:00:00 2001 From: Oleg Chernovskiy Date: Mon, 8 Dec 2014 00:10:46 +0300 Subject: drm/radeon: bind fan control on CI cards to hwmon interface (v2) This adds a possibility to control fan on CI parts via exported hwmon variables. Note that automatic ucode fan management pauses if you choose to enable manual fan control. Use with caution! v2: agd5f: fix formatting, squash in: minor fix for pwm1_enable exposed value Track smc control in addition to fan mode This fixes pwm1_enable being constantly set to 1 because of enabled smc control also handle the case where smc fan control is disabled. Signed-off-by: Oleg Chernovskiy Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 53 +++++++++++++++++++++++++++++------- drivers/gpu/drm/radeon/ci_dpm.h | 1 + drivers/gpu/drm/radeon/radeon_asic.c | 4 +++ drivers/gpu/drm/radeon/radeon_asic.h | 7 +++++ 4 files changed, 55 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index f373a81ba3d5..9d4699b946d7 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -187,6 +187,9 @@ static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate); static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev, PPSMC_Msg msg, u32 parameter); +static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev); +static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev); + static struct ci_power_info *ci_get_pi(struct radeon_device *rdev) { struct ci_power_info *pi = rdev->pm.dpm.priv; @@ -1043,22 +1046,24 @@ static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) return -EINVAL; } + pi->fan_is_controlled_by_smc = true; return 0; } -#if 0 static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) { PPSMC_Result ret; + struct ci_power_info *pi = ci_get_pi(rdev); ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl); - if (ret == PPSMC_Result_OK) + if (ret == PPSMC_Result_OK) { + pi->fan_is_controlled_by_smc = false; return 0; - else + } else return -EINVAL; } -static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, +int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, u32 *speed) { u32 duty, duty100; @@ -1083,21 +1088,22 @@ static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, return 0; } -static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, +int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, u32 speed) { u32 tmp; u32 duty, duty100; u64 tmp64; + struct ci_power_info *pi = ci_get_pi(rdev); if (rdev->pm.no_fan) return -ENOENT; - if (speed > 100) + if (pi->fan_is_controlled_by_smc) return -EINVAL; - if (rdev->pm.dpm.fan.ucode_fan_control) - ci_fan_ctrl_stop_smc_fan_control(rdev); + if (speed > 100) + return -EINVAL; duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; @@ -1112,11 +1118,38 @@ static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, tmp |= FDO_STATIC_DUTY(duty); WREG32_SMC(CG_FDO_CTRL0, tmp); - ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); - return 0; } +void ci_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode) +{ + if (mode) { + /* stop auto-manage */ + if (rdev->pm.dpm.fan.ucode_fan_control) + ci_fan_ctrl_stop_smc_fan_control(rdev); + ci_fan_ctrl_set_static_mode(rdev, mode); + } else { + /* restart auto-manage */ + if (rdev->pm.dpm.fan.ucode_fan_control) + ci_thermal_start_smc_fan_control(rdev); + else + ci_fan_ctrl_set_default_mode(rdev); + } +} + +u32 ci_fan_ctrl_get_mode(struct radeon_device *rdev) +{ + struct ci_power_info *pi = ci_get_pi(rdev); + u32 tmp; + + if (pi->fan_is_controlled_by_smc) + return 0; + + tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; + return (tmp >> FDO_PWM_MODE_SHIFT); +} + +#if 0 static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, u32 *speed) { diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h index 84e3d3bcf9f3..723220ffbea2 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.h +++ b/drivers/gpu/drm/radeon/ci_dpm.h @@ -291,6 +291,7 @@ struct ci_power_info { struct ci_ps requested_ps; /* fan control */ bool fan_ctrl_is_in_default_mode; + bool fan_is_controlled_by_smc; u32 t_min; u32 fan_ctrl_default_mode; }; diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 121aff6a3b41..c5ec52388144 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2118,6 +2118,10 @@ static struct radeon_asic ci_asic = { .force_performance_level = &ci_dpm_force_performance_level, .vblank_too_short = &ci_dpm_vblank_too_short, .powergate_uvd = &ci_dpm_powergate_uvd, + .fan_ctrl_set_mode = &ci_fan_ctrl_set_mode, + .fan_ctrl_get_mode = &ci_fan_ctrl_get_mode, + .get_fan_speed_percent = &ci_fan_ctrl_get_fan_speed_percent, + .set_fan_speed_percent = &ci_fan_ctrl_set_fan_speed_percent, }, .pflip = { .page_flip = &evergreen_page_flip, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 2a45d548d5ec..f918a8b0f45b 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -861,6 +861,13 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev, bool ci_dpm_vblank_too_short(struct radeon_device *rdev); void ci_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); +int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, + u32 *speed); +int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, + u32 speed); +u32 ci_fan_ctrl_get_mode(struct radeon_device *rdev); +void ci_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode); + int kv_dpm_init(struct radeon_device *rdev); int kv_dpm_enable(struct radeon_device *rdev); int kv_dpm_late_enable(struct radeon_device *rdev); -- cgit v1.2.3 From 5e8150a6876a2a7784b0029506c90ab3d26c9a41 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 7 Jan 2015 15:29:06 -0500 Subject: drm/radeon: bind fan control on SI cards to hwmon interface This adds a possibility to control fan on SI parts via exported hwmon variables. Note that automatic ucode fan management pauses if you choose to enable manual fan control. Use with caution! Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_asic.c | 4 +++ drivers/gpu/drm/radeon/radeon_asic.h | 6 ++++ drivers/gpu/drm/radeon/si_dpm.c | 65 ++++++++++++++++++++++++++++-------- drivers/gpu/drm/radeon/si_dpm.h | 1 + 4 files changed, 62 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index c5ec52388144..7c6e1930fa38 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1953,6 +1953,10 @@ static struct radeon_asic si_asic = { .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level, .force_performance_level = &si_dpm_force_performance_level, .vblank_too_short = &ni_dpm_vblank_too_short, + .fan_ctrl_set_mode = &si_fan_ctrl_set_mode, + .fan_ctrl_get_mode = &si_fan_ctrl_get_mode, + .get_fan_speed_percent = &si_fan_ctrl_get_fan_speed_percent, + .set_fan_speed_percent = &si_fan_ctrl_set_fan_speed_percent, }, .pflip = { .page_flip = &evergreen_page_flip, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f918a8b0f45b..5142bc97f6b6 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -744,6 +744,12 @@ void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, struct seq_file *m); int si_dpm_force_performance_level(struct radeon_device *rdev, enum radeon_dpm_forced_level level); +int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, + u32 *speed); +int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, + u32 speed); +u32 si_fan_ctrl_get_mode(struct radeon_device *rdev); +void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode); /* DCE8 - CIK */ void dce8_bandwidth_update(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index eff8a6444956..3cde272f82b2 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -1756,6 +1756,9 @@ static int si_calculate_sclk_params(struct radeon_device *rdev, u32 engine_clock, SISLANDS_SMC_SCLK_VALUE *sclk); +static void si_thermal_start_smc_fan_control(struct radeon_device *rdev); +static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev); + static struct si_power_info *si_get_pi(struct radeon_device *rdev) { struct si_power_info *pi = rdev->pm.dpm.priv; @@ -6012,36 +6015,46 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev) static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) { + struct si_power_info *si_pi = si_get_pi(rdev); PPSMC_Result ret; ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl); - if (ret == PPSMC_Result_OK) + if (ret == PPSMC_Result_OK) { + si_pi->fan_is_controlled_by_smc = true; return 0; - else + } else { return -EINVAL; + } } static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) { + struct si_power_info *si_pi = si_get_pi(rdev); PPSMC_Result ret; ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl); - if (ret == PPSMC_Result_OK) + + if (ret == PPSMC_Result_OK) { + si_pi->fan_is_controlled_by_smc = false; return 0; - else + } else { return -EINVAL; + } } -#if 0 -static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, - u32 *speed) +int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, + u32 *speed) { + struct si_power_info *si_pi = si_get_pi(rdev); u32 duty, duty100; u64 tmp64; if (rdev->pm.no_fan) return -ENOENT; + if (si_pi->fan_is_controlled_by_smc) + return -EINVAL; + duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; duty = (RREG32(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT; @@ -6058,8 +6071,8 @@ static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, return 0; } -static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, - u32 speed) +int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, + u32 speed) { u32 tmp; u32 duty, duty100; @@ -6071,9 +6084,6 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, if (speed > 100) return -EINVAL; - if (rdev->pm.dpm.fan.ucode_fan_control) - si_fan_ctrl_stop_smc_fan_control(rdev); - duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; if (duty100 == 0) @@ -6087,11 +6097,38 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, tmp |= FDO_STATIC_DUTY(duty); WREG32(CG_FDO_CTRL0, tmp); - si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); - return 0; } +void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode) +{ + if (mode) { + /* stop auto-manage */ + if (rdev->pm.dpm.fan.ucode_fan_control) + si_fan_ctrl_stop_smc_fan_control(rdev); + si_fan_ctrl_set_static_mode(rdev, mode); + } else { + /* restart auto-manage */ + if (rdev->pm.dpm.fan.ucode_fan_control) + si_thermal_start_smc_fan_control(rdev); + else + si_fan_ctrl_set_default_mode(rdev); + } +} + +u32 si_fan_ctrl_get_mode(struct radeon_device *rdev) +{ + struct si_power_info *si_pi = si_get_pi(rdev); + u32 tmp; + + if (si_pi->fan_is_controlled_by_smc) + return 0; + + tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; + return (tmp >> FDO_PWM_MODE_SHIFT); +} + +#if 0 static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, u32 *speed) { diff --git a/drivers/gpu/drm/radeon/si_dpm.h b/drivers/gpu/drm/radeon/si_dpm.h index d16bb1b5f10f..1032a68be792 100644 --- a/drivers/gpu/drm/radeon/si_dpm.h +++ b/drivers/gpu/drm/radeon/si_dpm.h @@ -202,6 +202,7 @@ struct si_power_info { bool fan_ctrl_is_in_default_mode; u32 t_min; u32 fan_ctrl_default_mode; + bool fan_is_controlled_by_smc; }; #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 -- cgit v1.2.3 From 47fd97ca739ee6636da241b796222ca0c2aac8db Mon Sep 17 00:00:00 2001 From: Oleg Chernovskiy Date: Sat, 17 Jan 2015 21:10:39 +0300 Subject: fixes for SI fan handling Added temperature values to SMC payload. Fan mode check moved check to proper place. Signed-off-by: Oleg Chernovskiy Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si_dpm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 3cde272f82b2..80e29448d363 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -5976,6 +5976,10 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev) slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + fan_table.temp_min = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100); + fan_table.temp_med = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100); + fan_table.temp_max = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100); + fan_table.slope1 = cpu_to_be16(slope1); fan_table.slope2 = cpu_to_be16(slope2); @@ -6045,16 +6049,12 @@ static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, u32 *speed) { - struct si_power_info *si_pi = si_get_pi(rdev); u32 duty, duty100; u64 tmp64; if (rdev->pm.no_fan) return -ENOENT; - if (si_pi->fan_is_controlled_by_smc) - return -EINVAL; - duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; duty = (RREG32(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT; @@ -6074,6 +6074,7 @@ int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, u32 speed) { + struct si_power_info *si_pi = si_get_pi(rdev); u32 tmp; u32 duty, duty100; u64 tmp64; @@ -6081,6 +6082,9 @@ int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, if (rdev->pm.no_fan) return -ENOENT; + if (si_pi->fan_is_controlled_by_smc) + return -EINVAL; + if (speed > 100) return -EINVAL; -- cgit v1.2.3 From de5670c2204f3456102568f164d568a9c487af7c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 18 Jan 2015 11:44:40 -0500 Subject: drm/radeon: enable smc fan control on SI Working now with Oleg's last round of fixes. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si_dpm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 80e29448d363..8e36c24b995d 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -6953,7 +6953,6 @@ int si_dpm_init(struct radeon_device *rdev) rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; si_pi->fan_ctrl_is_in_default_mode = true; - rdev->pm.dpm.fan.ucode_fan_control = false; return 0; } -- cgit v1.2.3 From 0554309e1938a72b2917691d3681c0e0e48311d9 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Tue, 13 Jan 2015 20:09:27 +0100 Subject: drm/radeon/radeon_i2c: Remove unused function Remove the function radeon_best_encoder() that is not used anywhere. This was partially found by using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_i2c.c | 5 ----- drivers/gpu/drm/radeon/radeon_mode.h | 2 -- 2 files changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index add622008407..9590bcd321c0 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -1048,11 +1048,6 @@ struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev, return NULL; } -struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) -{ - return NULL; -} - void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, u8 slave_addr, u8 addr, diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 390db897f322..403e733f3002 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -745,8 +745,6 @@ extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connec extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux); -extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); - extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, struct radeon_atom_ss *ss, int id); -- cgit v1.2.3 From 089e746be45d10754498380881211589cc98e1c5 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Tue, 13 Jan 2015 20:02:03 +0100 Subject: drm/radeon/radeon_fb: Remove unused function Remove the function radeon_fbdev_total_size() that is not used anywhere. This was partially found by using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_fb.c | 10 ---------- drivers/gpu/drm/radeon/radeon_mode.h | 1 - 2 files changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 29b9220ec399..ab4adf9c5a63 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -419,16 +419,6 @@ void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state) fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state); } -int radeon_fbdev_total_size(struct radeon_device *rdev) -{ - struct radeon_bo *robj; - int size = 0; - - robj = gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj); - size += radeon_bo_size(robj); - return size; -} - bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) { if (robj == gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj)) diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 403e733f3002..5135d02b7c1e 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -923,7 +923,6 @@ void dce8_program_fmt(struct drm_encoder *encoder); int radeon_fbdev_init(struct radeon_device *rdev); void radeon_fbdev_fini(struct radeon_device *rdev); void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state); -int radeon_fbdev_total_size(struct radeon_device *rdev); bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); void radeon_fb_output_poll_changed(struct radeon_device *rdev); -- cgit v1.2.3 From bcd705a0defb7a7ccdb2d9bdaa8719b166879ab8 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Sun, 11 Jan 2015 14:17:19 +0100 Subject: gpu: drm: radeon: radeon_object: Remove unused function Remove the function radeon_bo_fbdev_mmap() that is not used anywhere. This was partially found by using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_object.c | 6 ------ drivers/gpu/drm/radeon/radeon_object.h | 2 -- 2 files changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 86fc56434b28..1d955776f4d0 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -576,12 +576,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev, return 0; } -int radeon_bo_fbdev_mmap(struct radeon_bo *bo, - struct vm_area_struct *vma) -{ - return ttm_fbdev_mmap(vma, &bo->tbo); -} - int radeon_bo_get_surface_reg(struct radeon_bo *bo) { struct radeon_device *rdev = bo->rdev; diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 3b0b377f76cb..d8d295ee7c12 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -143,8 +143,6 @@ extern void radeon_bo_fini(struct radeon_device *rdev); extern int radeon_bo_list_validate(struct radeon_device *rdev, struct ww_acquire_ctx *ticket, struct list_head *head, int ring); -extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, - struct vm_area_struct *vma); extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, u32 tiling_flags, u32 pitch); extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo, -- cgit v1.2.3 From 64e580447f063fce4f4ed0f21b01bec979a3ed7a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:15:46 -0500 Subject: drm/radeon: comment out some currently unused ci dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 4 ++++ drivers/gpu/drm/radeon/ci_smc.c | 2 ++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 9d4699b946d7..bcd2f1fe803f 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -1731,10 +1731,12 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev, return 0; } +#if 0 static int ci_set_boot_state(struct radeon_device *rdev) { return ci_enable_sclk_mclk_dpm(rdev, false); } +#endif static u32 ci_get_average_sclk_freq(struct radeon_device *rdev) { @@ -5376,10 +5378,12 @@ int ci_dpm_set_power_state(struct radeon_device *rdev) return 0; } +#if 0 void ci_dpm_reset_asic(struct radeon_device *rdev) { ci_set_boot_state(rdev); } +#endif void ci_dpm_display_configuration_changed(struct radeon_device *rdev) { diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c index e78bcad7a43e..35c6f648ba04 100644 --- a/drivers/gpu/drm/radeon/ci_smc.c +++ b/drivers/gpu/drm/radeon/ci_smc.c @@ -184,6 +184,7 @@ PPSMC_Result ci_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg) return (PPSMC_Result)tmp; } +#if 0 PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev) { u32 tmp; @@ -201,6 +202,7 @@ PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev) return PPSMC_Result_OK; } +#endif int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit) { -- cgit v1.2.3 From 9876913179cbfa3440bb010fbc8825c8c4467a47 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:18:32 -0500 Subject: drm/radeon: comment out some currently unused si dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si_dpm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 8e36c24b995d..7be11651b7e6 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -3362,11 +3362,13 @@ int si_dpm_force_performance_level(struct radeon_device *rdev, return 0; } +#if 0 static int si_set_boot_state(struct radeon_device *rdev) { return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ? 0 : -EINVAL; } +#endif static int si_set_sw_state(struct radeon_device *rdev) { @@ -6579,13 +6581,14 @@ void si_dpm_post_set_power_state(struct radeon_device *rdev) ni_update_current_ps(rdev, new_ps); } - +#if 0 void si_dpm_reset_asic(struct radeon_device *rdev) { si_restrict_performance_levels_before_switch(rdev); si_disable_ulv(rdev); si_set_boot_state(rdev); } +#endif void si_dpm_display_configuration_changed(struct radeon_device *rdev) { -- cgit v1.2.3 From dafc519db3ee0ee000b09d3bdd2fcde7855db271 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:20:02 -0500 Subject: drm/radeon: comment out some currently unused kv dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/kv_dpm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index e3e9c10cfba9..c5eb286517a8 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -1925,6 +1925,7 @@ void kv_dpm_setup_asic(struct radeon_device *rdev) kv_init_sclk_t(rdev); } +#if 0 void kv_dpm_reset_asic(struct radeon_device *rdev) { struct kv_power_info *pi = kv_get_pi(rdev); @@ -1945,6 +1946,7 @@ void kv_dpm_reset_asic(struct radeon_device *rdev) kv_set_enabled_level(rdev, pi->graphics_boot_level); } } +#endif //XXX use sumo_dpm_display_configuration_changed -- cgit v1.2.3 From de6267d0a6b60c7c3e189f5c7200e310d6372de4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:26:31 -0500 Subject: drm/radeon: comment out some currently unused ni dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ni_dpm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 6d2f16cf2c1c..7bc9f8d9804a 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -3862,11 +3862,13 @@ void ni_dpm_post_set_power_state(struct radeon_device *rdev) ni_update_current_ps(rdev, new_ps); } +#if 0 void ni_dpm_reset_asic(struct radeon_device *rdev) { ni_restrict_performance_levels_before_switch(rdev); rv770_set_boot_state(rdev); } +#endif union power_info { struct _ATOM_POWERPLAY_INFO info; -- cgit v1.2.3 From 7ff96f9dd26e7336b780426da26ee1367c97cffb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:31:38 -0500 Subject: drm/radeon: comment out some currently unused btc dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/btc_dpm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 0b2929de9f41..db08f17be76b 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -2277,6 +2277,7 @@ static void btc_update_requested_ps(struct radeon_device *rdev, eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps; } +#if 0 void btc_dpm_reset_asic(struct radeon_device *rdev) { rv770_restrict_performance_levels_before_switch(rdev); @@ -2284,6 +2285,7 @@ void btc_dpm_reset_asic(struct radeon_device *rdev) btc_set_boot_state_timing(rdev); rv770_set_boot_state(rdev); } +#endif int btc_dpm_pre_set_power_state(struct radeon_device *rdev) { -- cgit v1.2.3 From 6421d6128a92fa71d8cff8e75053c29846c53bd6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:33:44 -0500 Subject: drm/radeon: comment out some currently unused tn dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/trinity_dpm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index b4ec5c4e7969..38dacb7a3689 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1269,6 +1269,7 @@ void trinity_dpm_setup_asic(struct radeon_device *rdev) trinity_release_mutex(rdev); } +#if 0 void trinity_dpm_reset_asic(struct radeon_device *rdev) { struct trinity_power_info *pi = trinity_get_pi(rdev); @@ -1284,6 +1285,7 @@ void trinity_dpm_reset_asic(struct radeon_device *rdev) } trinity_release_mutex(rdev); } +#endif static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev, u32 vid_2bit) -- cgit v1.2.3 From 1afde6b265924874e7f07a9d5214058fce1663bb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:35:52 -0500 Subject: drm/radeon: comment out some currently unused sumo dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/sumo_dpm.c | 4 ++++ drivers/gpu/drm/radeon/sumo_dpm.h | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index 1f8a8833e1be..25fd4ced36c8 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1338,6 +1338,7 @@ void sumo_dpm_post_set_power_state(struct radeon_device *rdev) sumo_update_current_ps(rdev, new_ps); } +#if 0 void sumo_dpm_reset_asic(struct radeon_device *rdev) { sumo_program_bootup_state(rdev); @@ -1349,6 +1350,7 @@ void sumo_dpm_reset_asic(struct radeon_device *rdev) sumo_set_forced_mode_enabled(rdev); sumo_set_forced_mode_disabled(rdev); } +#endif void sumo_dpm_setup_asic(struct radeon_device *rdev) { @@ -1537,6 +1539,7 @@ u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev, return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit; } +#if 0 u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev, struct sumo_vid_mapping_table *vid_mapping_table, u32 vid_7bit) @@ -1550,6 +1553,7 @@ u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev, return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit; } +#endif static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev, u32 vid_2bit) diff --git a/drivers/gpu/drm/radeon/sumo_dpm.h b/drivers/gpu/drm/radeon/sumo_dpm.h index db1ea32a907b..07dda299c784 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.h +++ b/drivers/gpu/drm/radeon/sumo_dpm.h @@ -202,9 +202,6 @@ void sumo_construct_vid_mapping_table(struct radeon_device *rdev, u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev, struct sumo_vid_mapping_table *vid_mapping_table, u32 vid_2bit); -u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev, - struct sumo_vid_mapping_table *vid_mapping_table, - u32 vid_7bit); u32 sumo_get_sleep_divider_from_id(u32 id); u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev, u32 sclk, -- cgit v1.2.3 From ed50890de61ddf04541f823430b9ed1ed9d1e937 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:37:28 -0500 Subject: drm/radeon: comment out some currently unused eg dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cypress_dpm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 9aad0327e4d1..ca058589ddef 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c @@ -2005,11 +2005,13 @@ int cypress_dpm_set_power_state(struct radeon_device *rdev) return 0; } +#if 0 void cypress_dpm_reset_asic(struct radeon_device *rdev) { rv770_restrict_performance_levels_before_switch(rdev); rv770_set_boot_state(rdev); } +#endif void cypress_dpm_display_configuration_changed(struct radeon_device *rdev) { -- cgit v1.2.3 From 49ead33b9f0e0ba0b528951a05986486196848ef Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 16:40:03 -0500 Subject: drm/radeon: comment out some currently unused 7xx dpm code Keep it around for reference. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/rv770_dpm.c | 4 ++++ drivers/gpu/drm/radeon/rv770_dpm.h | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 755a8f96fe46..306732641b23 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -231,6 +231,7 @@ u8 rv770_get_seq_value(struct radeon_device *rdev, MC_CG_SEQ_DRAMCONF_S0 : MC_CG_SEQ_DRAMCONF_S1; } +#if 0 int rv770_read_smc_soft_register(struct radeon_device *rdev, u16 reg_offset, u32 *value) { @@ -240,6 +241,7 @@ int rv770_read_smc_soft_register(struct radeon_device *rdev, pi->soft_regs_start + reg_offset, value, pi->sram_end); } +#endif int rv770_write_smc_soft_register(struct radeon_device *rdev, u16 reg_offset, u32 value) @@ -2075,6 +2077,7 @@ int rv770_dpm_set_power_state(struct radeon_device *rdev) return 0; } +#if 0 void rv770_dpm_reset_asic(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev); @@ -2087,6 +2090,7 @@ void rv770_dpm_reset_asic(struct radeon_device *rdev) if (pi->dcodt) rv770_program_dcodt_after_state_switch(rdev, boot_ps, boot_ps); } +#endif void rv770_dpm_setup_asic(struct radeon_device *rdev) { diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h index f776634840c9..d12beab7f3e6 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.h +++ b/drivers/gpu/drm/radeon/rv770_dpm.h @@ -278,8 +278,6 @@ void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, void rv770_get_engine_memory_ss(struct radeon_device *rdev); /* smc */ -int rv770_read_smc_soft_register(struct radeon_device *rdev, - u16 reg_offset, u32 *value); int rv770_write_smc_soft_register(struct radeon_device *rdev, u16 reg_offset, u32 value); -- cgit v1.2.3 From bfc1f97d8ac5d3dc6f7ded64ba9adbac371e912c Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Mon, 22 Dec 2014 17:26:51 -0500 Subject: radeon/audio: consolidate audio_init() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/Makefile | 2 +- drivers/gpu/drm/radeon/cik.c | 3 +- drivers/gpu/drm/radeon/dce6_afmt.c | 54 --------------------- drivers/gpu/drm/radeon/evergreen.c | 3 +- drivers/gpu/drm/radeon/ni.c | 13 ++--- drivers/gpu/drm/radeon/r600.c | 3 +- drivers/gpu/drm/radeon/r600_hdmi.c | 32 ------------- drivers/gpu/drm/radeon/radeon_asic.h | 2 - drivers/gpu/drm/radeon/radeon_audio.c | 90 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 29 +++++++++++ drivers/gpu/drm/radeon/rs600.c | 3 +- drivers/gpu/drm/radeon/rs690.c | 3 +- drivers/gpu/drm/radeon/rv770.c | 3 +- drivers/gpu/drm/radeon/si.c | 3 +- 14 files changed, 138 insertions(+), 105 deletions(-) create mode 100644 drivers/gpu/drm/radeon/radeon_audio.c create mode 100644 drivers/gpu/drm/radeon/radeon_audio.h (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index c58cfd3c3917..f9dab1cb85ba 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -81,7 +81,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \ - radeon_sync.o + radeon_sync.o radeon_audio.o # add async DMA block radeon-y += \ diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index ed336fbfab7c..efbcd23e9c51 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -27,6 +27,7 @@ #include "drmP.h" #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include "cikd.h" #include "atom.h" #include "cik_blit_shaders.h" @@ -8517,7 +8518,7 @@ static int cik_startup(struct radeon_device *rdev) return r; } - r = dce6_audio_init(rdev); + r = radeon_audio_init(rdev); if (r) return r; diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index f312edf4d50e..a97fb22ed06a 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -277,11 +277,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) kfree(sads); } -static int dce6_audio_chipset_supported(struct radeon_device *rdev) -{ - return !ASIC_IS_NODCE(rdev); -} - void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask) @@ -293,55 +288,6 @@ void dce6_audio_enable(struct radeon_device *rdev, enable_mask ? AUDIO_ENABLED : 0); } -static const u32 pin_offsets[7] = -{ - (0x5e00 - 0x5e00), - (0x5e18 - 0x5e00), - (0x5e30 - 0x5e00), - (0x5e48 - 0x5e00), - (0x5e60 - 0x5e00), - (0x5e78 - 0x5e00), - (0x5e90 - 0x5e00), -}; - -int dce6_audio_init(struct radeon_device *rdev) -{ - int i; - - if (!radeon_audio || !dce6_audio_chipset_supported(rdev)) - return 0; - - rdev->audio.enabled = true; - - if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */ - rdev->audio.num_pins = 7; - else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */ - rdev->audio.num_pins = 3; - else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */ - rdev->audio.num_pins = 7; - else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */ - rdev->audio.num_pins = 6; - else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */ - rdev->audio.num_pins = 2; - else /* SI: 6 streams, 6 endpoints */ - rdev->audio.num_pins = 6; - - for (i = 0; i < rdev->audio.num_pins; i++) { - rdev->audio.pin[i].channels = -1; - rdev->audio.pin[i].rate = -1; - rdev->audio.pin[i].bits_per_sample = -1; - rdev->audio.pin[i].status_bits = 0; - rdev->audio.pin[i].category_code = 0; - rdev->audio.pin[i].connected = false; - rdev->audio.pin[i].offset = pin_offsets[i]; - rdev->audio.pin[i].id = i; - /* disable audio. it will be set up later */ - dce6_audio_enable(rdev, &rdev->audio.pin[i], false); - } - - return 0; -} - void dce6_audio_fini(struct radeon_device *rdev) { int i; diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 85995b4e3338..406ea8ee0852 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -26,6 +26,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include #include "evergreend.h" #include "atom.h" @@ -5286,7 +5287,7 @@ static int evergreen_startup(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); + r = radeon_audio_init(rdev); if (r) { DRM_ERROR("radeon: audio init failed\n"); return r; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index aea48c89b241..d2f10408c560 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -27,6 +27,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include #include "nid.h" #include "atom.h" @@ -2097,15 +2098,9 @@ static int cayman_startup(struct radeon_device *rdev) return r; } - if (ASIC_IS_DCE6(rdev)) { - r = dce6_audio_init(rdev); - if (r) - return r; - } else { - r = r600_audio_init(rdev); - if (r) - return r; - } + r = radeon_audio_init(rdev); + if (r) + return r; return 0; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ef5d6066fa5b..de7878aef65c 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -33,6 +33,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include "radeon_mode.h" #include "r600d.h" #include "atom.h" @@ -3054,7 +3055,7 @@ static int r600_startup(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); + r = radeon_audio_init(rdev); if (r) { DRM_ERROR("radeon: audio init failed\n"); return r; diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index b90dc0eb08e6..96a26b0c435b 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -70,15 +70,6 @@ static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ }; - -/* - * check if the chipset is supported - */ -static int r600_audio_chipset_supported(struct radeon_device *rdev) -{ - return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); -} - static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) { struct r600_audio_pin status; @@ -191,29 +182,6 @@ void r600_audio_enable(struct radeon_device *rdev, WREG32(AZ_HOT_PLUG_CONTROL, tmp); } -/* - * initialize the audio vars - */ -int r600_audio_init(struct radeon_device *rdev) -{ - if (!radeon_audio || !r600_audio_chipset_supported(rdev)) - return 0; - - rdev->audio.enabled = true; - - rdev->audio.num_pins = 1; - rdev->audio.pin[0].channels = -1; - rdev->audio.pin[0].rate = -1; - rdev->audio.pin[0].bits_per_sample = -1; - rdev->audio.pin[0].status_bits = 0; - rdev->audio.pin[0].category_code = 0; - rdev->audio.pin[0].id = 0; - /* disable audio. it will be set up later */ - r600_audio_enable(rdev, &rdev->audio.pin[0], 0); - - return 0; -} - /* * release the audio timer * TODO: How to do this correctly on SMP systems? diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 5142bc97f6b6..6eacf410a45f 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -390,7 +390,6 @@ void r600_irq_suspend(struct radeon_device *rdev); void r600_disable_interrupts(struct radeon_device *rdev); void r600_rlc_stop(struct radeon_device *rdev); /* r600 audio */ -int r600_audio_init(struct radeon_device *rdev); void r600_audio_fini(struct radeon_device *rdev); void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock); void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, @@ -680,7 +679,6 @@ void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable); /* DCE6 - SI */ void dce6_bandwidth_update(struct radeon_device *rdev); -int dce6_audio_init(struct radeon_device *rdev); void dce6_audio_fini(struct radeon_device *rdev); /* diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c new file mode 100644 index 000000000000..cc835e2e0de5 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -0,0 +1,90 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Slava Grigorev + */ + +#include +#include "radeon.h" + +void r600_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, + u8 enable_mask); +void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, + u8 enable_mask); + +static const u32 pin_offsets[7] = +{ + (0x5e00 - 0x5e00), + (0x5e18 - 0x5e00), + (0x5e30 - 0x5e00), + (0x5e48 - 0x5e00), + (0x5e60 - 0x5e00), + (0x5e78 - 0x5e00), + (0x5e90 - 0x5e00), +}; + +static int radeon_audio_chipset_supported(struct radeon_device *rdev) +{ + return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); +} + +int radeon_audio_init(struct radeon_device *rdev) +{ + int i; + + if (!radeon_audio || !radeon_audio_chipset_supported(rdev)) + return 0; + + rdev->audio.enabled = true; + + if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */ + rdev->audio.num_pins = 3; + else if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */ + rdev->audio.num_pins = 7; + else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */ + rdev->audio.num_pins = 7; + else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */ + rdev->audio.num_pins = 2; + else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */ + rdev->audio.num_pins = 6; + else if (ASIC_IS_DCE6(rdev)) /* SI: 6 streams, 6 endpoints */ + rdev->audio.num_pins = 6; + else + rdev->audio.num_pins = 1; + + for (i = 0; i < rdev->audio.num_pins; i++) { + rdev->audio.pin[i].channels = -1; + rdev->audio.pin[i].rate = -1; + rdev->audio.pin[i].bits_per_sample = -1; + rdev->audio.pin[i].status_bits = 0; + rdev->audio.pin[i].category_code = 0; + rdev->audio.pin[i].connected = false; + rdev->audio.pin[i].offset = pin_offsets[i]; + rdev->audio.pin[i].id = i; + /* disable audio. it will be set up later */ + if (ASIC_IS_DCE6(rdev)) + dce6_audio_enable(rdev, &rdev->audio.pin[i], false); + else + r600_audio_enable(rdev, &rdev->audio.pin[i], false); + } + + return 0; +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h new file mode 100644 index 000000000000..8455fbdf97e4 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -0,0 +1,29 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Slava Grigorev + */ +#ifndef __RADEON_AUDIO_H__ +#define __RADEON_AUDIO_H__ + +int radeon_audio_init(struct radeon_device *rdev); + +#endif diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 9acb1c3c005b..c26f96093a10 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -38,6 +38,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include "atom.h" #include "rs600d.h" @@ -1012,7 +1013,7 @@ static int rs600_startup(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); + r = radeon_audio_init(rdev); if (r) { dev_err(rdev->dev, "failed initializing audio\n"); return r; diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 0a2d36e81108..0fc559221933 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -28,6 +28,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include "atom.h" #include "rs690d.h" @@ -729,7 +730,7 @@ static int rs690_startup(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); + r = radeon_audio_init(rdev); if (r) { dev_err(rdev->dev, "failed initializing audio\n"); return r; diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 372016e266d0..9bdeb4edb722 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -30,6 +30,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include #include "rv770d.h" #include "atom.h" @@ -1788,7 +1789,7 @@ static int rv770_startup(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); + r = radeon_audio_init(rdev); if (r) { DRM_ERROR("radeon: audio init failed\n"); return r; diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 5d89b874a1a2..86cdc6798240 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -27,6 +27,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include #include "sid.h" #include "atom.h" @@ -6869,7 +6870,7 @@ static int si_startup(struct radeon_device *rdev) return r; } - r = dce6_audio_init(rdev); + r = radeon_audio_init(rdev); if (r) return r; -- cgit v1.2.3 From 1a626b68fbfa4782477caad56f3b8b652a9dbf7e Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Mon, 1 Dec 2014 13:49:39 -0500 Subject: radeon/audio: defined initial audio interface that gets initialized via detect() call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce6_afmt.c | 9 +-- drivers/gpu/drm/radeon/radeon.h | 3 + drivers/gpu/drm/radeon/radeon_audio.c | 96 +++++++++++++++++++++++++++++- drivers/gpu/drm/radeon/radeon_audio.h | 26 ++++++++ drivers/gpu/drm/radeon/radeon_connectors.c | 8 +++ drivers/gpu/drm/radeon/radeon_mode.h | 1 + 6 files changed, 136 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index a97fb22ed06a..821f53ce3f65 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -23,9 +23,10 @@ #include #include #include "radeon.h" +#include "radeon_audio.h" #include "sid.h" -static u32 dce6_endpoint_rreg(struct radeon_device *rdev, +u32 dce6_endpoint_rreg(struct radeon_device *rdev, u32 block_offset, u32 reg) { unsigned long flags; @@ -39,7 +40,7 @@ static u32 dce6_endpoint_rreg(struct radeon_device *rdev, return r; } -static void dce6_endpoint_wreg(struct radeon_device *rdev, +void dce6_endpoint_wreg(struct radeon_device *rdev, u32 block_offset, u32 reg, u32 v) { unsigned long flags; @@ -54,10 +55,6 @@ static void dce6_endpoint_wreg(struct radeon_device *rdev, spin_unlock_irqrestore(&rdev->end_idx_lock, flags); } -#define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg)) -#define WREG32_ENDPOINT(block, reg, v) dce6_endpoint_wreg(rdev, (block), (reg), (v)) - - static void dce6_afmt_get_connected_pins(struct radeon_device *rdev) { int i; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 4195e6cc4e52..d15e3c0c09f5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1757,6 +1757,9 @@ struct r600_audio { bool enabled; struct r600_audio_pin pin[RADEON_MAX_AFMT_BLOCKS]; int num_pins; + struct radeon_audio_funcs *hdmi_funcs; + struct radeon_audio_funcs *dp_funcs; + struct radeon_audio_basic_funcs *funcs; }; /* diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index cc835e2e0de5..36174b6ca681 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -23,12 +23,18 @@ */ #include +#include #include "radeon.h" +#include "atom.h" +#include "radeon_audio.h" void r600_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); +u32 dce6_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg); +void dce6_endpoint_wreg(struct radeon_device *rdev, + u32 offset, u32 reg, u32 v); static const u32 pin_offsets[7] = { @@ -41,6 +47,43 @@ static const u32 pin_offsets[7] = (0x5e90 - 0x5e00), }; +static u32 radeon_audio_rreg(struct radeon_device *rdev, u32 offset, u32 reg) +{ + return RREG32(reg); +} + +static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset, + u32 reg, u32 v) +{ + WREG32(reg, v); +} + +static struct radeon_audio_basic_funcs dce32_funcs = { + .endpoint_rreg = radeon_audio_rreg, + .endpoint_wreg = radeon_audio_wreg, +}; + +static struct radeon_audio_basic_funcs dce4_funcs = { + .endpoint_rreg = radeon_audio_rreg, + .endpoint_wreg = radeon_audio_wreg, +}; + +static struct radeon_audio_basic_funcs dce6_funcs = { + .endpoint_rreg = dce6_endpoint_rreg, + .endpoint_wreg = dce6_endpoint_wreg, +}; + +static void radeon_audio_interface_init(struct radeon_device *rdev) +{ + if (ASIC_IS_DCE6(rdev)) { + rdev->audio.funcs = &dce6_funcs; + } else if (ASIC_IS_DCE4(rdev)) { + rdev->audio.funcs = &dce4_funcs; + } else { + rdev->audio.funcs = &dce32_funcs; + } +} + static int radeon_audio_chipset_supported(struct radeon_device *rdev) { return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); @@ -79,12 +122,63 @@ int radeon_audio_init(struct radeon_device *rdev) rdev->audio.pin[i].connected = false; rdev->audio.pin[i].offset = pin_offsets[i]; rdev->audio.pin[i].id = i; - /* disable audio. it will be set up later */ + } + + radeon_audio_interface_init(rdev); + + /* disable audio. it will be set up later */ + for (i = 0; i < rdev->audio.num_pins; i++) if (ASIC_IS_DCE6(rdev)) dce6_audio_enable(rdev, &rdev->audio.pin[i], false); else r600_audio_enable(rdev, &rdev->audio.pin[i], false); + + return 0; +} + +void radeon_audio_detect(struct drm_connector *connector, + enum drm_connector_status status) +{ + if (!connector || !connector->encoder) + return; + + if (status == connector_status_connected) { + int sink_type; + struct radeon_device *rdev = connector->encoder->dev->dev_private; + struct radeon_connector *radeon_connector; + struct radeon_encoder *radeon_encoder = + to_radeon_encoder(connector->encoder); + + if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { + radeon_encoder->audio = 0; + return; + } + + radeon_connector = to_radeon_connector(connector); + sink_type = radeon_dp_getsinktype(radeon_connector); + + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && + sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) + radeon_encoder->audio = rdev->audio.dp_funcs; + else + radeon_encoder->audio = rdev->audio.hdmi_funcs; + /* TODO: set up the sads, etc. and set the audio enable_mask */ + } else { + /* TODO: reset the audio enable_mask */ } +} + +u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg) +{ + if (rdev->audio.funcs->endpoint_rreg) + return rdev->audio.funcs->endpoint_rreg(rdev, offset, reg); return 0; } + +void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, + u32 reg, u32 v) +{ + if (rdev->audio.funcs->endpoint_wreg) + rdev->audio.funcs->endpoint_wreg(rdev, offset, reg, v); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 8455fbdf97e4..e4b0b6437df7 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -21,9 +21,35 @@ * * Authors: Slava Grigorev */ + #ifndef __RADEON_AUDIO_H__ #define __RADEON_AUDIO_H__ +#include + +#define RREG32_ENDPOINT(block, reg) \ + radeon_audio_endpoint_rreg(rdev, (block), (reg)) +#define WREG32_ENDPOINT(block, reg, v) \ + radeon_audio_endpoint_wreg(rdev, (block), (reg), (v)) + +struct radeon_audio_basic_funcs +{ + u32 (*endpoint_rreg)(struct radeon_device *rdev, u32 offset, u32 reg); + void (*endpoint_wreg)(struct radeon_device *rdev, + u32 offset, u32 reg, u32 v); +}; + +struct radeon_audio_funcs +{ + /* TODO: add mode depended audio interface */ +}; + int radeon_audio_init(struct radeon_device *rdev); +void radeon_audio_detect(struct drm_connector *connector, + enum drm_connector_status status); +u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, + u32 offset, u32 reg); +void radeon_audio_endpoint_wreg(struct radeon_device *rdev, + u32 offset, u32 reg, u32 v); #endif diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 26baa9c05f6c..27def67cb6be 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -29,6 +29,7 @@ #include #include #include "radeon.h" +#include "radeon_audio.h" #include "atom.h" #include @@ -1332,6 +1333,9 @@ out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret); + if (radeon_audio != 0) + radeon_audio_detect(connector, ret); + exit: pm_runtime_mark_last_busy(connector->dev->dev); pm_runtime_put_autosuspend(connector->dev->dev); @@ -1654,6 +1658,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) } radeon_connector_update_scratch_regs(connector, ret); + + if (radeon_audio != 0) + radeon_audio_detect(connector, ret); + out: pm_runtime_mark_last_busy(connector->dev->dev); pm_runtime_put_autosuspend(connector->dev->dev); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 5135d02b7c1e..920a8be8abad 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -449,6 +449,7 @@ struct radeon_encoder { int audio_polling_active; bool is_ext_encoder; u16 caps; + struct radeon_audio_funcs *audio; }; struct radeon_connector_atom_dig { -- cgit v1.2.3 From 070a2e63f6ed77d6e8fa533acd5417068274a972 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 22 Jan 2015 10:41:55 -0500 Subject: radeon/audio: consolidate write_sad_regs() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 35 +++------------- drivers/gpu/drm/radeon/dce6_afmt.c | 34 +++------------- drivers/gpu/drm/radeon/evergreen_hdmi.c | 38 ++++------------- drivers/gpu/drm/radeon/radeon_audio.c | 72 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 4 +- 5 files changed, 93 insertions(+), 90 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index bafdf92a5732..c74431e402e4 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -24,6 +24,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include "r600d.h" static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) @@ -67,14 +68,11 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) kfree(sadb); } -static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) +void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, + struct cea_sad *sads, int sad_count) { + int i; struct radeon_device *rdev = encoder->dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector = NULL; - struct cea_sad *sads; - int i, sad_count; - static const u16 eld_reg_to_type[][2] = { { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, @@ -90,25 +88,6 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, }; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - - sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); - if (sad_count <= 0) { - DRM_ERROR("Couldn't read SADs: %d\n", sad_count); - return; - } - BUG_ON(!sads); - for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; u8 stereo_freqs = 0; @@ -135,10 +114,8 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); - WREG32(eld_reg_to_type[i][0], value); + WREG32_ENDPOINT(0, eld_reg_to_type[i][0], value); } - - kfree(sads); } /* @@ -191,7 +168,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m if (ASIC_IS_DCE32(rdev)) { dce3_2_afmt_write_speaker_allocation(encoder); - dce3_2_afmt_write_sad_regs(encoder); + radeon_audio_write_sad_regs(encoder); } WREG32(HDMI0_ACR_PACKET_CONTROL + offset, diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 821f53ce3f65..f263eaa9d190 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -192,17 +192,14 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) kfree(sadb); } -void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) +void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, + struct cea_sad *sads, int sad_count) { - struct radeon_device *rdev = encoder->dev->dev_private; + u32 offset; + int i; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - u32 offset; - struct drm_connector *connector; - struct radeon_connector *radeon_connector = NULL; - struct cea_sad *sads; - int i, sad_count; - + struct radeon_device *rdev = encoder->dev->dev_private; static const u16 eld_reg_to_type[][2] = { { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, @@ -223,25 +220,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) offset = dig->afmt->pin->offset; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - - sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); - if (sad_count <= 0) { - DRM_ERROR("Couldn't read SADs: %d\n", sad_count); - return; - } - BUG_ON(!sads); - for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; u8 stereo_freqs = 0; @@ -270,8 +248,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); } - - kfree(sads); } void dce6_audio_enable(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 53abd9b17a50..2603f72234a1 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -29,11 +29,11 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include "evergreend.h" #include "atom.h" extern void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder); -extern void dce6_afmt_write_sad_regs(struct drm_encoder *encoder); extern void dce6_afmt_select_pin(struct drm_encoder *encoder); extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, struct drm_display_mode *mode); @@ -168,14 +168,11 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) kfree(sadb); } -static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) +void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, + struct cea_sad *sads, int sad_count) { + int i; struct radeon_device *rdev = encoder->dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector = NULL; - struct cea_sad *sads; - int i, sad_count; - static const u16 eld_reg_to_type[][2] = { { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, @@ -191,25 +188,6 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, }; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - - sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); - if (sad_count <= 0) { - DRM_ERROR("Couldn't read SADs: %d\n", sad_count); - return; - } - BUG_ON(!sads); - for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; u8 stereo_freqs = 0; @@ -236,10 +214,8 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); - WREG32(eld_reg_to_type[i][0], value); + WREG32_ENDPOINT(0, eld_reg_to_type[i][0], value); } - - kfree(sads); } /* @@ -454,13 +430,13 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode if (ASIC_IS_DCE6(rdev)) { dce6_afmt_select_pin(encoder); - dce6_afmt_write_sad_regs(encoder); dce6_afmt_write_latency_fields(encoder, mode); } else { - evergreen_hdmi_write_sad_regs(encoder); dce4_afmt_write_latency_fields(encoder, mode); } + radeon_audio_write_sad_regs(encoder); + err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); if (err < 0) { DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 36174b6ca681..0fc7a93a6fb2 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -35,6 +35,12 @@ void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u32 dce6_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg); void dce6_endpoint_wreg(struct radeon_device *rdev, u32 offset, u32 reg, u32 v); +void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, + struct cea_sad *sads, int sad_count); +void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, + struct cea_sad *sads, int sad_count); +void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, + struct cea_sad *sads, int sad_count); static const u32 pin_offsets[7] = { @@ -73,14 +79,44 @@ static struct radeon_audio_basic_funcs dce6_funcs = { .endpoint_wreg = dce6_endpoint_wreg, }; +static struct radeon_audio_funcs dce32_hdmi_funcs = { + .write_sad_regs = dce3_2_afmt_write_sad_regs, +}; + +static struct radeon_audio_funcs dce32_dp_funcs = { + .write_sad_regs = dce3_2_afmt_write_sad_regs, +}; + +static struct radeon_audio_funcs dce4_hdmi_funcs = { + .write_sad_regs = evergreen_hdmi_write_sad_regs, +}; + +static struct radeon_audio_funcs dce4_dp_funcs = { + .write_sad_regs = evergreen_hdmi_write_sad_regs, +}; + +static struct radeon_audio_funcs dce6_hdmi_funcs = { + .write_sad_regs = dce6_afmt_write_sad_regs, +}; + +static struct radeon_audio_funcs dce6_dp_funcs = { + .write_sad_regs = dce6_afmt_write_sad_regs, +}; + static void radeon_audio_interface_init(struct radeon_device *rdev) { if (ASIC_IS_DCE6(rdev)) { rdev->audio.funcs = &dce6_funcs; + rdev->audio.hdmi_funcs = &dce6_hdmi_funcs; + rdev->audio.dp_funcs = &dce6_dp_funcs; } else if (ASIC_IS_DCE4(rdev)) { rdev->audio.funcs = &dce4_funcs; + rdev->audio.hdmi_funcs = &dce4_hdmi_funcs; + rdev->audio.dp_funcs = &dce4_dp_funcs; } else { rdev->audio.funcs = &dce32_funcs; + rdev->audio.hdmi_funcs = &dce32_hdmi_funcs; + rdev->audio.dp_funcs = &dce32_dp_funcs; } } @@ -182,3 +218,39 @@ void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, if (rdev->audio.funcs->endpoint_wreg) rdev->audio.funcs->endpoint_wreg(rdev, offset, reg, v); } + +void radeon_audio_write_sad_regs(struct drm_encoder *encoder) +{ + struct radeon_encoder *radeon_encoder; + struct drm_connector *connector; + struct radeon_connector *radeon_connector = NULL; + struct cea_sad *sads; + int sad_count; + + list_for_each_entry(connector, + &encoder->dev->mode_config.connector_list, head) { + if (connector->encoder == encoder) { + radeon_connector = to_radeon_connector(connector); + break; + } + } + + if (!radeon_connector) { + DRM_ERROR("Couldn't find encoder's connector\n"); + return; + } + + sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); + if (sad_count <= 0) { + DRM_ERROR("Couldn't read SADs: %d\n", sad_count); + return; + } + BUG_ON(!sads); + + radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs) + radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count); + + kfree(sads); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index e4b0b6437df7..ea3594e3e03c 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -41,7 +41,8 @@ struct radeon_audio_basic_funcs struct radeon_audio_funcs { - /* TODO: add mode depended audio interface */ + void (*write_sad_regs)(struct drm_encoder *encoder, + struct cea_sad *sads, int sad_count); }; int radeon_audio_init(struct radeon_device *rdev); @@ -51,5 +52,6 @@ u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg); void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, u32 reg, u32 v); +void radeon_audio_write_sad_regs(struct drm_encoder *encoder); #endif -- cgit v1.2.3 From 00a9d4bcf8983a5aefcabf5de26b3cb7f805121c Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Mon, 1 Dec 2014 18:02:57 -0500 Subject: radeon/audio: consolidate write_speaker_allocation() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 49 ++++++++++++++---------------- drivers/gpu/drm/radeon/dce6_afmt.c | 50 +++++++++++++++--------------- drivers/gpu/drm/radeon/evergreen_hdmi.c | 54 ++++++++++++++------------------- drivers/gpu/drm/radeon/radeon_audio.c | 53 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 3 ++ 5 files changed, 126 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index c74431e402e4..613e611b507b 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -27,35 +27,14 @@ #include "radeon_audio.h" #include "r600d.h" -static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) +void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count) { struct radeon_device *rdev = encoder->dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector = NULL; u32 tmp; - u8 *sadb = NULL; - int sad_count; - - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - - sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); - if (sad_count < 0) { - DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); - sad_count = 0; - } /* program the speaker allocation */ - tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); + tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); /* set HDMI mode */ tmp |= HDMI_CONNECTION; @@ -63,9 +42,25 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) tmp |= SPEAKER_ALLOCATION(sadb[0]); else tmp |= SPEAKER_ALLOCATION(5); /* stereo */ - WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); + WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); +} - kfree(sadb); +void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count) +{ + struct radeon_device *rdev = encoder->dev->dev_private; + u32 tmp; + + /* program the speaker allocation */ + tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); + tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); + /* set DP mode */ + tmp |= DP_CONNECTION; + if (sad_count) + tmp |= SPEAKER_ALLOCATION(sadb[0]); + else + tmp |= SPEAKER_ALLOCATION(5); /* stereo */ + WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); } void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, @@ -167,7 +162,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m } if (ASIC_IS_DCE32(rdev)) { - dce3_2_afmt_write_speaker_allocation(encoder); + radeon_audio_write_speaker_allocation(encoder); radeon_audio_write_sad_regs(encoder); } diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index f263eaa9d190..a24c95a6e71e 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -144,40 +144,19 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); } -void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) +void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count) { struct radeon_device *rdev = encoder->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; - struct radeon_connector *radeon_connector = NULL; u32 offset, tmp; - u8 *sadb = NULL; - int sad_count; if (!dig || !dig->afmt || !dig->afmt->pin) return; offset = dig->afmt->pin->offset; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - - sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); - if (sad_count < 0) { - DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); - sad_count = 0; - } - /* program the speaker allocation */ tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); @@ -188,8 +167,31 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) else tmp |= SPEAKER_ALLOCATION(5); /* stereo */ WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); +} - kfree(sadb); +void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count) +{ + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + u32 offset, tmp; + + if (!dig || !dig->afmt || !dig->afmt->pin) + return; + + offset = dig->afmt->pin->offset; + + /* program the speaker allocation */ + tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); + tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); + /* set DP mode */ + tmp |= DP_CONNECTION; + if (sad_count) + tmp |= SPEAKER_ALLOCATION(sadb[0]); + else + tmp |= SPEAKER_ALLOCATION(5); /* stereo */ + WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); } void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 2603f72234a1..58ff82b94f97 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -33,7 +33,6 @@ #include "evergreend.h" #include "atom.h" -extern void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder); extern void dce6_afmt_select_pin(struct drm_encoder *encoder); extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, struct drm_display_mode *mode); @@ -127,35 +126,14 @@ static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, WREG32(AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp); } -static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) +void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count) { struct radeon_device *rdev = encoder->dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector = NULL; u32 tmp; - u8 *sadb = NULL; - int sad_count; - - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - - sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); - if (sad_count < 0) { - DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); - sad_count = 0; - } /* program the speaker allocation */ - tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); + tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); /* set HDMI mode */ tmp |= HDMI_CONNECTION; @@ -163,9 +141,25 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) tmp |= SPEAKER_ALLOCATION(sadb[0]); else tmp |= SPEAKER_ALLOCATION(5); /* stereo */ - WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); + WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); +} - kfree(sadb); +void dce4_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count) +{ + struct radeon_device *rdev = encoder->dev->dev_private; + u32 tmp; + + /* program the speaker allocation */ + tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); + tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); + /* set DP mode */ + tmp |= DP_CONNECTION; + if (sad_count) + tmp |= SPEAKER_ALLOCATION(sadb[0]); + else + tmp |= SPEAKER_ALLOCATION(5); /* stereo */ + WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); } void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, @@ -417,11 +411,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode AFMT_60958_CS_CHANNEL_NUMBER_6(7) | AFMT_60958_CS_CHANNEL_NUMBER_7(8)); - if (ASIC_IS_DCE6(rdev)) { - dce6_afmt_write_speaker_allocation(encoder); - } else { - dce4_afmt_write_speaker_allocation(encoder); - } + radeon_audio_write_speaker_allocation(encoder); WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset, AFMT_AUDIO_CHANNEL_ENABLE(0xff)); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 0fc7a93a6fb2..22f12e8e1b14 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -41,6 +41,18 @@ void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, struct cea_sad *sads, int sad_count); void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, struct cea_sad *sads, int sad_count); +void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count); +void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count); +void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count); +void dce4_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count); +void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count); +void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, + u8 *sadb, int sad_count); static const u32 pin_offsets[7] = { @@ -81,26 +93,32 @@ static struct radeon_audio_basic_funcs dce6_funcs = { static struct radeon_audio_funcs dce32_hdmi_funcs = { .write_sad_regs = dce3_2_afmt_write_sad_regs, + .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, }; static struct radeon_audio_funcs dce32_dp_funcs = { .write_sad_regs = dce3_2_afmt_write_sad_regs, + .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, }; static struct radeon_audio_funcs dce4_hdmi_funcs = { .write_sad_regs = evergreen_hdmi_write_sad_regs, + .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, }; static struct radeon_audio_funcs dce4_dp_funcs = { .write_sad_regs = evergreen_hdmi_write_sad_regs, + .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, }; static struct radeon_audio_funcs dce6_hdmi_funcs = { .write_sad_regs = dce6_afmt_write_sad_regs, + .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, }; static struct radeon_audio_funcs dce6_dp_funcs = { .write_sad_regs = dce6_afmt_write_sad_regs, + .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, }; static void radeon_audio_interface_init(struct radeon_device *rdev) @@ -254,3 +272,38 @@ void radeon_audio_write_sad_regs(struct drm_encoder *encoder) kfree(sads); } + +void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_connector *connector; + struct radeon_connector *radeon_connector = NULL; + u8 *sadb = NULL; + int sad_count; + + list_for_each_entry(connector, + &encoder->dev->mode_config.connector_list, head) { + if (connector->encoder == encoder) { + radeon_connector = to_radeon_connector(connector); + break; + } + } + + if (!radeon_connector) { + DRM_ERROR("Couldn't find encoder's connector\n"); + return; + } + + sad_count = drm_edid_to_speaker_allocation( + radeon_connector_edid(connector), &sadb); + if (sad_count < 0) { + DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", + sad_count); + sad_count = 0; + } + + if (radeon_encoder->audio && radeon_encoder->audio->write_speaker_allocation) + radeon_encoder->audio->write_speaker_allocation(encoder, sadb, sad_count); + + kfree(sadb); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index ea3594e3e03c..cc0596f24d9a 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -43,6 +43,8 @@ struct radeon_audio_funcs { void (*write_sad_regs)(struct drm_encoder *encoder, struct cea_sad *sads, int sad_count); + void (*write_speaker_allocation)(struct drm_encoder *encoder, + u8 *sadb, int sad_count); }; int radeon_audio_init(struct radeon_device *rdev); @@ -53,5 +55,6 @@ u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, u32 reg, u32 v); void radeon_audio_write_sad_regs(struct drm_encoder *encoder); +void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder); #endif -- cgit v1.2.3 From 87654f87af2a06f325cc1a1a6e6a6a27f8837bf3 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Tue, 2 Dec 2014 11:20:48 -0500 Subject: radeon/audio: consolidate write_latency_fields() functions Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce6_afmt.c | 16 +--------------- drivers/gpu/drm/radeon/evergreen_hdmi.c | 29 +++++----------------------- drivers/gpu/drm/radeon/radeon_audio.c | 34 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 4 ++++ 4 files changed, 44 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index a24c95a6e71e..96f298c92481 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -102,13 +102,11 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder) } void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, - struct drm_display_mode *mode) + struct drm_connector *connector, struct drm_display_mode *mode) { struct radeon_device *rdev = encoder->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; - struct radeon_connector *radeon_connector = NULL; u32 tmp = 0, offset; if (!dig || !dig->afmt || !dig->afmt->pin) @@ -116,18 +114,6 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, offset = dig->afmt->pin->offset; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - if (mode->flags & DRM_MODE_FLAG_INTERLACE) { if (connector->latency_present[1]) tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 58ff82b94f97..aa8a31b99c6e 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -34,8 +34,6 @@ #include "atom.h" extern void dce6_afmt_select_pin(struct drm_encoder *encoder); -extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, - struct drm_display_mode *mode); /* enable the audio stream */ static void dce4_audio_enable(struct radeon_device *rdev, @@ -90,26 +88,12 @@ static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t cloc WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); } -static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, - struct drm_display_mode *mode) +void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, + struct drm_connector *connector, struct drm_display_mode *mode) { struct radeon_device *rdev = encoder->dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector = NULL; u32 tmp = 0; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - if (mode->flags & DRM_MODE_FLAG_INTERLACE) { if (connector->latency_present[1]) tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | @@ -123,7 +107,7 @@ static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, else tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); } - WREG32(AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp); + WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp); } void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, @@ -418,14 +402,11 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode /* fglrx sets 0x40 in 0x5f80 here */ - if (ASIC_IS_DCE6(rdev)) { + if (ASIC_IS_DCE6(rdev)) dce6_afmt_select_pin(encoder); - dce6_afmt_write_latency_fields(encoder, mode); - } else { - dce4_afmt_write_latency_fields(encoder, mode); - } radeon_audio_write_sad_regs(encoder); + radeon_audio_write_latency_fields(encoder, mode); err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); if (err < 0) { diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 22f12e8e1b14..a95eee14c4bf 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -53,6 +53,10 @@ void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, u8 *sadb, int sad_count); void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, u8 *sadb, int sad_count); +void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, + struct drm_connector *connector, struct drm_display_mode *mode); +void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, + struct drm_connector *connector, struct drm_display_mode *mode); static const u32 pin_offsets[7] = { @@ -104,21 +108,25 @@ static struct radeon_audio_funcs dce32_dp_funcs = { static struct radeon_audio_funcs dce4_hdmi_funcs = { .write_sad_regs = evergreen_hdmi_write_sad_regs, .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, + .write_latency_fields = dce4_afmt_write_latency_fields, }; static struct radeon_audio_funcs dce4_dp_funcs = { .write_sad_regs = evergreen_hdmi_write_sad_regs, .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, + .write_latency_fields = dce4_afmt_write_latency_fields, }; static struct radeon_audio_funcs dce6_hdmi_funcs = { .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, + .write_latency_fields = dce6_afmt_write_latency_fields, }; static struct radeon_audio_funcs dce6_dp_funcs = { .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, + .write_latency_fields = dce6_afmt_write_latency_fields, }; static void radeon_audio_interface_init(struct radeon_device *rdev) @@ -307,3 +315,29 @@ void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) kfree(sadb); } + +void radeon_audio_write_latency_fields(struct drm_encoder *encoder, + struct drm_display_mode *mode) +{ + struct radeon_encoder *radeon_encoder; + struct drm_connector *connector; + struct radeon_connector *radeon_connector = 0; + + list_for_each_entry(connector, + &encoder->dev->mode_config.connector_list, head) { + if (connector->encoder == encoder) { + radeon_connector = to_radeon_connector(connector); + break; + } + } + + if (!radeon_connector) { + DRM_ERROR("Couldn't find encoder's connector\n"); + return; + } + + radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields) + radeon_encoder->audio->write_latency_fields(encoder, connector, mode); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index cc0596f24d9a..33981c8dd035 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -41,6 +41,8 @@ struct radeon_audio_basic_funcs struct radeon_audio_funcs { + void (*write_latency_fields)(struct drm_encoder *encoder, + struct drm_connector *connector, struct drm_display_mode *mode); void (*write_sad_regs)(struct drm_encoder *encoder, struct cea_sad *sads, int sad_count); void (*write_speaker_allocation)(struct drm_encoder *encoder, @@ -56,5 +58,7 @@ void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, u32 reg, u32 v); void radeon_audio_write_sad_regs(struct drm_encoder *encoder); void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder); +void radeon_audio_write_latency_fields(struct drm_encoder *encoder, + struct drm_display_mode *mode); #endif -- cgit v1.2.3 From 3cdde027aae8b2d3f49912e463f8083da50c8611 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Tue, 2 Dec 2014 15:22:43 -0500 Subject: radeon/audio: consolidate audio_get_pin() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 2 +- drivers/gpu/drm/radeon/evergreen_hdmi.c | 3 +-- drivers/gpu/drm/radeon/r600_hdmi.c | 3 ++- drivers/gpu/drm/radeon/radeon_audio.c | 19 +++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 2 ++ 5 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 613e611b507b..f4cddb2ad34e 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -136,7 +136,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m offset = dig->afmt->offset; /* disable audio prior to setting up hw */ - dig->afmt->pin = r600_audio_get_pin(rdev); + dig->afmt->pin = radeon_audio_get_pin(encoder); r600_audio_enable(rdev, dig->afmt->pin, 0); r600_audio_set_dto(encoder, mode->clock); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index aa8a31b99c6e..26d8cd5c20a1 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -301,11 +301,10 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode } /* disable audio prior to setting up hw */ + dig->afmt->pin = radeon_audio_get_pin(encoder); if (ASIC_IS_DCE6(rdev)) { - dig->afmt->pin = dce6_audio_get_pin(rdev); dce6_audio_enable(rdev, dig->afmt->pin, 0); } else { - dig->afmt->pin = r600_audio_get_pin(rdev); dce4_audio_enable(rdev, dig->afmt->pin, 0); } diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 96a26b0c435b..53159a2c7899 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -29,6 +29,7 @@ #include #include "radeon.h" #include "radeon_asic.h" +#include "radeon_audio.h" #include "r600d.h" #include "atom.h" @@ -487,7 +488,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod offset = dig->afmt->offset; /* disable audio prior to setting up hw */ - dig->afmt->pin = r600_audio_get_pin(rdev); + dig->afmt->pin = radeon_audio_get_pin(encoder); r600_audio_enable(rdev, dig->afmt->pin, 0xf); r600_audio_set_dto(encoder, mode->clock); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index a95eee14c4bf..795f84c8187e 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -57,6 +57,8 @@ void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, struct drm_connector *connector, struct drm_display_mode *mode); void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, struct drm_connector *connector, struct drm_display_mode *mode); +struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); +struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); static const u32 pin_offsets[7] = { @@ -96,34 +98,40 @@ static struct radeon_audio_basic_funcs dce6_funcs = { }; static struct radeon_audio_funcs dce32_hdmi_funcs = { + .get_pin = r600_audio_get_pin, .write_sad_regs = dce3_2_afmt_write_sad_regs, .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, }; static struct radeon_audio_funcs dce32_dp_funcs = { + .get_pin = r600_audio_get_pin, .write_sad_regs = dce3_2_afmt_write_sad_regs, .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, }; static struct radeon_audio_funcs dce4_hdmi_funcs = { + .get_pin = r600_audio_get_pin, .write_sad_regs = evergreen_hdmi_write_sad_regs, .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, .write_latency_fields = dce4_afmt_write_latency_fields, }; static struct radeon_audio_funcs dce4_dp_funcs = { + .get_pin = r600_audio_get_pin, .write_sad_regs = evergreen_hdmi_write_sad_regs, .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, .write_latency_fields = dce4_afmt_write_latency_fields, }; static struct radeon_audio_funcs dce6_hdmi_funcs = { + .get_pin = dce6_audio_get_pin, .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, .write_latency_fields = dce6_afmt_write_latency_fields, }; static struct radeon_audio_funcs dce6_dp_funcs = { + .get_pin = dce6_audio_get_pin, .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, .write_latency_fields = dce6_afmt_write_latency_fields, @@ -341,3 +349,14 @@ void radeon_audio_write_latency_fields(struct drm_encoder *encoder, if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields) radeon_encoder->audio->write_latency_fields(encoder, connector, mode); } + +struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder) +{ + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->audio && radeon_encoder->audio->get_pin) + return radeon_encoder->audio->get_pin(rdev); + + return NULL; +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 33981c8dd035..492f98b4df78 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -41,6 +41,7 @@ struct radeon_audio_basic_funcs struct radeon_audio_funcs { + struct r600_audio_pin* (*get_pin)(struct radeon_device *rdev); void (*write_latency_fields)(struct drm_encoder *encoder, struct drm_connector *connector, struct drm_display_mode *mode); void (*write_sad_regs)(struct drm_encoder *encoder, @@ -60,5 +61,6 @@ void radeon_audio_write_sad_regs(struct drm_encoder *encoder); void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder); void radeon_audio_write_latency_fields(struct drm_encoder *encoder, struct drm_display_mode *mode); +struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder); #endif -- cgit v1.2.3 From 88252d7728f414a838f6a7cfbe895ba708e8d26d Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Tue, 2 Dec 2014 17:27:29 -0500 Subject: radeon/audio: consolidate select_pin() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_hdmi.c | 6 +----- drivers/gpu/drm/radeon/radeon_audio.c | 11 +++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 26d8cd5c20a1..6bd113bc6551 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -33,8 +33,6 @@ #include "evergreend.h" #include "atom.h" -extern void dce6_afmt_select_pin(struct drm_encoder *encoder); - /* enable the audio stream */ static void dce4_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, @@ -401,9 +399,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode /* fglrx sets 0x40 in 0x5f80 here */ - if (ASIC_IS_DCE6(rdev)) - dce6_afmt_select_pin(encoder); - + radeon_audio_select_pin(encoder); radeon_audio_write_sad_regs(encoder); radeon_audio_write_latency_fields(encoder, mode); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 795f84c8187e..5aedf5b97b96 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -59,6 +59,7 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, struct drm_connector *connector, struct drm_display_mode *mode); struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); +void dce6_afmt_select_pin(struct drm_encoder *encoder); static const u32 pin_offsets[7] = { @@ -124,6 +125,7 @@ static struct radeon_audio_funcs dce4_dp_funcs = { }; static struct radeon_audio_funcs dce6_hdmi_funcs = { + .select_pin = dce6_afmt_select_pin, .get_pin = dce6_audio_get_pin, .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, @@ -131,6 +133,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { }; static struct radeon_audio_funcs dce6_dp_funcs = { + .select_pin = dce6_afmt_select_pin, .get_pin = dce6_audio_get_pin, .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, @@ -360,3 +363,11 @@ struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder) return NULL; } + +void radeon_audio_select_pin(struct drm_encoder *encoder) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->audio && radeon_encoder->audio->select_pin) + radeon_encoder->audio->select_pin(encoder); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 492f98b4df78..36d329a413c1 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -41,6 +41,7 @@ struct radeon_audio_basic_funcs struct radeon_audio_funcs { + void (*select_pin)(struct drm_encoder *encoder); struct r600_audio_pin* (*get_pin)(struct radeon_device *rdev); void (*write_latency_fields)(struct drm_encoder *encoder, struct drm_connector *connector, struct drm_display_mode *mode); @@ -62,5 +63,6 @@ void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder); void radeon_audio_write_latency_fields(struct drm_encoder *encoder, struct drm_display_mode *mode); struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder); +void radeon_audio_select_pin(struct drm_encoder *encoder); #endif -- cgit v1.2.3 From 8bf598207efb35ea17075b11bf116043c18aca40 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Wed, 3 Dec 2014 15:29:53 -0500 Subject: radeon/audio: consolidate audio_enable() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 4 ++-- drivers/gpu/drm/radeon/dce6_afmt.c | 2 +- drivers/gpu/drm/radeon/evergreen_hdmi.c | 18 ++++-------------- drivers/gpu/drm/radeon/r600_hdmi.c | 9 ++++----- drivers/gpu/drm/radeon/radeon_audio.c | 17 +++++++++++++---- drivers/gpu/drm/radeon/radeon_audio.h | 4 ++++ 6 files changed, 28 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index f4cddb2ad34e..f7b26592c74f 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -137,7 +137,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m /* disable audio prior to setting up hw */ dig->afmt->pin = radeon_audio_get_pin(encoder); - r600_audio_enable(rdev, dig->afmt->pin, 0); + radeon_audio_enable(rdev, dig->afmt->pin, 0); r600_audio_set_dto(encoder, mode->clock); @@ -212,5 +212,5 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m r600_hdmi_audio_workaround(encoder); /* enable audio after to setting up hw */ - r600_audio_enable(rdev, dig->afmt->pin, 0xf); + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 96f298c92481..7fd7f1573173 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -257,7 +257,7 @@ void dce6_audio_fini(struct radeon_device *rdev) return; for (i = 0; i < rdev->audio.num_pins; i++) - dce6_audio_enable(rdev, &rdev->audio.pin[i], false); + radeon_audio_enable(rdev, &rdev->audio.pin[i], false); rdev->audio.enabled = false; } diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 6bd113bc6551..2f29918ee49f 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -34,7 +34,7 @@ #include "atom.h" /* enable the audio stream */ -static void dce4_audio_enable(struct radeon_device *rdev, +void dce4_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask) { @@ -300,11 +300,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode /* disable audio prior to setting up hw */ dig->afmt->pin = radeon_audio_get_pin(encoder); - if (ASIC_IS_DCE6(rdev)) { - dce6_audio_enable(rdev, dig->afmt->pin, 0); - } else { - dce4_audio_enable(rdev, dig->afmt->pin, 0); - } + radeon_audio_enable(rdev, dig->afmt->pin, 0); evergreen_audio_set_dto(encoder, mode->clock); @@ -435,10 +431,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); /* enable audio after to setting up hw */ - if (ASIC_IS_DCE6(rdev)) - dce6_audio_enable(rdev, dig->afmt->pin, 1); - else - dce4_audio_enable(rdev, dig->afmt->pin, 0xf); + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) @@ -458,10 +451,7 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) return; if (!enable && dig->afmt->pin) { - if (ASIC_IS_DCE6(rdev)) - dce6_audio_enable(rdev, dig->afmt->pin, 0); - else - dce4_audio_enable(rdev, dig->afmt->pin, 0); + radeon_audio_enable(rdev, dig->afmt->pin, 0); dig->afmt->pin = NULL; } diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 53159a2c7899..f92eb77cdd60 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -192,8 +192,7 @@ void r600_audio_fini(struct radeon_device *rdev) if (!rdev->audio.enabled) return; - r600_audio_enable(rdev, &rdev->audio.pin[0], 0); - + radeon_audio_enable(rdev, &rdev->audio.pin[0], 0); rdev->audio.enabled = false; } @@ -489,7 +488,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod /* disable audio prior to setting up hw */ dig->afmt->pin = radeon_audio_get_pin(encoder); - r600_audio_enable(rdev, dig->afmt->pin, 0xf); + radeon_audio_enable(rdev, dig->afmt->pin, 0); r600_audio_set_dto(encoder, mode->clock); @@ -575,7 +574,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); /* enable audio after to setting up hw */ - r600_audio_enable(rdev, dig->afmt->pin, 0xf); + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } /** @@ -661,7 +660,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) return; if (!enable && dig->afmt->pin) { - r600_audio_enable(rdev, dig->afmt->pin, 0); + radeon_audio_enable(rdev, dig->afmt->pin, 0); dig->afmt->pin = NULL; } diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 5aedf5b97b96..eed5c740cefa 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -30,6 +30,8 @@ void r600_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); +void dce4_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, + u8 enable_mask); void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); u32 dce6_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg); @@ -86,16 +88,19 @@ static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset, static struct radeon_audio_basic_funcs dce32_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, + .enable = r600_audio_enable, }; static struct radeon_audio_basic_funcs dce4_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, + .enable = dce4_audio_enable, }; static struct radeon_audio_basic_funcs dce6_funcs = { .endpoint_rreg = dce6_endpoint_rreg, .endpoint_wreg = dce6_endpoint_wreg, + .enable = dce6_audio_enable, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -201,10 +206,7 @@ int radeon_audio_init(struct radeon_device *rdev) /* disable audio. it will be set up later */ for (i = 0; i < rdev->audio.num_pins; i++) - if (ASIC_IS_DCE6(rdev)) - dce6_audio_enable(rdev, &rdev->audio.pin[i], false); - else - r600_audio_enable(rdev, &rdev->audio.pin[i], false); + radeon_audio_enable(rdev, &rdev->audio.pin[i], false); return 0; } @@ -371,3 +373,10 @@ void radeon_audio_select_pin(struct drm_encoder *encoder) if (radeon_encoder->audio && radeon_encoder->audio->select_pin) radeon_encoder->audio->select_pin(encoder); } + +void radeon_audio_enable(struct radeon_device *rdev, + struct r600_audio_pin *pin, u8 enable_mask) +{ + if (rdev->audio.funcs->enable) + rdev->audio.funcs->enable(rdev, pin, enable_mask); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 36d329a413c1..2bd845de8d4d 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -37,6 +37,8 @@ struct radeon_audio_basic_funcs u32 (*endpoint_rreg)(struct radeon_device *rdev, u32 offset, u32 reg); void (*endpoint_wreg)(struct radeon_device *rdev, u32 offset, u32 reg, u32 v); + void (*enable)(struct radeon_device *rdev, + struct r600_audio_pin *pin, u8 enable_mask); }; struct radeon_audio_funcs @@ -64,5 +66,7 @@ void radeon_audio_write_latency_fields(struct drm_encoder *encoder, struct drm_display_mode *mode); struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder); void radeon_audio_select_pin(struct drm_encoder *encoder); +void radeon_audio_enable(struct radeon_device *rdev, + struct r600_audio_pin *pin, u8 enable_mask); #endif -- cgit v1.2.3 From 7991d6650117064ae1d2b215b5cbb4112711ed5e Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Wed, 3 Dec 2014 17:07:01 -0500 Subject: radeon/audio: consolidate audio_fini() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 2 +- drivers/gpu/drm/radeon/dce6_afmt.c | 13 ------------- drivers/gpu/drm/radeon/evergreen.c | 4 ++-- drivers/gpu/drm/radeon/ni.c | 5 +---- drivers/gpu/drm/radeon/r600.c | 4 ++-- drivers/gpu/drm/radeon/r600_hdmi.c | 13 ------------- drivers/gpu/drm/radeon/radeon_audio.c | 13 +++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 1 + drivers/gpu/drm/radeon/rs600.c | 4 ++-- drivers/gpu/drm/radeon/rs690.c | 4 ++-- drivers/gpu/drm/radeon/rv770.c | 2 +- drivers/gpu/drm/radeon/si.c | 2 +- 12 files changed, 26 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index efbcd23e9c51..de77c27d8106 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -8576,7 +8576,7 @@ int cik_suspend(struct radeon_device *rdev) { radeon_kfd_suspend(rdev); radeon_pm_suspend(rdev); - dce6_audio_fini(rdev); + radeon_audio_fini(rdev); radeon_vm_manager_fini(rdev); cik_cp_enable(rdev, false); cik_sdma_enable(rdev, false); diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 7fd7f1573173..c4ff60f005d2 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -248,16 +248,3 @@ void dce6_audio_enable(struct radeon_device *rdev, WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, enable_mask ? AUDIO_ENABLED : 0); } - -void dce6_audio_fini(struct radeon_device *rdev) -{ - int i; - - if (!rdev->audio.enabled) - return; - - for (i = 0; i < rdev->audio.num_pins; i++) - radeon_audio_enable(rdev, &rdev->audio.pin[i], false); - - rdev->audio.enabled = false; -} diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 406ea8ee0852..78600f534c80 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -5333,7 +5333,7 @@ int evergreen_resume(struct radeon_device *rdev) int evergreen_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); uvd_v1_0_fini(rdev); radeon_uvd_suspend(rdev); r700_cp_stop(rdev); @@ -5483,7 +5483,7 @@ int evergreen_init(struct radeon_device *rdev) void evergreen_fini(struct radeon_device *rdev) { radeon_pm_fini(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); r700_cp_fini(rdev); r600_dma_fini(rdev); r600_irq_fini(rdev); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index d2f10408c560..24242a7f0ac3 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2135,10 +2135,7 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); - if (ASIC_IS_DCE6(rdev)) - dce6_audio_fini(rdev); - else - r600_audio_fini(rdev); + radeon_audio_fini(rdev); radeon_vm_manager_fini(rdev); cayman_cp_enable(rdev, false); cayman_dma_stop(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index de7878aef65c..07a71a2488c9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -3106,7 +3106,7 @@ int r600_resume(struct radeon_device *rdev) int r600_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); r600_cp_stop(rdev); if (rdev->has_uvd) { uvd_v1_0_fini(rdev); @@ -3225,7 +3225,7 @@ int r600_init(struct radeon_device *rdev) void r600_fini(struct radeon_device *rdev) { radeon_pm_fini(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); r600_cp_fini(rdev); r600_irq_fini(rdev); if (rdev->has_uvd) { diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index f92eb77cdd60..1c49f4d2945a 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -183,19 +183,6 @@ void r600_audio_enable(struct radeon_device *rdev, WREG32(AZ_HOT_PLUG_CONTROL, tmp); } -/* - * release the audio timer - * TODO: How to do this correctly on SMP systems? - */ -void r600_audio_fini(struct radeon_device *rdev) -{ - if (!rdev->audio.enabled) - return; - - radeon_audio_enable(rdev, &rdev->audio.pin[0], 0); - rdev->audio.enabled = false; -} - struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) { /* only one pin on 6xx-NI */ diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index eed5c740cefa..e6c73f8206b2 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -380,3 +380,16 @@ void radeon_audio_enable(struct radeon_device *rdev, if (rdev->audio.funcs->enable) rdev->audio.funcs->enable(rdev, pin, enable_mask); } + +void radeon_audio_fini(struct radeon_device *rdev) +{ + int i; + + if (!rdev->audio.enabled) + return; + + for (i = 0; i < rdev->audio.num_pins; i++) + radeon_audio_enable(rdev, &rdev->audio.pin[i], false); + + rdev->audio.enabled = false; +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 2bd845de8d4d..5844993a1edb 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -68,5 +68,6 @@ struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder); void radeon_audio_select_pin(struct drm_encoder *encoder); void radeon_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); +void radeon_audio_fini(struct radeon_device *rdev); #endif diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index c26f96093a10..68f154a451c0 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -1054,7 +1054,7 @@ int rs600_resume(struct radeon_device *rdev) int rs600_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); rs600_irq_disable(rdev); @@ -1065,7 +1065,7 @@ int rs600_suspend(struct radeon_device *rdev) void rs600_fini(struct radeon_device *rdev) { radeon_pm_fini(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); radeon_ib_pool_fini(rdev); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 0fc559221933..516ca27cfa12 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -771,7 +771,7 @@ int rs690_resume(struct radeon_device *rdev) int rs690_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); rs600_irq_disable(rdev); @@ -782,7 +782,7 @@ int rs690_suspend(struct radeon_device *rdev) void rs690_fini(struct radeon_device *rdev) { radeon_pm_fini(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); radeon_ib_pool_fini(rdev); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 9bdeb4edb722..01ee96acb398 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1830,7 +1830,7 @@ int rv770_resume(struct radeon_device *rdev) int rv770_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); - r600_audio_fini(rdev); + radeon_audio_fini(rdev); uvd_v1_0_fini(rdev); radeon_uvd_suspend(rdev); r700_cp_stop(rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 86cdc6798240..73107fe9e46f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6909,7 +6909,7 @@ int si_resume(struct radeon_device *rdev) int si_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); - dce6_audio_fini(rdev); + radeon_audio_fini(rdev); radeon_vm_manager_fini(rdev); si_cp_enable(rdev, false); cayman_dma_stop(rdev); -- cgit v1.2.3 From a85d682a6578a3bd02c95afb4ef527fa0897bb69 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Fri, 5 Dec 2014 13:38:31 -0500 Subject: radeon/audio: consolidate audio_set_dto() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 56 +++++++++++++++++++- drivers/gpu/drm/radeon/dce6_afmt.c | 39 ++++++++++++++ drivers/gpu/drm/radeon/evergreen_hdmi.c | 92 ++++++++++++++++++++------------- drivers/gpu/drm/radeon/evergreend.h | 1 + drivers/gpu/drm/radeon/r600_hdmi.c | 80 +++++++--------------------- drivers/gpu/drm/radeon/radeon_audio.c | 45 +++++++++++++++- drivers/gpu/drm/radeon/radeon_audio.h | 3 ++ drivers/gpu/drm/radeon/sid.h | 10 ++++ 8 files changed, 226 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index f7b26592c74f..6cb2f1171539 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -113,6 +113,60 @@ void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, } } +void dce3_2_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock) +{ + struct radeon_encoder *radeon_encoder; + struct radeon_encoder_atom_dig *dig; + unsigned int max_ratio = clock / 24000; + u32 dto_phase; + u32 wallclock_ratio; + u32 dto_cntl; + + if (!crtc) + return; + + radeon_encoder = to_radeon_encoder(crtc->encoder); + dig = radeon_encoder->enc_priv; + + if (!dig) + return; + + if (max_ratio >= 8) { + dto_phase = 192 * 1000; + wallclock_ratio = 3; + } else if (max_ratio >= 4) { + dto_phase = 96 * 1000; + wallclock_ratio = 2; + } else if (max_ratio >= 2) { + dto_phase = 48 * 1000; + wallclock_ratio = 1; + } else { + dto_phase = 24 * 1000; + wallclock_ratio = 0; + } + + /* Express [24MHz / target pixel clock] as an exact rational + * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE + * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator + */ + if (dig->dig_encoder == 0) { + dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; + dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); + WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); + WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); + WREG32(DCCG_AUDIO_DTO0_MODULE, clock); + WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ + } else { + dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; + dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); + WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); + WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); + WREG32(DCCG_AUDIO_DTO1_MODULE, clock); + WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ + } +} + /* * update the info frames with the data from the current display mode */ @@ -139,7 +193,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m dig->afmt->pin = radeon_audio_get_pin(encoder); radeon_audio_enable(rdev, dig->afmt->pin, 0); - r600_audio_set_dto(encoder, mode->clock); + radeon_audio_set_dto(encoder, mode->clock); WREG32(HDMI0_VBI_PACKET_CONTROL + offset, HDMI0_NULL_SEND); /* send null packets when required */ diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index c4ff60f005d2..1c870060c29b 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -248,3 +248,42 @@ void dce6_audio_enable(struct radeon_device *rdev, WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, enable_mask ? AUDIO_ENABLED : 0); } + +void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock) +{ + /* Two dtos; generally use dto0 for HDMI */ + u32 value = 0; + + if (crtc) + value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); + + WREG32(DCCG_AUDIO_DTO_SOURCE, value); + + /* Express [24MHz / target pixel clock] as an exact rational + * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE + * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator + */ + WREG32(DCCG_AUDIO_DTO0_PHASE, 24000); + WREG32(DCCG_AUDIO_DTO0_MODULE, clock); +} + +void dce6_dp_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock) +{ + /* Two dtos; generally use dto1 for DP */ + u32 value = 0; + value |= DCCG_AUDIO_DTO_SEL; + + if (crtc) + value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); + + WREG32(DCCG_AUDIO_DTO_SOURCE, value); + + /* Express [24MHz / target pixel clock] as an exact rational + * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE + * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator + */ + WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); + WREG32(DCCG_AUDIO_DTO1_MODULE, clock); +} diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 2f29918ee49f..38b1c51cce4d 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -218,54 +218,74 @@ static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder, frame[0xC] | (frame[0xD] << 8) | (header[1] << 24)); } -static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) +void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock) { - struct drm_device *dev = encoder->dev; - 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 radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - u32 base_rate = 24000; - u32 max_ratio = clock / base_rate; + unsigned int max_ratio = clock / 24000; u32 dto_phase; - u32 dto_modulo = clock; u32 wallclock_ratio; - u32 dto_cntl; - - if (!dig || !dig->afmt) - return; - - if (ASIC_IS_DCE6(rdev)) { - dto_phase = 24 * 1000; + u32 value; + + if (max_ratio >= 8) { + dto_phase = 192 * 1000; + wallclock_ratio = 3; + } else if (max_ratio >= 4) { + dto_phase = 96 * 1000; + wallclock_ratio = 2; + } else if (max_ratio >= 2) { + dto_phase = 48 * 1000; + wallclock_ratio = 1; } else { - if (max_ratio >= 8) { - dto_phase = 192 * 1000; - wallclock_ratio = 3; - } else if (max_ratio >= 4) { - dto_phase = 96 * 1000; - wallclock_ratio = 2; - } else if (max_ratio >= 2) { - dto_phase = 48 * 1000; - wallclock_ratio = 1; - } else { - dto_phase = 24 * 1000; - wallclock_ratio = 0; - } - dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; - dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); - WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); + dto_phase = 24 * 1000; + wallclock_ratio = 0; } - /* XXX two dtos; generally use dto0 for hdmi */ + value = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; + value |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); + value &= ~DCCG_AUDIO_DTO1_USE_512FBR_DTO; + WREG32(DCCG_AUDIO_DTO0_CNTL, value); + + /* Two dtos; generally use dto0 for HDMI */ + value = 0; + + if (crtc) + value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); + + WREG32(DCCG_AUDIO_DTO_SOURCE, value); + /* Express [24MHz / target pixel clock] as an exact rational * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator */ - WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); - WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); + WREG32(DCCG_AUDIO_DTO0_MODULE, clock); } +void dce4_dp_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock) +{ + u32 value; + + value = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; + value |= DCCG_AUDIO_DTO1_USE_512FBR_DTO; + WREG32(DCCG_AUDIO_DTO1_CNTL, value); + + /* Two dtos; generally use dto1 for DP */ + value = 0; + value |= DCCG_AUDIO_DTO_SEL; + + if (crtc) + value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); + + WREG32(DCCG_AUDIO_DTO_SOURCE, value); + + /* Express [24MHz / target pixel clock] as an exact rational + * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE + * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator + */ + WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); + WREG32(DCCG_AUDIO_DTO1_MODULE, rdev->clock.max_pixel_clock * 10); +} /* * update the info frames with the data from the current display mode @@ -302,7 +322,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode dig->afmt->pin = radeon_audio_get_pin(encoder); radeon_audio_enable(rdev, dig->afmt->pin, 0); - evergreen_audio_set_dto(encoder, mode->clock); + radeon_audio_set_dto(encoder, mode->clock); WREG32(HDMI_VBI_PACKET_CONTROL + offset, HDMI_NULL_SEND); /* send null packets when required */ diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b066d6711b8d..ee83d2a88750 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -509,6 +509,7 @@ #define DCCG_AUDIO_DTO1_MODULE 0x05c4 #define DCCG_AUDIO_DTO1_LOAD 0x05c8 #define DCCG_AUDIO_DTO1_CNTL 0x05cc +# define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3) /* DCE 4.0 AFMT */ #define HDMI_CONTROL 0x7030 diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 1c49f4d2945a..30580d1a14f0 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -380,73 +380,29 @@ void r600_hdmi_audio_workaround(struct drm_encoder *encoder) value, ~HDMI0_AUDIO_TEST_EN); } -void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) +void r600_hdmi_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock) { - struct drm_device *dev = encoder->dev; - 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; - u32 base_rate = 24000; - u32 max_ratio = clock / base_rate; - u32 dto_phase; - u32 dto_modulo = clock; - u32 wallclock_ratio; - u32 dto_cntl; + struct radeon_encoder *radeon_encoder; + struct radeon_encoder_atom_dig *dig; - if (!dig || !dig->afmt) + if (!crtc) return; - if (max_ratio >= 8) { - dto_phase = 192 * 1000; - wallclock_ratio = 3; - } else if (max_ratio >= 4) { - dto_phase = 96 * 1000; - wallclock_ratio = 2; - } else if (max_ratio >= 2) { - dto_phase = 48 * 1000; - wallclock_ratio = 1; - } else { - dto_phase = 24 * 1000; - wallclock_ratio = 0; - } + radeon_encoder = to_radeon_encoder(crtc->encoder); + dig = radeon_encoder->enc_priv; - /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. - * doesn't matter which one you use. Just use the first one. - */ - /* XXX two dtos; generally use dto0 for hdmi */ - /* Express [24MHz / target pixel clock] as an exact rational - * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE - * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator - */ - if (ASIC_IS_DCE32(rdev)) { - if (dig->dig_encoder == 0) { - dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; - dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); - WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); - WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); - WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); - WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ - } else { - dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; - dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); - WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); - WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); - WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); - WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ - } + if (!dig) + return; + + if (dig->dig_encoder == 0) { + WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100); + WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); + WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ } else { - /* according to the reg specs, this should DCE3.2 only, but in - * practice it seems to cover DCE2.0/3.0/3.1 as well. - */ - if (dig->dig_encoder == 0) { - WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); - WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); - WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ - } else { - WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100); - WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); - WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ - } + WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100); + WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); + WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ } } @@ -477,7 +433,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod dig->afmt->pin = radeon_audio_get_pin(encoder); radeon_audio_enable(rdev, dig->afmt->pin, 0); - r600_audio_set_dto(encoder, mode->clock); + radeon_audio_set_dto(encoder, mode->clock); WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index e6c73f8206b2..2a2bf5b5b805 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -62,6 +62,18 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); void dce6_afmt_select_pin(struct drm_encoder *encoder); +void r600_hdmi_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock); +void dce3_2_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock); +void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock); +void dce4_dp_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock); +void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock); +void dce6_dp_audio_set_dto(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock); static const u32 pin_offsets[7] = { @@ -85,6 +97,12 @@ static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset, WREG32(reg, v); } +static struct radeon_audio_basic_funcs r600_funcs = { + .endpoint_rreg = radeon_audio_rreg, + .endpoint_wreg = radeon_audio_wreg, + .enable = r600_audio_enable, +}; + static struct radeon_audio_basic_funcs dce32_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, @@ -103,16 +121,23 @@ static struct radeon_audio_basic_funcs dce6_funcs = { .enable = dce6_audio_enable, }; +static struct radeon_audio_funcs r600_hdmi_funcs = { + .get_pin = r600_audio_get_pin, + .set_dto = r600_hdmi_audio_set_dto, +}; + static struct radeon_audio_funcs dce32_hdmi_funcs = { .get_pin = r600_audio_get_pin, .write_sad_regs = dce3_2_afmt_write_sad_regs, .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, + .set_dto = dce3_2_audio_set_dto, }; static struct radeon_audio_funcs dce32_dp_funcs = { .get_pin = r600_audio_get_pin, .write_sad_regs = dce3_2_afmt_write_sad_regs, .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, + .set_dto = dce3_2_audio_set_dto, }; static struct radeon_audio_funcs dce4_hdmi_funcs = { @@ -120,6 +145,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .write_sad_regs = evergreen_hdmi_write_sad_regs, .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, .write_latency_fields = dce4_afmt_write_latency_fields, + .set_dto = dce4_hdmi_audio_set_dto, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -127,6 +153,7 @@ static struct radeon_audio_funcs dce4_dp_funcs = { .write_sad_regs = evergreen_hdmi_write_sad_regs, .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, .write_latency_fields = dce4_afmt_write_latency_fields, + .set_dto = dce4_dp_audio_set_dto, }; static struct radeon_audio_funcs dce6_hdmi_funcs = { @@ -135,6 +162,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, .write_latency_fields = dce6_afmt_write_latency_fields, + .set_dto = dce6_hdmi_audio_set_dto, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -143,6 +171,7 @@ static struct radeon_audio_funcs dce6_dp_funcs = { .write_sad_regs = dce6_afmt_write_sad_regs, .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, .write_latency_fields = dce6_afmt_write_latency_fields, + .set_dto = dce6_dp_audio_set_dto, }; static void radeon_audio_interface_init(struct radeon_device *rdev) @@ -155,10 +184,14 @@ static void radeon_audio_interface_init(struct radeon_device *rdev) rdev->audio.funcs = &dce4_funcs; rdev->audio.hdmi_funcs = &dce4_hdmi_funcs; rdev->audio.dp_funcs = &dce4_dp_funcs; - } else { + } else if (ASIC_IS_DCE32(rdev)) { rdev->audio.funcs = &dce32_funcs; rdev->audio.hdmi_funcs = &dce32_hdmi_funcs; rdev->audio.dp_funcs = &dce32_dp_funcs; + } else { + rdev->audio.funcs = &r600_funcs; + rdev->audio.hdmi_funcs = &r600_hdmi_funcs; + rdev->audio.dp_funcs = 0; } } @@ -393,3 +426,13 @@ void radeon_audio_fini(struct radeon_device *rdev) rdev->audio.enabled = false; } + +void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) +{ + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_crtc *crtc = to_radeon_crtc(encoder->crtc); + + if (radeon_encoder->audio && radeon_encoder->audio->set_dto) + radeon_encoder->audio->set_dto(rdev, crtc, clock); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 5844993a1edb..06b80de7cdbe 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -51,6 +51,8 @@ struct radeon_audio_funcs struct cea_sad *sads, int sad_count); void (*write_speaker_allocation)(struct drm_encoder *encoder, u8 *sadb, int sad_count); + void (*set_dto)(struct radeon_device *rdev, + struct radeon_crtc *crtc, unsigned int clock); }; int radeon_audio_init(struct radeon_device *rdev); @@ -69,5 +71,6 @@ void radeon_audio_select_pin(struct drm_encoder *encoder); void radeon_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); void radeon_audio_fini(struct radeon_device *rdev); +void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); #endif diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 84999242c747..cbd91d226f3c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -901,6 +901,16 @@ /* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */ #define CRTC_STATUS_FRAME_COUNT 0x6e98 +/* Audio clocks */ +#define DCCG_AUDIO_DTO_SOURCE 0x05ac +# define DCCG_AUDIO_DTO0_SOURCE_SEL(x) ((x) << 0) /* crtc0 - crtc5 */ +# define DCCG_AUDIO_DTO_SEL (1 << 4) /* 0=dto0 1=dto1 */ + +#define DCCG_AUDIO_DTO0_PHASE 0x05b0 +#define DCCG_AUDIO_DTO0_MODULE 0x05b4 +#define DCCG_AUDIO_DTO1_PHASE 0x05b8 +#define DCCG_AUDIO_DTO1_MODULE 0x05bc + #define AFMT_AUDIO_SRC_CONTROL 0x713c #define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0) /* AFMT_AUDIO_SRC_SELECT -- cgit v1.2.3 From 96ea7afbc256ce7e2b2446909f52dab357942c3c Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Fri, 5 Dec 2014 17:59:56 -0500 Subject: radeon/audio: consolidate update_avi_infoframe() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 2 +- drivers/gpu/drm/radeon/evergreen_hdmi.c | 16 +++++----------- drivers/gpu/drm/radeon/r600_hdmi.c | 14 ++++---------- drivers/gpu/drm/radeon/radeon_audio.c | 20 ++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 4 ++++ 5 files changed, 34 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 6cb2f1171539..0accc5ee0e39 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -254,7 +254,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m return; } - r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); + radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); r600_hdmi_update_ACR(encoder, mode->clock); /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 38b1c51cce4d..f2896e5ff055 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -195,18 +195,12 @@ void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, } /* - * build a HDMI Video Info Frame + * build a AVI Info Frame */ -static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder, - void *buffer, size_t size) +void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset, + unsigned char *buffer, size_t size) { - struct drm_device *dev = encoder->dev; - 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; - uint32_t offset = dig->afmt->offset; uint8_t *frame = buffer + 3; - uint8_t *header = buffer; WREG32(AFMT_AVI_INFO0 + offset, frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); @@ -215,7 +209,7 @@ static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder, WREG32(AFMT_AVI_INFO2 + offset, frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); WREG32(AFMT_AVI_INFO3 + offset, - frame[0xC] | (frame[0xD] << 8) | (header[1] << 24)); + frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); } void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, @@ -431,7 +425,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode return; } - evergreen_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); + radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, HDMI_AVI_INFO_SEND | /* enable AVI info frames */ diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 30580d1a14f0..53ee7ad9612c 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -285,16 +285,10 @@ void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) /* * build a HDMI Video Info Frame */ -void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, - size_t size) +void r600_update_avi_infoframe(struct radeon_device *rdev, u32 offset, + unsigned char *buffer, size_t size) { - struct drm_device *dev = encoder->dev; - 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; - uint32_t offset = dig->afmt->offset; uint8_t *frame = buffer + 3; - uint8_t *header = buffer; WREG32(HDMI0_AVI_INFO0 + offset, frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); @@ -303,7 +297,7 @@ void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, WREG32(HDMI0_AVI_INFO2 + offset, frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); WREG32(HDMI0_AVI_INFO3 + offset, - frame[0xC] | (frame[0xD] << 8) | (header[1] << 24)); + frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); } /* @@ -486,7 +480,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod return; } - r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); + radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); /* fglrx duplicates INFOFRAME_CONTROL0 & INFOFRAME_CONTROL1 ops here */ diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 2a2bf5b5b805..cc58ee8c7d2f 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -74,6 +74,10 @@ void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, struct radeon_crtc *crtc, unsigned int clock); void dce6_dp_audio_set_dto(struct radeon_device *rdev, struct radeon_crtc *crtc, unsigned int clock); +void r600_update_avi_infoframe(struct radeon_device *rdev, u32 offset, + unsigned char *buffer, size_t size); +void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset, + unsigned char *buffer, size_t size); static const u32 pin_offsets[7] = { @@ -101,24 +105,28 @@ static struct radeon_audio_basic_funcs r600_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, .enable = r600_audio_enable, + .update_avi_infoframe = r600_update_avi_infoframe, }; static struct radeon_audio_basic_funcs dce32_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, .enable = r600_audio_enable, + .update_avi_infoframe = r600_update_avi_infoframe, }; static struct radeon_audio_basic_funcs dce4_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, .enable = dce4_audio_enable, + .update_avi_infoframe = evergreen_update_avi_infoframe, }; static struct radeon_audio_basic_funcs dce6_funcs = { .endpoint_rreg = dce6_endpoint_rreg, .endpoint_wreg = dce6_endpoint_wreg, .enable = dce6_audio_enable, + .update_avi_infoframe = evergreen_update_avi_infoframe, }; static struct radeon_audio_funcs r600_hdmi_funcs = { @@ -436,3 +444,15 @@ void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) if (radeon_encoder->audio && radeon_encoder->audio->set_dto) radeon_encoder->audio->set_dto(rdev, crtc, clock); } + +void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, + size_t size) +{ + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (dig && dig->afmt && rdev->audio.funcs->update_avi_infoframe) + rdev->audio.funcs->update_avi_infoframe(rdev, dig->afmt->offset, + buffer, size); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 06b80de7cdbe..dc85d53d1587 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -39,6 +39,8 @@ struct radeon_audio_basic_funcs u32 offset, u32 reg, u32 v); void (*enable)(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); + void (*update_avi_infoframe)(struct radeon_device *rdev, u32 offset, + unsigned char *buffer, size_t size); }; struct radeon_audio_funcs @@ -72,5 +74,7 @@ void radeon_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); void radeon_audio_fini(struct radeon_device *rdev); void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); +void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, + size_t size); #endif -- cgit v1.2.3 From 64424d6e45aeee311a4231def7e125bcc2de0855 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Sat, 6 Dec 2014 20:19:16 -0500 Subject: radeon/audio: consolidate update_acr() functions (v2) V2: fix missing dce6 callback Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 38 ++++++++-- drivers/gpu/drm/radeon/evergreen_hdmi.c | 46 ++++++------ drivers/gpu/drm/radeon/r600_hdmi.c | 129 ++++++-------------------------- drivers/gpu/drm/radeon/radeon_audio.c | 100 +++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 3 + 5 files changed, 183 insertions(+), 133 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 0accc5ee0e39..2a963c173cc1 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -167,6 +167,38 @@ void dce3_2_audio_set_dto(struct radeon_device *rdev, } } +void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, + const struct radeon_hdmi_acr *acr) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + WREG32(HDMI0_ACR_PACKET_CONTROL + offset, + HDMI0_ACR_SOURCE | /* select SW CTS value */ + HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ + + WREG32_P(HDMI0_ACR_32_0 + offset, + HDMI0_ACR_CTS_32(acr->cts_32khz), + ~HDMI0_ACR_CTS_32_MASK); + WREG32_P(HDMI0_ACR_32_1 + offset, + HDMI0_ACR_N_32(acr->n_32khz), + ~HDMI0_ACR_N_32_MASK); + + WREG32_P(HDMI0_ACR_44_0 + offset, + HDMI0_ACR_CTS_44(acr->cts_44_1khz), + ~HDMI0_ACR_CTS_44_MASK); + WREG32_P(HDMI0_ACR_44_1 + offset, + HDMI0_ACR_N_44(acr->n_44_1khz), + ~HDMI0_ACR_N_44_MASK); + + WREG32_P(HDMI0_ACR_48_0 + offset, + HDMI0_ACR_CTS_48(acr->cts_48khz), + ~HDMI0_ACR_CTS_48_MASK); + WREG32_P(HDMI0_ACR_48_1 + offset, + HDMI0_ACR_N_48(acr->n_48khz), + ~HDMI0_ACR_N_48_MASK); +} + /* * update the info frames with the data from the current display mode */ @@ -220,10 +252,6 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m radeon_audio_write_sad_regs(encoder); } - WREG32(HDMI0_ACR_PACKET_CONTROL + offset, - HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */ - HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ - WREG32(HDMI0_VBI_PACKET_CONTROL + offset, HDMI0_NULL_SEND | /* send null packets when required */ HDMI0_GC_SEND | /* send general control packets */ @@ -255,7 +283,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m } radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); - r600_hdmi_update_ACR(encoder, mode->clock); + radeon_audio_update_acr(encoder, mode->clock); /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index f2896e5ff055..05cef011c3af 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -64,26 +64,34 @@ void dce4_audio_enable(struct radeon_device *rdev, WREG32(AZ_HOT_PLUG_CONTROL, tmp); } -/* - * update the N and CTS parameters for a given pixel clock rate - */ -static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) +void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset, + const struct radeon_hdmi_acr *acr) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - uint32_t offset = dig->afmt->offset; + int bpc = 8; + + if (encoder->crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); + bpc = radeon_crtc->bpc; + } - WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr.cts_32khz)); - WREG32(HDMI_ACR_32_1 + offset, acr.n_32khz); + if (bpc > 8) + WREG32(HDMI_ACR_PACKET_CONTROL + offset, + HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ + else + WREG32(HDMI_ACR_PACKET_CONTROL + offset, + HDMI_ACR_SOURCE | /* select SW CTS value */ + HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ + + WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr->cts_32khz)); + WREG32(HDMI_ACR_32_1 + offset, acr->n_32khz); - WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr.cts_44_1khz)); - WREG32(HDMI_ACR_44_1 + offset, acr.n_44_1khz); + WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr->cts_44_1khz)); + WREG32(HDMI_ACR_44_1 + offset, acr->n_44_1khz); - WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr.cts_48khz)); - WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); + WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr->cts_48khz)); + WREG32(HDMI_ACR_48_1 + offset, acr->n_48khz); } void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, @@ -378,15 +386,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */ - if (bpc > 8) - WREG32(HDMI_ACR_PACKET_CONTROL + offset, - HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ - else - WREG32(HDMI_ACR_PACKET_CONTROL + offset, - HDMI_ACR_SOURCE | /* select SW CTS value */ - HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ - - evergreen_hdmi_update_ACR(encoder, mode->clock); + radeon_audio_update_acr(encoder, mode->clock); WREG32(AFMT_60958_0 + offset, AFMT_60958_CS_CHANNEL_NUMBER_L(1)); diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 53ee7ad9612c..f91273912eb8 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -56,21 +56,6 @@ enum r600_hdmi_iec_status_bits { AUDIO_STATUS_LEVEL = 0x80 }; -static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { - /* 32kHz 44.1kHz 48kHz */ - /* Clock N CTS N CTS N CTS */ - { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ - { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ - { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ - { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ - { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ - { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ - { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ - { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ - { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ - { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ -}; - static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) { struct r600_audio_pin status; @@ -189,97 +174,41 @@ struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) return &rdev->audio.pin[0]; } -/* - * calculate CTS and N values if they are not found in the table - */ -static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) -{ - int n, cts; - unsigned long div, mul; - - /* Safe, but overly large values */ - n = 128 * freq; - cts = clock * 1000; - - /* Smallest valid fraction */ - div = gcd(n, cts); - - n /= div; - cts /= div; - - /* - * The optimal N is 128*freq/1000. Calculate the closest larger - * value that doesn't truncate any bits. - */ - mul = ((128*freq/1000) + (n-1))/n; - - n *= mul; - cts *= mul; - - /* Check that we are in spec (not always possible) */ - if (n < (128*freq/1500)) - printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); - if (n > (128*freq/300)) - printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); - - *N = n; - *CTS = cts; - - DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", - *N, *CTS, freq); -} - -struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) -{ - struct radeon_hdmi_acr res; - u8 i; - - /* Precalculated values for common clocks */ - for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) { - if (r600_hdmi_predefined_acr[i].clock == clock) - return r600_hdmi_predefined_acr[i]; - } - - /* And odd clocks get manually calculated */ - r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); - r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); - r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); - - return res; -} - -/* - * update the N and CTS parameters for a given pixel clock rate - */ -void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) +void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset, + const struct radeon_hdmi_acr *acr) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - uint32_t offset = dig->afmt->offset; + + /* DCE 3.0 uses register that's normally for CRC_CONTROL */ + uint32_t acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL : + HDMI0_ACR_PACKET_CONTROL; + WREG32_P(acr_ctl + offset, + HDMI0_ACR_SOURCE | /* select SW CTS value */ + HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */ + ~(HDMI0_ACR_SOURCE | + HDMI0_ACR_AUTO_SEND)); WREG32_P(HDMI0_ACR_32_0 + offset, - HDMI0_ACR_CTS_32(acr.cts_32khz), - ~HDMI0_ACR_CTS_32_MASK); + HDMI0_ACR_CTS_32(acr->cts_32khz), + ~HDMI0_ACR_CTS_32_MASK); WREG32_P(HDMI0_ACR_32_1 + offset, - HDMI0_ACR_N_32(acr.n_32khz), - ~HDMI0_ACR_N_32_MASK); + HDMI0_ACR_N_32(acr->n_32khz), + ~HDMI0_ACR_N_32_MASK); WREG32_P(HDMI0_ACR_44_0 + offset, - HDMI0_ACR_CTS_44(acr.cts_44_1khz), - ~HDMI0_ACR_CTS_44_MASK); + HDMI0_ACR_CTS_44(acr->cts_44_1khz), + ~HDMI0_ACR_CTS_44_MASK); WREG32_P(HDMI0_ACR_44_1 + offset, - HDMI0_ACR_N_44(acr.n_44_1khz), - ~HDMI0_ACR_N_44_MASK); + HDMI0_ACR_N_44(acr->n_44_1khz), + ~HDMI0_ACR_N_44_MASK); WREG32_P(HDMI0_ACR_48_0 + offset, - HDMI0_ACR_CTS_48(acr.cts_48khz), - ~HDMI0_ACR_CTS_48_MASK); + HDMI0_ACR_CTS_48(acr->cts_48khz), + ~HDMI0_ACR_CTS_48_MASK); WREG32_P(HDMI0_ACR_48_1 + offset, - HDMI0_ACR_N_48(acr.n_48khz), - ~HDMI0_ACR_N_48_MASK); + HDMI0_ACR_N_48(acr->n_48khz), + ~HDMI0_ACR_N_48_MASK); } /* @@ -412,7 +341,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; struct hdmi_avi_infoframe frame; uint32_t offset; - uint32_t acr_ctl; ssize_t err; if (!dig || !dig->afmt) @@ -439,15 +367,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod HDMI0_AUDIO_PACKETS_PER_LINE_MASK | HDMI0_60958_CS_UPDATE)); - /* DCE 3.0 uses register that's normally for CRC_CONTROL */ - acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL : - HDMI0_ACR_PACKET_CONTROL; - WREG32_P(acr_ctl + offset, - HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */ - HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */ - ~(HDMI0_ACR_SOURCE | - HDMI0_ACR_AUTO_SEND)); - WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset, HDMI0_NULL_SEND | /* send null packets when required */ HDMI0_GC_SEND | /* send general control packets */ @@ -493,7 +412,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod HDMI0_GENERIC0_LINE_MASK | HDMI0_GENERIC1_LINE_MASK)); - r600_hdmi_update_ACR(encoder, mode->clock); + radeon_audio_update_acr(encoder, mode->clock); WREG32_P(HDMI0_60958_0 + offset, HDMI0_60958_CS_CHANNEL_NUMBER_L(1), diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index cc58ee8c7d2f..dbb3c594e9ae 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -22,6 +22,7 @@ * Authors: Slava Grigorev */ +#include #include #include #include "radeon.h" @@ -78,6 +79,12 @@ void r600_update_avi_infoframe(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size); void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size); +void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset, + const struct radeon_hdmi_acr *acr); +void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, + const struct radeon_hdmi_acr *acr); +void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset, + const struct radeon_hdmi_acr *acr); static const u32 pin_offsets[7] = { @@ -132,6 +139,7 @@ static struct radeon_audio_basic_funcs dce6_funcs = { static struct radeon_audio_funcs r600_hdmi_funcs = { .get_pin = r600_audio_get_pin, .set_dto = r600_hdmi_audio_set_dto, + .update_acr = r600_hdmi_update_acr, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -139,6 +147,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = { .write_sad_regs = dce3_2_afmt_write_sad_regs, .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, .set_dto = dce3_2_audio_set_dto, + .update_acr = dce3_2_hdmi_update_acr, }; static struct radeon_audio_funcs dce32_dp_funcs = { @@ -154,6 +163,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, .write_latency_fields = dce4_afmt_write_latency_fields, .set_dto = dce4_hdmi_audio_set_dto, + .update_acr = evergreen_hdmi_update_acr, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -171,6 +181,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, .write_latency_fields = dce6_afmt_write_latency_fields, .set_dto = dce6_hdmi_audio_set_dto, + .update_acr = evergreen_hdmi_update_acr, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -456,3 +467,92 @@ void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, rdev->audio.funcs->update_avi_infoframe(rdev, dig->afmt->offset, buffer, size); } + +/* + * calculate CTS and N values if they are not found in the table + */ +static void radeon_audio_calc_cts(unsigned int clock, int *CTS, int *N, int freq) +{ + int n, cts; + unsigned long div, mul; + + /* Safe, but overly large values */ + n = 128 * freq; + cts = clock * 1000; + + /* Smallest valid fraction */ + div = gcd(n, cts); + + n /= div; + cts /= div; + + /* + * The optimal N is 128*freq/1000. Calculate the closest larger + * value that doesn't truncate any bits. + */ + mul = ((128*freq/1000) + (n-1))/n; + + n *= mul; + cts *= mul; + + /* Check that we are in spec (not always possible) */ + if (n < (128*freq/1500)) + printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); + if (n > (128*freq/300)) + printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); + + *N = n; + *CTS = cts; + + DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", + *N, *CTS, freq); +} + +static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock) +{ + static struct radeon_hdmi_acr res; + u8 i; + + static const struct radeon_hdmi_acr hdmi_predefined_acr[] = { + /* 32kHz 44.1kHz 48kHz */ + /* Clock N CTS N CTS N CTS */ + { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ + { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ + { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ + { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ + { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ + { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ + { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ + { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ + { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ + { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ + }; + + /* Precalculated values for common clocks */ + for (i = 0; i < ARRAY_SIZE(hdmi_predefined_acr); i++) + if (hdmi_predefined_acr[i].clock == clock) + return &hdmi_predefined_acr[i]; + + /* And odd clocks get manually calculated */ + radeon_audio_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); + radeon_audio_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); + radeon_audio_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); + + return &res; +} + +/* + * update the N and CTS parameters for a given pixel clock rate + */ +void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock) +{ + const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock); + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (!dig || !dig->afmt) + return; + + if (radeon_encoder->audio && radeon_encoder->audio->update_acr) + radeon_encoder->audio->update_acr(encoder, dig->afmt->offset, acr); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index dc85d53d1587..a4d055311ab5 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -55,6 +55,8 @@ struct radeon_audio_funcs u8 *sadb, int sad_count); void (*set_dto)(struct radeon_device *rdev, struct radeon_crtc *crtc, unsigned int clock); + void (*update_acr)(struct drm_encoder *encoder, long offset, + const struct radeon_hdmi_acr *acr); }; int radeon_audio_init(struct radeon_device *rdev); @@ -76,5 +78,6 @@ void radeon_audio_fini(struct radeon_device *rdev); void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, size_t size); +void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock); #endif -- cgit v1.2.3 From 930a9785120d7397ba8912e1a4f72b65e7e25f25 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 20 Jan 2015 19:20:52 -0500 Subject: radeon/audio: moved VBI packet programming to separate functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 9 +-------- drivers/gpu/drm/radeon/evergreen_hdmi.c | 20 ++++++++++++-------- drivers/gpu/drm/radeon/r600_hdmi.c | 17 ++++++++++++----- drivers/gpu/drm/radeon/radeon_audio.c | 18 ++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 2 ++ 5 files changed, 45 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 2a963c173cc1..f07d7b689e49 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -226,9 +226,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m radeon_audio_enable(rdev, dig->afmt->pin, 0); radeon_audio_set_dto(encoder, mode->clock); - - WREG32(HDMI0_VBI_PACKET_CONTROL + offset, - HDMI0_NULL_SEND); /* send null packets when required */ + radeon_audio_set_vbi_packet(encoder); WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); @@ -252,11 +250,6 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m radeon_audio_write_sad_regs(encoder); } - WREG32(HDMI0_VBI_PACKET_CONTROL + offset, - HDMI0_NULL_SEND | /* send null packets when required */ - HDMI0_GC_SEND | /* send general control packets */ - HDMI0_GC_CONT); /* send general control packets every frame */ - /* TODO: HDMI0_AUDIO_INFO_UPDATE */ WREG32(HDMI0_INFOFRAME_CONTROL0 + offset, HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 05cef011c3af..3c4b33f094b9 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -289,6 +289,17 @@ void dce4_dp_audio_set_dto(struct radeon_device *rdev, WREG32(DCCG_AUDIO_DTO1_MODULE, rdev->clock.max_pixel_clock * 10); } +void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + WREG32(HDMI_VBI_PACKET_CONTROL + offset, + HDMI_NULL_SEND | /* send null packets when required */ + HDMI_GC_SEND | /* send general control packets */ + HDMI_GC_CONT); /* send general control packets every frame */ +} + /* * update the info frames with the data from the current display mode */ @@ -325,9 +336,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode radeon_audio_enable(rdev, dig->afmt->pin, 0); radeon_audio_set_dto(encoder, mode->clock); - - WREG32(HDMI_VBI_PACKET_CONTROL + offset, - HDMI_NULL_SEND); /* send null packets when required */ + radeon_audio_set_vbi_packet(encoder); WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000); @@ -360,11 +369,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode WREG32(HDMI_CONTROL + offset, val); - WREG32(HDMI_VBI_PACKET_CONTROL + offset, - HDMI_NULL_SEND | /* send null packets when required */ - HDMI_GC_SEND | /* send general control packets */ - HDMI_GC_CONT); /* send general control packets every frame */ - WREG32(HDMI_INFOFRAME_CONTROL0 + offset, HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index f91273912eb8..533fce0ef533 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -329,6 +329,17 @@ void r600_hdmi_audio_set_dto(struct radeon_device *rdev, } } +void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset, + HDMI0_NULL_SEND | /* send null packets when required */ + HDMI0_GC_SEND | /* send general control packets */ + HDMI0_GC_CONT); /* send general control packets every frame */ +} + /* * update the info frames with the data from the current display mode */ @@ -356,6 +367,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod radeon_audio_enable(rdev, dig->afmt->pin, 0); radeon_audio_set_dto(encoder, mode->clock); + radeon_audio_set_vbi_packet(encoder); WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ @@ -367,11 +379,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod HDMI0_AUDIO_PACKETS_PER_LINE_MASK | HDMI0_60958_CS_UPDATE)); - WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset, - HDMI0_NULL_SEND | /* send null packets when required */ - HDMI0_GC_SEND | /* send general control packets */ - HDMI0_GC_CONT); /* send general control packets every frame */ - WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */ diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index dbb3c594e9ae..8fad9af92ec8 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -85,6 +85,8 @@ void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, const struct radeon_hdmi_acr *acr); void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset, const struct radeon_hdmi_acr *acr); +void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset); +void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset); static const u32 pin_offsets[7] = { @@ -140,6 +142,7 @@ static struct radeon_audio_funcs r600_hdmi_funcs = { .get_pin = r600_audio_get_pin, .set_dto = r600_hdmi_audio_set_dto, .update_acr = r600_hdmi_update_acr, + .set_vbi_packet = r600_set_vbi_packet, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -148,6 +151,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = { .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, .set_dto = dce3_2_audio_set_dto, .update_acr = dce3_2_hdmi_update_acr, + .set_vbi_packet = r600_set_vbi_packet, }; static struct radeon_audio_funcs dce32_dp_funcs = { @@ -164,6 +168,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .write_latency_fields = dce4_afmt_write_latency_fields, .set_dto = dce4_hdmi_audio_set_dto, .update_acr = evergreen_hdmi_update_acr, + .set_vbi_packet = dce4_set_vbi_packet, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -182,6 +187,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .write_latency_fields = dce6_afmt_write_latency_fields, .set_dto = dce6_hdmi_audio_set_dto, .update_acr = evergreen_hdmi_update_acr, + .set_vbi_packet = dce4_set_vbi_packet, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -556,3 +562,15 @@ void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock) if (radeon_encoder->audio && radeon_encoder->audio->update_acr) radeon_encoder->audio->update_acr(encoder, dig->afmt->offset, acr); } + +void radeon_audio_set_vbi_packet(struct drm_encoder *encoder) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (!dig || !dig->afmt) + return; + + if (radeon_encoder->audio && radeon_encoder->audio->set_vbi_packet) + radeon_encoder->audio->set_vbi_packet(encoder, dig->afmt->offset); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index a4d055311ab5..7cdbd7f7faa4 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -57,6 +57,7 @@ struct radeon_audio_funcs struct radeon_crtc *crtc, unsigned int clock); void (*update_acr)(struct drm_encoder *encoder, long offset, const struct radeon_hdmi_acr *acr); + void (*set_vbi_packet)(struct drm_encoder *encoder, u32 offset); }; int radeon_audio_init(struct radeon_device *rdev); @@ -79,5 +80,6 @@ void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, size_t size); void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock); +void radeon_audio_set_vbi_packet(struct drm_encoder *encoder); #endif -- cgit v1.2.3 From be273e58f00f75c750fd0ece8f0d7c3cfb36c88e Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Mon, 8 Dec 2014 16:25:37 -0500 Subject: radeon: moved HDMI color depth programming to a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 2 + drivers/gpu/drm/radeon/evergreen_hdmi.c | 69 +++++++++++++++++---------------- drivers/gpu/drm/radeon/r600_hdmi.c | 1 + drivers/gpu/drm/radeon/radeon_audio.c | 22 +++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 2 + 5 files changed, 62 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index f07d7b689e49..c5f8d5d449e8 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -230,6 +230,8 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); + radeon_hdmi_set_color_depth(encoder); + if (ASIC_IS_DCE32(rdev)) { WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 3c4b33f094b9..44ae355f5669 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -300,45 +300,12 @@ void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset) HDMI_GC_CONT); /* send general control packets every frame */ } -/* - * update the info frames with the data from the current display mode - */ -void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) +void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, u32 offset, int bpc) { struct drm_device *dev = encoder->dev; 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); - u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; - struct hdmi_avi_infoframe frame; - uint32_t offset; - ssize_t err; uint32_t val; - int bpc = 8; - - if (!dig || !dig->afmt) - return; - - /* Silent, r600_hdmi_enable will raise WARN for us */ - if (!dig->afmt->enabled) - return; - offset = dig->afmt->offset; - - /* hdmi deep color mode general control packets setup, if bpc > 8 */ - if (encoder->crtc) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - bpc = radeon_crtc->bpc; - } - - /* disable audio prior to setting up hw */ - dig->afmt->pin = radeon_audio_get_pin(encoder); - radeon_audio_enable(rdev, dig->afmt->pin, 0); - - radeon_audio_set_dto(encoder, mode->clock); - radeon_audio_set_vbi_packet(encoder); - - WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000); val = RREG32(HDMI_CONTROL + offset); val &= ~HDMI_DEEP_COLOR_ENABLE; @@ -368,6 +335,40 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode } WREG32(HDMI_CONTROL + offset, val); +} + +/* + * update the info frames with the data from the current display mode + */ +void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) +{ + struct drm_device *dev = encoder->dev; + 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; + u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; + struct hdmi_avi_infoframe frame; + uint32_t offset; + ssize_t err; + + if (!dig || !dig->afmt) + return; + + /* Silent, r600_hdmi_enable will raise WARN for us */ + if (!dig->afmt->enabled) + return; + offset = dig->afmt->offset; + + /* disable audio prior to setting up hw */ + dig->afmt->pin = radeon_audio_get_pin(encoder); + radeon_audio_enable(rdev, dig->afmt->pin, 0); + + radeon_audio_set_dto(encoder, mode->clock); + radeon_audio_set_vbi_packet(encoder); + + WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000); + + radeon_hdmi_set_color_depth(encoder); WREG32(HDMI_INFOFRAME_CONTROL0 + offset, HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 533fce0ef533..5c5e723787ab 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -368,6 +368,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod radeon_audio_set_dto(encoder, mode->clock); radeon_audio_set_vbi_packet(encoder); + radeon_hdmi_set_color_depth(encoder); WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 8fad9af92ec8..ac9ebbfc48af 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -87,6 +87,8 @@ void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset, const struct radeon_hdmi_acr *acr); void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset); void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset); +void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, + u32 offset, int bpc); static const u32 pin_offsets[7] = { @@ -169,6 +171,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .set_dto = dce4_hdmi_audio_set_dto, .update_acr = evergreen_hdmi_update_acr, .set_vbi_packet = dce4_set_vbi_packet, + .set_color_depth = dce4_hdmi_set_color_depth, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -188,6 +191,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .set_dto = dce6_hdmi_audio_set_dto, .update_acr = evergreen_hdmi_update_acr, .set_vbi_packet = dce4_set_vbi_packet, + .set_color_depth = dce4_hdmi_set_color_depth, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -574,3 +578,21 @@ void radeon_audio_set_vbi_packet(struct drm_encoder *encoder) if (radeon_encoder->audio && radeon_encoder->audio->set_vbi_packet) radeon_encoder->audio->set_vbi_packet(encoder, dig->afmt->offset); } + +void radeon_hdmi_set_color_depth(struct drm_encoder *encoder) +{ + int bpc = 8; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (!dig || !dig->afmt) + return; + + if (encoder->crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); + bpc = radeon_crtc->bpc; + } + + if (radeon_encoder->audio && radeon_encoder->audio->set_color_depth) + radeon_encoder->audio->set_color_depth(encoder, dig->afmt->offset, bpc); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 7cdbd7f7faa4..f179e5646e42 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -58,6 +58,7 @@ struct radeon_audio_funcs void (*update_acr)(struct drm_encoder *encoder, long offset, const struct radeon_hdmi_acr *acr); void (*set_vbi_packet)(struct drm_encoder *encoder, u32 offset); + void (*set_color_depth)(struct drm_encoder *encoder, u32 offset, int bpc); }; int radeon_audio_init(struct radeon_device *rdev); @@ -81,5 +82,6 @@ void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, size_t size); void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock); void radeon_audio_set_vbi_packet(struct drm_encoder *encoder); +void radeon_hdmi_set_color_depth(struct drm_encoder *encoder); #endif -- cgit v1.2.3 From 8ffea8570d5a7e9dd3c10349ebc3bd79487ae30b Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Mon, 8 Dec 2014 16:41:45 -0500 Subject: radeon/audio: removed unnecessary CRC control programing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 3 --- drivers/gpu/drm/radeon/evergreen_hdmi.c | 3 --- 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index c5f8d5d449e8..e96dd35fe59e 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -227,9 +227,6 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m radeon_audio_set_dto(encoder, mode->clock); radeon_audio_set_vbi_packet(encoder); - - WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); - radeon_hdmi_set_color_depth(encoder); if (ASIC_IS_DCE32(rdev)) { diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 44ae355f5669..454f656a79d0 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -365,9 +365,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode radeon_audio_set_dto(encoder, mode->clock); radeon_audio_set_vbi_packet(encoder); - - WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000); - radeon_hdmi_set_color_depth(encoder); WREG32(HDMI_INFOFRAME_CONTROL0 + offset, -- cgit v1.2.3 From baa7d8e451f030c049f83f943b9995620d6d6bd3 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Mon, 8 Dec 2014 18:28:33 -0500 Subject: radeon/audio: set_avi_packet() function cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 22 +++-------------- drivers/gpu/drm/radeon/evergreen_hdmi.c | 34 ++++++++------------------ drivers/gpu/drm/radeon/r600_hdmi.c | 31 ++++++++---------------- drivers/gpu/drm/radeon/radeon_audio.c | 43 ++++++++++++++++++++++++--------- drivers/gpu/drm/radeon/radeon_audio.h | 8 +++--- 5 files changed, 59 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index e96dd35fe59e..3ec9dea76ed1 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -208,10 +208,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m 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; - u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; - struct hdmi_avi_infoframe frame; uint32_t offset; - ssize_t err; if (!dig || !dig->afmt) return; @@ -250,31 +247,18 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m } /* TODO: HDMI0_AUDIO_INFO_UPDATE */ - WREG32(HDMI0_INFOFRAME_CONTROL0 + offset, - HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ - HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */ + WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ - WREG32(HDMI0_INFOFRAME_CONTROL1 + offset, - HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ + WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ - err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); - if (err < 0) { - DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); + if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - } - - err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); - if (err < 0) { - DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); - return; - } - radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); radeon_audio_update_acr(encoder, mode->clock); /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 454f656a79d0..6d22da986aa6 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -205,7 +205,7 @@ void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, /* * build a AVI Info Frame */ -void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset, +void evergreen_set_avi_packet(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size) { uint8_t *frame = buffer + 3; @@ -218,6 +218,14 @@ void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset, frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); WREG32(AFMT_AVI_INFO3 + offset, frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); + + WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, + HDMI_AVI_INFO_SEND | /* enable AVI info frames */ + HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ + + WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset, + HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ + ~HDMI_AVI_INFO_LINE_MASK); } void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, @@ -346,10 +354,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode 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; - u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; - struct hdmi_avi_infoframe frame; uint32_t offset; - ssize_t err; if (!dig || !dig->afmt) return; @@ -415,27 +420,8 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode radeon_audio_write_sad_regs(encoder); radeon_audio_write_latency_fields(encoder, mode); - err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); - if (err < 0) { - DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); - return; - } - - err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); - if (err < 0) { - DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); + if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - } - - radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); - - WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, - HDMI_AVI_INFO_SEND | /* enable AVI info frames */ - HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ - - WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset, - HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ - ~HDMI_AVI_INFO_LINE_MASK); WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset, AFMT_AUDIO_SAMPLE_SEND); /* send audio packets */ diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 5c5e723787ab..d6447da82c86 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -214,7 +214,7 @@ void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset, /* * build a HDMI Video Info Frame */ -void r600_update_avi_infoframe(struct radeon_device *rdev, u32 offset, +void r600_set_avi_packet(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size) { uint8_t *frame = buffer + 3; @@ -227,6 +227,13 @@ void r600_update_avi_infoframe(struct radeon_device *rdev, u32 offset, frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); WREG32(HDMI0_AVI_INFO3 + offset, frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); + + WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, + HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ + HDMI0_AVI_INFO_CONT); /* send AVI info frames every frame/field */ + + WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, + HDMI0_AVI_INFO_LINE(2)); /* anything other than 0 */ } /* @@ -349,10 +356,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod 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; - u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; - struct hdmi_avi_infoframe frame; uint32_t offset; - ssize_t err; if (!dig || !dig->afmt) return; @@ -381,33 +385,18 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod HDMI0_60958_CS_UPDATE)); WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, - HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ - HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */ HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset, - HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */ - ~(HDMI0_AVI_INFO_LINE_MASK | - HDMI0_AUDIO_INFO_LINE_MASK)); + ~HDMI0_AUDIO_INFO_LINE_MASK); WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); /* unset HDMI0_GC_AVMUTE */ - err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); - if (err < 0) { - DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); + if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - } - - err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); - if (err < 0) { - DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); - return; - } - - radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); /* fglrx duplicates INFOFRAME_CONTROL0 & INFOFRAME_CONTROL1 ops here */ diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index ac9ebbfc48af..cafd2f8ec7c1 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -75,9 +75,9 @@ void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, struct radeon_crtc *crtc, unsigned int clock); void dce6_dp_audio_set_dto(struct radeon_device *rdev, struct radeon_crtc *crtc, unsigned int clock); -void r600_update_avi_infoframe(struct radeon_device *rdev, u32 offset, +void r600_set_avi_packet(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size); -void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset, +void evergreen_set_avi_packet(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size); void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset, const struct radeon_hdmi_acr *acr); @@ -116,28 +116,24 @@ static struct radeon_audio_basic_funcs r600_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, .enable = r600_audio_enable, - .update_avi_infoframe = r600_update_avi_infoframe, }; static struct radeon_audio_basic_funcs dce32_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, .enable = r600_audio_enable, - .update_avi_infoframe = r600_update_avi_infoframe, }; static struct radeon_audio_basic_funcs dce4_funcs = { .endpoint_rreg = radeon_audio_rreg, .endpoint_wreg = radeon_audio_wreg, .enable = dce4_audio_enable, - .update_avi_infoframe = evergreen_update_avi_infoframe, }; static struct radeon_audio_basic_funcs dce6_funcs = { .endpoint_rreg = dce6_endpoint_rreg, .endpoint_wreg = dce6_endpoint_wreg, .enable = dce6_audio_enable, - .update_avi_infoframe = evergreen_update_avi_infoframe, }; static struct radeon_audio_funcs r600_hdmi_funcs = { @@ -145,6 +141,7 @@ static struct radeon_audio_funcs r600_hdmi_funcs = { .set_dto = r600_hdmi_audio_set_dto, .update_acr = r600_hdmi_update_acr, .set_vbi_packet = r600_set_vbi_packet, + .set_avi_packet = r600_set_avi_packet, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -154,6 +151,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = { .set_dto = dce3_2_audio_set_dto, .update_acr = dce3_2_hdmi_update_acr, .set_vbi_packet = r600_set_vbi_packet, + .set_avi_packet = r600_set_avi_packet, }; static struct radeon_audio_funcs dce32_dp_funcs = { @@ -161,6 +159,7 @@ static struct radeon_audio_funcs dce32_dp_funcs = { .write_sad_regs = dce3_2_afmt_write_sad_regs, .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, .set_dto = dce3_2_audio_set_dto, + .set_avi_packet = r600_set_avi_packet, }; static struct radeon_audio_funcs dce4_hdmi_funcs = { @@ -172,6 +171,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .update_acr = evergreen_hdmi_update_acr, .set_vbi_packet = dce4_set_vbi_packet, .set_color_depth = dce4_hdmi_set_color_depth, + .set_avi_packet = evergreen_set_avi_packet, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -180,6 +180,7 @@ static struct radeon_audio_funcs dce4_dp_funcs = { .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, .write_latency_fields = dce4_afmt_write_latency_fields, .set_dto = dce4_dp_audio_set_dto, + .set_avi_packet = evergreen_set_avi_packet, }; static struct radeon_audio_funcs dce6_hdmi_funcs = { @@ -192,6 +193,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .update_acr = evergreen_hdmi_update_acr, .set_vbi_packet = dce4_set_vbi_packet, .set_color_depth = dce4_hdmi_set_color_depth, + .set_avi_packet = evergreen_set_avi_packet, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -201,6 +203,7 @@ static struct radeon_audio_funcs dce6_dp_funcs = { .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, .write_latency_fields = dce6_afmt_write_latency_fields, .set_dto = dce6_dp_audio_set_dto, + .set_avi_packet = evergreen_set_avi_packet, }; static void radeon_audio_interface_init(struct radeon_device *rdev) @@ -466,16 +469,34 @@ void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) radeon_encoder->audio->set_dto(rdev, crtc, clock); } -void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, - size_t size) +int radeon_audio_set_avi_packet(struct drm_encoder *encoder, + struct drm_display_mode *mode) { struct radeon_device *rdev = encoder->dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; + struct hdmi_avi_infoframe frame; + int err; + + err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); + if (err < 0) { + DRM_ERROR("failed to setup AVI infoframe: %d\n", err); + return err; + } + + err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); + if (err < 0) { + DRM_ERROR("failed to pack AVI infoframe: %d\n", err); + return err; + } + + if (dig && dig->afmt && + radeon_encoder->audio && radeon_encoder->audio->set_avi_packet) + radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset, + buffer, sizeof(buffer)); - if (dig && dig->afmt && rdev->audio.funcs->update_avi_infoframe) - rdev->audio.funcs->update_avi_infoframe(rdev, dig->afmt->offset, - buffer, size); + return 0; } /* diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index f179e5646e42..4880396b5afc 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -39,8 +39,6 @@ struct radeon_audio_basic_funcs u32 offset, u32 reg, u32 v); void (*enable)(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); - void (*update_avi_infoframe)(struct radeon_device *rdev, u32 offset, - unsigned char *buffer, size_t size); }; struct radeon_audio_funcs @@ -59,6 +57,8 @@ struct radeon_audio_funcs const struct radeon_hdmi_acr *acr); void (*set_vbi_packet)(struct drm_encoder *encoder, u32 offset); void (*set_color_depth)(struct drm_encoder *encoder, u32 offset, int bpc); + void (*set_avi_packet)(struct radeon_device *rdev, u32 offset, + unsigned char *buffer, size_t size); }; int radeon_audio_init(struct radeon_device *rdev); @@ -78,8 +78,8 @@ void radeon_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); void radeon_audio_fini(struct radeon_device *rdev); void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); -void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, - size_t size); +int radeon_audio_set_avi_packet(struct drm_encoder *encoder, + struct drm_display_mode *mode); void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock); void radeon_audio_set_vbi_packet(struct drm_encoder *encoder); void radeon_hdmi_set_color_depth(struct drm_encoder *encoder); -- cgit v1.2.3 From 1852c9a09a25aad40c80b0012ad19379b1fb78be Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Tue, 9 Dec 2014 16:44:18 -0500 Subject: radeon/audio: moved audio packet programming to a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 56 ++++++++++------------ drivers/gpu/drm/radeon/evergreen_hdmi.c | 84 ++++++++++++++++---------------- drivers/gpu/drm/radeon/r600_hdmi.c | 85 +++++++++++++++++---------------- drivers/gpu/drm/radeon/radeon_audio.c | 19 ++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 2 + 5 files changed, 134 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 3ec9dea76ed1..cf788db5873a 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -199,6 +199,27 @@ void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, ~HDMI0_ACR_N_48_MASK); } +void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, + HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ + HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ + + WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, + AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ + AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ + + WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, + HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ + HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ + + WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, + HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ +} + /* * update the info frames with the data from the current display mode */ @@ -226,41 +247,16 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m radeon_audio_set_vbi_packet(encoder); radeon_hdmi_set_color_depth(encoder); - if (ASIC_IS_DCE32(rdev)) { - WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, - HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ - HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ - WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, - AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ - AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ - } else { - WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, - HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ - HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ - HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ - HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ - } - - if (ASIC_IS_DCE32(rdev)) { - radeon_audio_write_speaker_allocation(encoder); - radeon_audio_write_sad_regs(encoder); - } - - /* TODO: HDMI0_AUDIO_INFO_UPDATE */ - WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, - HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ - HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ - - WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, - HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ - WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ + radeon_audio_update_acr(encoder, mode->clock); + radeon_audio_write_speaker_allocation(encoder); + radeon_audio_set_audio_packet(encoder); + radeon_audio_write_sad_regs(encoder); + if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - radeon_audio_update_acr(encoder, mode->clock); - /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 6d22da986aa6..d0155c0a8529 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -345,6 +345,47 @@ void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, u32 offset, int bpc) WREG32(HDMI_CONTROL + offset, val); } +void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + WREG32(HDMI_INFOFRAME_CONTROL0 + offset, + HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ + HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ + + WREG32(AFMT_INFOFRAME_CONTROL0 + offset, + AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ + + WREG32(HDMI_INFOFRAME_CONTROL1 + offset, + HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */ + + WREG32(HDMI_AUDIO_PACKET_CONTROL + offset, + HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */ + HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ + + WREG32(AFMT_60958_0 + offset, + AFMT_60958_CS_CHANNEL_NUMBER_L(1)); + + WREG32(AFMT_60958_1 + offset, + AFMT_60958_CS_CHANNEL_NUMBER_R(2)); + + WREG32(AFMT_60958_2 + offset, + AFMT_60958_CS_CHANNEL_NUMBER_2(3) | + AFMT_60958_CS_CHANNEL_NUMBER_3(4) | + AFMT_60958_CS_CHANNEL_NUMBER_4(5) | + AFMT_60958_CS_CHANNEL_NUMBER_5(6) | + AFMT_60958_CS_CHANNEL_NUMBER_6(7) | + AFMT_60958_CS_CHANNEL_NUMBER_7(8)); + + WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset, + AFMT_AUDIO_CHANNEL_ENABLE(0xff)); + + /* allow 60958 channel status and send audio packets fields to be updated */ + WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, + AFMT_AUDIO_SAMPLE_SEND | AFMT_RESET_FIFO_WHEN_AUDIO_DIS | AFMT_60958_CS_UPDATE); +} + /* * update the info frames with the data from the current display mode */ @@ -372,49 +413,11 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode radeon_audio_set_vbi_packet(encoder); radeon_hdmi_set_color_depth(encoder); - WREG32(HDMI_INFOFRAME_CONTROL0 + offset, - HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ - HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ - - WREG32(AFMT_INFOFRAME_CONTROL0 + offset, - AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ - - WREG32(HDMI_INFOFRAME_CONTROL1 + offset, - HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */ - WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */ - WREG32(HDMI_AUDIO_PACKET_CONTROL + offset, - HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */ - HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ - - WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, - AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ - - /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */ - radeon_audio_update_acr(encoder, mode->clock); - - WREG32(AFMT_60958_0 + offset, - AFMT_60958_CS_CHANNEL_NUMBER_L(1)); - - WREG32(AFMT_60958_1 + offset, - AFMT_60958_CS_CHANNEL_NUMBER_R(2)); - - WREG32(AFMT_60958_2 + offset, - AFMT_60958_CS_CHANNEL_NUMBER_2(3) | - AFMT_60958_CS_CHANNEL_NUMBER_3(4) | - AFMT_60958_CS_CHANNEL_NUMBER_4(5) | - AFMT_60958_CS_CHANNEL_NUMBER_5(6) | - AFMT_60958_CS_CHANNEL_NUMBER_6(7) | - AFMT_60958_CS_CHANNEL_NUMBER_7(8)); - radeon_audio_write_speaker_allocation(encoder); - - WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset, - AFMT_AUDIO_CHANNEL_ENABLE(0xff)); - - /* fglrx sets 0x40 in 0x5f80 here */ + radeon_audio_set_audio_packet(encoder); radeon_audio_select_pin(encoder); radeon_audio_write_sad_regs(encoder); @@ -423,9 +426,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset, - AFMT_AUDIO_SAMPLE_SEND); /* send audio packets */ - /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ WREG32(AFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF); WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index d6447da82c86..d38001525364 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -347,6 +347,48 @@ void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset) HDMI0_GC_CONT); /* send general control packets every frame */ } +void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, + HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ + HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ + HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ + HDMI0_60958_CS_UPDATE, /* allow 60958 channel status fields to be updated */ + ~(HDMI0_AUDIO_SAMPLE_SEND | + HDMI0_AUDIO_DELAY_EN_MASK | + HDMI0_AUDIO_PACKETS_PER_LINE_MASK | + HDMI0_60958_CS_UPDATE)); + + WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, + HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ + HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ + + WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset, + HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */ + ~HDMI0_AUDIO_INFO_LINE_MASK); + + WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset, + ~(HDMI0_GENERIC0_SEND | + HDMI0_GENERIC0_CONT | + HDMI0_GENERIC0_UPDATE | + HDMI0_GENERIC1_SEND | + HDMI0_GENERIC1_CONT | + HDMI0_GENERIC0_LINE_MASK | + HDMI0_GENERIC1_LINE_MASK)); + + WREG32_P(HDMI0_60958_0 + offset, + HDMI0_60958_CS_CHANNEL_NUMBER_L(1), + ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK | + HDMI0_60958_CS_CLOCK_ACCURACY_MASK)); + + WREG32_P(HDMI0_60958_1 + offset, + HDMI0_60958_CS_CHANNEL_NUMBER_R(2), + ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK); +} + /* * update the info frames with the data from the current display mode */ @@ -374,51 +416,14 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod radeon_audio_set_vbi_packet(encoder); radeon_hdmi_set_color_depth(encoder); - WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, - HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ - HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ - HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ - HDMI0_60958_CS_UPDATE, /* allow 60958 channel status fields to be updated */ - ~(HDMI0_AUDIO_SAMPLE_SEND | - HDMI0_AUDIO_DELAY_EN_MASK | - HDMI0_AUDIO_PACKETS_PER_LINE_MASK | - HDMI0_60958_CS_UPDATE)); - - WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, - HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ - HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ - - WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset, - HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */ - ~HDMI0_AUDIO_INFO_LINE_MASK); - WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); /* unset HDMI0_GC_AVMUTE */ - if (radeon_audio_set_avi_packet(encoder, mode) < 0) - return; - - /* fglrx duplicates INFOFRAME_CONTROL0 & INFOFRAME_CONTROL1 ops here */ - - WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset, - ~(HDMI0_GENERIC0_SEND | - HDMI0_GENERIC0_CONT | - HDMI0_GENERIC0_UPDATE | - HDMI0_GENERIC1_SEND | - HDMI0_GENERIC1_CONT | - HDMI0_GENERIC0_LINE_MASK | - HDMI0_GENERIC1_LINE_MASK)); - radeon_audio_update_acr(encoder, mode->clock); + radeon_audio_set_audio_packet(encoder); - WREG32_P(HDMI0_60958_0 + offset, - HDMI0_60958_CS_CHANNEL_NUMBER_L(1), - ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK | - HDMI0_60958_CS_CLOCK_ACCURACY_MASK)); - - WREG32_P(HDMI0_60958_1 + offset, - HDMI0_60958_CS_CHANNEL_NUMBER_R(2), - ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK); + if (radeon_audio_set_avi_packet(encoder, mode) < 0) + return; /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index cafd2f8ec7c1..e29d6552bb62 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -89,6 +89,9 @@ void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset); void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset); void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, u32 offset, int bpc); +void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset); +void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset); +void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset); static const u32 pin_offsets[7] = { @@ -142,6 +145,7 @@ static struct radeon_audio_funcs r600_hdmi_funcs = { .update_acr = r600_hdmi_update_acr, .set_vbi_packet = r600_set_vbi_packet, .set_avi_packet = r600_set_avi_packet, + .set_audio_packet = r600_set_audio_packet, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -152,6 +156,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = { .update_acr = dce3_2_hdmi_update_acr, .set_vbi_packet = r600_set_vbi_packet, .set_avi_packet = r600_set_avi_packet, + .set_audio_packet = dce3_2_set_audio_packet, }; static struct radeon_audio_funcs dce32_dp_funcs = { @@ -172,6 +177,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .set_vbi_packet = dce4_set_vbi_packet, .set_color_depth = dce4_hdmi_set_color_depth, .set_avi_packet = evergreen_set_avi_packet, + .set_audio_packet = dce4_set_audio_packet, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -194,6 +200,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .set_vbi_packet = dce4_set_vbi_packet, .set_color_depth = dce4_hdmi_set_color_depth, .set_avi_packet = evergreen_set_avi_packet, + .set_audio_packet = dce4_set_audio_packet, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -617,3 +624,15 @@ void radeon_hdmi_set_color_depth(struct drm_encoder *encoder) if (radeon_encoder->audio && radeon_encoder->audio->set_color_depth) radeon_encoder->audio->set_color_depth(encoder, dig->afmt->offset, bpc); } + +void radeon_audio_set_audio_packet(struct drm_encoder *encoder) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (!dig || !dig->afmt) + return; + + if (radeon_encoder->audio && radeon_encoder->audio->set_audio_packet) + radeon_encoder->audio->set_audio_packet(encoder, dig->afmt->offset); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 4880396b5afc..cefe45716386 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -59,6 +59,7 @@ struct radeon_audio_funcs void (*set_color_depth)(struct drm_encoder *encoder, u32 offset, int bpc); void (*set_avi_packet)(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size); + void (*set_audio_packet)(struct drm_encoder *encoder, u32 offset); }; int radeon_audio_init(struct radeon_device *rdev); @@ -83,5 +84,6 @@ int radeon_audio_set_avi_packet(struct drm_encoder *encoder, void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock); void radeon_audio_set_vbi_packet(struct drm_encoder *encoder); void radeon_hdmi_set_color_depth(struct drm_encoder *encoder); +void radeon_audio_set_audio_packet(struct drm_encoder *encoder); #endif -- cgit v1.2.3 From 3be2e7d0e705621c1bb41eeabb63b122d50ecff3 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Tue, 9 Dec 2014 17:17:35 -0500 Subject: radeon/audio: moved mute programming to a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 15 ++++++++++++--- drivers/gpu/drm/radeon/evergreen_hdmi.c | 17 +++++++++++++---- drivers/gpu/drm/radeon/r600_hdmi.c | 16 ++++++++++++---- drivers/gpu/drm/radeon/radeon_audio.c | 19 +++++++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 2 ++ 5 files changed, 58 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index cf788db5873a..07869ca8125d 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -220,6 +220,17 @@ void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset) HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ } +void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + if (mute) + WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE); + else + WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); +} + /* * update the info frames with the data from the current display mode */ @@ -246,9 +257,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m radeon_audio_set_dto(encoder, mode->clock); radeon_audio_set_vbi_packet(encoder); radeon_hdmi_set_color_depth(encoder); - - WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ - + radeon_audio_set_mute(encoder, false); radeon_audio_update_acr(encoder, mode->clock); radeon_audio_write_speaker_allocation(encoder); radeon_audio_set_audio_packet(encoder); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index d0155c0a8529..e240586ac42e 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -386,6 +386,18 @@ void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset) AFMT_AUDIO_SAMPLE_SEND | AFMT_RESET_FIFO_WHEN_AUDIO_DIS | AFMT_60958_CS_UPDATE); } + +void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + if (mute) + WREG32_OR(HDMI_GC + offset, HDMI_GC_AVMUTE); + else + WREG32_AND(HDMI_GC + offset, ~HDMI_GC_AVMUTE); +} + /* * update the info frames with the data from the current display mode */ @@ -412,13 +424,10 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode radeon_audio_set_dto(encoder, mode->clock); radeon_audio_set_vbi_packet(encoder); radeon_hdmi_set_color_depth(encoder); - - WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */ - + radeon_audio_set_mute(encoder, false); radeon_audio_update_acr(encoder, mode->clock); radeon_audio_write_speaker_allocation(encoder); radeon_audio_set_audio_packet(encoder); - radeon_audio_select_pin(encoder); radeon_audio_write_sad_regs(encoder); radeon_audio_write_latency_fields(encoder, mode); diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index d38001525364..8955efa01514 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -389,6 +389,17 @@ void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset) ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK); } +void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + if (mute) + WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE); + else + WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); +} + /* * update the info frames with the data from the current display mode */ @@ -415,10 +426,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod radeon_audio_set_dto(encoder, mode->clock); radeon_audio_set_vbi_packet(encoder); radeon_hdmi_set_color_depth(encoder); - - WREG32_AND(HDMI0_GC + offset, - ~HDMI0_GC_AVMUTE); /* unset HDMI0_GC_AVMUTE */ - + radeon_audio_set_mute(encoder, false); radeon_audio_update_acr(encoder, mode->clock); radeon_audio_set_audio_packet(encoder); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index e29d6552bb62..3aa5d111f650 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -92,6 +92,9 @@ void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset); void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset); void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset); +void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); +void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); +void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); static const u32 pin_offsets[7] = { @@ -146,6 +149,7 @@ static struct radeon_audio_funcs r600_hdmi_funcs = { .set_vbi_packet = r600_set_vbi_packet, .set_avi_packet = r600_set_avi_packet, .set_audio_packet = r600_set_audio_packet, + .set_mute = r600_set_mute, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -157,6 +161,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = { .set_vbi_packet = r600_set_vbi_packet, .set_avi_packet = r600_set_avi_packet, .set_audio_packet = dce3_2_set_audio_packet, + .set_mute = dce3_2_set_mute, }; static struct radeon_audio_funcs dce32_dp_funcs = { @@ -178,6 +183,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .set_color_depth = dce4_hdmi_set_color_depth, .set_avi_packet = evergreen_set_avi_packet, .set_audio_packet = dce4_set_audio_packet, + .set_mute = dce4_set_mute, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -201,6 +207,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .set_color_depth = dce4_hdmi_set_color_depth, .set_avi_packet = evergreen_set_avi_packet, .set_audio_packet = dce4_set_audio_packet, + .set_mute = dce4_set_mute, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -636,3 +643,15 @@ void radeon_audio_set_audio_packet(struct drm_encoder *encoder) if (radeon_encoder->audio && radeon_encoder->audio->set_audio_packet) radeon_encoder->audio->set_audio_packet(encoder, dig->afmt->offset); } + +void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (!dig || !dig->afmt) + return; + + if (radeon_encoder->audio && radeon_encoder->audio->set_mute) + radeon_encoder->audio->set_mute(encoder, dig->afmt->offset, mute); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index cefe45716386..5ca5e7edc680 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -60,6 +60,7 @@ struct radeon_audio_funcs void (*set_avi_packet)(struct radeon_device *rdev, u32 offset, unsigned char *buffer, size_t size); void (*set_audio_packet)(struct drm_encoder *encoder, u32 offset); + void (*set_mute)(struct drm_encoder *encoder, u32 offset, bool mute); }; int radeon_audio_init(struct radeon_device *rdev); @@ -85,5 +86,6 @@ void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock); void radeon_audio_set_vbi_packet(struct drm_encoder *encoder); void radeon_hdmi_set_color_depth(struct drm_encoder *encoder); void radeon_audio_set_audio_packet(struct drm_encoder *encoder); +void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute); #endif -- cgit v1.2.3 From 7f604077ac9cacb9a6b04b977e2cd1f26cb3f667 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Tue, 9 Dec 2014 17:32:37 -0500 Subject: radeon/audio: removed unnecessary debug settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce3_1_afmt.c | 6 ------ drivers/gpu/drm/radeon/evergreen_hdmi.c | 6 ------ drivers/gpu/drm/radeon/r600_hdmi.c | 6 ------ 3 files changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 07869ca8125d..cbd07f5f276a 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -266,12 +266,6 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ - WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); - WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); - WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); - WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); - r600_hdmi_audio_workaround(encoder); /* enable audio after to setting up hw */ diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index e240586ac42e..84a000d361e6 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -435,12 +435,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ - WREG32(AFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF); - WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); - WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); - WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); - /* enable audio after to setting up hw */ radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 8955efa01514..0f90d70537e9 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -433,12 +433,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; - /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ - WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); - WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); - WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); - WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); - /* enable audio after to setting up hw */ radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } -- cgit v1.2.3 From 6e72376dcc663e4b8a00cdd08f61a8623f572ef1 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Wed, 10 Dec 2014 10:43:51 -0500 Subject: radeon/audio: consolidate audio_mode_set() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_encoders.c | 4 +- drivers/gpu/drm/radeon/dce3_1_afmt.c | 41 ----------------- drivers/gpu/drm/radeon/evergreen_hdmi.c | 41 ----------------- drivers/gpu/drm/radeon/r600_hdmi.c | 37 --------------- drivers/gpu/drm/radeon/radeon_asic.c | 14 ------ drivers/gpu/drm/radeon/radeon_asic.h | 4 -- drivers/gpu/drm/radeon/radeon_audio.c | 72 +++++++++++++++++++++++++----- drivers/gpu/drm/radeon/radeon_audio.h | 15 ++----- 8 files changed, 66 insertions(+), 162 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index b8cd7975f797..9354c99ca3c2 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -27,6 +27,7 @@ #include #include #include "radeon.h" +#include "radeon_audio.h" #include "atom.h" #include @@ -2174,8 +2175,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { if (rdev->asic->display.hdmi_enable) radeon_hdmi_enable(rdev, encoder, true); - if (rdev->asic->display.hdmi_setmode) - radeon_hdmi_setmode(rdev, encoder, adjusted_mode); + radeon_audio_mode_set(encoder, adjusted_mode); } } diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index cbd07f5f276a..f04205170b8a 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -230,44 +230,3 @@ void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) else WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); } - -/* - * update the info frames with the data from the current display mode - */ -void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) -{ - struct drm_device *dev = encoder->dev; - 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; - uint32_t offset; - - if (!dig || !dig->afmt) - return; - - /* Silent, r600_hdmi_enable will raise WARN for us */ - if (!dig->afmt->enabled) - return; - offset = dig->afmt->offset; - - /* disable audio prior to setting up hw */ - dig->afmt->pin = radeon_audio_get_pin(encoder); - radeon_audio_enable(rdev, dig->afmt->pin, 0); - - radeon_audio_set_dto(encoder, mode->clock); - radeon_audio_set_vbi_packet(encoder); - radeon_hdmi_set_color_depth(encoder); - radeon_audio_set_mute(encoder, false); - radeon_audio_update_acr(encoder, mode->clock); - radeon_audio_write_speaker_allocation(encoder); - radeon_audio_set_audio_packet(encoder); - radeon_audio_write_sad_regs(encoder); - - if (radeon_audio_set_avi_packet(encoder, mode) < 0) - return; - - r600_hdmi_audio_workaround(encoder); - - /* enable audio after to setting up hw */ - radeon_audio_enable(rdev, dig->afmt->pin, 0xf); -} diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 84a000d361e6..c893fe1f0685 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -398,47 +398,6 @@ void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) WREG32_AND(HDMI_GC + offset, ~HDMI_GC_AVMUTE); } -/* - * update the info frames with the data from the current display mode - */ -void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) -{ - struct drm_device *dev = encoder->dev; - 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; - uint32_t offset; - - if (!dig || !dig->afmt) - return; - - /* Silent, r600_hdmi_enable will raise WARN for us */ - if (!dig->afmt->enabled) - return; - offset = dig->afmt->offset; - - /* disable audio prior to setting up hw */ - dig->afmt->pin = radeon_audio_get_pin(encoder); - radeon_audio_enable(rdev, dig->afmt->pin, 0); - - radeon_audio_set_dto(encoder, mode->clock); - radeon_audio_set_vbi_packet(encoder); - radeon_hdmi_set_color_depth(encoder); - radeon_audio_set_mute(encoder, false); - radeon_audio_update_acr(encoder, mode->clock); - radeon_audio_write_speaker_allocation(encoder); - radeon_audio_set_audio_packet(encoder); - radeon_audio_select_pin(encoder); - radeon_audio_write_sad_regs(encoder); - radeon_audio_write_latency_fields(encoder, mode); - - if (radeon_audio_set_avi_packet(encoder, mode) < 0) - return; - - /* enable audio after to setting up hw */ - radeon_audio_enable(rdev, dig->afmt->pin, 0xf); -} - void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) { struct drm_device *dev = encoder->dev; diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 0f90d70537e9..62c91ed669ce 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -400,43 +400,6 @@ void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); } -/* - * update the info frames with the data from the current display mode - */ -void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) -{ - struct drm_device *dev = encoder->dev; - 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; - uint32_t offset; - - if (!dig || !dig->afmt) - return; - - /* Silent, r600_hdmi_enable will raise WARN for us */ - if (!dig->afmt->enabled) - return; - offset = dig->afmt->offset; - - /* disable audio prior to setting up hw */ - dig->afmt->pin = radeon_audio_get_pin(encoder); - radeon_audio_enable(rdev, dig->afmt->pin, 0); - - radeon_audio_set_dto(encoder, mode->clock); - radeon_audio_set_vbi_packet(encoder); - radeon_hdmi_set_color_depth(encoder); - radeon_audio_set_mute(encoder, false); - radeon_audio_update_acr(encoder, mode->clock); - radeon_audio_set_audio_packet(encoder); - - if (radeon_audio_set_avi_packet(encoder, mode) < 0) - return; - - /* enable audio after to setting up hw */ - radeon_audio_enable(rdev, dig->afmt->pin, 0xf); -} - /** * r600_hdmi_update_audio_settings - Update audio infoframe * diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 7c6e1930fa38..b8478882e321 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -639,7 +639,6 @@ static struct radeon_asic rs600_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &r600_hdmi_enable, - .hdmi_setmode = &r600_hdmi_setmode, }, .copy = { .blit = &r100_copy_blit, @@ -707,7 +706,6 @@ static struct radeon_asic rs690_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &r600_hdmi_enable, - .hdmi_setmode = &r600_hdmi_setmode, }, .copy = { .blit = &r100_copy_blit, @@ -936,7 +934,6 @@ static struct radeon_asic r600_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &r600_hdmi_enable, - .hdmi_setmode = &r600_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1022,7 +1019,6 @@ static struct radeon_asic rv6xx_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &r600_hdmi_enable, - .hdmi_setmode = &r600_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1113,7 +1109,6 @@ static struct radeon_asic rs780_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &r600_hdmi_enable, - .hdmi_setmode = &r600_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1217,7 +1212,6 @@ static struct radeon_asic rv770_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &r600_hdmi_enable, - .hdmi_setmode = &dce3_1_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1335,7 +1329,6 @@ static struct radeon_asic evergreen_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1427,7 +1420,6 @@ static struct radeon_asic sumo_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1518,7 +1510,6 @@ static struct radeon_asic btc_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1664,7 +1655,6 @@ static struct radeon_asic cayman_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1767,7 +1757,6 @@ static struct radeon_asic trinity_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -1900,7 +1889,6 @@ static struct radeon_asic si_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, @@ -2067,7 +2055,6 @@ static struct radeon_asic ci_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &cik_copy_cpdma, @@ -2178,7 +2165,6 @@ static struct radeon_asic kv_asic = { .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, - .hdmi_setmode = &evergreen_hdmi_setmode, }, .copy = { .blit = &cik_copy_cpdma, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 6eacf410a45f..fee8d2297e54 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -399,7 +399,6 @@ void r600_hdmi_audio_workaround(struct drm_encoder *encoder); int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); -void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); int r600_mc_wait_for_idle(struct radeon_device *rdev); u32 r600_get_xclk(struct radeon_device *rdev); uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev); @@ -468,8 +467,6 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, u32 rv770_get_xclk(struct radeon_device *rdev); int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); int rv770_get_temp(struct radeon_device *rdev); -/* hdmi */ -void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); /* rv7xx pm */ int rv770_dpm_init(struct radeon_device *rdev); int rv770_dpm_enable(struct radeon_device *rdev); @@ -540,7 +537,6 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv); void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); -void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); int evergreen_get_temp(struct radeon_device *rdev); int sumo_get_temp(struct radeon_device *rdev); int tn_get_temp(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 3aa5d111f650..05c7ffed6996 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -95,6 +95,8 @@ void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset); void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); +static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode); static const u32 pin_offsets[7] = { @@ -150,6 +152,7 @@ static struct radeon_audio_funcs r600_hdmi_funcs = { .set_avi_packet = r600_set_avi_packet, .set_audio_packet = r600_set_audio_packet, .set_mute = r600_set_mute, + .mode_set = radeon_audio_hdmi_mode_set, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -162,6 +165,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = { .set_avi_packet = r600_set_avi_packet, .set_audio_packet = dce3_2_set_audio_packet, .set_mute = dce3_2_set_mute, + .mode_set = radeon_audio_hdmi_mode_set, }; static struct radeon_audio_funcs dce32_dp_funcs = { @@ -184,6 +188,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .set_avi_packet = evergreen_set_avi_packet, .set_audio_packet = dce4_set_audio_packet, .set_mute = dce4_set_mute, + .mode_set = radeon_audio_hdmi_mode_set, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -208,6 +213,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .set_avi_packet = evergreen_set_avi_packet, .set_audio_packet = dce4_set_audio_packet, .set_mute = dce4_set_mute, + .mode_set = radeon_audio_hdmi_mode_set, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -337,7 +343,7 @@ void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, rdev->audio.funcs->endpoint_wreg(rdev, offset, reg, v); } -void radeon_audio_write_sad_regs(struct drm_encoder *encoder) +static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder; struct drm_connector *connector; @@ -373,7 +379,7 @@ void radeon_audio_write_sad_regs(struct drm_encoder *encoder) kfree(sads); } -void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) +static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct drm_connector *connector; @@ -408,7 +414,7 @@ void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) kfree(sadb); } -void radeon_audio_write_latency_fields(struct drm_encoder *encoder, +static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, struct drm_display_mode *mode) { struct radeon_encoder *radeon_encoder; @@ -445,7 +451,7 @@ struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder) return NULL; } -void radeon_audio_select_pin(struct drm_encoder *encoder) +static void radeon_audio_select_pin(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -473,7 +479,7 @@ void radeon_audio_fini(struct radeon_device *rdev) rdev->audio.enabled = false; } -void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) +static void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) { struct radeon_device *rdev = encoder->dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -483,7 +489,7 @@ void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) radeon_encoder->audio->set_dto(rdev, crtc, clock); } -int radeon_audio_set_avi_packet(struct drm_encoder *encoder, +static int radeon_audio_set_avi_packet(struct drm_encoder *encoder, struct drm_display_mode *mode) { struct radeon_device *rdev = encoder->dev->dev_private; @@ -589,7 +595,7 @@ static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock) /* * update the N and CTS parameters for a given pixel clock rate */ -void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock) +static void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock) { const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -602,7 +608,7 @@ void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock) radeon_encoder->audio->update_acr(encoder, dig->afmt->offset, acr); } -void radeon_audio_set_vbi_packet(struct drm_encoder *encoder) +static void radeon_audio_set_vbi_packet(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; @@ -614,7 +620,7 @@ void radeon_audio_set_vbi_packet(struct drm_encoder *encoder) radeon_encoder->audio->set_vbi_packet(encoder, dig->afmt->offset); } -void radeon_hdmi_set_color_depth(struct drm_encoder *encoder) +static void radeon_hdmi_set_color_depth(struct drm_encoder *encoder) { int bpc = 8; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -632,7 +638,7 @@ void radeon_hdmi_set_color_depth(struct drm_encoder *encoder) radeon_encoder->audio->set_color_depth(encoder, dig->afmt->offset, bpc); } -void radeon_audio_set_audio_packet(struct drm_encoder *encoder) +static void radeon_audio_set_audio_packet(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; @@ -644,7 +650,7 @@ void radeon_audio_set_audio_packet(struct drm_encoder *encoder) radeon_encoder->audio->set_audio_packet(encoder, dig->afmt->offset); } -void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) +static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; @@ -655,3 +661,47 @@ void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) if (radeon_encoder->audio && radeon_encoder->audio->set_mute) radeon_encoder->audio->set_mute(encoder, dig->afmt->offset, mute); } + +/* + * update the info frames with the data from the current display mode + */ +static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode) +{ + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (!dig || !dig->afmt) + return; + + /* disable audio prior to setting up hw */ + dig->afmt->pin = radeon_audio_get_pin(encoder); + radeon_audio_enable(rdev, dig->afmt->pin, 0); + + radeon_audio_set_dto(encoder, mode->clock); + radeon_audio_set_vbi_packet(encoder); + radeon_hdmi_set_color_depth(encoder); + radeon_audio_set_mute(encoder, false); + radeon_audio_update_acr(encoder, mode->clock); + radeon_audio_write_speaker_allocation(encoder); + radeon_audio_set_audio_packet(encoder); + radeon_audio_select_pin(encoder); + radeon_audio_write_sad_regs(encoder); + radeon_audio_write_latency_fields(encoder, mode); + + if (radeon_audio_set_avi_packet(encoder, mode) < 0) + return; + + /* enable audio after to setting up hw */ + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); +} + +void radeon_audio_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->audio && radeon_encoder->audio->mode_set) + radeon_encoder->audio->mode_set(encoder, mode); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 5ca5e7edc680..69022116b6a4 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -61,6 +61,8 @@ struct radeon_audio_funcs unsigned char *buffer, size_t size); void (*set_audio_packet)(struct drm_encoder *encoder, u32 offset); void (*set_mute)(struct drm_encoder *encoder, u32 offset, bool mute); + void (*mode_set)(struct drm_encoder *encoder, + struct drm_display_mode *mode); }; int radeon_audio_init(struct radeon_device *rdev); @@ -70,22 +72,11 @@ u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg); void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, u32 reg, u32 v); -void radeon_audio_write_sad_regs(struct drm_encoder *encoder); -void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder); -void radeon_audio_write_latency_fields(struct drm_encoder *encoder, - struct drm_display_mode *mode); struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder); -void radeon_audio_select_pin(struct drm_encoder *encoder); void radeon_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); void radeon_audio_fini(struct radeon_device *rdev); -void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); -int radeon_audio_set_avi_packet(struct drm_encoder *encoder, +void radeon_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); -void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock); -void radeon_audio_set_vbi_packet(struct drm_encoder *encoder); -void radeon_hdmi_set_color_depth(struct drm_encoder *encoder); -void radeon_audio_set_audio_packet(struct drm_encoder *encoder); -void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute); #endif -- cgit v1.2.3 From 6f945693be7eea24b1a8e5ce252a96df98d55a5c Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Wed, 10 Dec 2014 14:52:43 -0500 Subject: radeon/audio: applied audio_dpms() and audio_mode_set() calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_encoders.c | 21 +++++++++++---------- drivers/gpu/drm/radeon/radeon_asic.c | 14 -------------- drivers/gpu/drm/radeon/radeon_asic.h | 2 -- drivers/gpu/drm/radeon/radeon_audio.c | 14 ++++++++++++++ drivers/gpu/drm/radeon/radeon_audio.h | 2 ++ 5 files changed, 27 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 9354c99ca3c2..8ca8b4fcb10c 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1616,6 +1616,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) struct radeon_connector *radeon_connector = NULL; struct radeon_connector_atom_dig *radeon_dig_connector = NULL; bool travis_quirk = false; + int encoder_mode; if (connector) { radeon_connector = to_radeon_connector(connector); @@ -1711,6 +1712,11 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) } break; } + + encoder_mode = atombios_get_encoder_mode(encoder); + if (radeon_audio != 0 && + (encoder_mode == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(encoder_mode))) + radeon_audio_dpms(encoder, mode); } static void @@ -2124,6 +2130,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + int encoder_mode; radeon_encoder->pixel_clock = adjusted_mode->clock; @@ -2150,6 +2157,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: /* handled in dpms */ + encoder_mode = atombios_get_encoder_mode(encoder); + if (radeon_audio != 0 && + (encoder_mode == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(encoder_mode))) + radeon_audio_mode_set(encoder, adjusted_mode); break; case ENCODER_OBJECT_ID_INTERNAL_DDI: case ENCODER_OBJECT_ID_INTERNAL_DVO1: @@ -2171,12 +2182,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, } atombios_apply_encoder_quirks(encoder, adjusted_mode); - - if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { - if (rdev->asic->display.hdmi_enable) - radeon_hdmi_enable(rdev, encoder, true); - radeon_audio_mode_set(encoder, adjusted_mode); - } } static bool @@ -2442,10 +2447,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) disable_done: if (radeon_encoder_is_digital(encoder)) { - if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { - if (rdev->asic->display.hdmi_enable) - radeon_hdmi_enable(rdev, encoder, false); - } dig = radeon_encoder->enc_priv; dig->dig_encoder = -1; } diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index b8478882e321..f811ee14a237 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -638,7 +638,6 @@ static struct radeon_asic rs600_asic = { .wait_for_vblank = &avivo_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &r600_hdmi_enable, }, .copy = { .blit = &r100_copy_blit, @@ -705,7 +704,6 @@ static struct radeon_asic rs690_asic = { .wait_for_vblank = &avivo_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &r600_hdmi_enable, }, .copy = { .blit = &r100_copy_blit, @@ -933,7 +931,6 @@ static struct radeon_asic r600_asic = { .wait_for_vblank = &avivo_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &r600_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1018,7 +1015,6 @@ static struct radeon_asic rv6xx_asic = { .wait_for_vblank = &avivo_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &r600_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1108,7 +1104,6 @@ static struct radeon_asic rs780_asic = { .wait_for_vblank = &avivo_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &r600_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1211,7 +1206,6 @@ static struct radeon_asic rv770_asic = { .wait_for_vblank = &avivo_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &r600_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1328,7 +1322,6 @@ static struct radeon_asic evergreen_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1419,7 +1412,6 @@ static struct radeon_asic sumo_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1509,7 +1501,6 @@ static struct radeon_asic btc_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1654,7 +1645,6 @@ static struct radeon_asic cayman_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1756,7 +1746,6 @@ static struct radeon_asic trinity_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -1888,7 +1877,6 @@ static struct radeon_asic si_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &r600_copy_cpdma, @@ -2054,7 +2042,6 @@ static struct radeon_asic ci_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &cik_copy_cpdma, @@ -2164,7 +2151,6 @@ static struct radeon_asic kv_asic = { .wait_for_vblank = &dce4_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, - .hdmi_enable = &evergreen_hdmi_enable, }, .copy = { .blit = &cik_copy_cpdma, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index fee8d2297e54..4045a320a424 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -398,7 +398,6 @@ void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock); void r600_hdmi_audio_workaround(struct drm_encoder *encoder); int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); -void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); int r600_mc_wait_for_idle(struct radeon_device *rdev); u32 r600_get_xclk(struct radeon_device *rdev); uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev); @@ -536,7 +535,6 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, unsigned num_gpu_pages, struct reservation_object *resv); -void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); int evergreen_get_temp(struct radeon_device *rdev); int sumo_get_temp(struct radeon_device *rdev); int tn_get_temp(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 05c7ffed6996..4a2774ac7827 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -97,6 +97,8 @@ void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); +void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); +void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); static const u32 pin_offsets[7] = { @@ -153,6 +155,7 @@ static struct radeon_audio_funcs r600_hdmi_funcs = { .set_audio_packet = r600_set_audio_packet, .set_mute = r600_set_mute, .mode_set = radeon_audio_hdmi_mode_set, + .dpms = r600_hdmi_enable, }; static struct radeon_audio_funcs dce32_hdmi_funcs = { @@ -166,6 +169,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = { .set_audio_packet = dce3_2_set_audio_packet, .set_mute = dce3_2_set_mute, .mode_set = radeon_audio_hdmi_mode_set, + .dpms = r600_hdmi_enable, }; static struct radeon_audio_funcs dce32_dp_funcs = { @@ -189,6 +193,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { .set_audio_packet = dce4_set_audio_packet, .set_mute = dce4_set_mute, .mode_set = radeon_audio_hdmi_mode_set, + .dpms = evergreen_hdmi_enable, }; static struct radeon_audio_funcs dce4_dp_funcs = { @@ -214,6 +219,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { .set_audio_packet = dce4_set_audio_packet, .set_mute = dce4_set_mute, .mode_set = radeon_audio_hdmi_mode_set, + .dpms = evergreen_hdmi_enable, }; static struct radeon_audio_funcs dce6_dp_funcs = { @@ -705,3 +711,11 @@ void radeon_audio_mode_set(struct drm_encoder *encoder, if (radeon_encoder->audio && radeon_encoder->audio->mode_set) radeon_encoder->audio->mode_set(encoder, mode); } + +void radeon_audio_dpms(struct drm_encoder *encoder, int mode) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->audio && radeon_encoder->audio->dpms) + radeon_encoder->audio->dpms(encoder, mode == DRM_MODE_DPMS_ON); +} diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 69022116b6a4..c92d059ab204 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -63,6 +63,7 @@ struct radeon_audio_funcs void (*set_mute)(struct drm_encoder *encoder, u32 offset, bool mute); void (*mode_set)(struct drm_encoder *encoder, struct drm_display_mode *mode); + void (*dpms)(struct drm_encoder *encoder, bool mode); }; int radeon_audio_init(struct radeon_device *rdev); @@ -78,5 +79,6 @@ void radeon_audio_enable(struct radeon_device *rdev, void radeon_audio_fini(struct radeon_device *rdev); void radeon_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); +void radeon_audio_dpms(struct drm_encoder *encoder, int mode); #endif -- cgit v1.2.3 From ccd4be7eb7ef2aac076b604c716f36aa926651e3 Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Thu, 11 Dec 2014 13:11:29 -0500 Subject: radeon/audio: moved audio caps programming to audio_hotplug() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_audio.c | 78 +++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 4a2774ac7827..f1e22a857da9 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -302,38 +302,6 @@ int radeon_audio_init(struct radeon_device *rdev) return 0; } -void radeon_audio_detect(struct drm_connector *connector, - enum drm_connector_status status) -{ - if (!connector || !connector->encoder) - return; - - if (status == connector_status_connected) { - int sink_type; - struct radeon_device *rdev = connector->encoder->dev->dev_private; - struct radeon_connector *radeon_connector; - struct radeon_encoder *radeon_encoder = - to_radeon_encoder(connector->encoder); - - if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { - radeon_encoder->audio = 0; - return; - } - - radeon_connector = to_radeon_connector(connector); - sink_type = radeon_dp_getsinktype(radeon_connector); - - if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && - sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) - radeon_encoder->audio = rdev->audio.dp_funcs; - else - radeon_encoder->audio = rdev->audio.hdmi_funcs; - /* TODO: set up the sads, etc. and set the audio enable_mask */ - } else { - /* TODO: reset the audio enable_mask */ - } -} - u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg) { if (rdev->audio.funcs->endpoint_rreg) @@ -472,6 +440,49 @@ void radeon_audio_enable(struct radeon_device *rdev, rdev->audio.funcs->enable(rdev, pin, enable_mask); } +void radeon_audio_detect(struct drm_connector *connector, + enum drm_connector_status status) +{ + struct radeon_device *rdev; + struct radeon_encoder *radeon_encoder; + struct radeon_encoder_atom_dig *dig; + + if (!connector || !connector->encoder) + return; + + rdev = connector->encoder->dev->dev_private; + radeon_encoder = to_radeon_encoder(connector->encoder); + dig = radeon_encoder->enc_priv; + + if (status == connector_status_connected) { + struct radeon_connector *radeon_connector; + int sink_type; + + if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { + radeon_encoder->audio = 0; + return; + } + + radeon_connector = to_radeon_connector(connector); + sink_type = radeon_dp_getsinktype(radeon_connector); + + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && + sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) + radeon_encoder->audio = rdev->audio.dp_funcs; + else + radeon_encoder->audio = rdev->audio.hdmi_funcs; + + radeon_audio_write_speaker_allocation(connector->encoder); + radeon_audio_write_sad_regs(connector->encoder); + if (connector->encoder->crtc) + radeon_audio_write_latency_fields(connector->encoder, + &connector->encoder->crtc->mode); + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); + } else { + radeon_audio_enable(rdev, dig->afmt->pin, 0); + } +} + void radeon_audio_fini(struct radeon_device *rdev) { int i; @@ -690,11 +701,8 @@ static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, radeon_hdmi_set_color_depth(encoder); radeon_audio_set_mute(encoder, false); radeon_audio_update_acr(encoder, mode->clock); - radeon_audio_write_speaker_allocation(encoder); radeon_audio_set_audio_packet(encoder); radeon_audio_select_pin(encoder); - radeon_audio_write_sad_regs(encoder); - radeon_audio_write_latency_fields(encoder, mode); if (radeon_audio_set_avi_packet(encoder, mode) < 0) return; -- cgit v1.2.3 From e55bca26188e45f209597abf986c87cc5a49894a Mon Sep 17 00:00:00 2001 From: Slava Grigorev Date: Fri, 12 Dec 2014 17:01:42 -0500 Subject: radeon/audio: enable DP audio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Slava Grigorev Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_encoders.c | 6 ++++ drivers/gpu/drm/radeon/dce6_afmt.c | 35 +++++++++++++++++++ drivers/gpu/drm/radeon/evergreen_hdmi.c | 54 ++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/evergreen_reg.h | 15 +++++++++ drivers/gpu/drm/radeon/radeon_audio.c | 37 ++++++++++++++++++++ 5 files changed, 147 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 8ca8b4fcb10c..7c9df1eac065 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -665,6 +665,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) int atombios_get_encoder_mode(struct drm_encoder *encoder) { + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct drm_connector *connector; struct radeon_connector *radeon_connector; @@ -729,6 +731,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) dig_connector = radeon_connector->con_priv; if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { + if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) + return ATOM_ENCODER_MODE_DP_AUDIO; return ATOM_ENCODER_MODE_DP; } else if (radeon_audio != 0) { if (radeon_connector->audio == RADEON_AUDIO_ENABLE) @@ -743,6 +747,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) } break; case DRM_MODE_CONNECTOR_eDP: + if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) + return ATOM_ENCODER_MODE_DP_AUDIO; return ATOM_ENCODER_MODE_DP; case DRM_MODE_CONNECTOR_DVIA: case DRM_MODE_CONNECTOR_VGA: diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 1c870060c29b..192c80389151 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -287,3 +287,38 @@ void dce6_dp_audio_set_dto(struct radeon_device *rdev, WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); WREG32(DCCG_AUDIO_DTO1_MODULE, clock); } + +void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) +{ + struct drm_device *dev = encoder->dev; + 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; + uint32_t offset; + + if (!dig || !dig->afmt) + return; + + offset = dig->afmt->offset; + + if (enable) { + if (dig->afmt->enabled) + return; + + WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); + WREG32(EVERGREEN_DP_SEC_CNTL + offset, + EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ + EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ + EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ + EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ + radeon_audio_enable(rdev, dig->afmt->pin, true); + } else { + if (!dig->afmt->enabled) + return; + + WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0); + radeon_audio_enable(rdev, dig->afmt->pin, false); + } + + dig->afmt->enabled = enable; +} diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index c893fe1f0685..1d9aebc79595 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -424,3 +424,57 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id); } + +void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) +{ + struct drm_device *dev = encoder->dev; + 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; + uint32_t offset; + + if (!dig || !dig->afmt) + return; + + offset = dig->afmt->offset; + + if (enable) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *dig_connector; + uint32_t val; + + if (dig->afmt->enabled) + return; + + WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); + + if (radeon_connector->con_priv) { + dig_connector = radeon_connector->con_priv; + val = RREG32(EVERGREEN_DP_SEC_AUD_N + offset); + val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf); + + if (dig_connector->dp_clock == 162000) + val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(3); + else + val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(5); + + WREG32(EVERGREEN_DP_SEC_AUD_N + offset, val); + } + + WREG32(EVERGREEN_DP_SEC_CNTL + offset, + EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ + EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ + EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ + EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); + } else { + if (!dig->afmt->enabled) + return; + + WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0); + radeon_audio_enable(rdev, dig->afmt->pin, 0); + } + + dig->afmt->enabled = enable; +} diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 23bff590fb6e..aa939dfed3a3 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -251,4 +251,19 @@ /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ #define EVERGREEN_HDMI_BASE 0x7030 +/* Display Port block */ +#define EVERGREEN_DP_SEC_CNTL 0x7280 +# define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) +# define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) +# define EVERGREEN_DP_SEC_ATP_ENABLE (1 << 8) +# define EVERGREEN_DP_SEC_AIP_ENABLE (1 << 12) +# define EVERGREEN_DP_SEC_GSP_ENABLE (1 << 20) +# define EVERGREEN_DP_SEC_AVI_ENABLE (1 << 24) +# define EVERGREEN_DP_SEC_MPG_ENABLE (1 << 28) +#define EVERGREEN_DP_SEC_TIMESTAMP 0x72a4 +# define EVERGREEN_DP_SEC_TIMESTAMP_MODE(x) (((x) & 0x3) << 0) +#define EVERGREEN_DP_SEC_AUD_N 0x7294 +# define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) +# define EVERGREEN_DP_SEC_SS_EN (1 << 28) + #endif diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index f1e22a857da9..192a614255e9 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -97,8 +97,12 @@ void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); +static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode); void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); +void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); +void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); static const u32 pin_offsets[7] = { @@ -178,6 +182,7 @@ static struct radeon_audio_funcs dce32_dp_funcs = { .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, .set_dto = dce3_2_audio_set_dto, .set_avi_packet = r600_set_avi_packet, + .set_audio_packet = dce3_2_set_audio_packet, }; static struct radeon_audio_funcs dce4_hdmi_funcs = { @@ -203,6 +208,9 @@ static struct radeon_audio_funcs dce4_dp_funcs = { .write_latency_fields = dce4_afmt_write_latency_fields, .set_dto = dce4_dp_audio_set_dto, .set_avi_packet = evergreen_set_avi_packet, + .set_audio_packet = dce4_set_audio_packet, + .mode_set = radeon_audio_dp_mode_set, + .dpms = evergreen_enable_dp_audio_packets, }; static struct radeon_audio_funcs dce6_hdmi_funcs = { @@ -230,6 +238,9 @@ static struct radeon_audio_funcs dce6_dp_funcs = { .write_latency_fields = dce6_afmt_write_latency_fields, .set_dto = dce6_dp_audio_set_dto, .set_avi_packet = evergreen_set_avi_packet, + .set_audio_packet = dce4_set_audio_packet, + .mode_set = radeon_audio_dp_mode_set, + .dpms = dce6_enable_dp_audio_packets, }; static void radeon_audio_interface_init(struct radeon_device *rdev) @@ -711,6 +722,32 @@ static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } +static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode) +{ + struct drm_device *dev = encoder->dev; + 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; + + if (!dig || !dig->afmt) + return; + + /* disable audio prior to setting up hw */ + dig->afmt->pin = radeon_audio_get_pin(encoder); + radeon_audio_enable(rdev, dig->afmt->pin, 0); + + radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10); + radeon_audio_set_audio_packet(encoder); + radeon_audio_select_pin(encoder); + + if (radeon_audio_set_avi_packet(encoder, mode) < 0) + return; + + /* enable audio after to setting up hw */ + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); +} + void radeon_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) { -- cgit v1.2.3 From f4c6c08182b3f648b788422f27926f097759b0eb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 13 Jan 2015 12:41:40 -0500 Subject: drm/radeon: whitespace clean up in radeon_audio.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up some formatting in radeon_audio.c to be more consistent with the rest of the driver. Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_audio.c | 70 +++++++++++++++++------------------ 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 192a614255e9..8b4352d206b0 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -367,36 +367,36 @@ static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector; - struct radeon_connector *radeon_connector = NULL; - u8 *sadb = NULL; - int sad_count; + struct drm_connector *connector; + struct radeon_connector *radeon_connector = NULL; + u8 *sadb = NULL; + int sad_count; - list_for_each_entry(connector, - &encoder->dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - radeon_connector = to_radeon_connector(connector); - break; - } - } - - if (!radeon_connector) { - DRM_ERROR("Couldn't find encoder's connector\n"); - return; - } - - sad_count = drm_edid_to_speaker_allocation( + list_for_each_entry(connector, + &encoder->dev->mode_config.connector_list, head) { + if (connector->encoder == encoder) { + radeon_connector = to_radeon_connector(connector); + break; + } + } + + if (!radeon_connector) { + DRM_ERROR("Couldn't find encoder's connector\n"); + return; + } + + sad_count = drm_edid_to_speaker_allocation( radeon_connector_edid(connector), &sadb); - if (sad_count < 0) { - DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", - sad_count); - sad_count = 0; - } + if (sad_count < 0) { + DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", + sad_count); + sad_count = 0; + } if (radeon_encoder->audio && radeon_encoder->audio->write_speaker_allocation) radeon_encoder->audio->write_speaker_allocation(encoder, sadb, sad_count); - kfree(sadb); + kfree(sadb); } static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, @@ -520,7 +520,7 @@ static void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock static int radeon_audio_set_avi_packet(struct drm_encoder *encoder, struct drm_display_mode *mode) { - struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_device *rdev = encoder->dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; @@ -625,9 +625,9 @@ static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock) */ static void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock) { - const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock); + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; if (!dig || !dig->afmt) return; @@ -638,8 +638,8 @@ static void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int cl static void radeon_audio_set_vbi_packet(struct drm_encoder *encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; if (!dig || !dig->afmt) return; @@ -668,8 +668,8 @@ static void radeon_hdmi_set_color_depth(struct drm_encoder *encoder) static void radeon_audio_set_audio_packet(struct drm_encoder *encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; if (!dig || !dig->afmt) return; @@ -680,8 +680,8 @@ static void radeon_audio_set_audio_packet(struct drm_encoder *encoder) static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; if (!dig || !dig->afmt) return; @@ -696,7 +696,7 @@ static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) { - struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_device *rdev = encoder->dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -- cgit v1.2.3 From 308de41ba3bde80d50833718a2e37e49be868f5a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Jan 2015 17:20:10 -0500 Subject: drm/radeon: use NULL rather then 0 in audio detect Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 8b4352d206b0..a3ceef6d9632 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -470,7 +470,7 @@ void radeon_audio_detect(struct drm_connector *connector, int sink_type; if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { - radeon_encoder->audio = 0; + radeon_encoder->audio = NULL; return; } -- cgit v1.2.3 From 5a1aa4b447868b0ea66d2903df479b3b94c34151 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 21 Jan 2015 17:49:59 -0500 Subject: drm/radeon: make MMU_NOTIFIER optional In cases where MMU_NOTIFIER is not available, userptr will not be available. Similar to i915, although not making an exception for CAP_SYS_ADMIN. The proposed userspace patches for userptr seem to handle the fall- back properly, so a userptr-less kernel should not be a problem. Signed-off-by: Rob Clark Signed-off-by: Alex Deucher --- drivers/gpu/drm/Kconfig | 1 - drivers/gpu/drm/radeon/Makefile | 4 +++- drivers/gpu/drm/radeon/radeon.h | 8 ++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index ea283894a12a..308c104ccdbd 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -110,7 +110,6 @@ config DRM_RADEON select HWMON select BACKLIGHT_CLASS_DEVICE select INTERVAL_TREE - select MMU_NOTIFIER help Choose this option if you have an ATI Radeon graphics card. There are both PCI and AGP versions. You don't need to choose this to diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index f9dab1cb85ba..4605633e253b 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -80,9 +80,11 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ - ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \ + ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o \ radeon_sync.o radeon_audio.o +radeon-$(CONFIG_MMU_NOTIFIER) += radeon_mn.o + # add async DMA block radeon-y += \ r600_dma.o \ diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index d15e3c0c09f5..93e407b7e7a7 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1780,8 +1780,16 @@ void radeon_test_syncing(struct radeon_device *rdev); /* * MMU Notifier */ +#if defined(CONFIG_MMU_NOTIFIER) int radeon_mn_register(struct radeon_bo *bo, unsigned long addr); void radeon_mn_unregister(struct radeon_bo *bo); +#else +static inline int radeon_mn_register(struct radeon_bo *bo, unsigned long addr) +{ + return -ENODEV; +} +static inline void radeon_mn_unregister(struct radeon_bo *bo) {} +#endif /* * Debugfs -- cgit v1.2.3