Skip to content

Commit

Permalink
drm/nv84: add support for the PCRYPT engine
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Dec 3, 2010
1 parent b8c157d commit bd2e597
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 11 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nv04_graph.o nv10_graph.o nv20_graph.o \
nv40_graph.o nv50_graph.o nvc0_graph.o \
nv40_grctx.o nv50_grctx.o \
nv84_crypt.o \
nv04_instmem.o nv50_instmem.o nvc0_instmem.o \
nv50_crtc.o nv50_dac.o nv50_sor.o \
nv50_cursor.o nv50_display.o nv50_fbcon.o \
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
struct nouveau_channel *chan;
unsigned long flags;
int user, ret;
Expand Down Expand Up @@ -214,6 +215,14 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
return ret;
}

if (pcrypt->create_context) {
ret = pcrypt->create_context(chan);
if (ret) {
nouveau_channel_put(&chan);
return ret;
}
}

/* Construct inital RAMFC for new channel */
ret = pfifo->create_context(chan);
if (ret) {
Expand Down Expand Up @@ -280,6 +289,7 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
unsigned long flags;
int ret;

Expand Down Expand Up @@ -328,6 +338,8 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
/* destroy the engine specific contexts */
pfifo->destroy_context(chan);
pgraph->destroy_context(chan);
if (pcrypt->destroy_context)
pcrypt->destroy_context(chan);

pfifo->reassign(dev, true);

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
engine->timer.init(dev);
engine->fb.init(dev);
engine->graph.init(dev);
engine->crypt.init(dev);
engine->fifo.init(dev);

NV_INFO(dev, "Restoring GPU objects...\n");
Expand Down
24 changes: 24 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ enum nouveau_flags {

#define NVOBJ_ENGINE_SW 0
#define NVOBJ_ENGINE_GR 1
#define NVOBJ_ENGINE_PPP 2
#define NVOBJ_ENGINE_COPY 3
#define NVOBJ_ENGINE_VP 4
#define NVOBJ_ENGINE_CRYPT 5
#define NVOBJ_ENGINE_BSP 6
#define NVOBJ_ENGINE_DISPLAY 0xcafe0001
#define NVOBJ_ENGINE_INT 0xdeadbeef

Expand Down Expand Up @@ -208,6 +213,7 @@ struct nouveau_channel {
/* PGRAPH context */
/* XXX may be merge 2 pointers as private data ??? */
struct nouveau_gpuobj *ramin_grctx;
struct nouveau_gpuobj *crypt_ctx;
void *pgraph_ctx;

/* NV50 VM */
Expand Down Expand Up @@ -444,6 +450,16 @@ struct nouveau_pm_engine {
int (*temp_get)(struct drm_device *);
};

struct nouveau_crypt_engine {
bool registered;

int (*init)(struct drm_device *);
void (*takedown)(struct drm_device *);
int (*create_context)(struct nouveau_channel *);
void (*destroy_context)(struct nouveau_channel *);
void (*tlb_flush)(struct drm_device *dev);
};

struct nouveau_engine {
struct nouveau_instmem_engine instmem;
struct nouveau_mc_engine mc;
Expand All @@ -454,6 +470,7 @@ struct nouveau_engine {
struct nouveau_display_engine display;
struct nouveau_gpio_engine gpio;
struct nouveau_pm_engine pm;
struct nouveau_crypt_engine crypt;
};

struct nouveau_pll_vals {
Expand Down Expand Up @@ -1113,6 +1130,13 @@ extern void nvc0_graph_destroy_context(struct nouveau_channel *);
extern int nvc0_graph_load_context(struct nouveau_channel *);
extern int nvc0_graph_unload_context(struct drm_device *);

/* nv84_crypt.c */
extern int nv84_crypt_init(struct drm_device *dev);
extern void nv84_crypt_fini(struct drm_device *dev);
extern int nv84_crypt_create_context(struct nouveau_channel *);
extern void nv84_crypt_destroy_context(struct nouveau_channel *);
extern void nv84_crypt_tlb_flush(struct drm_device *dev);

/* nv04_instmem.c */
extern int nv04_instmem_init(struct drm_device *);
extern void nv04_instmem_takedown(struct drm_device *);
Expand Down
16 changes: 16 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,22 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
status &= ~NV_PMC_INTR_0_PGRAPH_PENDING;
}

if (status & 0x00004000) {
u32 stat = nv_rd32(dev, 0x102130);
u32 mthd = nv_rd32(dev, 0x102190);
u32 data = nv_rd32(dev, 0x102194);
u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff;

NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n",
stat, mthd, data, inst);
nv_wr32(dev, 0x102130, stat);
nv_wr32(dev, 0x10200c, 0x10);

nv50_fb_vm_trap(dev, nouveau_ratelimit(), "PCRYPT");
status &= ~0x00004000;

}

if (status & NV_PMC_INTR_0_CRTCn_PENDING) {
nouveau_crtc_irq_handler(dev, (status>>24)&3);
status &= ~NV_PMC_INTR_0_CRTCn_PENDING;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/nouveau/nouveau_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ nouveau_gpuobj_init(struct drm_device *dev)
NV_DEBUG(dev, "\n");

INIT_LIST_HEAD(&dev_priv->gpuobj_list);
INIT_LIST_HEAD(&dev_priv->classes);
spin_lock_init(&dev_priv->ramin_lock);
dev_priv->ramin_base = ~0;

Expand Down Expand Up @@ -686,7 +687,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
NV_DEBUG(dev, "ch%d\n", chan->id);

/* Base amount for object storage (4KiB enough?) */
size = 0x1000;
size = 0x2000;
base = 0;

/* PGRAPH context */
Expand Down
62 changes: 52 additions & 10 deletions drivers/gpu/drm/nouveau/nouveau_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_get = nv04_pm_clock_get;
engine->pm.clock_pre = nv04_pm_clock_pre;
engine->pm.clock_set = nv04_pm_clock_set;
engine->crypt.init = nouveau_stub_init;
engine->crypt.takedown = nouveau_stub_takedown;
break;
case 0x10:
engine->instmem.init = nv04_instmem_init;
Expand Down Expand Up @@ -151,6 +153,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_get = nv04_pm_clock_get;
engine->pm.clock_pre = nv04_pm_clock_pre;
engine->pm.clock_set = nv04_pm_clock_set;
engine->crypt.init = nouveau_stub_init;
engine->crypt.takedown = nouveau_stub_takedown;
break;
case 0x20:
engine->instmem.init = nv04_instmem_init;
Expand Down Expand Up @@ -204,6 +208,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_get = nv04_pm_clock_get;
engine->pm.clock_pre = nv04_pm_clock_pre;
engine->pm.clock_set = nv04_pm_clock_set;
engine->crypt.init = nouveau_stub_init;
engine->crypt.takedown = nouveau_stub_takedown;
break;
case 0x30:
engine->instmem.init = nv04_instmem_init;
Expand Down Expand Up @@ -259,6 +265,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_set = nv04_pm_clock_set;
engine->pm.voltage_get = nouveau_voltage_gpio_get;
engine->pm.voltage_set = nouveau_voltage_gpio_set;
engine->crypt.init = nouveau_stub_init;
engine->crypt.takedown = nouveau_stub_takedown;
break;
case 0x40:
case 0x60:
Expand Down Expand Up @@ -316,6 +324,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.voltage_get = nouveau_voltage_gpio_get;
engine->pm.voltage_set = nouveau_voltage_gpio_set;
engine->pm.temp_get = nv40_temp_get;
engine->crypt.init = nouveau_stub_init;
engine->crypt.takedown = nouveau_stub_takedown;
break;
case 0x50:
case 0x80: /* gotta love NVIDIA's consistency.. */
Expand Down Expand Up @@ -380,26 +390,47 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->gpio.set = nv50_gpio_set;
engine->gpio.irq_enable = nv50_gpio_irq_enable;
switch (dev_priv->chipset) {
case 0xa3:
case 0xa5:
case 0xa8:
case 0xaf:
engine->pm.clock_get = nva3_pm_clock_get;
engine->pm.clock_pre = nva3_pm_clock_pre;
engine->pm.clock_set = nva3_pm_clock_set;
break;
default:
case 0x84:
case 0x86:
case 0x92:
case 0x94:
case 0x96:
case 0x98:
case 0xa0:
case 0x50:
engine->pm.clock_get = nv50_pm_clock_get;
engine->pm.clock_pre = nv50_pm_clock_pre;
engine->pm.clock_set = nv50_pm_clock_set;
break;
default:
engine->pm.clock_get = nva3_pm_clock_get;
engine->pm.clock_pre = nva3_pm_clock_pre;
engine->pm.clock_set = nva3_pm_clock_set;
break;
}
engine->pm.voltage_get = nouveau_voltage_gpio_get;
engine->pm.voltage_set = nouveau_voltage_gpio_set;
if (dev_priv->chipset >= 0x84)
engine->pm.temp_get = nv84_temp_get;
else
engine->pm.temp_get = nv40_temp_get;
switch (dev_priv->chipset) {
case 0x84:
case 0x86:
case 0x92:
case 0x94:
case 0x96:
case 0xa0:
engine->crypt.init = nv84_crypt_init;
engine->crypt.takedown = nv84_crypt_fini;
engine->crypt.create_context = nv84_crypt_create_context;
engine->crypt.destroy_context = nv84_crypt_destroy_context;
break;
default:
engine->crypt.init = nouveau_stub_init;
engine->crypt.takedown = nouveau_stub_takedown;
break;
}
break;
case 0xC0:
engine->instmem.init = nvc0_instmem_init;
Expand Down Expand Up @@ -447,6 +478,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->gpio.get = nv50_gpio_get;
engine->gpio.set = nv50_gpio_set;
engine->gpio.irq_enable = nv50_gpio_irq_enable;
engine->crypt.init = nouveau_stub_init;
engine->crypt.takedown = nouveau_stub_takedown;
break;
default:
NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
Expand Down Expand Up @@ -619,10 +652,15 @@ nouveau_card_init(struct drm_device *dev)
if (ret)
goto out_fb;

/* PCRYPT */
ret = engine->crypt.init(dev);
if (ret)
goto out_graph;

/* PFIFO */
ret = engine->fifo.init(dev);
if (ret)
goto out_graph;
goto out_crypt;
}

ret = engine->display.create(dev);
Expand Down Expand Up @@ -669,6 +707,9 @@ nouveau_card_init(struct drm_device *dev)
out_fifo:
if (!nouveau_noaccel)
engine->fifo.takedown(dev);
out_crypt:
if (!nouveau_noaccel)
engine->crypt.takedown(dev);
out_graph:
if (!nouveau_noaccel)
engine->graph.takedown(dev);
Expand Down Expand Up @@ -712,6 +753,7 @@ static void nouveau_card_takedown(struct drm_device *dev)

if (!nouveau_noaccel) {
engine->fifo.takedown(dev);
engine->crypt.takedown(dev);
engine->graph.takedown(dev);
}
engine->fb.takedown(dev);
Expand Down
Loading

0 comments on commit bd2e597

Please sign in to comment.