Merge branch 'drm-nouveau-fixes' of git://git.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes
Fixes from Ben, off note: ACPI ROM regression fix, some IGP and AGP regressions fixes from rework fallout. * 'drm-nouveau-fixes' of git://git.freedesktop.org/git/nouveau/linux-2.6: drm/nouveau/clock: fix missing pll type/addr when matching default entry drm/nouveau/fb: fix reporting of memory type on GF8+ IGPs drm/nv41/vm: don't init hw pciegart on boards with agp bridge drm/nouveau/bios: fetch full 4KiB block to determine ACPI ROM image size drm/nouveau: validate vbios size drm/nouveau: warn when trying to free mm which is still in use drm/nouveau: fix nouveau_mm/nouveau_mm_node leak drm/nouveau/bios: improve error handling when reading the vbios from ACPI drm/nouveau: handle same-fb page flips
This commit is contained in:
Коммит
ae168d973f
|
@ -39,6 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
|
|||
nv_wo32(gpuobj, i, 0x00000000);
|
||||
}
|
||||
|
||||
if (gpuobj->node) {
|
||||
nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
|
||||
&gpuobj->node);
|
||||
}
|
||||
|
||||
if (gpuobj->heap.block_size)
|
||||
nouveau_mm_fini(&gpuobj->heap);
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ nouveau_mm_fini(struct nouveau_mm *mm)
|
|||
int nodes = 0;
|
||||
|
||||
list_for_each_entry(node, &mm->nodes, nl_entry) {
|
||||
if (nodes++ == mm->heap_nodes)
|
||||
if (WARN_ON(nodes++ == mm->heap_nodes))
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ nouveau_bios_shadow_of(struct nouveau_bios *bios)
|
|||
}
|
||||
|
||||
data = of_get_property(dn, "NVDA,BMP", &size);
|
||||
if (data) {
|
||||
if (data && size) {
|
||||
bios->size = size;
|
||||
bios->data = kmalloc(bios->size, GFP_KERNEL);
|
||||
if (bios->data)
|
||||
|
@ -104,6 +104,9 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
|
|||
goto out;
|
||||
|
||||
bios->size = nv_rd08(bios, 0x700002) * 512;
|
||||
if (!bios->size)
|
||||
goto out;
|
||||
|
||||
bios->data = kmalloc(bios->size, GFP_KERNEL);
|
||||
if (bios->data) {
|
||||
for (i = 0; i < bios->size; i++)
|
||||
|
@ -155,6 +158,9 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
|
|||
|
||||
/* read entire bios image to system memory */
|
||||
bios->size = nv_rd08(bios, 0x300002) * 512;
|
||||
if (!bios->size)
|
||||
goto out;
|
||||
|
||||
bios->data = kmalloc(bios->size, GFP_KERNEL);
|
||||
if (bios->data) {
|
||||
for (i = 0; i < bios->size; i++)
|
||||
|
@ -186,14 +192,22 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios)
|
|||
{
|
||||
struct pci_dev *pdev = nv_device(bios)->pdev;
|
||||
int ret, cnt, i;
|
||||
u8 data[3];
|
||||
|
||||
if (!nouveau_acpi_rom_supported(pdev))
|
||||
if (!nouveau_acpi_rom_supported(pdev)) {
|
||||
bios->data = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
bios->size = 0;
|
||||
if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3)
|
||||
bios->size = data[2] * 512;
|
||||
bios->data = kmalloc(4096, GFP_KERNEL);
|
||||
if (bios->data) {
|
||||
if (nouveau_acpi_get_bios_chunk(bios->data, 0, 4096) == 4096)
|
||||
bios->size = bios->data[2] * 512;
|
||||
kfree(bios->data);
|
||||
}
|
||||
|
||||
if (!bios->size)
|
||||
return;
|
||||
|
||||
bios->data = kmalloc(bios->size, GFP_KERNEL);
|
||||
for (i = 0; bios->data && i < bios->size; i += cnt) {
|
||||
|
@ -229,12 +243,14 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios)
|
|||
static int
|
||||
nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
|
||||
{
|
||||
if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) {
|
||||
if (bios->size < 3 || !bios->data || bios->data[0] != 0x55 ||
|
||||
bios->data[1] != 0xAA) {
|
||||
nv_info(bios, "... signature not found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nvbios_checksum(bios->data, bios->data[2] * 512)) {
|
||||
if (nvbios_checksum(bios->data,
|
||||
min_t(u32, bios->data[2] * 512, bios->size))) {
|
||||
nv_info(bios, "... checksum invalid\n");
|
||||
/* if a ro image is somewhat bad, it's probably all rubbish */
|
||||
return writeable ? 2 : 1;
|
||||
|
|
|
@ -157,11 +157,10 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
|
|||
while (map->reg) {
|
||||
if (map->reg == reg && *ver >= 0x20) {
|
||||
u16 addr = (data += hdr);
|
||||
*type = map->type;
|
||||
while (cnt--) {
|
||||
if (nv_ro32(bios, data) == map->reg) {
|
||||
*type = map->type;
|
||||
if (nv_ro32(bios, data) == map->reg)
|
||||
return data;
|
||||
}
|
||||
data += *len;
|
||||
}
|
||||
return addr;
|
||||
|
@ -200,11 +199,10 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
|
|||
while (map->reg) {
|
||||
if (map->type == type && *ver >= 0x20) {
|
||||
u16 addr = (data += hdr);
|
||||
*reg = map->reg;
|
||||
while (cnt--) {
|
||||
if (nv_ro32(bios, data) == map->reg) {
|
||||
*reg = map->reg;
|
||||
if (nv_ro32(bios, data) == map->reg)
|
||||
return data;
|
||||
}
|
||||
data += *len;
|
||||
}
|
||||
return addr;
|
||||
|
|
|
@ -237,6 +237,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
return ret;
|
||||
|
||||
priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12;
|
||||
priv->base.ram.type = NV_MEM_TYPE_STOLEN;
|
||||
break;
|
||||
default:
|
||||
ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size,
|
||||
|
|
|
@ -92,7 +92,8 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nv04_vmmgr_priv *priv;
|
||||
int ret;
|
||||
|
||||
if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
|
||||
if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
|
||||
!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
|
||||
return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
|
||||
data, size, pobject);
|
||||
}
|
||||
|
|
|
@ -163,7 +163,8 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nv04_vmmgr_priv *priv;
|
||||
int ret;
|
||||
|
||||
if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
|
||||
if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
|
||||
!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
|
||||
return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
|
||||
data, size, pobject);
|
||||
}
|
||||
|
|
|
@ -530,9 +530,11 @@ nouveau_page_flip_reserve(struct nouveau_bo *old_bo,
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
if (likely(old_bo != new_bo)) {
|
||||
ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -551,8 +553,10 @@ nouveau_page_flip_unreserve(struct nouveau_bo *old_bo,
|
|||
nouveau_bo_fence(new_bo, fence);
|
||||
ttm_bo_unreserve(&new_bo->bo);
|
||||
|
||||
nouveau_bo_fence(old_bo, fence);
|
||||
ttm_bo_unreserve(&old_bo->bo);
|
||||
if (likely(old_bo != new_bo)) {
|
||||
nouveau_bo_fence(old_bo, fence);
|
||||
ttm_bo_unreserve(&old_bo->bo);
|
||||
}
|
||||
|
||||
nouveau_bo_unpin(old_bo);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче