forked from Minki/linux
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "I got a bit behind last week, so here is a delayed fixes pull: - a bunch of radeon/amd gpu fixes - some nouveau regression fixes (ppc bios reading and runtime pm fix) - one drm core oops fix - two qxl locking fixes - one qxl regression fix" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/nouveau/bios: fix OF loading drm/nouveau/fbcon: take runpm reference when userspace has an open fd drm/nouveau/nouveau: Disable AGP for SiS 761 drm/nouveau/display: allow up to 16k width/height for fermi+ drm/nouveau/bios: translate devinit pri/sec i2c bus to internal identifiers drm: Fix locking for sysfs dpms file drm/amdgpu: fix memory leak in amdgpu_vm_update_page_directory drm/amdgpu: fix 32-bit compiler warning drm/qxl: avoid dependency lock drm/qxl: avoid buffer reservation in qxl_crtc_page_flip drm/qxl: fix framebuffer dirty rectangle tracking. drm/amdgpu: flag iceland as experimental drm/amdgpu: check before checking pci bridge registers drm/amdgpu: fix num_crtc on CZ drm/amdgpu: restore the fbdev mode in lastclose drm/radeon: restore the fbdev mode in lastclose drm/radeon: add quirk for ASUS R7 370 drm/amdgpu: add pm sysfs files late drm/radeon: add pm sysfs files late
This commit is contained in:
commit
06d1ee32a4
@ -177,7 +177,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
||||
|
||||
/* get chunks */
|
||||
INIT_LIST_HEAD(&p->validated);
|
||||
chunk_array_user = (uint64_t __user *)(cs->in.chunks);
|
||||
chunk_array_user = (uint64_t __user *)(unsigned long)(cs->in.chunks);
|
||||
if (copy_from_user(chunk_array, chunk_array_user,
|
||||
sizeof(uint64_t)*cs->in.num_chunks)) {
|
||||
ret = -EFAULT;
|
||||
@ -197,7 +197,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
||||
struct drm_amdgpu_cs_chunk user_chunk;
|
||||
uint32_t __user *cdata;
|
||||
|
||||
chunk_ptr = (void __user *)chunk_array[i];
|
||||
chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
|
||||
if (copy_from_user(&user_chunk, chunk_ptr,
|
||||
sizeof(struct drm_amdgpu_cs_chunk))) {
|
||||
ret = -EFAULT;
|
||||
@ -208,7 +208,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
||||
p->chunks[i].length_dw = user_chunk.length_dw;
|
||||
|
||||
size = p->chunks[i].length_dw;
|
||||
cdata = (void __user *)user_chunk.chunk_data;
|
||||
cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
|
||||
p->chunks[i].user_ptr = cdata;
|
||||
|
||||
p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
|
||||
|
@ -242,11 +242,11 @@ static struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
|
||||
#endif
|
||||
/* topaz */
|
||||
{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
/* tonga */
|
||||
{0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
|
||||
{0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
|
||||
|
@ -402,3 +402,19 @@ bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_fbdev *afbdev = adev->mode_info.rfbdev;
|
||||
struct drm_fb_helper *fb_helper;
|
||||
int ret;
|
||||
|
||||
if (!afbdev)
|
||||
return;
|
||||
|
||||
fb_helper = &afbdev->helper;
|
||||
|
||||
ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
|
||||
if (ret)
|
||||
DRM_DEBUG("failed to restore crtc mode\n");
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
||||
* Outdated mess for old drm with Xorg being in charge (void function now).
|
||||
*/
|
||||
/**
|
||||
* amdgpu_driver_firstopen_kms - drm callback for last close
|
||||
* amdgpu_driver_lastclose_kms - drm callback for last close
|
||||
*
|
||||
* @dev: drm dev pointer
|
||||
*
|
||||
@ -493,6 +493,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
||||
*/
|
||||
void amdgpu_driver_lastclose_kms(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
amdgpu_fbdev_restore_mode(adev);
|
||||
vga_switcheroo_process_delayed_switch();
|
||||
}
|
||||
|
||||
|
@ -567,6 +567,7 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev);
|
||||
void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state);
|
||||
int amdgpu_fbdev_total_size(struct amdgpu_device *adev);
|
||||
bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj);
|
||||
void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev);
|
||||
|
||||
|
@ -455,8 +455,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
|
||||
return -ENOMEM;
|
||||
|
||||
r = amdgpu_ib_get(ring, NULL, ndw * 4, ib);
|
||||
if (r)
|
||||
if (r) {
|
||||
kfree(ib);
|
||||
return r;
|
||||
}
|
||||
ib->length_dw = 0;
|
||||
|
||||
/* walk over the address space and update the page directory */
|
||||
|
@ -6185,6 +6185,11 @@ static int ci_dpm_late_init(void *handle)
|
||||
if (!amdgpu_dpm)
|
||||
return 0;
|
||||
|
||||
/* init the sysfs and debugfs files late */
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ci_set_temperature_range(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -6232,9 +6237,6 @@ static int ci_dpm_sw_init(void *handle)
|
||||
adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
|
||||
if (amdgpu_dpm == 1)
|
||||
amdgpu_pm_print_power_states(adev);
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
goto dpm_failed;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
DRM_INFO("amdgpu: dpm initialized\n");
|
||||
|
||||
|
@ -1567,6 +1567,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
int ret, i;
|
||||
u16 tmp16;
|
||||
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
|
@ -596,6 +596,12 @@ static int cz_dpm_late_init(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_dpm) {
|
||||
int ret;
|
||||
/* init the sysfs and debugfs files late */
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* powerdown unused blocks for now */
|
||||
cz_dpm_powergate_uvd(adev, true);
|
||||
cz_dpm_powergate_vce(adev, true);
|
||||
@ -632,10 +638,6 @@ static int cz_dpm_sw_init(void *handle)
|
||||
if (amdgpu_dpm == 1)
|
||||
amdgpu_pm_print_power_states(adev);
|
||||
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
goto dpm_init_failed;
|
||||
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
DRM_INFO("amdgpu: dpm initialized\n");
|
||||
|
||||
|
@ -2888,7 +2888,7 @@ static int dce_v11_0_early_init(void *handle)
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_CARRIZO:
|
||||
adev->mode_info.num_crtc = 4;
|
||||
adev->mode_info.num_crtc = 3;
|
||||
adev->mode_info.num_hpd = 6;
|
||||
adev->mode_info.num_dig = 9;
|
||||
break;
|
||||
|
@ -2995,6 +2995,12 @@ static int kv_dpm_late_init(void *handle)
|
||||
{
|
||||
/* powerdown unused blocks for now */
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret;
|
||||
|
||||
/* init the sysfs and debugfs files late */
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
kv_dpm_powergate_acp(adev, true);
|
||||
kv_dpm_powergate_samu(adev, true);
|
||||
@ -3038,9 +3044,6 @@ static int kv_dpm_sw_init(void *handle)
|
||||
adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
|
||||
if (amdgpu_dpm == 1)
|
||||
amdgpu_pm_print_power_states(adev);
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
goto dpm_failed;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
DRM_INFO("amdgpu: dpm initialized\n");
|
||||
|
||||
|
@ -1005,6 +1005,9 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
u32 mask;
|
||||
int ret;
|
||||
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
|
@ -235,18 +235,12 @@ static ssize_t dpms_show(struct device *device,
|
||||
char *buf)
|
||||
{
|
||||
struct drm_connector *connector = to_drm_connector(device);
|
||||
struct drm_device *dev = connector->dev;
|
||||
uint64_t dpms_status;
|
||||
int ret;
|
||||
int dpms;
|
||||
|
||||
ret = drm_object_property_get_value(&connector->base,
|
||||
dev->mode_config.dpms_property,
|
||||
&dpms_status);
|
||||
if (ret)
|
||||
return 0;
|
||||
dpms = READ_ONCE(connector->dpms);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
drm_get_dpms_name((int)dpms_status));
|
||||
drm_get_dpms_name(dpms));
|
||||
}
|
||||
|
||||
static ssize_t enabled_show(struct device *device,
|
||||
|
@ -469,9 +469,13 @@ nouveau_display_create(struct drm_device *dev)
|
||||
if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
|
||||
dev->mode_config.max_width = 4096;
|
||||
dev->mode_config.max_height = 4096;
|
||||
} else {
|
||||
} else
|
||||
if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) {
|
||||
dev->mode_config.max_width = 8192;
|
||||
dev->mode_config.max_height = 8192;
|
||||
} else {
|
||||
dev->mode_config.max_width = 16384;
|
||||
dev->mode_config.max_height = 16384;
|
||||
}
|
||||
|
||||
dev->mode_config.preferred_depth = 24;
|
||||
|
@ -178,8 +178,30 @@ nouveau_fbcon_sync(struct fb_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_fbcon_open(struct fb_info *info, int user)
|
||||
{
|
||||
struct nouveau_fbdev *fbcon = info->par;
|
||||
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
|
||||
int ret = pm_runtime_get_sync(drm->dev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_fbcon_release(struct fb_info *info, int user)
|
||||
{
|
||||
struct nouveau_fbdev *fbcon = info->par;
|
||||
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
|
||||
pm_runtime_put(drm->dev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops nouveau_fbcon_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_open = nouveau_fbcon_open,
|
||||
.fb_release = nouveau_fbcon_release,
|
||||
.fb_check_var = drm_fb_helper_check_var,
|
||||
.fb_set_par = drm_fb_helper_set_par,
|
||||
.fb_fillrect = nouveau_fbcon_fillrect,
|
||||
@ -195,6 +217,8 @@ static struct fb_ops nouveau_fbcon_ops = {
|
||||
|
||||
static struct fb_ops nouveau_fbcon_sw_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_open = nouveau_fbcon_open,
|
||||
.fb_release = nouveau_fbcon_release,
|
||||
.fb_check_var = drm_fb_helper_check_var,
|
||||
.fb_set_par = drm_fb_helper_set_par,
|
||||
.fb_fillrect = drm_fb_helper_cfb_fillrect,
|
||||
|
@ -267,6 +267,12 @@ init_i2c(struct nvbios_init *init, int index)
|
||||
index = NVKM_I2C_BUS_PRI;
|
||||
if (init->outp && init->outp->i2c_upper_default)
|
||||
index = NVKM_I2C_BUS_SEC;
|
||||
} else
|
||||
if (index == 0x80) {
|
||||
index = NVKM_I2C_BUS_PRI;
|
||||
} else
|
||||
if (index == 0x81) {
|
||||
index = NVKM_I2C_BUS_SEC;
|
||||
}
|
||||
|
||||
bus = nvkm_i2c_bus_find(i2c, index);
|
||||
|
@ -8,7 +8,10 @@ struct nvbios_source {
|
||||
void *(*init)(struct nvkm_bios *, const char *);
|
||||
void (*fini)(void *);
|
||||
u32 (*read)(void *, u32 offset, u32 length, struct nvkm_bios *);
|
||||
u32 (*size)(void *);
|
||||
bool rw;
|
||||
bool ignore_checksum;
|
||||
bool no_pcir;
|
||||
};
|
||||
|
||||
int nvbios_extend(struct nvkm_bios *, u32 length);
|
||||
|
@ -45,7 +45,7 @@ shadow_fetch(struct nvkm_bios *bios, struct shadow *mthd, u32 upto)
|
||||
u32 read = mthd->func->read(data, start, limit - start, bios);
|
||||
bios->size = start + read;
|
||||
}
|
||||
return bios->size >= limit;
|
||||
return bios->size >= upto;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -55,14 +55,22 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
|
||||
struct nvbios_image image;
|
||||
int score = 1;
|
||||
|
||||
if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
|
||||
nvkm_debug(subdev, "%08x: header fetch failed\n", offset);
|
||||
return 0;
|
||||
}
|
||||
if (mthd->func->no_pcir) {
|
||||
image.base = 0;
|
||||
image.type = 0;
|
||||
image.size = mthd->func->size(mthd->data);
|
||||
image.last = 1;
|
||||
} else {
|
||||
if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
|
||||
nvkm_debug(subdev, "%08x: header fetch failed\n",
|
||||
offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!nvbios_image(bios, idx, &image)) {
|
||||
nvkm_debug(subdev, "image %d invalid\n", idx);
|
||||
return 0;
|
||||
if (!nvbios_image(bios, idx, &image)) {
|
||||
nvkm_debug(subdev, "image %d invalid\n", idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
nvkm_debug(subdev, "%08x: type %02x, %d bytes\n",
|
||||
image.base, image.type, image.size);
|
||||
@ -74,7 +82,8 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
|
||||
|
||||
switch (image.type) {
|
||||
case 0x00:
|
||||
if (nvbios_checksum(&bios->data[image.base], image.size)) {
|
||||
if (!mthd->func->ignore_checksum &&
|
||||
nvbios_checksum(&bios->data[image.base], image.size)) {
|
||||
nvkm_debug(subdev, "%08x: checksum failed\n",
|
||||
image.base);
|
||||
if (mthd->func->rw)
|
||||
|
@ -21,6 +21,7 @@
|
||||
*
|
||||
*/
|
||||
#include "priv.h"
|
||||
|
||||
#include <core/pci.h>
|
||||
|
||||
#if defined(__powerpc__)
|
||||
@ -33,17 +34,26 @@ static u32
|
||||
of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
|
||||
{
|
||||
struct priv *priv = data;
|
||||
if (offset + length <= priv->size) {
|
||||
if (offset < priv->size) {
|
||||
length = min_t(u32, length, priv->size - offset);
|
||||
memcpy_fromio(bios->data + offset, priv->data + offset, length);
|
||||
return length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32
|
||||
of_size(void *data)
|
||||
{
|
||||
struct priv *priv = data;
|
||||
return priv->size;
|
||||
}
|
||||
|
||||
static void *
|
||||
of_init(struct nvkm_bios *bios, const char *name)
|
||||
{
|
||||
struct pci_dev *pdev = bios->subdev.device->func->pci(bios->subdev.device)->pdev;
|
||||
struct nvkm_device *device = bios->subdev.device;
|
||||
struct pci_dev *pdev = device->func->pci(device)->pdev;
|
||||
struct device_node *dn;
|
||||
struct priv *priv;
|
||||
if (!(dn = pci_device_to_OF_node(pdev)))
|
||||
@ -62,7 +72,10 @@ nvbios_of = {
|
||||
.init = of_init,
|
||||
.fini = (void(*)(void *))kfree,
|
||||
.read = of_read,
|
||||
.size = of_size,
|
||||
.rw = false,
|
||||
.ignore_checksum = true,
|
||||
.no_pcir = true,
|
||||
};
|
||||
#else
|
||||
const struct nvbios_source
|
||||
|
@ -35,6 +35,8 @@ static const struct nvkm_device_agp_quirk
|
||||
nvkm_device_agp_quirks[] = {
|
||||
/* VIA Apollo PRO133x / GeForce FX 5600 Ultra - fdo#20341 */
|
||||
{ PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 },
|
||||
/* SiS 761 does not support AGP cards, use PCI mode */
|
||||
{ PCI_VENDOR_ID_SI, 0x0761, PCI_ANY_ID, PCI_ANY_ID, 0 },
|
||||
{},
|
||||
};
|
||||
|
||||
@ -137,8 +139,10 @@ nvkm_agp_ctor(struct nvkm_pci *pci)
|
||||
while (quirk->hostbridge_vendor) {
|
||||
if (info.device->vendor == quirk->hostbridge_vendor &&
|
||||
info.device->device == quirk->hostbridge_device &&
|
||||
pci->pdev->vendor == quirk->chip_vendor &&
|
||||
pci->pdev->device == quirk->chip_device) {
|
||||
(quirk->chip_vendor == (u16)PCI_ANY_ID ||
|
||||
pci->pdev->vendor == quirk->chip_vendor) &&
|
||||
(quirk->chip_device == (u16)PCI_ANY_ID ||
|
||||
pci->pdev->device == quirk->chip_device)) {
|
||||
nvkm_info(subdev, "forcing default agp mode to %dX, "
|
||||
"use NvAGP=<mode> to override\n",
|
||||
quirk->mode);
|
||||
|
@ -242,6 +242,10 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
|
||||
bo->is_primary = true;
|
||||
|
||||
ret = qxl_bo_reserve(bo, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = qxl_bo_pin(bo, bo->type, NULL);
|
||||
qxl_bo_unreserve(bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -257,7 +261,11 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
|
||||
}
|
||||
drm_vblank_put(dev, qcrtc->index);
|
||||
|
||||
qxl_bo_unreserve(bo);
|
||||
ret = qxl_bo_reserve(bo, false);
|
||||
if (!ret) {
|
||||
qxl_bo_unpin(bo);
|
||||
qxl_bo_unreserve(bo);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -144,14 +144,17 @@ static void qxl_dirty_update(struct qxl_fbdev *qfbdev,
|
||||
|
||||
spin_lock_irqsave(&qfbdev->dirty.lock, flags);
|
||||
|
||||
if (qfbdev->dirty.y1 < y)
|
||||
y = qfbdev->dirty.y1;
|
||||
if (qfbdev->dirty.y2 > y2)
|
||||
y2 = qfbdev->dirty.y2;
|
||||
if (qfbdev->dirty.x1 < x)
|
||||
x = qfbdev->dirty.x1;
|
||||
if (qfbdev->dirty.x2 > x2)
|
||||
x2 = qfbdev->dirty.x2;
|
||||
if ((qfbdev->dirty.y2 - qfbdev->dirty.y1) &&
|
||||
(qfbdev->dirty.x2 - qfbdev->dirty.x1)) {
|
||||
if (qfbdev->dirty.y1 < y)
|
||||
y = qfbdev->dirty.y1;
|
||||
if (qfbdev->dirty.y2 > y2)
|
||||
y2 = qfbdev->dirty.y2;
|
||||
if (qfbdev->dirty.x1 < x)
|
||||
x = qfbdev->dirty.x1;
|
||||
if (qfbdev->dirty.x2 > x2)
|
||||
x2 = qfbdev->dirty.x2;
|
||||
}
|
||||
|
||||
qfbdev->dirty.x1 = x;
|
||||
qfbdev->dirty.x2 = x2;
|
||||
|
@ -307,7 +307,7 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
|
||||
idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
|
||||
if (idr_ret < 0)
|
||||
return idr_ret;
|
||||
bo = qxl_bo_ref(to_qxl_bo(entry->tv.bo));
|
||||
bo = to_qxl_bo(entry->tv.bo);
|
||||
|
||||
(*release)->release_offset = create_rel->release_offset + 64;
|
||||
|
||||
@ -316,8 +316,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
|
||||
info = qxl_release_map(qdev, *release);
|
||||
info->id = idr_ret;
|
||||
qxl_release_unmap(qdev, *release, info);
|
||||
|
||||
qxl_bo_unref(&bo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1633,18 +1633,8 @@ int radeon_modeset_init(struct radeon_device *rdev)
|
||||
radeon_fbdev_init(rdev);
|
||||
drm_kms_helper_poll_init(rdev->ddev);
|
||||
|
||||
if (rdev->pm.dpm_enabled) {
|
||||
/* do dpm late init */
|
||||
ret = radeon_pm_late_init(rdev);
|
||||
if (ret) {
|
||||
rdev->pm.dpm_enabled = false;
|
||||
DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
|
||||
}
|
||||
/* set the dpm state for PX since there won't be
|
||||
* a modeset to call this.
|
||||
*/
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
}
|
||||
/* do pm late init */
|
||||
ret = radeon_pm_late_init(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -397,3 +397,19 @@ void radeon_fb_remove_connector(struct radeon_device *rdev, struct drm_connector
|
||||
{
|
||||
drm_fb_helper_remove_one_connector(&rdev->mode_info.rfbdev->helper, connector);
|
||||
}
|
||||
|
||||
void radeon_fbdev_restore_mode(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_fbdev *rfbdev = rdev->mode_info.rfbdev;
|
||||
struct drm_fb_helper *fb_helper;
|
||||
int ret;
|
||||
|
||||
if (!rfbdev)
|
||||
return;
|
||||
|
||||
fb_helper = &rfbdev->helper;
|
||||
|
||||
ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
|
||||
if (ret)
|
||||
DRM_DEBUG("failed to restore crtc mode\n");
|
||||
}
|
||||
|
@ -598,7 +598,7 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
||||
* Outdated mess for old drm with Xorg being in charge (void function now).
|
||||
*/
|
||||
/**
|
||||
* radeon_driver_firstopen_kms - drm callback for last close
|
||||
* radeon_driver_lastclose_kms - drm callback for last close
|
||||
*
|
||||
* @dev: drm dev pointer
|
||||
*
|
||||
@ -606,6 +606,9 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
||||
*/
|
||||
void radeon_driver_lastclose_kms(struct drm_device *dev)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
radeon_fbdev_restore_mode(rdev);
|
||||
vga_switcheroo_process_delayed_switch();
|
||||
}
|
||||
|
||||
|
@ -980,6 +980,7 @@ int radeon_fbdev_init(struct radeon_device *rdev);
|
||||
void radeon_fbdev_fini(struct radeon_device *rdev);
|
||||
void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
|
||||
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
|
||||
void radeon_fbdev_restore_mode(struct radeon_device *rdev);
|
||||
|
||||
void radeon_fb_output_poll_changed(struct radeon_device *rdev);
|
||||
|
||||
|
@ -1326,14 +1326,6 @@ static int radeon_pm_init_old(struct radeon_device *rdev)
|
||||
INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
|
||||
|
||||
if (rdev->pm.num_power_states > 1) {
|
||||
/* where's the best place to put these? */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
|
||||
if (radeon_debugfs_pm_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for PM!\n");
|
||||
}
|
||||
@ -1391,20 +1383,6 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
|
||||
goto dpm_failed;
|
||||
rdev->pm.dpm_enabled = true;
|
||||
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
/* XXX: these are noops for dpm but are here for backwards compat */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
|
||||
if (radeon_debugfs_pm_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for dpm!\n");
|
||||
}
|
||||
@ -1545,9 +1523,44 @@ int radeon_pm_late_init(struct radeon_device *rdev)
|
||||
int ret = 0;
|
||||
|
||||
if (rdev->pm.pm_method == PM_METHOD_DPM) {
|
||||
mutex_lock(&rdev->pm.mutex);
|
||||
ret = radeon_dpm_late_enable(rdev);
|
||||
mutex_unlock(&rdev->pm.mutex);
|
||||
if (rdev->pm.dpm_enabled) {
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
/* XXX: these are noops for dpm but are here for backwards compat */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
|
||||
mutex_lock(&rdev->pm.mutex);
|
||||
ret = radeon_dpm_late_enable(rdev);
|
||||
mutex_unlock(&rdev->pm.mutex);
|
||||
if (ret) {
|
||||
rdev->pm.dpm_enabled = false;
|
||||
DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
|
||||
} else {
|
||||
/* set the dpm state for PX since there won't be
|
||||
* a modeset to call this.
|
||||
*/
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rdev->pm.num_power_states > 1) {
|
||||
/* where's the best place to put these? */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -2928,6 +2928,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = {
|
||||
{ PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 },
|
||||
{ PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 },
|
||||
{ PCI_VENDOR_ID_ATI, 0x6811, 0x1762, 0x2015, 0, 120000 },
|
||||
{ PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user