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:
Коммит
eb0c5ff6f3
|
@ -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,}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче