Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "Intel, nouveau, radeon and qxl.

  Mostly for bugs introduced in the merge window, nothing too shocking"

[ And one cirrus fix added later and not mentioned in the pull request..  - Linus ]

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/cirrus: bind also to qemu-xen-traditional
  qxl: don't create too large primary surface
  drm/nouveau: fix regression on agp boards
  drm/gt215/gr: fix initialisation on gddr5 boards
  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
  drm/i915: fix short vs. long hpd detection
  drm/i915: Don't trust the DP_DETECT bit for eDP ports on CHV
  Revert "drm/radeon/dpm: drop clk/voltage dependency filters for SI"
  Revert "drm/radeon: drop btc_get_max_clock_from_voltage_dependency_table"
  drm/i915: properly reenable gen8 pipe IRQs
  drm/i915: Move DIV_ROUND_CLOSEST_ULL macro to header
  drm/i915: intel_backlight scale() math WA
This commit is contained in:
Linus Torvalds 2014-10-23 12:44:59 -07:00
commit eb0c5ff6f3
28 changed files with 176 additions and 77 deletions

View File

@ -32,6 +32,8 @@ static struct drm_driver driver;
static const struct pci_device_id pciidlist[] = {
{ PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0,
0, 0 },
{ PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, PCI_VENDOR_ID_XEN,
0x0001, 0, 0, 0 },
{0,}
};

View File

@ -1711,7 +1711,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
#define HPD_STORM_DETECT_PERIOD 1000
#define HPD_STORM_THRESHOLD 5
static int ilk_port_to_hotplug_shift(enum port port)
static int pch_port_to_hotplug_shift(enum port port)
{
switch (port) {
case PORT_A:
@ -1727,7 +1727,7 @@ static int ilk_port_to_hotplug_shift(enum port port)
}
}
static int g4x_port_to_hotplug_shift(enum port port)
static int i915_port_to_hotplug_shift(enum port port)
{
switch (port) {
case PORT_A:
@ -1785,12 +1785,12 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
if (port && dev_priv->hpd_irq_port[port]) {
bool long_hpd;
if (IS_G4X(dev)) {
dig_shift = g4x_port_to_hotplug_shift(port);
long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT;
} else {
dig_shift = ilk_port_to_hotplug_shift(port);
if (HAS_PCH_SPLIT(dev)) {
dig_shift = pch_port_to_hotplug_shift(port);
long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT;
} else {
dig_shift = i915_port_to_hotplug_shift(port);
long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT;
}
DRM_DEBUG_DRIVER("digital hpd port %c - %s\n",
@ -3458,12 +3458,13 @@ static void gen8_irq_reset(struct drm_device *dev)
void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv)
{
unsigned long irqflags;
uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B],
~dev_priv->de_irq_mask[PIPE_B]);
~dev_priv->de_irq_mask[PIPE_B] | extra_ier);
GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C],
~dev_priv->de_irq_mask[PIPE_C]);
~dev_priv->de_irq_mask[PIPE_C] | extra_ier);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}

View File

@ -73,9 +73,6 @@ static const uint32_t intel_cursor_formats[] = {
DRM_FORMAT_ARGB8888,
};
#define DIV_ROUND_CLOSEST_ULL(ll, d) \
({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; })
static void intel_increase_pllclock(struct drm_device *dev,
enum pipe pipe);
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
@ -12357,27 +12354,36 @@ static void intel_setup_outputs(struct drm_device *dev)
if (I915_READ(PCH_DP_D) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_D, PORT_D);
} else if (IS_VALLEYVIEW(dev)) {
if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) {
/*
* The DP_DETECTED bit is the latched state of the DDC
* SDA pin at boot. However since eDP doesn't require DDC
* (no way to plug in a DP->HDMI dongle) the DDC pins for
* eDP ports may have been muxed to an alternate function.
* Thus we can't rely on the DP_DETECTED bit alone to detect
* eDP ports. Consult the VBT as well as DP_DETECTED to
* detect eDP ports.
*/
if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED)
intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB,
PORT_B);
if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED)
intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B);
}
if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED ||
intel_dp_is_edp(dev, PORT_B))
intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B);
if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) {
if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED)
intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC,
PORT_C);
if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED)
intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C);
}
if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED ||
intel_dp_is_edp(dev, PORT_C))
intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C);
if (IS_CHERRYVIEW(dev)) {
if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) {
if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED)
intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID,
PORT_D);
if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED)
intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D);
}
/* eDP not supported on port D, so don't check VBT */
if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED)
intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D);
}
intel_dsi_init(dev);

View File

@ -35,6 +35,9 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_dp_mst_helper.h>
#define DIV_ROUND_CLOSEST_ULL(ll, d) \
({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; })
/**
* _wait_for - magic (register) wait macro
*

View File

@ -419,9 +419,8 @@ static uint32_t scale(uint32_t source_val,
source_val = clamp(source_val, source_min, source_max);
/* avoid overflows */
target_val = (uint64_t)(source_val - source_min) *
(target_max - target_min);
do_div(target_val, source_max - source_min);
target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) *
(target_max - target_min), source_max - source_min);
target_val += target_min;
return target_val;

View File

@ -113,6 +113,8 @@
#define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf)
#define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac)
#include <subdev/fb.h>
/*
* This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's
* the GPU itself that does context-switching, but it needs a special
@ -569,8 +571,12 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, 0x407d08, 0x00010040);
else if (device->chipset < 0xa0)
gr_def(ctx, 0x407d08, 0x00390040);
else
gr_def(ctx, 0x407d08, 0x003d0040);
else {
if (nouveau_fb(device)->ram->type != NV_MEM_TYPE_GDDR5)
gr_def(ctx, 0x407d08, 0x003d0040);
else
gr_def(ctx, 0x407d08, 0x003c0040);
}
gr_def(ctx, 0x407d0c, 0x00000022);
}

View File

@ -400,15 +400,20 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
struct nouveau_channel **pchan)
{
struct nouveau_cli *cli = (void *)nvif_client(&device->base);
bool super;
int ret;
/* hack until fencenv50 is fixed, and agp access relaxed */
super = cli->base.super;
cli->base.super = true;
ret = nouveau_channel_ind(drm, device, handle, arg0, pchan);
if (ret) {
NV_PRINTK(debug, cli, "ib channel create, %d\n", ret);
ret = nouveau_channel_dma(drm, device, handle, pchan);
if (ret) {
NV_PRINTK(debug, cli, "dma channel create, %d\n", ret);
return ret;
goto done;
}
}
@ -416,8 +421,9 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
if (ret) {
NV_PRINTK(error, cli, "channel failed to initialise, %d\n", ret);
nouveau_channel_del(pchan);
return ret;
}
return 0;
done:
cli->base.super = super;
return ret;
}

View File

@ -572,7 +572,6 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
struct qxl_framebuffer *qfb;
struct qxl_bo *bo, *old_bo = NULL;
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
uint32_t width, height, base_offset;
bool recreate_primary = false;
int ret;
int surf_id;
@ -602,9 +601,10 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
if (qcrtc->index == 0)
recreate_primary = true;
width = mode->hdisplay;
height = mode->vdisplay;
base_offset = 0;
if (bo->surf.stride * bo->surf.height > qdev->vram_size) {
DRM_ERROR("Mode doesn't fit in vram size (vgamem)");
return -EINVAL;
}
ret = qxl_bo_reserve(bo, false);
if (ret != 0)
@ -618,10 +618,10 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
if (recreate_primary) {
qxl_io_destroy_primary(qdev);
qxl_io_log(qdev,
"recreate primary: %dx%d (was %dx%d,%d,%d)\n",
width, height, bo->surf.width,
bo->surf.height, bo->surf.stride, bo->surf.format);
qxl_io_create_primary(qdev, base_offset, bo);
"recreate primary: %dx%d,%d,%d\n",
bo->surf.width, bo->surf.height,
bo->surf.stride, bo->surf.format);
qxl_io_create_primary(qdev, 0, bo);
bo->is_primary = true;
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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"

View File

@ -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);

View File

@ -24,6 +24,7 @@
#include "drmP.h"
#include "radeon.h"
#include "radeon_asic.h"
#include "r600d.h"
#include "r600_dpm.h"
#include "atom.h"

View File

@ -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

View File

@ -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 */

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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) {

View File

@ -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"

View File

@ -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"

View File

@ -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;