Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (42 commits) drm/radeon/kms/pm: switch to dynamically allocating clock mode array drm/radeon/kms: optimize r600_pm_profile_init drm/radeon/kms/pm: add a proper pm profile init function for fusion drm/radeon/kms: remove extraneous calls to radeon_pm_compute_clocks() drm/exynos: added padding to be 64-bit align. drm: fix kconfig unmet dependency warning drm: add some comments to drm_wait_vblank and drm_queue_vblank_event drm/radeon/benchmark: signedness bug in radeon_benchmark_move() drm: do not sleep on vblank while holding a mutex MAINTAINERS: exynos: Add EXYNOS DRM maintainer entry drm: try to restore previous CRTC config if mode set fails drm/radeon/kms: make an aux failure debug only drm: drop select of SLOW_WORK drm: serialize access to list of debugfs files drm/radeon/kms: fix use of vram scratch page on evergreen/ni drm/radeon: Make sure CS mutex is held across GPU reset. drm: Ensure string is null terminated. vmwgfx: Only allow 64x64 cursors vmwgfx: Initialize clip rect loop correctly in surface dirty vmwgfx: Close screen object system ...
This commit is contained in:
commit
f28ad3b44a
@ -2342,6 +2342,13 @@ S: Supported
|
||||
F: drivers/gpu/drm/i915
|
||||
F: include/drm/i915*
|
||||
|
||||
DRM DRIVERS FOR EXYNOS
|
||||
M: Inki Dae <inki.dae@samsung.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
F: drivers/gpu/drm/exynos
|
||||
F: include/drm/exynos*
|
||||
|
||||
DSCC4 DRIVER
|
||||
M: Francois Romieu <romieu@fr.zoreil.com>
|
||||
L: netdev@vger.kernel.org
|
||||
|
@ -1186,10 +1186,11 @@ static void gen6_cleanup(void)
|
||||
/* Certain Gen5 chipsets require require idling the GPU before
|
||||
* unmapping anything from the GTT when VT-d is enabled.
|
||||
*/
|
||||
extern int intel_iommu_gfx_mapped;
|
||||
static inline int needs_idle_maps(void)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
const unsigned short gpu_devid = intel_private.pcidev->device;
|
||||
extern int intel_iommu_gfx_mapped;
|
||||
|
||||
/* Query intel_iommu to see if we need the workaround. Presumably that
|
||||
* was loaded first.
|
||||
@ -1198,7 +1199,7 @@ static inline int needs_idle_maps(void)
|
||||
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
|
||||
intel_iommu_gfx_mapped)
|
||||
return 1;
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1236,7 +1237,7 @@ static int i9xx_setup(void)
|
||||
intel_private.gtt_bus_addr = reg_addr + gtt_offset;
|
||||
}
|
||||
|
||||
if (needs_idle_maps());
|
||||
if (needs_idle_maps())
|
||||
intel_private.base.do_idle_maps = 1;
|
||||
|
||||
intel_i9xx_setup_flush();
|
||||
|
@ -9,7 +9,6 @@ menuconfig DRM
|
||||
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
|
||||
select I2C
|
||||
select I2C_ALGOBIT
|
||||
select SLOW_WORK
|
||||
help
|
||||
Kernel-level support for the Direct Rendering Infrastructure (DRI)
|
||||
introduced in XFree86 4.0. If you say Y here, you need to select
|
||||
@ -96,6 +95,7 @@ config DRM_I915
|
||||
select FB_CFB_IMAGEBLIT
|
||||
# i915 depends on ACPI_VIDEO when ACPI is enabled
|
||||
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
|
||||
select BACKLIGHT_LCD_SUPPORT if ACPI
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select VIDEO_OUTPUT_CONTROL if ACPI
|
||||
select INPUT if ACPI
|
||||
|
@ -2118,8 +2118,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
|
||||
property->num_values = num_values;
|
||||
INIT_LIST_HEAD(&property->enum_blob_list);
|
||||
|
||||
if (name)
|
||||
if (name) {
|
||||
strncpy(property->name, name, DRM_PROP_NAME_LEN);
|
||||
property->name[DRM_PROP_NAME_LEN-1] = '\0';
|
||||
}
|
||||
|
||||
list_add_tail(&property->head, &dev->mode_config.property_list);
|
||||
return property;
|
||||
|
@ -484,6 +484,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
||||
struct drm_connector *save_connectors, *connector;
|
||||
int count = 0, ro, fail = 0;
|
||||
struct drm_crtc_helper_funcs *crtc_funcs;
|
||||
struct drm_mode_set save_set;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
@ -556,6 +557,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
||||
save_connectors[count++] = *connector;
|
||||
}
|
||||
|
||||
save_set.crtc = set->crtc;
|
||||
save_set.mode = &set->crtc->mode;
|
||||
save_set.x = set->crtc->x;
|
||||
save_set.y = set->crtc->y;
|
||||
save_set.fb = set->crtc->fb;
|
||||
|
||||
/* We should be able to check here if the fb has the same properties
|
||||
* and then just flip_or_move it */
|
||||
if (set->crtc->fb != set->fb) {
|
||||
@ -721,6 +728,12 @@ fail:
|
||||
*connector = save_connectors[count++];
|
||||
}
|
||||
|
||||
/* Try to restore the config */
|
||||
if (mode_changed &&
|
||||
!drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
|
||||
save_set.y, save_set.fb))
|
||||
DRM_ERROR("failed to restore config after modeset failure\n");
|
||||
|
||||
kfree(save_connectors);
|
||||
kfree(save_encoders);
|
||||
kfree(save_crtcs);
|
||||
|
@ -118,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
|
||||
tmp->minor = minor;
|
||||
tmp->dent = ent;
|
||||
tmp->info_ent = &files[i];
|
||||
list_add(&(tmp->list), &(minor->debugfs_nodes.list));
|
||||
|
||||
mutex_lock(&minor->debugfs_lock);
|
||||
list_add(&tmp->list, &minor->debugfs_list);
|
||||
mutex_unlock(&minor->debugfs_lock);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@ -146,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
|
||||
char name[64];
|
||||
int ret;
|
||||
|
||||
INIT_LIST_HEAD(&minor->debugfs_nodes.list);
|
||||
INIT_LIST_HEAD(&minor->debugfs_list);
|
||||
mutex_init(&minor->debugfs_lock);
|
||||
sprintf(name, "%d", minor_id);
|
||||
minor->debugfs_root = debugfs_create_dir(name, root);
|
||||
if (!minor->debugfs_root) {
|
||||
@ -192,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
|
||||
struct drm_info_node *tmp;
|
||||
int i;
|
||||
|
||||
mutex_lock(&minor->debugfs_lock);
|
||||
for (i = 0; i < count; i++) {
|
||||
list_for_each_safe(pos, q, &minor->debugfs_nodes.list) {
|
||||
list_for_each_safe(pos, q, &minor->debugfs_list) {
|
||||
tmp = list_entry(pos, struct drm_info_node, list);
|
||||
if (tmp->info_ent == &files[i]) {
|
||||
debugfs_remove(tmp->dent);
|
||||
@ -202,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&minor->debugfs_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_debugfs_remove_files);
|
||||
|
@ -125,7 +125,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
|
||||
|
||||
|
@ -407,13 +407,16 @@ int drm_irq_uninstall(struct drm_device *dev)
|
||||
/*
|
||||
* Wake up any waiters so they don't hang.
|
||||
*/
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
for (i = 0; i < dev->num_crtcs; i++) {
|
||||
DRM_WAKEUP(&dev->vbl_queue[i]);
|
||||
dev->vblank_enabled[i] = 0;
|
||||
dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
|
||||
if (dev->num_crtcs) {
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
for (i = 0; i < dev->num_crtcs; i++) {
|
||||
DRM_WAKEUP(&dev->vbl_queue[i]);
|
||||
dev->vblank_enabled[i] = 0;
|
||||
dev->last_vblank[i] =
|
||||
dev->driver->get_vblank_counter(dev, i);
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
|
||||
if (!irq_enabled)
|
||||
return -EINVAL;
|
||||
@ -1125,6 +1128,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
|
||||
trace_drm_vblank_event_delivered(current->pid, pipe,
|
||||
vblwait->request.sequence);
|
||||
} else {
|
||||
/* drm_handle_vblank_events will call drm_vblank_put */
|
||||
list_add_tail(&e->base.link, &dev->vblank_event_list);
|
||||
vblwait->reply.sequence = vblwait->request.sequence;
|
||||
}
|
||||
@ -1205,8 +1209,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (flags & _DRM_VBLANK_EVENT)
|
||||
if (flags & _DRM_VBLANK_EVENT) {
|
||||
/* must hold on to the vblank ref until the event fires
|
||||
* drm_vblank_put will be called asynchronously
|
||||
*/
|
||||
return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
|
||||
}
|
||||
|
||||
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
|
||||
(seq - vblwait->request.sequence) <= (1<<23)) {
|
||||
|
@ -1506,7 +1506,10 @@ drm_add_fake_info_node(struct drm_minor *minor,
|
||||
node->minor = minor;
|
||||
node->dent = ent;
|
||||
node->info_ent = (void *) key;
|
||||
list_add(&node->list, &minor->debugfs_nodes.list);
|
||||
|
||||
mutex_lock(&minor->debugfs_lock);
|
||||
list_add(&node->list, &minor->debugfs_list);
|
||||
mutex_unlock(&minor->debugfs_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file,
|
||||
|
||||
if (obj->base.size > dev_priv->mm.gtt_mappable_end) {
|
||||
ret = -E2BIG;
|
||||
goto unlock;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (obj->madv != I915_MADV_WILLNEED) {
|
||||
|
@ -640,10 +640,9 @@ static int
|
||||
nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t reg0 = nv_rd32(dev, reg + 0);
|
||||
uint32_t reg1 = nv_rd32(dev, reg + 4);
|
||||
struct nouveau_pll_vals pll;
|
||||
struct pll_lims pll_limits;
|
||||
u32 ctrl, mask, coef;
|
||||
int ret;
|
||||
|
||||
ret = get_pll_limits(dev, reg, &pll_limits);
|
||||
@ -654,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
|
||||
if (!clk)
|
||||
return -ERANGE;
|
||||
|
||||
reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16);
|
||||
reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1;
|
||||
|
||||
if (dev_priv->vbios.execute) {
|
||||
still_alive();
|
||||
nv_wr32(dev, reg + 4, reg1);
|
||||
nv_wr32(dev, reg + 0, reg0);
|
||||
coef = pll.N1 << 8 | pll.M1;
|
||||
ctrl = pll.log2P << 16;
|
||||
mask = 0x00070000;
|
||||
if (reg == 0x004008) {
|
||||
mask |= 0x01f80000;
|
||||
ctrl |= (pll_limits.log2p_bias << 19);
|
||||
ctrl |= (pll.log2P << 22);
|
||||
}
|
||||
|
||||
if (!dev_priv->vbios.execute)
|
||||
return 0;
|
||||
|
||||
nv_mask(dev, reg + 0, mask, ctrl);
|
||||
nv_wr32(dev, reg + 4, coef);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
|
||||
|
||||
if (dev_priv->card_type == NV_10 &&
|
||||
nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
|
||||
nvbo->bo.mem.num_pages < vram_pages / 2) {
|
||||
nvbo->bo.mem.num_pages < vram_pages / 4) {
|
||||
/*
|
||||
* Make sure that the color and depth buffers are handled
|
||||
* by independent memory controller units. Up to a 9x
|
||||
|
@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
|
||||
INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
|
||||
INIT_LIST_HEAD(&chan->nvsw.flip);
|
||||
INIT_LIST_HEAD(&chan->fence.pending);
|
||||
spin_lock_init(&chan->fence.lock);
|
||||
|
||||
/* setup channel's memory and vm */
|
||||
ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle);
|
||||
|
@ -710,7 +710,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
||||
case OUTPUT_DP:
|
||||
max_clock = nv_encoder->dp.link_nr;
|
||||
max_clock *= nv_encoder->dp.link_bw;
|
||||
clock = clock * nouveau_connector_bpp(connector) / 8;
|
||||
clock = clock * nouveau_connector_bpp(connector) / 10;
|
||||
break;
|
||||
default:
|
||||
BUG_ON(1);
|
||||
|
@ -487,6 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_fbdev *nfbdev;
|
||||
int preferred_bpp;
|
||||
int ret;
|
||||
|
||||
nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
|
||||
@ -505,7 +506,15 @@ int nouveau_fbcon_init(struct drm_device *dev)
|
||||
}
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
|
||||
drm_fb_helper_initial_config(&nfbdev->helper, 32);
|
||||
|
||||
if (dev_priv->vram_size <= 32 * 1024 * 1024)
|
||||
preferred_bpp = 8;
|
||||
else if (dev_priv->vram_size <= 64 * 1024 * 1024)
|
||||
preferred_bpp = 16;
|
||||
else
|
||||
preferred_bpp = 32;
|
||||
|
||||
drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
|
||||
return ret;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&chan->fence.pending);
|
||||
spin_lock_init(&chan->fence.lock);
|
||||
atomic_set(&chan->fence.last_sequence_irq, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what,
|
||||
|
||||
NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
|
||||
|
||||
for (i = 0; info[i].addr; i++) {
|
||||
for (i = 0; i2c && info[i].addr; i++) {
|
||||
if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
|
||||
(!match || match(i2c, &info[i]))) {
|
||||
NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
|
||||
|
@ -239,7 +239,7 @@ nouveau_perf_init(struct drm_device *dev)
|
||||
if(version == 0x15) {
|
||||
memtimings->timing =
|
||||
kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL);
|
||||
if(!memtimings) {
|
||||
if (!memtimings->timing) {
|
||||
NV_WARN(dev,"Could not allocate memtiming table\n");
|
||||
return;
|
||||
}
|
||||
|
@ -579,6 +579,14 @@ nouveau_card_init(struct drm_device *dev)
|
||||
if (ret)
|
||||
goto out_display_early;
|
||||
|
||||
/* workaround an odd issue on nvc1 by disabling the device's
|
||||
* nosnoop capability. hopefully won't cause issues until a
|
||||
* better fix is found - assuming there is one...
|
||||
*/
|
||||
if (dev_priv->chipset == 0xc1) {
|
||||
nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
|
||||
}
|
||||
|
||||
nouveau_pm_init(dev);
|
||||
|
||||
ret = engine->vram.init(dev);
|
||||
@ -1102,12 +1110,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
||||
dev_priv->noaccel = !!nouveau_noaccel;
|
||||
if (nouveau_noaccel == -1) {
|
||||
switch (dev_priv->chipset) {
|
||||
case 0xc1: /* known broken */
|
||||
case 0xc8: /* never tested */
|
||||
#if 0
|
||||
case 0xXX: /* known broken */
|
||||
NV_INFO(dev, "acceleration disabled by default, pass "
|
||||
"noaccel=0 to force enable\n");
|
||||
dev_priv->noaccel = true;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
dev_priv->noaccel = false;
|
||||
break;
|
||||
|
@ -57,12 +57,14 @@ read_pll_2(struct drm_device *dev, u32 reg)
|
||||
int P = (ctrl & 0x00070000) >> 16;
|
||||
u32 ref = 27000, clk = 0;
|
||||
|
||||
if (ctrl & 0x80000000)
|
||||
if ((ctrl & 0x80000000) && M1) {
|
||||
clk = ref * N1 / M1;
|
||||
|
||||
if (!(ctrl & 0x00000100)) {
|
||||
if (ctrl & 0x40000000)
|
||||
clk = clk * N2 / M2;
|
||||
if ((ctrl & 0x40000100) == 0x40000000) {
|
||||
if (M2)
|
||||
clk = clk * N2 / M2;
|
||||
else
|
||||
clk = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return clk >> P;
|
||||
@ -177,6 +179,11 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
|
||||
}
|
||||
|
||||
/* memory clock */
|
||||
if (!perflvl->memory) {
|
||||
info->mpll_ctrl = 0x00000000;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory,
|
||||
&N1, &M1, &N2, &M2, &log2P);
|
||||
if (ret < 0)
|
||||
@ -264,6 +271,9 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
|
||||
mdelay(5);
|
||||
nv_mask(dev, 0x00c040, 0x00000333, info->ctrl);
|
||||
|
||||
if (!info->mpll_ctrl)
|
||||
goto resume;
|
||||
|
||||
/* wait for vblank start on active crtcs, disable memory access */
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!(crtc_mask & (1 << i)))
|
||||
|
@ -131,8 +131,8 @@ nv50_graph_init(struct drm_device *dev, int engine)
|
||||
NV_DEBUG(dev, "\n");
|
||||
|
||||
/* master reset */
|
||||
nv_mask(dev, 0x000200, 0x00200100, 0x00000000);
|
||||
nv_mask(dev, 0x000200, 0x00200100, 0x00200100);
|
||||
nv_mask(dev, 0x000200, 0x00201000, 0x00000000);
|
||||
nv_mask(dev, 0x000200, 0x00201000, 0x00201000);
|
||||
nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */
|
||||
|
||||
/* reset/enable traps and interrupts */
|
||||
|
@ -601,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
|
||||
gr_def(ctx, offset + 0x1c, 0x00880000);
|
||||
break;
|
||||
case 0x86:
|
||||
gr_def(ctx, offset + 0x1c, 0x008c0000);
|
||||
gr_def(ctx, offset + 0x1c, 0x018c0000);
|
||||
break;
|
||||
case 0x92:
|
||||
case 0x96:
|
||||
|
@ -160,7 +160,7 @@ nv50_vram_rblock(struct drm_device *dev)
|
||||
colbits = (r4 & 0x0000f000) >> 12;
|
||||
rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
|
||||
rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
|
||||
banks = ((r4 & 0x01000000) ? 8 : 4);
|
||||
banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
|
||||
|
||||
rowsize = parts * banks * (1 << colbits) * 8;
|
||||
predicted = rowsize << rowbitsa;
|
||||
|
@ -157,8 +157,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
|
||||
struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
|
||||
struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
int i = 0, gpc, tp, ret;
|
||||
u32 magic;
|
||||
|
||||
ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM,
|
||||
&grch->unk408004);
|
||||
@ -207,14 +207,37 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
|
||||
nv_wo32(grch->mmio, i++ * 4, 0x0041880c);
|
||||
nv_wo32(grch->mmio, i++ * 4, 0x80000018);
|
||||
|
||||
magic = 0x02180000;
|
||||
nv_wo32(grch->mmio, i++ * 4, 0x00405830);
|
||||
nv_wo32(grch->mmio, i++ * 4, magic);
|
||||
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
|
||||
for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x0324) {
|
||||
u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800);
|
||||
nv_wo32(grch->mmio, i++ * 4, reg);
|
||||
nv_wo32(grch->mmio, i++ * 4, magic);
|
||||
if (dev_priv->chipset != 0xc1) {
|
||||
u32 magic = 0x02180000;
|
||||
nv_wo32(grch->mmio, i++ * 4, 0x00405830);
|
||||
nv_wo32(grch->mmio, i++ * 4, magic);
|
||||
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
|
||||
for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
|
||||
u32 reg = TP_UNIT(gpc, tp, 0x520);
|
||||
nv_wo32(grch->mmio, i++ * 4, reg);
|
||||
nv_wo32(grch->mmio, i++ * 4, magic);
|
||||
magic += 0x0324;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
u32 magic = 0x02180000;
|
||||
nv_wo32(grch->mmio, i++ * 4, 0x00405830);
|
||||
nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218);
|
||||
nv_wo32(grch->mmio, i++ * 4, 0x004064c4);
|
||||
nv_wo32(grch->mmio, i++ * 4, 0x0086ffff);
|
||||
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
|
||||
for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
|
||||
u32 reg = TP_UNIT(gpc, tp, 0x520);
|
||||
nv_wo32(grch->mmio, i++ * 4, reg);
|
||||
nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic);
|
||||
magic += 0x0324;
|
||||
}
|
||||
for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
|
||||
u32 reg = TP_UNIT(gpc, tp, 0x544);
|
||||
nv_wo32(grch->mmio, i++ * 4, reg);
|
||||
nv_wo32(grch->mmio, i++ * 4, magic);
|
||||
magic += 0x0324;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1812,6 +1812,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
|
||||
/* calculate first set of magics */
|
||||
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
|
||||
|
||||
gpc = -1;
|
||||
for (tp = 0; tp < priv->tp_total; tp++) {
|
||||
do {
|
||||
gpc = (gpc + 1) % priv->gpc_nr;
|
||||
@ -1861,30 +1862,26 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
|
||||
|
||||
if (1) {
|
||||
u32 tp_mask = 0, tp_set = 0;
|
||||
u8 tpnr[GPC_MAX];
|
||||
u8 tpnr[GPC_MAX], a, b;
|
||||
|
||||
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
|
||||
for (gpc = 0; gpc < priv->gpc_nr; gpc++)
|
||||
tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8);
|
||||
|
||||
gpc = -1;
|
||||
for (i = 0, gpc = -1; i < 32; i++) {
|
||||
int ltp = i * (priv->tp_total - 1) / 32;
|
||||
for (i = 0, gpc = -1, b = -1; i < 32; i++) {
|
||||
a = (i * (priv->tp_total - 1)) / 32;
|
||||
if (a != b) {
|
||||
b = a;
|
||||
do {
|
||||
gpc = (gpc + 1) % priv->gpc_nr;
|
||||
} while (!tpnr[gpc]);
|
||||
tp = priv->tp_nr[gpc] - tpnr[gpc]--;
|
||||
|
||||
do {
|
||||
gpc = (gpc + 1) % priv->gpc_nr;
|
||||
} while (!tpnr[gpc]);
|
||||
tp = priv->tp_nr[gpc] - tpnr[gpc]--;
|
||||
tp_set |= 1 << ((gpc * 8) + tp);
|
||||
}
|
||||
|
||||
tp_set |= 1 << ((gpc * 8) + tp);
|
||||
|
||||
do {
|
||||
nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
|
||||
tp_set ^= tp_mask;
|
||||
nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set);
|
||||
tp_set ^= tp_mask;
|
||||
} while (ltp == (++i * (priv->tp_total - 1) / 32));
|
||||
i--;
|
||||
nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
|
||||
nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ static const u8 types[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
|
||||
3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
|
||||
3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
|
||||
3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
|
||||
3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
|
||||
@ -110,22 +110,26 @@ nvc0_vram_init(struct drm_device *dev)
|
||||
u32 bsize = nv_rd32(dev, 0x10f20c);
|
||||
u32 offset, length;
|
||||
bool uniform = true;
|
||||
int ret, i;
|
||||
int ret, part;
|
||||
|
||||
NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));
|
||||
NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize);
|
||||
|
||||
/* read amount of vram attached to each memory controller */
|
||||
for (i = 0; i < parts; i++) {
|
||||
u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000));
|
||||
part = 0;
|
||||
while (parts) {
|
||||
u32 psize = nv_rd32(dev, 0x11020c + (part++ * 0x1000));
|
||||
if (psize == 0)
|
||||
continue;
|
||||
parts--;
|
||||
|
||||
if (psize != bsize) {
|
||||
if (psize < bsize)
|
||||
bsize = psize;
|
||||
uniform = false;
|
||||
}
|
||||
|
||||
NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize);
|
||||
|
||||
NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);
|
||||
dev_priv->vram_size += (u64)psize << 20;
|
||||
}
|
||||
|
||||
|
@ -1522,12 +1522,6 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
/* adjust pm to upcoming mode change */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
|
||||
if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
|
||||
return false;
|
||||
return true;
|
||||
|
@ -283,7 +283,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
||||
}
|
||||
}
|
||||
|
||||
DRM_ERROR("aux i2c too many retries, giving up\n");
|
||||
DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,57 @@ int sumo_get_temp(struct radeon_device *rdev)
|
||||
return actual_temp * 1000;
|
||||
}
|
||||
|
||||
void sumo_pm_init_profile(struct radeon_device *rdev)
|
||||
{
|
||||
int idx;
|
||||
|
||||
/* default */
|
||||
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
|
||||
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
|
||||
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
|
||||
|
||||
/* low,mid sh/mh */
|
||||
if (rdev->flags & RADEON_IS_MOBILITY)
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
|
||||
else
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
|
||||
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
|
||||
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
|
||||
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
|
||||
|
||||
/* high sh/mh */
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx =
|
||||
rdev->pm.power_state[idx].num_clock_modes - 1;
|
||||
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx =
|
||||
rdev->pm.power_state[idx].num_clock_modes - 1;
|
||||
}
|
||||
|
||||
void evergreen_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
int req_ps_idx = rdev->pm.requested_power_state_index;
|
||||
@ -1219,7 +1270,7 @@ void evergreen_mc_program(struct radeon_device *rdev)
|
||||
WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
rdev->mc.vram_end >> 12);
|
||||
}
|
||||
WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
|
||||
WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;
|
||||
tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24;
|
||||
|
@ -288,24 +288,6 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev)
|
||||
pcie_lanes);
|
||||
}
|
||||
|
||||
static int r600_pm_get_type_index(struct radeon_device *rdev,
|
||||
enum radeon_pm_state_type ps_type,
|
||||
int instance)
|
||||
{
|
||||
int i;
|
||||
int found_instance = -1;
|
||||
|
||||
for (i = 0; i < rdev->pm.num_power_states; i++) {
|
||||
if (rdev->pm.power_state[i].type == ps_type) {
|
||||
found_instance++;
|
||||
if (found_instance == instance)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
/* return default if no match */
|
||||
return rdev->pm.default_power_state_index;
|
||||
}
|
||||
|
||||
void rs780_pm_init_profile(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->pm.num_power_states == 2) {
|
||||
@ -421,6 +403,8 @@ void rs780_pm_init_profile(struct radeon_device *rdev)
|
||||
|
||||
void r600_pm_init_profile(struct radeon_device *rdev)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (rdev->family == CHIP_R600) {
|
||||
/* XXX */
|
||||
/* default */
|
||||
@ -502,81 +486,43 @@ void r600_pm_init_profile(struct radeon_device *rdev)
|
||||
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
|
||||
/* low sh */
|
||||
if (rdev->flags & RADEON_IS_MOBILITY) {
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
|
||||
} else {
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
|
||||
}
|
||||
if (rdev->flags & RADEON_IS_MOBILITY)
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
|
||||
else
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
|
||||
/* mid sh */
|
||||
if (rdev->flags & RADEON_IS_MOBILITY) {
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
|
||||
} else {
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
|
||||
}
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
|
||||
/* high sh */
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
|
||||
/* low mh */
|
||||
if (rdev->flags & RADEON_IS_MOBILITY) {
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
|
||||
} else {
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
|
||||
}
|
||||
if (rdev->flags & RADEON_IS_MOBILITY)
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
|
||||
else
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
|
||||
/* mid mh */
|
||||
if (rdev->flags & RADEON_IS_MOBILITY) {
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
|
||||
} else {
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
|
||||
}
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
|
||||
/* high mh */
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx =
|
||||
r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
|
||||
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
|
||||
}
|
||||
|
@ -784,8 +784,7 @@ struct radeon_pm_clock_info {
|
||||
|
||||
struct radeon_power_state {
|
||||
enum radeon_pm_state_type type;
|
||||
/* XXX: use a define for num clock modes */
|
||||
struct radeon_pm_clock_info clock_info[8];
|
||||
struct radeon_pm_clock_info *clock_info;
|
||||
/* number of valid clock modes in this power state */
|
||||
int num_clock_modes;
|
||||
struct radeon_pm_clock_info *default_clock_mode;
|
||||
@ -855,6 +854,9 @@ struct radeon_pm {
|
||||
struct device *int_hwmon_dev;
|
||||
};
|
||||
|
||||
int radeon_pm_get_type_index(struct radeon_device *rdev,
|
||||
enum radeon_pm_state_type ps_type,
|
||||
int instance);
|
||||
|
||||
/*
|
||||
* Benchmarking
|
||||
@ -1142,6 +1144,48 @@ struct r600_vram_scratch {
|
||||
u64 gpu_addr;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Mutex which allows recursive locking from the same process.
|
||||
*/
|
||||
struct radeon_mutex {
|
||||
struct mutex mutex;
|
||||
struct task_struct *owner;
|
||||
int level;
|
||||
};
|
||||
|
||||
static inline void radeon_mutex_init(struct radeon_mutex *mutex)
|
||||
{
|
||||
mutex_init(&mutex->mutex);
|
||||
mutex->owner = NULL;
|
||||
mutex->level = 0;
|
||||
}
|
||||
|
||||
static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
|
||||
{
|
||||
if (mutex_trylock(&mutex->mutex)) {
|
||||
/* The mutex was unlocked before, so it's ours now */
|
||||
mutex->owner = current;
|
||||
} else if (mutex->owner != current) {
|
||||
/* Another process locked the mutex, take it */
|
||||
mutex_lock(&mutex->mutex);
|
||||
mutex->owner = current;
|
||||
}
|
||||
/* Otherwise the mutex was already locked by this process */
|
||||
|
||||
mutex->level++;
|
||||
}
|
||||
|
||||
static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
|
||||
{
|
||||
if (--mutex->level > 0)
|
||||
return;
|
||||
|
||||
mutex->owner = NULL;
|
||||
mutex_unlock(&mutex->mutex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Core structure, functions and helpers.
|
||||
*/
|
||||
@ -1197,7 +1241,7 @@ struct radeon_device {
|
||||
struct radeon_gem gem;
|
||||
struct radeon_pm pm;
|
||||
uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH];
|
||||
struct mutex cs_mutex;
|
||||
struct radeon_mutex cs_mutex;
|
||||
struct radeon_wb wb;
|
||||
struct radeon_dummy_page dummy_page;
|
||||
bool gpu_lockup;
|
||||
|
@ -834,7 +834,7 @@ static struct radeon_asic sumo_asic = {
|
||||
.pm_misc = &evergreen_pm_misc,
|
||||
.pm_prepare = &evergreen_pm_prepare,
|
||||
.pm_finish = &evergreen_pm_finish,
|
||||
.pm_init_profile = &rs780_pm_init_profile,
|
||||
.pm_init_profile = &sumo_pm_init_profile,
|
||||
.pm_get_dynpm_state = &r600_pm_get_dynpm_state,
|
||||
.pre_page_flip = &evergreen_pre_page_flip,
|
||||
.page_flip = &evergreen_page_flip,
|
||||
|
@ -413,6 +413,7 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p);
|
||||
extern void evergreen_pm_misc(struct radeon_device *rdev);
|
||||
extern void evergreen_pm_prepare(struct radeon_device *rdev);
|
||||
extern void evergreen_pm_finish(struct radeon_device *rdev);
|
||||
extern void sumo_pm_init_profile(struct radeon_device *rdev);
|
||||
extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
|
||||
extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
|
||||
extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
|
||||
|
@ -1999,6 +1999,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
|
||||
switch (frev) {
|
||||
case 1:
|
||||
rdev->pm.power_state[state_index].clock_info =
|
||||
kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
|
||||
if (!rdev->pm.power_state[state_index].clock_info)
|
||||
return state_index;
|
||||
rdev->pm.power_state[state_index].num_clock_modes = 1;
|
||||
rdev->pm.power_state[state_index].clock_info[0].mclk =
|
||||
le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
|
||||
@ -2035,6 +2039,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
|
||||
state_index++;
|
||||
break;
|
||||
case 2:
|
||||
rdev->pm.power_state[state_index].clock_info =
|
||||
kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
|
||||
if (!rdev->pm.power_state[state_index].clock_info)
|
||||
return state_index;
|
||||
rdev->pm.power_state[state_index].num_clock_modes = 1;
|
||||
rdev->pm.power_state[state_index].clock_info[0].mclk =
|
||||
le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
|
||||
@ -2072,6 +2080,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
|
||||
state_index++;
|
||||
break;
|
||||
case 3:
|
||||
rdev->pm.power_state[state_index].clock_info =
|
||||
kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
|
||||
if (!rdev->pm.power_state[state_index].clock_info)
|
||||
return state_index;
|
||||
rdev->pm.power_state[state_index].num_clock_modes = 1;
|
||||
rdev->pm.power_state[state_index].clock_info[0].mclk =
|
||||
le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
|
||||
@ -2257,7 +2269,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[mode_index - 1];
|
||||
if (ASIC_IS_DCE5(rdev)) {
|
||||
if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
|
||||
/* NI chips post without MC ucode, so default clocks are strobe mode only */
|
||||
rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
|
||||
rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
|
||||
@ -2377,17 +2389,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
|
||||
le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
|
||||
(power_state->v1.ucNonClockStateIndex *
|
||||
power_info->pplib.ucNonClockSize));
|
||||
for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
|
||||
clock_info = (union pplib_clock_info *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
|
||||
(power_state->v1.ucClockStateIndices[j] *
|
||||
power_info->pplib.ucClockInfoSize));
|
||||
valid = radeon_atombios_parse_pplib_clock_info(rdev,
|
||||
state_index, mode_index,
|
||||
clock_info);
|
||||
if (valid)
|
||||
mode_index++;
|
||||
rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
|
||||
((power_info->pplib.ucStateEntrySize - 1) ?
|
||||
(power_info->pplib.ucStateEntrySize - 1) : 1),
|
||||
GFP_KERNEL);
|
||||
if (!rdev->pm.power_state[i].clock_info)
|
||||
return state_index;
|
||||
if (power_info->pplib.ucStateEntrySize - 1) {
|
||||
for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
|
||||
clock_info = (union pplib_clock_info *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
|
||||
(power_state->v1.ucClockStateIndices[j] *
|
||||
power_info->pplib.ucClockInfoSize));
|
||||
valid = radeon_atombios_parse_pplib_clock_info(rdev,
|
||||
state_index, mode_index,
|
||||
clock_info);
|
||||
if (valid)
|
||||
mode_index++;
|
||||
}
|
||||
} else {
|
||||
rdev->pm.power_state[state_index].clock_info[0].mclk =
|
||||
rdev->clock.default_mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[0].sclk =
|
||||
rdev->clock.default_sclk;
|
||||
mode_index++;
|
||||
}
|
||||
rdev->pm.power_state[state_index].num_clock_modes = mode_index;
|
||||
if (mode_index) {
|
||||
@ -2456,18 +2482,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
|
||||
non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
|
||||
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
|
||||
&non_clock_info_array->nonClockInfo[non_clock_array_index];
|
||||
for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
|
||||
clock_array_index = power_state->v2.clockInfoIndex[j];
|
||||
/* XXX this might be an inagua bug... */
|
||||
if (clock_array_index >= clock_info_array->ucNumEntries)
|
||||
continue;
|
||||
clock_info = (union pplib_clock_info *)
|
||||
&clock_info_array->clockInfo[clock_array_index];
|
||||
valid = radeon_atombios_parse_pplib_clock_info(rdev,
|
||||
state_index, mode_index,
|
||||
clock_info);
|
||||
if (valid)
|
||||
mode_index++;
|
||||
rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
|
||||
(power_state->v2.ucNumDPMLevels ?
|
||||
power_state->v2.ucNumDPMLevels : 1),
|
||||
GFP_KERNEL);
|
||||
if (!rdev->pm.power_state[i].clock_info)
|
||||
return state_index;
|
||||
if (power_state->v2.ucNumDPMLevels) {
|
||||
for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
|
||||
clock_array_index = power_state->v2.clockInfoIndex[j];
|
||||
/* XXX this might be an inagua bug... */
|
||||
if (clock_array_index >= clock_info_array->ucNumEntries)
|
||||
continue;
|
||||
clock_info = (union pplib_clock_info *)
|
||||
&clock_info_array->clockInfo[clock_array_index];
|
||||
valid = radeon_atombios_parse_pplib_clock_info(rdev,
|
||||
state_index, mode_index,
|
||||
clock_info);
|
||||
if (valid)
|
||||
mode_index++;
|
||||
}
|
||||
} else {
|
||||
rdev->pm.power_state[state_index].clock_info[0].mclk =
|
||||
rdev->clock.default_mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[0].sclk =
|
||||
rdev->clock.default_sclk;
|
||||
mode_index++;
|
||||
}
|
||||
rdev->pm.power_state[state_index].num_clock_modes = mode_index;
|
||||
if (mode_index) {
|
||||
@ -2524,19 +2564,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
} else {
|
||||
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
|
||||
if (rdev->pm.power_state) {
|
||||
/* add the default mode */
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
rdev->pm.power_state[state_index].num_clock_modes = 1;
|
||||
rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
|
||||
rdev->pm.power_state[state_index].pcie_lanes = 16;
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].flags = 0;
|
||||
state_index++;
|
||||
rdev->pm.power_state[0].clock_info =
|
||||
kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
|
||||
if (rdev->pm.power_state[0].clock_info) {
|
||||
/* add the default mode */
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
rdev->pm.power_state[state_index].num_clock_modes = 1;
|
||||
rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
|
||||
rdev->pm.power_state[state_index].pcie_lanes = 16;
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].flags = 0;
|
||||
state_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
|
||||
struct radeon_bo *sobj = NULL;
|
||||
uint64_t saddr, daddr;
|
||||
int r, n;
|
||||
unsigned int time;
|
||||
int time;
|
||||
|
||||
n = RADEON_BENCHMARK_ITERATIONS;
|
||||
r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj);
|
||||
|
@ -222,7 +222,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
int r;
|
||||
|
||||
mutex_lock(&rdev->cs_mutex);
|
||||
radeon_mutex_lock(&rdev->cs_mutex);
|
||||
/* initialize parser */
|
||||
memset(&parser, 0, sizeof(struct radeon_cs_parser));
|
||||
parser.filp = filp;
|
||||
@ -233,14 +233,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to initialize parser !\n");
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
radeon_mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
r = radeon_ib_get(rdev, &parser.ib);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to get ib !\n");
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
radeon_mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
r = radeon_cs_parser_relocs(&parser);
|
||||
@ -248,7 +248,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
if (r != -ERESTARTSYS)
|
||||
DRM_ERROR("Failed to parse relocation %d!\n", r);
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
radeon_mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
/* Copy the packet into the IB, the parser will read from the
|
||||
@ -260,14 +260,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
if (r || parser.parser_error) {
|
||||
DRM_ERROR("Invalid command stream !\n");
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
radeon_mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
r = radeon_cs_finish_pages(&parser);
|
||||
if (r) {
|
||||
DRM_ERROR("Invalid command stream !\n");
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
radeon_mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
r = radeon_ib_schedule(rdev, parser.ib);
|
||||
@ -275,7 +275,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
DRM_ERROR("Failed to schedule IB !\n");
|
||||
}
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
radeon_mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -716,7 +716,7 @@ int radeon_device_init(struct radeon_device *rdev,
|
||||
|
||||
/* mutex initialization are all done here so we
|
||||
* can recall function without having locking issues */
|
||||
mutex_init(&rdev->cs_mutex);
|
||||
radeon_mutex_init(&rdev->cs_mutex);
|
||||
mutex_init(&rdev->ib_pool.mutex);
|
||||
mutex_init(&rdev->cp.mutex);
|
||||
mutex_init(&rdev->dc_hw_i2c_mutex);
|
||||
@ -955,6 +955,9 @@ int radeon_gpu_reset(struct radeon_device *rdev)
|
||||
int r;
|
||||
int resched;
|
||||
|
||||
/* Prevent CS ioctl from interfering */
|
||||
radeon_mutex_lock(&rdev->cs_mutex);
|
||||
|
||||
radeon_save_bios_scratch_regs(rdev);
|
||||
/* block TTM */
|
||||
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
|
||||
@ -967,10 +970,15 @@ int radeon_gpu_reset(struct radeon_device *rdev)
|
||||
radeon_restore_bios_scratch_regs(rdev);
|
||||
drm_helper_resume_force_mode(rdev->ddev);
|
||||
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
|
||||
return 0;
|
||||
}
|
||||
/* bad news, how to tell it to userspace ? */
|
||||
dev_info(rdev->dev, "GPU reset failed\n");
|
||||
|
||||
radeon_mutex_unlock(&rdev->cs_mutex);
|
||||
|
||||
if (r) {
|
||||
/* bad news, how to tell it to userspace ? */
|
||||
dev_info(rdev->dev, "GPU reset failed\n");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -991,12 +991,6 @@ static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
/* adjust pm to upcoming mode change */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
|
||||
if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
|
||||
return false;
|
||||
return true;
|
||||
|
@ -53,6 +53,24 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev);
|
||||
|
||||
#define ACPI_AC_CLASS "ac_adapter"
|
||||
|
||||
int radeon_pm_get_type_index(struct radeon_device *rdev,
|
||||
enum radeon_pm_state_type ps_type,
|
||||
int instance)
|
||||
{
|
||||
int i;
|
||||
int found_instance = -1;
|
||||
|
||||
for (i = 0; i < rdev->pm.num_power_states; i++) {
|
||||
if (rdev->pm.power_state[i].type == ps_type) {
|
||||
found_instance++;
|
||||
if (found_instance == instance)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
/* return default if no match */
|
||||
return rdev->pm.default_power_state_index;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static int radeon_acpi_event(struct notifier_block *nb,
|
||||
unsigned long val,
|
||||
|
@ -105,6 +105,10 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
|
||||
struct vmw_dma_buffer *dmabuf = NULL;
|
||||
int ret;
|
||||
|
||||
/* A lot of the code assumes this */
|
||||
if (handle && (width != 64 || height != 64))
|
||||
return -EINVAL;
|
||||
|
||||
if (handle) {
|
||||
ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
|
||||
handle, &surface);
|
||||
@ -410,8 +414,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
|
||||
top = clips->y1;
|
||||
bottom = clips->y2;
|
||||
|
||||
clips_ptr = clips;
|
||||
for (i = 1; i < num_clips; i++, clips_ptr += inc) {
|
||||
/* skip the first clip rect */
|
||||
for (i = 1, clips_ptr = clips + inc;
|
||||
i < num_clips; i++, clips_ptr += inc) {
|
||||
left = min_t(int, left, (int)clips_ptr->x1);
|
||||
right = max_t(int, right, (int)clips_ptr->x2);
|
||||
top = min_t(int, top, (int)clips_ptr->y1);
|
||||
@ -1323,7 +1328,10 @@ int vmw_kms_close(struct vmw_private *dev_priv)
|
||||
* drm_encoder_cleanup which takes the lock we deadlock.
|
||||
*/
|
||||
drm_mode_config_cleanup(dev_priv->dev);
|
||||
vmw_kms_close_legacy_display_system(dev_priv);
|
||||
if (dev_priv->sou_priv)
|
||||
vmw_kms_close_screen_object_display(dev_priv);
|
||||
else
|
||||
vmw_kms_close_legacy_display_system(dev_priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -990,7 +990,9 @@ struct drm_minor {
|
||||
struct proc_dir_entry *proc_root; /**< proc directory entry */
|
||||
struct drm_info_node proc_nodes;
|
||||
struct dentry *debugfs_root;
|
||||
struct drm_info_node debugfs_nodes;
|
||||
|
||||
struct list_head debugfs_list;
|
||||
struct mutex debugfs_lock; /* Protects debugfs_list. */
|
||||
|
||||
struct drm_master *master; /* currently active master for this node */
|
||||
struct list_head master_list;
|
||||
|
@ -36,11 +36,13 @@
|
||||
* - this size value would be page-aligned internally.
|
||||
* @flags: user request for setting memory type or cache attributes.
|
||||
* @handle: returned handle for the object.
|
||||
* @pad: just padding to be 64-bit aligned.
|
||||
*/
|
||||
struct drm_exynos_gem_create {
|
||||
unsigned int size;
|
||||
unsigned int flags;
|
||||
unsigned int handle;
|
||||
unsigned int pad;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user