mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +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
20 changed files with 113 additions and 37 deletions
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "btcd.h"
|
#include "btcd.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "cypress_dpm.h"
|
#include "cypress_dpm.h"
|
||||||
|
@ -1170,6 +1171,23 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
|
||||||
{ 25000, 30000, RADEON_SCLK_UP }
|
{ 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,
|
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
|
||||||
u32 clock, u16 max_voltage, u16 *voltage)
|
u32 clock, u16 max_voltage, u16 *voltage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,6 +46,8 @@ void btc_adjust_clock_combinations(struct radeon_device *rdev,
|
||||||
struct rv7xx_pl *pl);
|
struct rv7xx_pl *pl);
|
||||||
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
|
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
|
||||||
u32 clock, u16 max_voltage, u16 *voltage);
|
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,
|
void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
|
||||||
u16 max_vddc, u16 max_vddci,
|
u16 max_vddc, u16 max_vddci,
|
||||||
u16 *vddc, u16 *vddci);
|
u16 *vddc, u16 *vddci);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "radeon_ucode.h"
|
#include "radeon_ucode.h"
|
||||||
#include "cikd.h"
|
#include "cikd.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
|
|
|
@ -611,16 +611,19 @@ int cik_sdma_ring_test(struct radeon_device *rdev,
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int r;
|
int r;
|
||||||
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
|
unsigned index;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
u64 gpu_addr;
|
||||||
|
|
||||||
if (!ptr) {
|
if (ring->idx == R600_RING_TYPE_DMA_INDEX)
|
||||||
DRM_ERROR("invalid vram scratch pointer\n");
|
index = R600_WB_DMA_RING_TEST_OFFSET;
|
||||||
return -EINVAL;
|
else
|
||||||
}
|
index = CAYMAN_WB_DMA1_RING_TEST_OFFSET;
|
||||||
|
|
||||||
|
gpu_addr = rdev->wb.gpu_addr + index;
|
||||||
|
|
||||||
tmp = 0xCAFEDEAD;
|
tmp = 0xCAFEDEAD;
|
||||||
writel(tmp, ptr);
|
rdev->wb.wb[index/4] = cpu_to_le32(tmp);
|
||||||
|
|
||||||
r = radeon_ring_lock(rdev, ring, 5);
|
r = radeon_ring_lock(rdev, ring, 5);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
@ -628,14 +631,14 @@ int cik_sdma_ring_test(struct radeon_device *rdev,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0));
|
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, lower_32_bits(gpu_addr));
|
||||||
radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.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, 1); /* number of DWs to follow */
|
||||||
radeon_ring_write(ring, 0xDEADBEEF);
|
radeon_ring_write(ring, 0xDEADBEEF);
|
||||||
radeon_ring_unlock_commit(rdev, ring, false);
|
radeon_ring_unlock_commit(rdev, ring, false);
|
||||||
|
|
||||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||||
tmp = readl(ptr);
|
tmp = le32_to_cpu(rdev->wb.wb[index/4]);
|
||||||
if (tmp == 0xDEADBEEF)
|
if (tmp == 0xDEADBEEF)
|
||||||
break;
|
break;
|
||||||
DRM_UDELAY(1);
|
DRM_UDELAY(1);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "evergreend.h"
|
#include "evergreend.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "cypress_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 drm_connector *connector;
|
||||||
struct radeon_connector *radeon_connector = NULL;
|
struct radeon_connector *radeon_connector = NULL;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
u8 *sadb;
|
u8 *sadb = NULL;
|
||||||
int sad_count;
|
int sad_count;
|
||||||
|
|
||||||
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
|
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);
|
sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
|
||||||
if (sad_count < 0) {
|
if (sad_count < 0) {
|
||||||
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||||
return;
|
sad_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* program the speaker allocation */
|
/* program the speaker allocation */
|
||||||
|
|
|
@ -155,7 +155,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
struct radeon_connector *radeon_connector = NULL;
|
struct radeon_connector *radeon_connector = NULL;
|
||||||
u32 offset, tmp;
|
u32 offset, tmp;
|
||||||
u8 *sadb;
|
u8 *sadb = NULL;
|
||||||
int sad_count;
|
int sad_count;
|
||||||
|
|
||||||
if (!dig || !dig->afmt || !dig->afmt->pin)
|
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);
|
sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
|
||||||
if (sad_count <= 0) {
|
if (sad_count < 0) {
|
||||||
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||||
return;
|
sad_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* program the speaker allocation */
|
/* program the speaker allocation */
|
||||||
|
|
|
@ -133,7 +133,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
struct radeon_connector *radeon_connector = NULL;
|
struct radeon_connector *radeon_connector = NULL;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
u8 *sadb;
|
u8 *sadb = NULL;
|
||||||
int sad_count;
|
int sad_count;
|
||||||
|
|
||||||
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
|
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);
|
sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
|
||||||
if (sad_count <= 0) {
|
if (sad_count < 0) {
|
||||||
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
|
||||||
return;
|
sad_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* program the speaker allocation */
|
/* program the speaker allocation */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "nid.h"
|
#include "nid.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "ni_dpm.h"
|
#include "ni_dpm.h"
|
||||||
|
|
|
@ -232,16 +232,19 @@ int r600_dma_ring_test(struct radeon_device *rdev,
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int r;
|
int r;
|
||||||
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
|
unsigned index;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
u64 gpu_addr;
|
||||||
|
|
||||||
if (!ptr) {
|
if (ring->idx == R600_RING_TYPE_DMA_INDEX)
|
||||||
DRM_ERROR("invalid vram scratch pointer\n");
|
index = R600_WB_DMA_RING_TEST_OFFSET;
|
||||||
return -EINVAL;
|
else
|
||||||
}
|
index = CAYMAN_WB_DMA1_RING_TEST_OFFSET;
|
||||||
|
|
||||||
|
gpu_addr = rdev->wb.gpu_addr + index;
|
||||||
|
|
||||||
tmp = 0xCAFEDEAD;
|
tmp = 0xCAFEDEAD;
|
||||||
writel(tmp, ptr);
|
rdev->wb.wb[index/4] = cpu_to_le32(tmp);
|
||||||
|
|
||||||
r = radeon_ring_lock(rdev, ring, 4);
|
r = radeon_ring_lock(rdev, ring, 4);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
@ -249,13 +252,13 @@ int r600_dma_ring_test(struct radeon_device *rdev,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
|
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, lower_32_bits(gpu_addr));
|
||||||
radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff);
|
radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xff);
|
||||||
radeon_ring_write(ring, 0xDEADBEEF);
|
radeon_ring_write(ring, 0xDEADBEEF);
|
||||||
radeon_ring_unlock_commit(rdev, ring, false);
|
radeon_ring_unlock_commit(rdev, ring, false);
|
||||||
|
|
||||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||||
tmp = readl(ptr);
|
tmp = le32_to_cpu(rdev->wb.wb[index/4]);
|
||||||
if (tmp == 0xDEADBEEF)
|
if (tmp == 0xDEADBEEF)
|
||||||
break;
|
break;
|
||||||
DRM_UDELAY(1);
|
DRM_UDELAY(1);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "r600d.h"
|
#include "r600d.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
|
|
@ -1133,6 +1133,8 @@ struct radeon_wb {
|
||||||
#define R600_WB_EVENT_OFFSET 3072
|
#define R600_WB_EVENT_OFFSET 3072
|
||||||
#define CIK_WB_CP1_WPTR_OFFSET 3328
|
#define CIK_WB_CP1_WPTR_OFFSET 3328
|
||||||
#define CIK_WB_CP2_WPTR_OFFSET 3584
|
#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
|
* 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) {
|
if (radeon_vm_block_size == -1) {
|
||||||
|
|
||||||
/* Total bits covered by PD + PTs */
|
/* 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.
|
/* Make sure the PD is 4K in size up to 8GB address space.
|
||||||
Above that split equal between PD and PTs */
|
Above that split equal between PD and PTs */
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "rs780d.h"
|
#include "rs780d.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "rs780_dpm.h"
|
#include "rs780_dpm.h"
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "rv6xxd.h"
|
#include "rv6xxd.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "rv6xx_dpm.h"
|
#include "rv6xx_dpm.h"
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "rv770d.h"
|
#include "rv770d.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "rv770_dpm.h"
|
#include "rv770_dpm.h"
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "sid.h"
|
#include "sid.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "si_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;
|
bool disable_sclk_switching = false;
|
||||||
u32 mclk, sclk;
|
u32 mclk, sclk;
|
||||||
u16 vddc, vddci;
|
u16 vddc, vddci;
|
||||||
|
u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
|
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 */
|
/* XXX validate the min clocks required for display */
|
||||||
|
|
||||||
if (disable_mclk_switching) {
|
if (disable_mclk_switching) {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "sumod.h"
|
#include "sumod.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "cypress_dpm.h"
|
#include "cypress_dpm.h"
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
#include "radeon_asic.h"
|
||||||
#include "trinityd.h"
|
#include "trinityd.h"
|
||||||
#include "r600_dpm.h"
|
#include "r600_dpm.h"
|
||||||
#include "trinity_dpm.h"
|
#include "trinity_dpm.h"
|
||||||
|
|
|
@ -709,6 +709,7 @@ out:
|
||||||
|
|
||||||
static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
|
static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
|
||||||
uint32_t mem_type,
|
uint32_t mem_type,
|
||||||
|
const struct ttm_place *place,
|
||||||
bool interruptible,
|
bool interruptible,
|
||||||
bool no_wait_gpu)
|
bool no_wait_gpu)
|
||||||
{
|
{
|
||||||
|
@ -720,8 +721,21 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
|
||||||
spin_lock(&glob->lru_lock);
|
spin_lock(&glob->lru_lock);
|
||||||
list_for_each_entry(bo, &man->lru, lru) {
|
list_for_each_entry(bo, &man->lru, lru) {
|
||||||
ret = __ttm_bo_reserve(bo, false, true, false, NULL);
|
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;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -782,7 +796,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
|
||||||
return ret;
|
return ret;
|
||||||
if (mem->mm_node)
|
if (mem->mm_node)
|
||||||
break;
|
break;
|
||||||
ret = ttm_mem_evict_first(bdev, mem_type,
|
ret = ttm_mem_evict_first(bdev, mem_type, place,
|
||||||
interruptible, no_wait_gpu);
|
interruptible, no_wait_gpu);
|
||||||
if (unlikely(ret != 0))
|
if (unlikely(ret != 0))
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -994,9 +1008,9 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement,
|
||||||
|
|
||||||
for (i = 0; i < placement->num_placement; i++) {
|
for (i = 0; i < placement->num_placement; i++) {
|
||||||
const struct ttm_place *heap = &placement->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 < heap->fpfn ||
|
||||||
mem->start + mem->num_pages > heap->lpfn))
|
(heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*new_flags = heap->flags;
|
*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++) {
|
for (i = 0; i < placement->num_busy_placement; i++) {
|
||||||
const struct ttm_place *heap = &placement->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 < heap->fpfn ||
|
||||||
mem->start + mem->num_pages > heap->lpfn))
|
(heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*new_flags = heap->flags;
|
*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);
|
spin_lock(&glob->lru_lock);
|
||||||
while (!list_empty(&man->lru)) {
|
while (!list_empty(&man->lru)) {
|
||||||
spin_unlock(&glob->lru_lock);
|
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 (ret) {
|
||||||
if (allow_errors) {
|
if (allow_errors) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Reference in a new issue