summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-02-12 10:01:51 +1000
committerDave Airlie <airlied@redhat.com>2015-02-12 10:01:51 +1000
commit96abd10ecc2e9ab5c8060697ce721683f387c64e (patch)
tree37452abd7abe3797ab10c97d4f05b720da33ada3 /drivers/gpu
parent64aa7e342a0a05cc19e278bc0822e2e667ebb645 (diff)
parent410af8d7285a0b96314845c75c39fd612b755688 (diff)
Merge branch 'drm-next-3.20' of git://people.freedesktop.org/~agd5f/linux into drm-next
Some radeon fixes for 3.20. * 'drm-next-3.20' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: only enable kv/kb dpm interrupts once v3 drm/radeon: workaround for CP HW bug on CIK drm/radeon: Don't try to enable write-combining without PAT drm/radeon: use 0-255 rather than 0-100 for pwm fan range
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/cik.c37
-rw-r--r--drivers/gpu/drm/radeon/kv_dpm.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c8
4 files changed, 48 insertions, 26 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index de77c27d8106..e6a4ba236c70 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -3905,7 +3905,21 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring = &rdev->ring[fence->ring];
u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
- /* EVENT_WRITE_EOP - flush caches, send int */
+ /* Workaround for cache flush problems. First send a dummy EOP
+ * event down the pipe with seq one below.
+ */
+ radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
+ radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
+ EOP_TC_ACTION_EN |
+ EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
+ EVENT_INDEX(5)));
+ radeon_ring_write(ring, addr & 0xfffffffc);
+ radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) |
+ DATA_SEL(1) | INT_SEL(0));
+ radeon_ring_write(ring, fence->seq - 1);
+ radeon_ring_write(ring, 0);
+
+ /* Then send the real EOP event down the pipe. */
radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
EOP_TC_ACTION_EN |
@@ -7359,7 +7373,6 @@ int cik_irq_set(struct radeon_device *rdev)
u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
u32 grbm_int_cntl = 0;
u32 dma_cntl, dma_cntl1;
- u32 thermal_int;
if (!rdev->irq.installed) {
WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
@@ -7389,13 +7402,6 @@ int cik_irq_set(struct radeon_device *rdev)
cp_m1p0 = RREG32(CP_ME1_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
- if (rdev->flags & RADEON_IS_IGP)
- thermal_int = RREG32_SMC(CG_THERMAL_INT_CTRL) &
- ~(THERM_INTH_MASK | THERM_INTL_MASK);
- else
- thermal_int = RREG32_SMC(CG_THERMAL_INT) &
- ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
-
/* enable CP interrupts on all rings */
if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
DRM_DEBUG("cik_irq_set: sw int gfx\n");
@@ -7499,14 +7505,6 @@ int cik_irq_set(struct radeon_device *rdev)
hpd6 |= DC_HPDx_INT_EN;
}
- if (rdev->irq.dpm_thermal) {
- DRM_DEBUG("dpm thermal\n");
- if (rdev->flags & RADEON_IS_IGP)
- thermal_int |= THERM_INTH_MASK | THERM_INTL_MASK;
- else
- thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
- }
-
WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, dma_cntl);
@@ -7553,11 +7551,6 @@ int cik_irq_set(struct radeon_device *rdev)
WREG32(DC_HPD5_INT_CONTROL, hpd5);
WREG32(DC_HPD6_INT_CONTROL, hpd6);
- if (rdev->flags & RADEON_IS_IGP)
- WREG32_SMC(CG_THERMAL_INT_CTRL, thermal_int);
- else
- WREG32_SMC(CG_THERMAL_INT, thermal_int);
-
return 0;
}
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index c5eb286517a8..0e236d067d66 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -1169,6 +1169,19 @@ void kv_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
}
}
+static void kv_enable_thermal_int(struct radeon_device *rdev, bool enable)
+{
+ u32 thermal_int;
+
+ thermal_int = RREG32_SMC(CG_THERMAL_INT_CTRL);
+ if (enable)
+ thermal_int |= THERM_INTH_MASK | THERM_INTL_MASK;
+ else
+ thermal_int &= ~(THERM_INTH_MASK | THERM_INTL_MASK);
+ WREG32_SMC(CG_THERMAL_INT_CTRL, thermal_int);
+
+}
+
int kv_dpm_enable(struct radeon_device *rdev)
{
struct kv_power_info *pi = kv_get_pi(rdev);
@@ -1280,8 +1293,7 @@ int kv_dpm_late_enable(struct radeon_device *rdev)
DRM_ERROR("kv_set_thermal_temperature_range failed\n");
return ret;
}
- rdev->irq.dpm_thermal = true;
- radeon_irq_set(rdev);
+ kv_enable_thermal_int(rdev, true);
}
/* powerdown unused blocks for now */
@@ -1312,6 +1324,7 @@ void kv_dpm_disable(struct radeon_device *rdev)
kv_stop_dpm(rdev);
kv_enable_ulv(rdev, false);
kv_reset_am(rdev);
+ kv_enable_thermal_int(rdev, false);
kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
}
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 1d955776f4d0..43e09942823e 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -238,6 +238,18 @@ int radeon_bo_create(struct radeon_device *rdev,
* See https://bugs.freedesktop.org/show_bug.cgi?id=84627
*/
bo->flags &= ~RADEON_GEM_GTT_WC;
+#elif defined(CONFIG_X86) && !defined(CONFIG_X86_PAT)
+ /* Don't try to enable write-combining when it can't work, or things
+ * may be slow
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=88758
+ */
+
+#warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \
+ thanks to write-combining
+
+ DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
+ "better performance thanks to write-combining\n");
+ bo->flags &= ~RADEON_GEM_GTT_WC;
#endif
radeon_ttm_placement_from_domain(bo, domain);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 91e1bd246cad..9f758d39420d 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -585,7 +585,7 @@ static ssize_t radeon_hwmon_set_pwm1_enable(struct device *dev,
if (err)
return err;
- switch(value) {
+ switch (value) {
case 1: /* manual, percent-based */
rdev->asic->dpm.fan_ctrl_set_mode(rdev, FDO_PWM_MODE_STATIC);
break;
@@ -608,7 +608,7 @@ 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 */
+ return sprintf(buf, "%i\n", 255);
}
static ssize_t radeon_hwmon_set_pwm1(struct device *dev,
@@ -623,6 +623,8 @@ static ssize_t radeon_hwmon_set_pwm1(struct device *dev,
if (err)
return err;
+ value = (value * 100) / 255;
+
err = rdev->asic->dpm.set_fan_speed_percent(rdev, value);
if (err)
return err;
@@ -642,6 +644,8 @@ static ssize_t radeon_hwmon_get_pwm1(struct device *dev,
if (err)
return err;
+ speed = (speed * 255) / 100;
+
return sprintf(buf, "%i\n", speed);
}