mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 01:22:07 +00:00
Merge branch 'drm-fixes-3.18' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
First round of fixes for 3.18. - Use gart for DMA ring tests to avoid caching issues with HDP - SI dpm stability fixes - Performance stabilization fixes - misc other things * 'drm-fixes-3.18' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: reduce sparse false positive warnings drm/radeon: fix vm page table block size calculation drm/ttm: Don't evict BOs outside of the requested placement range drm/ttm: Don't skip fpfn check if lpfn is 0 in ttm_bo_mem_compat drm/radeon: use gart memory for DMA ring tests drm/radeon: fix speaker allocation setup drm/radeon: initialize sadb to NULL in the audio code Revert "drm/radeon/dpm: drop clk/voltage dependency filters for SI" Revert "drm/radeon: drop btc_get_max_clock_from_voltage_dependency_table"
This commit is contained in:
commit
da36bbd0bf
@ -24,6 +24,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "btcd.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "cypress_dpm.h"
|
||||
@ -1170,6 +1171,23 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
|
||||
{ 25000, 30000, RADEON_SCLK_UP }
|
||||
};
|
||||
|
||||
void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table,
|
||||
u32 *max_clock)
|
||||
{
|
||||
u32 i, clock = 0;
|
||||
|
||||
if ((table == NULL) || (table->count == 0)) {
|
||||
*max_clock = clock;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < table->count; i++) {
|
||||
if (clock < table->entries[i].clk)
|
||||
clock = table->entries[i].clk;
|
||||
}
|
||||
*max_clock = clock;
|
||||
}
|
||||
|
||||
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
|
||||
u32 clock, u16 max_voltage, u16 *voltage)
|
||||
{
|
||||
|
@ -46,6 +46,8 @@ void btc_adjust_clock_combinations(struct radeon_device *rdev,
|
||||
struct rv7xx_pl *pl);
|
||||
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
|
||||
u32 clock, u16 max_voltage, u16 *voltage);
|
||||
void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table,
|
||||
u32 *max_clock);
|
||||
void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
|
||||
u16 max_vddc, u16 max_vddci,
|
||||
u16 *vddc, u16 *vddci);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/firmware.h>
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "radeon_ucode.h"
|
||||
#include "cikd.h"
|
||||
#include "r600_dpm.h"
|
||||
|
@ -611,16 +611,19 @@ int cik_sdma_ring_test(struct radeon_device *rdev,
|
||||
{
|
||||
unsigned i;
|
||||
int r;
|
||||
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
|
||||
unsigned index;
|
||||
u32 tmp;
|
||||
u64 gpu_addr;
|
||||
|
||||
if (!ptr) {
|
||||
DRM_ERROR("invalid vram scratch pointer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ring->idx == R600_RING_TYPE_DMA_INDEX)
|
||||
index = R600_WB_DMA_RING_TEST_OFFSET;
|
||||
else
|
||||
index = CAYMAN_WB_DMA1_RING_TEST_OFFSET;
|
||||
|
||||
gpu_addr = rdev->wb.gpu_addr + index;
|
||||
|
||||
tmp = 0xCAFEDEAD;
|
||||
writel(tmp, ptr);
|
||||
rdev->wb.wb[index/4] = cpu_to_le32(tmp);
|
||||
|
||||
r = radeon_ring_lock(rdev, ring, 5);
|
||||
if (r) {
|
||||
@ -628,14 +631,14 @@ int cik_sdma_ring_test(struct radeon_device *rdev,
|
||||
return r;
|
||||
}
|
||||
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0));
|
||||
radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc);
|
||||
radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr));
|
||||
radeon_ring_write(ring, lower_32_bits(gpu_addr));
|
||||
radeon_ring_write(ring, upper_32_bits(gpu_addr));
|
||||
radeon_ring_write(ring, 1); /* number of DWs to follow */
|
||||
radeon_ring_write(ring, 0xDEADBEEF);
|
||||
radeon_ring_unlock_commit(rdev, ring, false);
|
||||
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
tmp = readl(ptr);
|
||||
tmp = le32_to_cpu(rdev->wb.wb[index/4]);
|
||||
if (tmp == 0xDEADBEEF)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "evergreend.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "cypress_dpm.h"
|
||||
|
@ -32,7 +32,7 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||
struct drm_connector *connector;
|
||||
struct radeon_connector *radeon_connector = NULL;
|
||||
u32 tmp;
|
||||
u8 *sadb;
|
||||
u8 *sadb = NULL;
|
||||
int sad_count;
|
||||
|
||||
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
|
||||
@ -49,8 +49,8 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||
|
||||
sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
|
||||
if (sad_count < 0) {
|
||||
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||
return;
|
||||
DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||
sad_count = 0;
|
||||
}
|
||||
|
||||
/* program the speaker allocation */
|
||||
|
@ -155,7 +155,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||
struct drm_connector *connector;
|
||||
struct radeon_connector *radeon_connector = NULL;
|
||||
u32 offset, tmp;
|
||||
u8 *sadb;
|
||||
u8 *sadb = NULL;
|
||||
int sad_count;
|
||||
|
||||
if (!dig || !dig->afmt || !dig->afmt->pin)
|
||||
@ -176,9 +176,9 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
|
||||
if (sad_count <= 0) {
|
||||
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||
return;
|
||||
if (sad_count < 0) {
|
||||
DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||
sad_count = 0;
|
||||
}
|
||||
|
||||
/* program the speaker allocation */
|
||||
|
@ -133,7 +133,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||
struct drm_connector *connector;
|
||||
struct radeon_connector *radeon_connector = NULL;
|
||||
u32 tmp;
|
||||
u8 *sadb;
|
||||
u8 *sadb = NULL;
|
||||
int sad_count;
|
||||
|
||||
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
|
||||
@ -149,9 +149,9 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
|
||||
if (sad_count <= 0) {
|
||||
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||
return;
|
||||
if (sad_count < 0) {
|
||||
DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||
sad_count = 0;
|
||||
}
|
||||
|
||||
/* program the speaker allocation */
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "nid.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "ni_dpm.h"
|
||||
|
@ -232,16 +232,19 @@ int r600_dma_ring_test(struct radeon_device *rdev,
|
||||
{
|
||||
unsigned i;
|
||||
int r;
|
||||
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
|
||||
unsigned index;
|
||||
u32 tmp;
|
||||
u64 gpu_addr;
|
||||
|
||||
if (!ptr) {
|
||||
DRM_ERROR("invalid vram scratch pointer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ring->idx == R600_RING_TYPE_DMA_INDEX)
|
||||
index = R600_WB_DMA_RING_TEST_OFFSET;
|
||||
else
|
||||
index = CAYMAN_WB_DMA1_RING_TEST_OFFSET;
|
||||
|
||||
gpu_addr = rdev->wb.gpu_addr + index;
|
||||
|
||||
tmp = 0xCAFEDEAD;
|
||||
writel(tmp, ptr);
|
||||
rdev->wb.wb[index/4] = cpu_to_le32(tmp);
|
||||
|
||||
r = radeon_ring_lock(rdev, ring, 4);
|
||||
if (r) {
|
||||
@ -249,13 +252,13 @@ int r600_dma_ring_test(struct radeon_device *rdev,
|
||||
return r;
|
||||
}
|
||||
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
|
||||
radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc);
|
||||
radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff);
|
||||
radeon_ring_write(ring, lower_32_bits(gpu_addr));
|
||||
radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xff);
|
||||
radeon_ring_write(ring, 0xDEADBEEF);
|
||||
radeon_ring_unlock_commit(rdev, ring, false);
|
||||
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
tmp = readl(ptr);
|
||||
tmp = le32_to_cpu(rdev->wb.wb[index/4]);
|
||||
if (tmp == 0xDEADBEEF)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "r600d.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "atom.h"
|
||||
|
@ -1133,6 +1133,8 @@ struct radeon_wb {
|
||||
#define R600_WB_EVENT_OFFSET 3072
|
||||
#define CIK_WB_CP1_WPTR_OFFSET 3328
|
||||
#define CIK_WB_CP2_WPTR_OFFSET 3584
|
||||
#define R600_WB_DMA_RING_TEST_OFFSET 3588
|
||||
#define CAYMAN_WB_DMA1_RING_TEST_OFFSET 3592
|
||||
|
||||
/**
|
||||
* struct radeon_pm - power management datas
|
||||
|
@ -1130,7 +1130,7 @@ static void radeon_check_arguments(struct radeon_device *rdev)
|
||||
if (radeon_vm_block_size == -1) {
|
||||
|
||||
/* Total bits covered by PD + PTs */
|
||||
unsigned bits = ilog2(radeon_vm_size) + 17;
|
||||
unsigned bits = ilog2(radeon_vm_size) + 18;
|
||||
|
||||
/* Make sure the PD is 4K in size up to 8GB address space.
|
||||
Above that split equal between PD and PTs */
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "rs780d.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "rs780_dpm.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "rv6xxd.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "rv6xx_dpm.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "rv770d.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "rv770_dpm.h"
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "sid.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "si_dpm.h"
|
||||
@ -2916,6 +2917,7 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
||||
bool disable_sclk_switching = false;
|
||||
u32 mclk, sclk;
|
||||
u16 vddc, vddci;
|
||||
u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
|
||||
int i;
|
||||
|
||||
if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
|
||||
@ -2949,6 +2951,29 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
||||
}
|
||||
}
|
||||
|
||||
/* limit clocks to max supported clocks based on voltage dependency tables */
|
||||
btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
|
||||
&max_sclk_vddc);
|
||||
btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
|
||||
&max_mclk_vddci);
|
||||
btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
|
||||
&max_mclk_vddc);
|
||||
|
||||
for (i = 0; i < ps->performance_level_count; i++) {
|
||||
if (max_sclk_vddc) {
|
||||
if (ps->performance_levels[i].sclk > max_sclk_vddc)
|
||||
ps->performance_levels[i].sclk = max_sclk_vddc;
|
||||
}
|
||||
if (max_mclk_vddci) {
|
||||
if (ps->performance_levels[i].mclk > max_mclk_vddci)
|
||||
ps->performance_levels[i].mclk = max_mclk_vddci;
|
||||
}
|
||||
if (max_mclk_vddc) {
|
||||
if (ps->performance_levels[i].mclk > max_mclk_vddc)
|
||||
ps->performance_levels[i].mclk = max_mclk_vddc;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX validate the min clocks required for display */
|
||||
|
||||
if (disable_mclk_switching) {
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "sumod.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "cypress_dpm.h"
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "trinityd.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "trinity_dpm.h"
|
||||
|
@ -709,6 +709,7 @@ out:
|
||||
|
||||
static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
|
||||
uint32_t mem_type,
|
||||
const struct ttm_place *place,
|
||||
bool interruptible,
|
||||
bool no_wait_gpu)
|
||||
{
|
||||
@ -720,8 +721,21 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
|
||||
spin_lock(&glob->lru_lock);
|
||||
list_for_each_entry(bo, &man->lru, lru) {
|
||||
ret = __ttm_bo_reserve(bo, false, true, false, NULL);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (place && (place->fpfn || place->lpfn)) {
|
||||
/* Don't evict this BO if it's outside of the
|
||||
* requested placement range
|
||||
*/
|
||||
if (place->fpfn >= (bo->mem.start + bo->mem.size) ||
|
||||
(place->lpfn && place->lpfn <= bo->mem.start)) {
|
||||
__ttm_bo_unreserve(bo);
|
||||
ret = -EBUSY;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
@ -782,7 +796,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
|
||||
return ret;
|
||||
if (mem->mm_node)
|
||||
break;
|
||||
ret = ttm_mem_evict_first(bdev, mem_type,
|
||||
ret = ttm_mem_evict_first(bdev, mem_type, place,
|
||||
interruptible, no_wait_gpu);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
@ -994,9 +1008,9 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement,
|
||||
|
||||
for (i = 0; i < placement->num_placement; i++) {
|
||||
const struct ttm_place *heap = &placement->placement[i];
|
||||
if (mem->mm_node && heap->lpfn != 0 &&
|
||||
if (mem->mm_node &&
|
||||
(mem->start < heap->fpfn ||
|
||||
mem->start + mem->num_pages > heap->lpfn))
|
||||
(heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn)))
|
||||
continue;
|
||||
|
||||
*new_flags = heap->flags;
|
||||
@ -1007,9 +1021,9 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement,
|
||||
|
||||
for (i = 0; i < placement->num_busy_placement; i++) {
|
||||
const struct ttm_place *heap = &placement->busy_placement[i];
|
||||
if (mem->mm_node && heap->lpfn != 0 &&
|
||||
if (mem->mm_node &&
|
||||
(mem->start < heap->fpfn ||
|
||||
mem->start + mem->num_pages > heap->lpfn))
|
||||
(heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn)))
|
||||
continue;
|
||||
|
||||
*new_flags = heap->flags;
|
||||
@ -1233,7 +1247,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
|
||||
spin_lock(&glob->lru_lock);
|
||||
while (!list_empty(&man->lru)) {
|
||||
spin_unlock(&glob->lru_lock);
|
||||
ret = ttm_mem_evict_first(bdev, mem_type, false, false);
|
||||
ret = ttm_mem_evict_first(bdev, mem_type, NULL, false, false);
|
||||
if (ret) {
|
||||
if (allow_errors) {
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user