Commit ec91db26 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau: remove ability to use external firmware

This was always really a developer option, and if it's really necessary we
can hack this in ourselves.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 63187215
...@@ -9,7 +9,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ ...@@ -9,7 +9,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
nouveau_dp.o nouveau_grctx.o \ nouveau_dp.o \
nv04_timer.o \ nv04_timer.o \
nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_mc.o nv40_mc.o nv50_mc.o \
nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
......
...@@ -35,10 +35,6 @@ ...@@ -35,10 +35,6 @@
#include "drm_pciids.h" #include "drm_pciids.h"
MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)");
int nouveau_ctxfw = 0;
module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
MODULE_PARM_DESC(noagp, "Disable AGP"); MODULE_PARM_DESC(noagp, "Disable AGP");
int nouveau_noagp; int nouveau_noagp;
module_param_named(noagp, nouveau_noagp, int, 0400); module_param_named(noagp, nouveau_noagp, int, 0400);
......
...@@ -330,8 +330,6 @@ struct nouveau_pgraph_object_class { ...@@ -330,8 +330,6 @@ struct nouveau_pgraph_object_class {
struct nouveau_pgraph_engine { struct nouveau_pgraph_engine {
struct nouveau_pgraph_object_class *grclass; struct nouveau_pgraph_object_class *grclass;
bool accel_blocked; bool accel_blocked;
void *ctxprog;
void *ctxvals;
int grctx_size; int grctx_size;
int (*init)(struct drm_device *); int (*init)(struct drm_device *);
...@@ -665,7 +663,6 @@ extern int nouveau_tv_disable; ...@@ -665,7 +663,6 @@ extern int nouveau_tv_disable;
extern char *nouveau_tv_norm; extern char *nouveau_tv_norm;
extern int nouveau_reg_debug; extern int nouveau_reg_debug;
extern char *nouveau_vbios; extern char *nouveau_vbios;
extern int nouveau_ctxfw;
extern int nouveau_ignorelid; extern int nouveau_ignorelid;
extern int nouveau_nofbaccel; extern int nouveau_nofbaccel;
extern int nouveau_noaccel; extern int nouveau_noaccel;
...@@ -1010,12 +1007,6 @@ extern int nv50_graph_unload_context(struct drm_device *); ...@@ -1010,12 +1007,6 @@ extern int nv50_graph_unload_context(struct drm_device *);
extern void nv50_graph_context_switch(struct drm_device *); extern void nv50_graph_context_switch(struct drm_device *);
extern int nv50_grctx_init(struct nouveau_grctx *); extern int nv50_grctx_init(struct nouveau_grctx *);
/* nouveau_grctx.c */
extern int nouveau_grctx_prog_load(struct drm_device *);
extern void nouveau_grctx_vals_load(struct drm_device *,
struct nouveau_gpuobj *);
extern void nouveau_grctx_fini(struct drm_device *);
/* nv04_instmem.c */ /* nv04_instmem.c */
extern int nv04_instmem_init(struct drm_device *); extern int nv04_instmem_init(struct drm_device *);
extern void nv04_instmem_takedown(struct drm_device *); extern void nv04_instmem_takedown(struct drm_device *);
......
/*
* Copyright 2009 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include <linux/firmware.h>
#include <linux/slab.h>
#include "drmP.h"
#include "nouveau_drv.h"
struct nouveau_ctxprog {
uint32_t signature;
uint8_t version;
uint16_t length;
uint32_t data[];
} __attribute__ ((packed));
struct nouveau_ctxvals {
uint32_t signature;
uint8_t version;
uint32_t length;
struct {
uint32_t offset;
uint32_t value;
} data[];
} __attribute__ ((packed));
int
nouveau_grctx_prog_load(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
const int chipset = dev_priv->chipset;
const struct firmware *fw;
const struct nouveau_ctxprog *cp;
const struct nouveau_ctxvals *cv;
char name[32];
int ret, i;
if (pgraph->accel_blocked)
return -ENODEV;
if (!pgraph->ctxprog) {
sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
ret = request_firmware(&fw, name, &dev->pdev->dev);
if (ret) {
NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
return ret;
}
pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!pgraph->ctxprog) {
NV_ERROR(dev, "OOM copying ctxprog\n");
release_firmware(fw);
return -ENOMEM;
}
cp = pgraph->ctxprog;
if (le32_to_cpu(cp->signature) != 0x5043564e ||
cp->version != 0 ||
le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
NV_ERROR(dev, "ctxprog invalid\n");
release_firmware(fw);
nouveau_grctx_fini(dev);
return -EINVAL;
}
release_firmware(fw);
}
if (!pgraph->ctxvals) {
sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
ret = request_firmware(&fw, name, &dev->pdev->dev);
if (ret) {
NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
nouveau_grctx_fini(dev);
return ret;
}
pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!pgraph->ctxvals) {
NV_ERROR(dev, "OOM copying ctxvals\n");
release_firmware(fw);
nouveau_grctx_fini(dev);
return -ENOMEM;
}
cv = (void *)pgraph->ctxvals;
if (le32_to_cpu(cv->signature) != 0x5643564e ||
cv->version != 0 ||
le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
NV_ERROR(dev, "ctxvals invalid\n");
release_firmware(fw);
nouveau_grctx_fini(dev);
return -EINVAL;
}
release_firmware(fw);
}
cp = pgraph->ctxprog;
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
for (i = 0; i < le16_to_cpu(cp->length); i++)
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
le32_to_cpu(cp->data[i]));
return 0;
}
void
nouveau_grctx_fini(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
if (pgraph->ctxprog) {
kfree(pgraph->ctxprog);
pgraph->ctxprog = NULL;
}
if (pgraph->ctxvals) {
kfree(pgraph->ctxprog);
pgraph->ctxvals = NULL;
}
}
void
nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_ctxvals *cv = pgraph->ctxvals;
int i;
if (!cv)
return;
for (i = 0; i < le32_to_cpu(cv->length); i++)
nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
le32_to_cpu(cv->data[i].value));
}
...@@ -58,6 +58,7 @@ nv40_graph_create_context(struct nouveau_channel *chan) ...@@ -58,6 +58,7 @@ nv40_graph_create_context(struct nouveau_channel *chan)
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_grctx ctx = {};
int ret; int ret;
ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
...@@ -67,16 +68,11 @@ nv40_graph_create_context(struct nouveau_channel *chan) ...@@ -67,16 +68,11 @@ nv40_graph_create_context(struct nouveau_channel *chan)
return ret; return ret;
/* Initialise default context values */ /* Initialise default context values */
if (!pgraph->ctxprog) { ctx.dev = chan->dev;
struct nouveau_grctx ctx = {}; ctx.mode = NOUVEAU_GRCTX_VALS;
ctx.data = chan->ramin_grctx->gpuobj;
nv40_grctx_init(&ctx);
ctx.dev = chan->dev;
ctx.mode = NOUVEAU_GRCTX_VALS;
ctx.data = chan->ramin_grctx->gpuobj;
nv40_grctx_init(&ctx);
} else {
nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj);
}
nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, nv_wo32(dev, chan->ramin_grctx->gpuobj, 0,
chan->ramin_grctx->gpuobj->im_pramin->start); chan->ramin_grctx->gpuobj->im_pramin->start);
return 0; return 0;
...@@ -236,7 +232,8 @@ nv40_graph_init(struct drm_device *dev) ...@@ -236,7 +232,8 @@ nv40_graph_init(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = struct drm_nouveau_private *dev_priv =
(struct drm_nouveau_private *)dev->dev_private; (struct drm_nouveau_private *)dev->dev_private;
struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
uint32_t vramsz; struct nouveau_grctx ctx = {};
uint32_t vramsz, *cp;
int i, j; int i, j;
nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
...@@ -244,32 +241,22 @@ nv40_graph_init(struct drm_device *dev) ...@@ -244,32 +241,22 @@ nv40_graph_init(struct drm_device *dev)
nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
NV_PMC_ENABLE_PGRAPH); NV_PMC_ENABLE_PGRAPH);
if (nouveau_ctxfw) { cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL);
nouveau_grctx_prog_load(dev); if (!cp)
dev_priv->engine.graph.grctx_size = 175 * 1024; return -ENOMEM;
}
if (!dev_priv->engine.graph.ctxprog) {
struct nouveau_grctx ctx = {};
uint32_t *cp;
cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL);
if (!cp)
return -ENOMEM;
ctx.dev = dev; ctx.dev = dev;
ctx.mode = NOUVEAU_GRCTX_PROG; ctx.mode = NOUVEAU_GRCTX_PROG;
ctx.data = cp; ctx.data = cp;
ctx.ctxprog_max = 256; ctx.ctxprog_max = 256;
nv40_grctx_init(&ctx); nv40_grctx_init(&ctx);
dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
for (i = 0; i < ctx.ctxprog_len; i++) for (i = 0; i < ctx.ctxprog_len; i++)
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
kfree(cp); kfree(cp);
}
/* No context present currently */ /* No context present currently */
nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
...@@ -405,7 +392,6 @@ nv40_graph_init(struct drm_device *dev) ...@@ -405,7 +392,6 @@ nv40_graph_init(struct drm_device *dev)
void nv40_graph_takedown(struct drm_device *dev) void nv40_graph_takedown(struct drm_device *dev)
{ {
nouveau_grctx_fini(dev);
} }
struct nouveau_pgraph_object_class nv40_graph_grclass[] = { struct nouveau_pgraph_object_class nv40_graph_grclass[] = {
......
...@@ -103,37 +103,33 @@ static int ...@@ -103,37 +103,33 @@ static int
nv50_graph_init_ctxctl(struct drm_device *dev) nv50_graph_init_ctxctl(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_grctx ctx = {};
uint32_t *cp;
int i;
NV_DEBUG(dev, "\n"); NV_DEBUG(dev, "\n");
if (nouveau_ctxfw) { cp = kmalloc(512 * 4, GFP_KERNEL);
nouveau_grctx_prog_load(dev); if (!cp) {
dev_priv->engine.graph.grctx_size = 0x70000; NV_ERROR(dev, "failed to allocate ctxprog\n");
dev_priv->engine.graph.accel_blocked = true;
return 0;
} }
if (!dev_priv->engine.graph.ctxprog) {
struct nouveau_grctx ctx = {}; ctx.dev = dev;
uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL); ctx.mode = NOUVEAU_GRCTX_PROG;
int i; ctx.data = cp;
if (!cp) { ctx.ctxprog_max = 512;
NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n"); if (!nv50_grctx_init(&ctx)) {
dev_priv->engine.graph.accel_blocked = true; dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
return 0;
} nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
ctx.dev = dev; for (i = 0; i < ctx.ctxprog_len; i++)
ctx.mode = NOUVEAU_GRCTX_PROG; nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
ctx.data = cp; } else {
ctx.ctxprog_max = 512; dev_priv->engine.graph.accel_blocked = true;
if (!nv50_grctx_init(&ctx)) {
dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
for (i = 0; i < ctx.ctxprog_len; i++)
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
} else {
dev_priv->engine.graph.accel_blocked = true;
}
kfree(cp);
} }
kfree(cp);
nv_wr32(dev, 0x400320, 4); nv_wr32(dev, 0x400320, 4);
nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
...@@ -164,7 +160,6 @@ void ...@@ -164,7 +160,6 @@ void
nv50_graph_takedown(struct drm_device *dev) nv50_graph_takedown(struct drm_device *dev)
{ {
NV_DEBUG(dev, "\n"); NV_DEBUG(dev, "\n");
nouveau_grctx_fini(dev);
} }
void void
...@@ -214,6 +209,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) ...@@ -214,6 +209,7 @@ nv50_graph_create_context(struct nouveau_channel *chan)
struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
struct nouveau_gpuobj *obj; struct nouveau_gpuobj *obj;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_grctx ctx = {};
int hdr, ret; int hdr, ret;
NV_DEBUG(dev, "ch%d\n", chan->id); NV_DEBUG(dev, "ch%d\n", chan->id);
...@@ -234,15 +230,11 @@ nv50_graph_create_context(struct nouveau_channel *chan) ...@@ -234,15 +230,11 @@ nv50_graph_create_context(struct nouveau_channel *chan)
nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000);
if (!pgraph->ctxprog) { ctx.dev = chan->dev;
struct nouveau_grctx ctx = {}; ctx.mode = NOUVEAU_GRCTX_VALS;
ctx.dev = chan->dev; ctx.data = obj;
ctx.mode = NOUVEAU_GRCTX_VALS; nv50_grctx_init(&ctx);
ctx.data = obj;
nv50_grctx_init(&ctx);
} else {
nouveau_grctx_vals_load(dev, obj);
}
nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12); nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12);
dev_priv->engine.instmem.flush(dev); dev_priv->engine.instmem.flush(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment