diff options
Diffstat (limited to 'kernel/drivers/gpu/drm/nouveau')
22 files changed, 92 insertions, 46 deletions
diff --git a/kernel/drivers/gpu/drm/nouveau/dispnv04/hw.c b/kernel/drivers/gpu/drm/nouveau/dispnv04/hw.c index 956a833b8..57c7389fe 100644 --- a/kernel/drivers/gpu/drm/nouveau/dispnv04/hw.c +++ b/kernel/drivers/gpu/drm/nouveau/dispnv04/hw.c @@ -222,6 +222,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype) uint32_t mpllP; pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP); + mpllP = (mpllP >> 8) & 0xf; if (!mpllP) mpllP = 4; @@ -232,7 +233,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype) uint32_t clock; pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock); - return clock; + return clock / 1000; } ret = nouveau_hw_get_pllvals(dev, plltype, &pllvals); diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_bios.c b/kernel/drivers/gpu/drm/nouveau/nouveau_bios.c index 4dca65a63..af224fafa 100644 --- a/kernel/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/kernel/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -333,6 +333,9 @@ get_fp_strap(struct drm_device *dev, struct nvbios *bios) if (bios->major_version < 5 && bios->data[0x48] & 0x4) return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf; + if (drm->device.info.family >= NV_DEVICE_INFO_V0_MAXWELL) + return nvif_rd32(device, 0x001800) & 0x0000000f; + else if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) return (nvif_rd32(device, NV_PEXTDEV_BOOT_0) >> 24) & 0xf; else diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c b/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c index 1d3ee5179..d236fc7c4 100644 --- a/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -308,7 +308,16 @@ static int nouveau_drm_probe(struct pci_dev *pdev, bool boot = false; int ret; - /* remove conflicting drivers (vesafb, efifb etc) */ + /* We need to check that the chipset is supported before booting + * fbdev off the hardware, as there's no way to put it back. + */ + ret = nvkm_device_pci_new(pdev, NULL, "error", true, false, 0, &device); + if (ret) + return ret; + + nvkm_device_del(&device); + + /* Remove conflicting drivers (vesafb, efifb etc). */ aper = alloc_apertures(3); if (!aper) return -ENOMEM; diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/kernel/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 59f27e774..e40a1b07a 100644 --- a/kernel/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/kernel/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -557,6 +557,8 @@ nouveau_fbcon_init(struct drm_device *dev) if (ret) goto fini; + if (fbcon->helper.fbdev) + fbcon->helper.fbdev->pixmap.buf_align = 4; return 0; fini: diff --git a/kernel/drivers/gpu/drm/nouveau/nv04_fbcon.c b/kernel/drivers/gpu/drm/nouveau/nv04_fbcon.c index 789dc2993..f90568327 100644 --- a/kernel/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/kernel/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) uint32_t fg; uint32_t bg; uint32_t dsize; - uint32_t width; uint32_t *data = (uint32_t *)image->data; int ret; @@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) if (ret) return ret; - width = ALIGN(image->width, 8); - dsize = ALIGN(width * image->height, 32) >> 5; - if (info->fix.visual == FB_VISUAL_TRUECOLOR || info->fix.visual == FB_VISUAL_DIRECTCOLOR) { fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; @@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ((image->dx + image->width) & 0xffff)); OUT_RING(chan, bg); OUT_RING(chan, fg); - OUT_RING(chan, (image->height << 16) | width); + OUT_RING(chan, (image->height << 16) | ALIGN(image->width, 8)); OUT_RING(chan, (image->height << 16) | image->width); OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); + dsize = ALIGN(ALIGN(image->width, 8) * image->height, 32) >> 5; while (dsize) { int iter_len = dsize > 128 ? 128 : dsize; diff --git a/kernel/drivers/gpu/drm/nouveau/nv50_fbcon.c b/kernel/drivers/gpu/drm/nouveau/nv50_fbcon.c index e05499d6e..c8e096533 100644 --- a/kernel/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/kernel/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) struct nouveau_fbdev *nfbdev = info->par; struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); struct nouveau_channel *chan = drm->channel; - uint32_t width, dwords, *data = (uint32_t *)image->data; + uint32_t dwords, *data = (uint32_t *)image->data; uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); uint32_t *palette = info->pseudo_palette; int ret; @@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) if (ret) return ret; - width = ALIGN(image->width, 32); - dwords = (width * image->height) >> 5; - BEGIN_NV04(chan, NvSub2D, 0x0814, 2); if (info->fix.visual == FB_VISUAL_TRUECOLOR || info->fix.visual == FB_VISUAL_DIRECTCOLOR) { @@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) OUT_RING(chan, 0); OUT_RING(chan, image->dy); + dwords = ALIGN(ALIGN(image->width, 8) * image->height, 32) >> 5; while (dwords) { int push = dwords > 2047 ? 2047 : dwords; diff --git a/kernel/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/kernel/drivers/gpu/drm/nouveau/nvc0_fbcon.c index c97395b4a..22d32578d 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/kernel/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) struct nouveau_fbdev *nfbdev = info->par; struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); struct nouveau_channel *chan = drm->channel; - uint32_t width, dwords, *data = (uint32_t *)image->data; + uint32_t dwords, *data = (uint32_t *)image->data; uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); uint32_t *palette = info->pseudo_palette; int ret; @@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) if (ret) return ret; - width = ALIGN(image->width, 32); - dwords = (width * image->height) >> 5; - BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); if (info->fix.visual == FB_VISUAL_TRUECOLOR || info->fix.visual == FB_VISUAL_DIRECTCOLOR) { @@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) OUT_RING (chan, 0); OUT_RING (chan, image->dy); + dwords = ALIGN(ALIGN(image->width, 8) * image->height, 32) >> 5; while (dwords) { int push = dwords > 2047 ? 2047 : dwords; diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/core/ramht.c b/kernel/drivers/gpu/drm/nouveau/nvkm/core/ramht.c index 3216e157a..89da47234 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/core/ramht.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/core/ramht.c @@ -131,7 +131,7 @@ nvkm_ramht_del(struct nvkm_ramht **pramht) struct nvkm_ramht *ramht = *pramht; if (ramht) { nvkm_gpuobj_del(&ramht->gpuobj); - kfree(*pramht); + vfree(*pramht); *pramht = NULL; } } @@ -143,8 +143,8 @@ nvkm_ramht_new(struct nvkm_device *device, u32 size, u32 align, struct nvkm_ramht *ramht; int ret, i; - if (!(ramht = *pramht = kzalloc(sizeof(*ramht) + (size >> 3) * - sizeof(*ramht->data), GFP_KERNEL))) + if (!(ramht = *pramht = vzalloc(sizeof(*ramht) + + (size >> 3) * sizeof(*ramht->data)))) return -ENOMEM; ramht->device = device; diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index bbc9824af..ece9f4102 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -1833,7 +1833,7 @@ nvf1_chipset = { .fb = gk104_fb_new, .fuse = gf100_fuse_new, .gpio = gk104_gpio_new, - .i2c = gf119_i2c_new, + .i2c = gk104_i2c_new, .ibus = gk104_ibus_new, .imem = nv50_instmem_new, .ltc = gk104_ltc_new, @@ -1941,7 +1941,7 @@ nv117_chipset = { .fb = gm107_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, - .i2c = gf119_i2c_new, + .i2c = gk104_i2c_new, .ibus = gk104_ibus_new, .imem = nv50_instmem_new, .ltc = gm107_ltc_new, diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c index c1590b746..eb58cd7bf 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c @@ -59,7 +59,7 @@ gt215_hda_eld(NV50_DISP_MTHD_V1) ); } for (i = 0; i < size; i++) - nvkm_wr32(device, 0x61c440 + soff, (i << 8) | args->v0.data[0]); + nvkm_wr32(device, 0x61c440 + soff, (i << 8) | args->v0.data[i]); for (; i < 0x60; i++) nvkm_wr32(device, 0x61c440 + soff, (i << 8)); nvkm_mask(device, 0x61c448 + soff, 0x80000003, 0x80000003); diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index b4b41b135..2aaf0dd19 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c @@ -40,8 +40,8 @@ static int gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) { struct nvkm_device *device = outp->base.disp->engine.subdev.device; - const u32 loff = gf119_sor_loff(outp); - nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern); + const u32 soff = gf119_sor_soff(outp); + nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, 0x01010101 * pattern); return 0; } diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c index bfcc6408a..b7f4b826f 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c @@ -36,7 +36,10 @@ nv04_fifo_dma_object_dtor(struct nvkm_fifo_chan *base, int cookie) { struct nv04_fifo_chan *chan = nv04_fifo_chan(base); struct nvkm_instmem *imem = chan->fifo->base.engine.subdev.device->imem; + + mutex_lock(&chan->fifo->base.engine.subdev.mutex); nvkm_ramht_remove(imem->ramht, cookie); + mutex_unlock(&chan->fifo->base.engine.subdev.mutex); } static int diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index e7cbc139c..89976ff4b 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c @@ -59,6 +59,7 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base, struct nvkm_gpuobj *inst = chan->base.inst; int ret = 0; + mutex_lock(&subdev->mutex); nvkm_wr32(device, 0x002634, chan->base.chid); if (nvkm_msec(device, 2000, if (nvkm_rd32(device, 0x002634) == chan->base.chid) @@ -66,10 +67,12 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base, ) < 0) { nvkm_error(subdev, "channel %d [%s] kick timeout\n", chan->base.chid, chan->base.object.client->name); - ret = -EBUSY; - if (suspend) - return ret; + ret = -ETIMEDOUT; } + mutex_unlock(&subdev->mutex); + + if (ret && suspend) + return ret; if (offset) { nvkm_kmap(inst); diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 0b817540a..aa1692e56 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -39,7 +39,9 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; struct nvkm_client *client = chan->base.object.client; + int ret = 0; + mutex_lock(&subdev->mutex); nvkm_wr32(device, 0x002634, chan->base.chid); if (nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x002634) & 0x00100000)) @@ -47,10 +49,10 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) ) < 0) { nvkm_error(subdev, "channel %d [%s] kick timeout\n", chan->base.chid, client->name); - return -EBUSY; + ret = -ETIMEDOUT; } - - return 0; + mutex_unlock(&subdev->mutex); + return ret; } static u32 diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 9f5dfc851..eeeea1c2c 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -874,22 +874,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *gr, int gpc) } static const struct nvkm_enum gf100_mp_warp_error[] = { - { 0x00, "NO_ERROR" }, - { 0x01, "STACK_MISMATCH" }, + { 0x01, "STACK_ERROR" }, + { 0x02, "API_STACK_ERROR" }, + { 0x03, "RET_EMPTY_STACK_ERROR" }, + { 0x04, "PC_WRAP" }, { 0x05, "MISALIGNED_PC" }, - { 0x08, "MISALIGNED_GPR" }, - { 0x09, "INVALID_OPCODE" }, - { 0x0d, "GPR_OUT_OF_BOUNDS" }, - { 0x0e, "MEM_OUT_OF_BOUNDS" }, - { 0x0f, "UNALIGNED_MEM_ACCESS" }, + { 0x06, "PC_OVERFLOW" }, + { 0x07, "MISALIGNED_IMMC_ADDR" }, + { 0x08, "MISALIGNED_REG" }, + { 0x09, "ILLEGAL_INSTR_ENCODING" }, + { 0x0a, "ILLEGAL_SPH_INSTR_COMBO" }, + { 0x0b, "ILLEGAL_INSTR_PARAM" }, + { 0x0c, "INVALID_CONST_ADDR" }, + { 0x0d, "OOR_REG" }, + { 0x0e, "OOR_ADDR" }, + { 0x0f, "MISALIGNED_ADDR" }, { 0x10, "INVALID_ADDR_SPACE" }, - { 0x11, "INVALID_PARAM" }, + { 0x11, "ILLEGAL_INSTR_PARAM2" }, + { 0x12, "INVALID_CONST_ADDR_LDC" }, + { 0x13, "GEOMETRY_SM_ERROR" }, + { 0x14, "DIVERGENT" }, + { 0x15, "WARP_EXIT" }, {} }; static const struct nvkm_bitfield gf100_mp_global_error[] = { + { 0x00000001, "SM_TO_SM_FAULT" }, + { 0x00000002, "L1_ERROR" }, { 0x00000004, "MULTIPLE_WARP_ERRORS" }, - { 0x00000008, "OUT_OF_STACK_SPACE" }, + { 0x00000008, "PHYSICAL_STACK_OVERFLOW" }, + { 0x00000010, "BPT_INT" }, + { 0x00000020, "BPT_PAUSE" }, + { 0x00000040, "SINGLE_STEP_COMPLETE" }, + { 0x20000000, "ECC_SEC_ERROR" }, + { 0x40000000, "ECC_DED_ERROR" }, + { 0x80000000, "TIMEOUT" }, {} }; @@ -1717,6 +1736,8 @@ gf100_gr_init(struct gf100_gr *gr) gf100_gr_mmio(gr, gr->func->mmio); + nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); + memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); for (i = 0, gpc = -1; i < gr->tpc_total; i++) { do { diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c index 69de8c625..f1e15a4d4 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c @@ -76,8 +76,8 @@ nv30_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, nvkm_wo32(chan->inst, i, 0x00040004); for (i = 0x1f18; i <= 0x3088 ; i += 16) { nvkm_wo32(chan->inst, i + 0, 0x10700ff9); - nvkm_wo32(chan->inst, i + 1, 0x0436086c); - nvkm_wo32(chan->inst, i + 2, 0x000c001b); + nvkm_wo32(chan->inst, i + 4, 0x0436086c); + nvkm_wo32(chan->inst, i + 8, 0x000c001b); } for (i = 0x30b8; i < 0x30c8; i += 4) nvkm_wo32(chan->inst, i, 0x0000ffff); diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c index 2207dac23..300f5ed5d 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c @@ -75,8 +75,8 @@ nv34_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, nvkm_wo32(chan->inst, i, 0x00040004); for (i = 0x15ac; i <= 0x271c ; i += 16) { nvkm_wo32(chan->inst, i + 0, 0x10700ff9); - nvkm_wo32(chan->inst, i + 1, 0x0436086c); - nvkm_wo32(chan->inst, i + 2, 0x000c001b); + nvkm_wo32(chan->inst, i + 4, 0x0436086c); + nvkm_wo32(chan->inst, i + 8, 0x000c001b); } for (i = 0x274c; i < 0x275c; i += 4) nvkm_wo32(chan->inst, i, 0x0000ffff); diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c index 4bef72a9d..3fda59470 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c @@ -59,9 +59,11 @@ static void nv40_perfctr_next(struct nvkm_pm *pm, struct nvkm_perfdom *dom) { struct nvkm_device *device = pm->engine.subdev.device; - if (pm->sequence != pm->sequence) { + struct nv40_pm *nv40pm = container_of(pm, struct nv40_pm, base); + + if (nv40pm->sequence != pm->sequence) { nvkm_wr32(device, 0x400084, 0x00000020); - pm->sequence = pm->sequence; + nv40pm->sequence = pm->sequence; } } diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h index 212800ecd..7d1d3c6b4 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h @@ -12,6 +12,7 @@ struct nvbios_source { bool rw; bool ignore_checksum; bool no_pcir; + bool require_checksum; }; int nvbios_extend(struct nvkm_bios *, u32 length); diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c index b2557e87a..7deb81b6d 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c @@ -86,9 +86,12 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd) nvbios_checksum(&bios->data[image.base], image.size)) { nvkm_debug(subdev, "%08x: checksum failed\n", image.base); - if (mthd->func->rw) + if (!mthd->func->require_checksum) { + if (mthd->func->rw) + score += 1; score += 1; - score += 1; + } else + return 0; } else { score += 3; } diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c index 8fecb5ff2..06572f8ce 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c @@ -99,6 +99,7 @@ nvbios_acpi_fast = { .init = acpi_init, .read = acpi_read_fast, .rw = false, + .require_checksum = true, }; const struct nvbios_source diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index 85b1464c0..587c52f08 100644 --- a/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/kernel/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -47,8 +47,10 @@ nvkm_ltc_tags_clear(struct nvkm_ltc *ltc, u32 first, u32 count) BUG_ON((first > limit) || (limit >= ltc->num_tags)); + mutex_lock(<c->subdev.mutex); ltc->func->cbc_clear(ltc, first, limit); ltc->func->cbc_wait(ltc); + mutex_unlock(<c->subdev.mutex); } int |