mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-26 06:04:14 +08:00
Merge branch 'linux-3.19' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes
- Fix BUG() on !SMP builds - Fix for OOPS on pre-NV50 that snuck into -next - MCP7[789A] hang fix where firmware hasn't already setup NISO pollers - NV4x IGP MSI disable, it doesn't appear to work correctly - Add GK208B to recognised boards (no code change aside from adding chipset recognition) * 'linux-3.19' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: drm/nouveau/nouveau: Do not BUG_ON(!spin_is_locked()) on UP drm/nv4c/mc: disable msi drm/nouveau/fb/ram/mcp77: enable NISO poller drm/nouveau/fb/ram/mcp77: use carveout reg to determine size drm/nouveau/fb/ram/mcp77: subclass nouveau_ram drm/nouveau: wake up the card if necessary during gem callbacks drm/nouveau/device: Add support for GK208B, resolves bug 86935 drm/nouveau: fix missing return statement in nouveau_ttm_tt_unpopulate drm/nouveau/bios: fix oops on pre-nv50 chipsets
This commit is contained in:
commit
f6624888a5
@ -26,7 +26,7 @@
|
|||||||
void
|
void
|
||||||
nvkm_event_put(struct nvkm_event *event, u32 types, int index)
|
nvkm_event_put(struct nvkm_event *event, u32 types, int index)
|
||||||
{
|
{
|
||||||
BUG_ON(!spin_is_locked(&event->refs_lock));
|
assert_spin_locked(&event->refs_lock);
|
||||||
while (types) {
|
while (types) {
|
||||||
int type = __ffs(types); types &= ~(1 << type);
|
int type = __ffs(types); types &= ~(1 << type);
|
||||||
if (--event->refs[index * event->types_nr + type] == 0) {
|
if (--event->refs[index * event->types_nr + type] == 0) {
|
||||||
@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index)
|
|||||||
void
|
void
|
||||||
nvkm_event_get(struct nvkm_event *event, u32 types, int index)
|
nvkm_event_get(struct nvkm_event *event, u32 types, int index)
|
||||||
{
|
{
|
||||||
BUG_ON(!spin_is_locked(&event->refs_lock));
|
assert_spin_locked(&event->refs_lock);
|
||||||
while (types) {
|
while (types) {
|
||||||
int type = __ffs(types); types &= ~(1 << type);
|
int type = __ffs(types); types &= ~(1 << type);
|
||||||
if (++event->refs[index * event->types_nr + type] == 1) {
|
if (++event->refs[index * event->types_nr + type] == 1) {
|
||||||
|
@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size)
|
|||||||
struct nvkm_event *event = notify->event;
|
struct nvkm_event *event = notify->event;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
BUG_ON(!spin_is_locked(&event->list_lock));
|
assert_spin_locked(&event->list_lock);
|
||||||
BUG_ON(size != notify->size);
|
BUG_ON(size != notify->size);
|
||||||
|
|
||||||
spin_lock_irqsave(&event->refs_lock, flags);
|
spin_lock_irqsave(&event->refs_lock, flags);
|
||||||
|
@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device)
|
|||||||
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||||
device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
|
device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
|
||||||
break;
|
break;
|
||||||
|
case 0x106:
|
||||||
|
device->cname = "GK208B";
|
||||||
|
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass;
|
||||||
|
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
|
||||||
|
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||||
|
break;
|
||||||
case 0x108:
|
case 0x108:
|
||||||
device->cname = "GK208";
|
device->cname = "GK208";
|
||||||
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
||||||
|
@ -44,8 +44,10 @@ static void
|
|||||||
pramin_fini(void *data)
|
pramin_fini(void *data)
|
||||||
{
|
{
|
||||||
struct priv *priv = data;
|
struct priv *priv = data;
|
||||||
nv_wr32(priv->bios, 0x001700, priv->bar0);
|
if (priv) {
|
||||||
kfree(priv);
|
nv_wr32(priv->bios, 0x001700, priv->bar0);
|
||||||
|
kfree(priv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
@ -24,34 +24,71 @@
|
|||||||
|
|
||||||
#include "nv50.h"
|
#include "nv50.h"
|
||||||
|
|
||||||
|
struct nvaa_ram_priv {
|
||||||
|
struct nouveau_ram base;
|
||||||
|
u64 poller_base;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||||
struct nouveau_oclass *oclass, void *data, u32 datasize,
|
struct nouveau_oclass *oclass, void *data, u32 datasize,
|
||||||
struct nouveau_object **pobject)
|
struct nouveau_object **pobject)
|
||||||
{
|
{
|
||||||
const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
|
u32 rsvd_head = ( 256 * 1024); /* vga memory */
|
||||||
const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
|
u32 rsvd_tail = (1024 * 1024); /* vbios etc */
|
||||||
struct nouveau_fb *pfb = nouveau_fb(parent);
|
struct nouveau_fb *pfb = nouveau_fb(parent);
|
||||||
struct nouveau_ram *ram;
|
struct nvaa_ram_priv *priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = nouveau_ram_create(parent, engine, oclass, &ram);
|
ret = nouveau_ram_create(parent, engine, oclass, &priv);
|
||||||
*pobject = nv_object(ram);
|
*pobject = nv_object(priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ram->size = nv_rd32(pfb, 0x10020c);
|
priv->base.type = NV_MEM_TYPE_STOLEN;
|
||||||
ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32);
|
priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
|
||||||
|
priv->base.size = (u64)nv_rd32(pfb, 0x100e14) << 12;
|
||||||
|
|
||||||
ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) -
|
rsvd_tail += 0x1000;
|
||||||
(rsvd_head + rsvd_tail), 1);
|
priv->poller_base = priv->base.size - rsvd_tail;
|
||||||
|
|
||||||
|
ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12,
|
||||||
|
(priv->base.size - (rsvd_head + rsvd_tail)) >> 12,
|
||||||
|
1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ram->type = NV_MEM_TYPE_STOLEN;
|
priv->base.get = nv50_ram_get;
|
||||||
ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
|
priv->base.put = nv50_ram_put;
|
||||||
ram->get = nv50_ram_get;
|
return 0;
|
||||||
ram->put = nv50_ram_put;
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvaa_ram_init(struct nouveau_object *object)
|
||||||
|
{
|
||||||
|
struct nouveau_fb *pfb = nouveau_fb(object);
|
||||||
|
struct nvaa_ram_priv *priv = (void *)object;
|
||||||
|
int ret;
|
||||||
|
u64 dniso, hostnb, flush;
|
||||||
|
|
||||||
|
ret = nouveau_ram_init(&priv->base);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
dniso = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1;
|
||||||
|
hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1;
|
||||||
|
flush = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1;
|
||||||
|
|
||||||
|
/* Enable NISO poller for various clients and set their associated
|
||||||
|
* read address, only for MCP77/78 and MCP79/7A. (fd#25701)
|
||||||
|
*/
|
||||||
|
nv_wr32(pfb, 0x100c18, dniso);
|
||||||
|
nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001);
|
||||||
|
nv_wr32(pfb, 0x100c1c, hostnb);
|
||||||
|
nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002);
|
||||||
|
nv_wr32(pfb, 0x100c24, flush);
|
||||||
|
nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +97,7 @@ nvaa_ram_oclass = {
|
|||||||
.ofuncs = &(struct nouveau_ofuncs) {
|
.ofuncs = &(struct nouveau_ofuncs) {
|
||||||
.ctor = nvaa_ram_ctor,
|
.ctor = nvaa_ram_ctor,
|
||||||
.dtor = _nouveau_ram_dtor,
|
.dtor = _nouveau_ram_dtor,
|
||||||
.init = _nouveau_ram_init,
|
.init = nvaa_ram_init,
|
||||||
.fini = _nouveau_ram_fini,
|
.fini = _nouveau_ram_fini,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -24,13 +24,6 @@
|
|||||||
|
|
||||||
#include "nv04.h"
|
#include "nv04.h"
|
||||||
|
|
||||||
static void
|
|
||||||
nv4c_mc_msi_rearm(struct nouveau_mc *pmc)
|
|
||||||
{
|
|
||||||
struct nv04_mc_priv *priv = (void *)pmc;
|
|
||||||
nv_wr08(priv, 0x088050, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nouveau_oclass *
|
struct nouveau_oclass *
|
||||||
nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
|
nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
|
||||||
.base.handle = NV_SUBDEV(MC, 0x4c),
|
.base.handle = NV_SUBDEV(MC, 0x4c),
|
||||||
@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
|
|||||||
.fini = _nouveau_mc_fini,
|
.fini = _nouveau_mc_fini,
|
||||||
},
|
},
|
||||||
.intr = nv04_mc_intr,
|
.intr = nv04_mc_intr,
|
||||||
.msi_rearm = nv4c_mc_msi_rearm,
|
|
||||||
}.base;
|
}.base;
|
||||||
|
@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
|||||||
* so use the DMA API for them.
|
* so use the DMA API for them.
|
||||||
*/
|
*/
|
||||||
if (!nv_device_is_cpu_coherent(device) &&
|
if (!nv_device_is_cpu_coherent(device) &&
|
||||||
ttm->caching_state == tt_uncached)
|
ttm->caching_state == tt_uncached) {
|
||||||
ttm_dma_unpopulate(ttm_dma, dev->dev);
|
ttm_dma_unpopulate(ttm_dma, dev->dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (drm->agp.stat == ENABLED) {
|
if (drm->agp.stat == ENABLED) {
|
||||||
|
@ -36,7 +36,14 @@ void
|
|||||||
nouveau_gem_object_del(struct drm_gem_object *gem)
|
nouveau_gem_object_del(struct drm_gem_object *gem)
|
||||||
{
|
{
|
||||||
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
||||||
|
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
|
||||||
struct ttm_buffer_object *bo = &nvbo->bo;
|
struct ttm_buffer_object *bo = &nvbo->bo;
|
||||||
|
struct device *dev = drm->dev->dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = pm_runtime_get_sync(dev);
|
||||||
|
if (WARN_ON(ret < 0 && ret != -EACCES))
|
||||||
|
return;
|
||||||
|
|
||||||
if (gem->import_attach)
|
if (gem->import_attach)
|
||||||
drm_prime_gem_destroy(gem, nvbo->bo.sg);
|
drm_prime_gem_destroy(gem, nvbo->bo.sg);
|
||||||
@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
|
|||||||
/* reset filp so nouveau_bo_del_ttm() can test for it */
|
/* reset filp so nouveau_bo_del_ttm() can test for it */
|
||||||
gem->filp = NULL;
|
gem->filp = NULL;
|
||||||
ttm_bo_unref(&bo);
|
ttm_bo_unref(&bo);
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(dev);
|
||||||
|
pm_runtime_put_autosuspend(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||||||
{
|
{
|
||||||
struct nouveau_cli *cli = nouveau_cli(file_priv);
|
struct nouveau_cli *cli = nouveau_cli(file_priv);
|
||||||
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
||||||
|
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
|
||||||
struct nouveau_vma *vma;
|
struct nouveau_vma *vma;
|
||||||
|
struct device *dev = drm->dev->dev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!cli->vm)
|
if (!cli->vm)
|
||||||
@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
|
ret = pm_runtime_get_sync(dev);
|
||||||
if (ret) {
|
if (ret < 0 && ret != -EACCES)
|
||||||
kfree(vma);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
|
||||||
|
if (ret)
|
||||||
|
kfree(vma);
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(dev);
|
||||||
|
pm_runtime_put_autosuspend(dev);
|
||||||
} else {
|
} else {
|
||||||
vma->refcount++;
|
vma->refcount++;
|
||||||
}
|
}
|
||||||
@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||||||
{
|
{
|
||||||
struct nouveau_cli *cli = nouveau_cli(file_priv);
|
struct nouveau_cli *cli = nouveau_cli(file_priv);
|
||||||
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
||||||
|
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
|
||||||
|
struct device *dev = drm->dev->dev;
|
||||||
struct nouveau_vma *vma;
|
struct nouveau_vma *vma;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||||||
|
|
||||||
vma = nouveau_bo_vma_find(nvbo, cli->vm);
|
vma = nouveau_bo_vma_find(nvbo, cli->vm);
|
||||||
if (vma) {
|
if (vma) {
|
||||||
if (--vma->refcount == 0)
|
if (--vma->refcount == 0) {
|
||||||
nouveau_gem_object_unmap(nvbo, vma);
|
ret = pm_runtime_get_sync(dev);
|
||||||
|
if (!WARN_ON(ret < 0 && ret != -EACCES)) {
|
||||||
|
nouveau_gem_object_unmap(nvbo, vma);
|
||||||
|
pm_runtime_mark_last_busy(dev);
|
||||||
|
pm_runtime_put_autosuspend(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ttm_bo_unreserve(&nvbo->bo);
|
ttm_bo_unreserve(&nvbo->bo);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user