Commit c85ee6ca authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/gr: convert to new-style nvkm_engine

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 13de7f46
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <core/subdev.h> #include <core/subdev.h>
struct nvkm_device_oclass; /*XXX: DEV!ENG */ struct nvkm_device_oclass; /*XXX: DEV!ENG */
struct nvkm_fifo_chan; struct nvkm_fifo_chan;
struct nvkm_fb_tile;
#define NV_ENGINE_(eng,var) (((var) << 8) | (eng)) #define NV_ENGINE_(eng,var) (((var) << 8) | (eng))
#define NV_ENGINE(name,var) NV_ENGINE_(NVDEV_ENGINE_##name, (var)) #define NV_ENGINE(name,var) NV_ENGINE_(NVDEV_ENGINE_##name, (var))
...@@ -20,7 +21,6 @@ struct nvkm_engine { ...@@ -20,7 +21,6 @@ struct nvkm_engine {
spinlock_t lock; spinlock_t lock;
void (*tile_prog)(struct nvkm_engine *, int region); void (*tile_prog)(struct nvkm_engine *, int region);
int (*tlb_flush)(struct nvkm_engine *);
}; };
struct nvkm_engine_func { struct nvkm_engine_func {
...@@ -29,6 +29,7 @@ struct nvkm_engine_func { ...@@ -29,6 +29,7 @@ struct nvkm_engine_func {
int (*init)(struct nvkm_engine *); int (*init)(struct nvkm_engine *);
int (*fini)(struct nvkm_engine *, bool suspend); int (*fini)(struct nvkm_engine *, bool suspend);
void (*intr)(struct nvkm_engine *); void (*intr)(struct nvkm_engine *);
void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
struct { struct {
int (*sclass)(struct nvkm_oclass *, int index, int (*sclass)(struct nvkm_oclass *, int index,
...@@ -54,6 +55,7 @@ int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *, ...@@ -54,6 +55,7 @@ int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *,
struct nvkm_engine **); struct nvkm_engine **);
struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *); struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *);
void nvkm_engine_unref(struct nvkm_engine **); void nvkm_engine_unref(struct nvkm_engine **);
void nvkm_engine_tile(struct nvkm_engine *, int region);
static inline struct nvkm_engine * static inline struct nvkm_engine *
nv_engine(void *obj) nv_engine(void *obj)
......
...@@ -3,64 +3,44 @@ ...@@ -3,64 +3,44 @@
#include <core/engine.h> #include <core/engine.h>
struct nvkm_gr { struct nvkm_gr {
struct nvkm_engine engine;
const struct nvkm_gr_func *func; const struct nvkm_gr_func *func;
struct nvkm_engine engine;
/* Returns chipset-specific counts of units packed into an u64.
*/
u64 (*units)(struct nvkm_gr *);
}; };
#define nvkm_gr_create(p,e,c,y,d) \ u64 nvkm_gr_units(struct nvkm_gr *);
nvkm_gr_create_((p), (e), (c), (y), sizeof(**d), (void **)(d)) int nvkm_gr_tlb_flush(struct nvkm_gr *);
int
nvkm_gr_create_(struct nvkm_object *parent, struct nvkm_object *engine, int nv04_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
struct nvkm_oclass *oclass, bool enable, int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int length, void **pobject); int nv15_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#define nvkm_gr_destroy(d) \ int nv17_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
nvkm_engine_destroy(&(d)->engine) int nv20_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#define nvkm_gr_init(d) \ int nv25_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
nvkm_engine_init_old(&(d)->engine) int nv2a_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#define nvkm_gr_fini(d,s) \ int nv30_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
nvkm_engine_fini_old(&(d)->engine, (s)) int nv34_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv35_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#define _nvkm_gr_dtor _nvkm_engine_dtor int nv40_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#define _nvkm_gr_init _nvkm_engine_init int nv44_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#define _nvkm_gr_fini _nvkm_engine_fini int nv50_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int g84_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv04_gr_oclass; int gt200_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv10_gr_oclass; int mcp79_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv20_gr_oclass; int gt215_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv25_gr_oclass; int mcp89_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv2a_gr_oclass; int gf100_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv30_gr_oclass; int gf104_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv34_gr_oclass; int gf108_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv35_gr_oclass; int gf110_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv40_gr_oclass; int gf117_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass nv50_gr_oclass; int gf119_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gf100_gr_oclass; int gk104_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gf108_gr_oclass; int gk110_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gf104_gr_oclass; int gk110b_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gf110_gr_oclass; int gk208_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gf117_gr_oclass; int gk20a_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gf119_gr_oclass; int gm107_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gk104_gr_oclass; int gm204_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gk20a_gr_oclass; int gm206_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gk110_gr_oclass; int gm20b_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
extern struct nvkm_oclass *gk110b_gr_oclass;
extern struct nvkm_oclass *gk208_gr_oclass;
extern struct nvkm_oclass *gm107_gr_oclass;
extern struct nvkm_oclass *gm204_gr_oclass;
extern struct nvkm_oclass *gm206_gr_oclass;
extern struct nvkm_oclass *gm20b_gr_oclass;
#include <core/enum.h>
extern const struct nvkm_bitfield nv04_gr_nsource[];
bool nv04_gr_idle(struct nvkm_gr *);
extern const struct nvkm_bitfield nv10_gr_intr_name[];
extern const struct nvkm_bitfield nv10_gr_nstatus[];
extern const struct nvkm_enum nv50_data_error_names[];
#endif #endif
...@@ -215,7 +215,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) ...@@ -215,7 +215,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
getparam->value = 1; getparam->value = 1;
break; break;
case NOUVEAU_GETPARAM_GRAPH_UNITS: case NOUVEAU_GETPARAM_GRAPH_UNITS:
getparam->value = gr->units ? gr->units(gr) : 0; getparam->value = nvkm_gr_units(gr);
break; break;
default: default:
NV_PRINTK(dbg, cli, "unknown parameter %lld\n", getparam->param); NV_PRINTK(dbg, cli, "unknown parameter %lld\n", getparam->param);
......
...@@ -48,7 +48,8 @@ nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg, ...@@ -48,7 +48,8 @@ nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg,
{ {
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
int i = reg - drm->tile.reg; int i = reg - drm->tile.reg;
struct nvkm_fb *fb = nvxx_fb(&drm->device); struct nvkm_device *device = nvxx_device(&drm->device);
struct nvkm_fb *fb = device->fb;
struct nvkm_fb_tile *tile = &fb->tile.region[i]; struct nvkm_fb_tile *tile = &fb->tile.region[i];
nouveau_fence_unref(&reg->fence); nouveau_fence_unref(&reg->fence);
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <core/device.h> #include <core/device.h>
#include <core/option.h> #include <core/option.h>
#include <subdev/fb.h>
void void
nvkm_engine_unref(struct nvkm_engine **pengine) nvkm_engine_unref(struct nvkm_engine **pengine)
{ {
...@@ -56,6 +58,14 @@ nvkm_engine_ref(struct nvkm_engine *engine) ...@@ -56,6 +58,14 @@ nvkm_engine_ref(struct nvkm_engine *engine)
return engine; return engine;
} }
void
nvkm_engine_tile(struct nvkm_engine *engine, int region)
{
struct nvkm_fb *fb = engine->subdev.device->fb;
if (engine->func->tile)
engine->func->tile(engine, region, &fb->tile.region[region]);
}
static void static void
nvkm_engine_intr(struct nvkm_subdev *obj) nvkm_engine_intr(struct nvkm_subdev *obj)
{ {
...@@ -80,7 +90,8 @@ nvkm_engine_init(struct nvkm_subdev *obj) ...@@ -80,7 +90,8 @@ nvkm_engine_init(struct nvkm_subdev *obj)
{ {
struct nvkm_engine *engine = container_of(obj, typeof(*engine), subdev); struct nvkm_engine *engine = container_of(obj, typeof(*engine), subdev);
struct nvkm_subdev *subdev = &engine->subdev; struct nvkm_subdev *subdev = &engine->subdev;
int ret = 0; struct nvkm_fb *fb = subdev->device->fb;
int ret = 0, i;
s64 time; s64 time;
if (!engine->usecount) { if (!engine->usecount) {
...@@ -108,6 +119,8 @@ nvkm_engine_init(struct nvkm_subdev *obj) ...@@ -108,6 +119,8 @@ nvkm_engine_init(struct nvkm_subdev *obj)
if (engine->func->init) if (engine->func->init)
ret = engine->func->init(engine); ret = engine->func->init(engine);
for (i = 0; fb && i < fb->tile.regions; i++)
nvkm_engine_tile(engine, i);
return ret; return ret;
} }
......
...@@ -29,47 +29,38 @@ gf100_identify(struct nvkm_device *device) ...@@ -29,47 +29,38 @@ gf100_identify(struct nvkm_device *device)
switch (device->chipset) { switch (device->chipset) {
case 0xc0: case 0xc0:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf100_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break; break;
case 0xc4: case 0xc4:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break; break;
case 0xc3: case 0xc3:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break; break;
case 0xce: case 0xce:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break; break;
case 0xcf: case 0xcf:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break; break;
case 0xc1: case 0xc1:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf108_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf108_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf108_pm_oclass;
break; break;
case 0xc8: case 0xc8:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf110_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break; break;
case 0xd9: case 0xd9:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf119_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf117_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf117_pm_oclass;
break; break;
case 0xd7: case 0xd7:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf117_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf117_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gf117_pm_oclass;
break; break;
default: default:
......
...@@ -29,41 +29,33 @@ gk104_identify(struct nvkm_device *device) ...@@ -29,41 +29,33 @@ gk104_identify(struct nvkm_device *device)
switch (device->chipset) { switch (device->chipset) {
case 0xe4: case 0xe4:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break; break;
case 0xe7: case 0xe7:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break; break;
case 0xe6: case 0xe6:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break; break;
case 0xea: case 0xea:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk20a_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break; break;
case 0xf0: case 0xf0:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk110_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
break; break;
case 0xf1: case 0xf1:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk110b_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
break; break;
case 0x106: case 0x106:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk208_gr_oclass;
break; break;
case 0x108: case 0x108:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk208_gr_oclass;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -32,7 +32,6 @@ gm100_identify(struct nvkm_device *device) ...@@ -32,7 +32,6 @@ gm100_identify(struct nvkm_device *device)
#if 0 #if 0
#endif #endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass;
#if 0 #if 0
#endif #endif
#if 0 #if 0
...@@ -46,7 +45,6 @@ gm100_identify(struct nvkm_device *device) ...@@ -46,7 +45,6 @@ gm100_identify(struct nvkm_device *device)
#if 0 #if 0
#endif #endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm204_gr_oclass;
#if 0 #if 0
#endif #endif
break; break;
...@@ -58,14 +56,12 @@ gm100_identify(struct nvkm_device *device) ...@@ -58,14 +56,12 @@ gm100_identify(struct nvkm_device *device)
#if 0 #if 0
#endif #endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm206_gr_oclass;
#if 0 #if 0
#endif #endif
break; break;
case 0x12b: case 0x12b:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm20b_gr_oclass;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -29,11 +29,9 @@ nv04_identify(struct nvkm_device *device) ...@@ -29,11 +29,9 @@ nv04_identify(struct nvkm_device *device)
switch (device->chipset) { switch (device->chipset) {
case 0x04: case 0x04:
device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_gr_oclass;
break; break;
case 0x05: case 0x05:
device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_gr_oclass;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -28,35 +28,27 @@ nv10_identify(struct nvkm_device *device) ...@@ -28,35 +28,27 @@ nv10_identify(struct nvkm_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0x10: case 0x10:
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
case 0x15: case 0x15:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
case 0x16: case 0x16:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
case 0x1a: case 0x1a:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
case 0x11: case 0x11:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
case 0x17: case 0x17:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
case 0x1f: case 0x1f:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
case 0x18: case 0x18:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -29,19 +29,15 @@ nv20_identify(struct nvkm_device *device) ...@@ -29,19 +29,15 @@ nv20_identify(struct nvkm_device *device)
switch (device->chipset) { switch (device->chipset) {
case 0x20: case 0x20:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv20_gr_oclass;
break; break;
case 0x25: case 0x25:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_gr_oclass;
break; break;
case 0x28: case 0x28:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_gr_oclass;
break; break;
case 0x2a: case 0x2a:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv2a_gr_oclass;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -29,25 +29,20 @@ nv30_identify(struct nvkm_device *device) ...@@ -29,25 +29,20 @@ nv30_identify(struct nvkm_device *device)
switch (device->chipset) { switch (device->chipset) {
case 0x30: case 0x30:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_gr_oclass;
break; break;
case 0x35: case 0x35:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_gr_oclass;
break; break;
case 0x31: case 0x31:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
break; break;
case 0x36: case 0x36:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
break; break;
case 0x34: case 0x34:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv34_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
break; break;
default: default:
......
...@@ -29,97 +29,81 @@ nv40_identify(struct nvkm_device *device) ...@@ -29,97 +29,81 @@ nv40_identify(struct nvkm_device *device)
switch (device->chipset) { switch (device->chipset) {
case 0x40: case 0x40:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x41: case 0x41:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x42: case 0x42:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x43: case 0x43:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x45: case 0x45:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x47: case 0x47:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x49: case 0x49:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x4b: case 0x4b:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x44: case 0x44:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x46: case 0x46:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x4a: case 0x4a:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x4c: case 0x4c:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x4e: case 0x4e:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x63: case 0x63:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x67: case 0x67:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
case 0x68: case 0x68:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break; break;
......
...@@ -29,80 +29,66 @@ nv50_identify(struct nvkm_device *device) ...@@ -29,80 +29,66 @@ nv50_identify(struct nvkm_device *device)
switch (device->chipset) { switch (device->chipset) {
case 0x50: case 0x50:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv50_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = nv50_pm_oclass;
break; break;
case 0x84: case 0x84:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0x86: case 0x86:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0x92: case 0x92:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0x94: case 0x94:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0x96: case 0x96:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0x98: case 0x98:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0xa0: case 0xa0:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt200_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gt200_pm_oclass;
break; break;
case 0xaa: case 0xaa:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0xac: case 0xac:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break; break;
case 0xa3: case 0xa3:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break; break;
case 0xa5: case 0xa5:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break; break;
case 0xa8: case 0xa8:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break; break;
case 0xaf: case 0xaf:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass; device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break; break;
default: default:
......
nvkm-y += nvkm/engine/gr/base.o nvkm-y += nvkm/engine/gr/base.o
nvkm-y += nvkm/engine/gr/nv04.o nvkm-y += nvkm/engine/gr/nv04.o
nvkm-y += nvkm/engine/gr/nv10.o nvkm-y += nvkm/engine/gr/nv10.o
nvkm-y += nvkm/engine/gr/nv15.o
nvkm-y += nvkm/engine/gr/nv17.o
nvkm-y += nvkm/engine/gr/nv20.o nvkm-y += nvkm/engine/gr/nv20.o
nvkm-y += nvkm/engine/gr/nv25.o nvkm-y += nvkm/engine/gr/nv25.o
nvkm-y += nvkm/engine/gr/nv2a.o nvkm-y += nvkm/engine/gr/nv2a.o
...@@ -8,18 +10,24 @@ nvkm-y += nvkm/engine/gr/nv30.o ...@@ -8,18 +10,24 @@ nvkm-y += nvkm/engine/gr/nv30.o
nvkm-y += nvkm/engine/gr/nv34.o nvkm-y += nvkm/engine/gr/nv34.o
nvkm-y += nvkm/engine/gr/nv35.o nvkm-y += nvkm/engine/gr/nv35.o
nvkm-y += nvkm/engine/gr/nv40.o nvkm-y += nvkm/engine/gr/nv40.o
nvkm-y += nvkm/engine/gr/nv44.o
nvkm-y += nvkm/engine/gr/nv50.o nvkm-y += nvkm/engine/gr/nv50.o
nvkm-y += nvkm/engine/gr/g84.o
nvkm-y += nvkm/engine/gr/gt200.o
nvkm-y += nvkm/engine/gr/mcp79.o
nvkm-y += nvkm/engine/gr/gt215.o
nvkm-y += nvkm/engine/gr/mcp89.o
nvkm-y += nvkm/engine/gr/gf100.o nvkm-y += nvkm/engine/gr/gf100.o
nvkm-y += nvkm/engine/gr/gf108.o
nvkm-y += nvkm/engine/gr/gf104.o nvkm-y += nvkm/engine/gr/gf104.o
nvkm-y += nvkm/engine/gr/gf108.o
nvkm-y += nvkm/engine/gr/gf110.o nvkm-y += nvkm/engine/gr/gf110.o
nvkm-y += nvkm/engine/gr/gf117.o nvkm-y += nvkm/engine/gr/gf117.o
nvkm-y += nvkm/engine/gr/gf119.o nvkm-y += nvkm/engine/gr/gf119.o
nvkm-y += nvkm/engine/gr/gk104.o nvkm-y += nvkm/engine/gr/gk104.o
nvkm-y += nvkm/engine/gr/gk20a.o
nvkm-y += nvkm/engine/gr/gk110.o nvkm-y += nvkm/engine/gr/gk110.o
nvkm-y += nvkm/engine/gr/gk110b.o nvkm-y += nvkm/engine/gr/gk110b.o
nvkm-y += nvkm/engine/gr/gk208.o nvkm-y += nvkm/engine/gr/gk208.o
nvkm-y += nvkm/engine/gr/gk20a.o
nvkm-y += nvkm/engine/gr/gm107.o nvkm-y += nvkm/engine/gr/gm107.o
nvkm-y += nvkm/engine/gr/gm204.o nvkm-y += nvkm/engine/gr/gm204.o
nvkm-y += nvkm/engine/gr/gm206.o nvkm-y += nvkm/engine/gr/gm206.o
...@@ -28,16 +36,16 @@ nvkm-y += nvkm/engine/gr/gm20b.o ...@@ -28,16 +36,16 @@ nvkm-y += nvkm/engine/gr/gm20b.o
nvkm-y += nvkm/engine/gr/ctxnv40.o nvkm-y += nvkm/engine/gr/ctxnv40.o
nvkm-y += nvkm/engine/gr/ctxnv50.o nvkm-y += nvkm/engine/gr/ctxnv50.o
nvkm-y += nvkm/engine/gr/ctxgf100.o nvkm-y += nvkm/engine/gr/ctxgf100.o
nvkm-y += nvkm/engine/gr/ctxgf108.o
nvkm-y += nvkm/engine/gr/ctxgf104.o nvkm-y += nvkm/engine/gr/ctxgf104.o
nvkm-y += nvkm/engine/gr/ctxgf108.o
nvkm-y += nvkm/engine/gr/ctxgf110.o nvkm-y += nvkm/engine/gr/ctxgf110.o
nvkm-y += nvkm/engine/gr/ctxgf117.o nvkm-y += nvkm/engine/gr/ctxgf117.o
nvkm-y += nvkm/engine/gr/ctxgf119.o nvkm-y += nvkm/engine/gr/ctxgf119.o
nvkm-y += nvkm/engine/gr/ctxgk104.o nvkm-y += nvkm/engine/gr/ctxgk104.o
nvkm-y += nvkm/engine/gr/ctxgk20a.o
nvkm-y += nvkm/engine/gr/ctxgk110.o nvkm-y += nvkm/engine/gr/ctxgk110.o
nvkm-y += nvkm/engine/gr/ctxgk110b.o nvkm-y += nvkm/engine/gr/ctxgk110b.o
nvkm-y += nvkm/engine/gr/ctxgk208.o nvkm-y += nvkm/engine/gr/ctxgk208.o
nvkm-y += nvkm/engine/gr/ctxgk20a.o
nvkm-y += nvkm/engine/gr/ctxgm107.o nvkm-y += nvkm/engine/gr/ctxgm107.o
nvkm-y += nvkm/engine/gr/ctxgm204.o nvkm-y += nvkm/engine/gr/ctxgm204.o
nvkm-y += nvkm/engine/gr/ctxgm206.o nvkm-y += nvkm/engine/gr/ctxgm206.o
......
...@@ -25,6 +25,30 @@ ...@@ -25,6 +25,30 @@
#include <engine/fifo.h> #include <engine/fifo.h>
static void
nvkm_gr_tile(struct nvkm_engine *engine, int region, struct nvkm_fb_tile *tile)
{
struct nvkm_gr *gr = nvkm_gr(engine);
if (gr->func->tile)
gr->func->tile(gr, region, tile);
}
u64
nvkm_gr_units(struct nvkm_gr *gr)
{
if (gr->func->units)
return gr->func->units(gr);
return 0;
}
int
nvkm_gr_tlb_flush(struct nvkm_gr *gr)
{
if (gr->func->tlb_flush)
return gr->func->tlb_flush(gr);
return -ENODEV;
}
static int static int
nvkm_gr_oclass_get(struct nvkm_oclass *oclass, int index) nvkm_gr_oclass_get(struct nvkm_oclass *oclass, int index)
{ {
...@@ -59,26 +83,54 @@ nvkm_gr_cclass_new(struct nvkm_fifo_chan *chan, ...@@ -59,26 +83,54 @@ nvkm_gr_cclass_new(struct nvkm_fifo_chan *chan,
return 0; return 0;
} }
struct nvkm_engine_func static void
nvkm_gr_intr(struct nvkm_engine *engine)
{
struct nvkm_gr *gr = nvkm_gr(engine);
gr->func->intr(gr);
}
static int
nvkm_gr_oneinit(struct nvkm_engine *engine)
{
struct nvkm_gr *gr = nvkm_gr(engine);
if (gr->func->oneinit)
return gr->func->oneinit(gr);
return 0;
}
static int
nvkm_gr_init(struct nvkm_engine *engine)
{
struct nvkm_gr *gr = nvkm_gr(engine);
return gr->func->init(gr);
}
static void *
nvkm_gr_dtor(struct nvkm_engine *engine)
{
struct nvkm_gr *gr = nvkm_gr(engine);
if (gr->func->dtor)
return gr->func->dtor(gr);
return gr;
}
static const struct nvkm_engine_func
nvkm_gr = { nvkm_gr = {
.dtor = nvkm_gr_dtor,
.oneinit = nvkm_gr_oneinit,
.init = nvkm_gr_init,
.intr = nvkm_gr_intr,
.tile = nvkm_gr_tile,
.fifo.cclass = nvkm_gr_cclass_new, .fifo.cclass = nvkm_gr_cclass_new,
.fifo.sclass = nvkm_gr_oclass_get, .fifo.sclass = nvkm_gr_oclass_get,
}; };
int int
nvkm_gr_create_(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_gr_ctor(const struct nvkm_gr_func *func, struct nvkm_device *device,
struct nvkm_oclass *oclass, bool enable, int index, u32 pmc_enable, bool enable, struct nvkm_gr *gr)
int length, void **pobject)
{ {
struct nvkm_gr *gr; gr->func = func;
int ret; return nvkm_engine_ctor(&nvkm_gr, device, index, pmc_enable,
enable, &gr->engine);
ret = nvkm_engine_create_(parent, engine, oclass, enable,
"gr", "gr", length, pobject);
gr = *pobject;
if (ret)
return ret;
gr->engine.func = &nvkm_gr;
return 0;
} }
...@@ -19,9 +19,8 @@ ...@@ -19,9 +19,8 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*/ */
#include "ctxgf100.h" #include "ctxgf100.h"
#include "gk20a.h" #include "gf100.h"
#include <subdev/mc.h> #include <subdev/mc.h>
......
/*
* Copyright 2012 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 "nv50.h"
#include <subdev/timer.h>
static const struct nvkm_bitfield nv50_gr_status[] = {
{ 0x00000001, "BUSY" }, /* set when any bit is set */
{ 0x00000002, "DISPATCH" },
{ 0x00000004, "UNK2" },
{ 0x00000008, "UNK3" },
{ 0x00000010, "UNK4" },
{ 0x00000020, "UNK5" },
{ 0x00000040, "M2MF" },
{ 0x00000080, "UNK7" },
{ 0x00000100, "CTXPROG" },
{ 0x00000200, "VFETCH" },
{ 0x00000400, "CCACHE_PREGEOM" },
{ 0x00000800, "STRMOUT_VATTR_POSTGEOM" },
{ 0x00001000, "VCLIP" },
{ 0x00002000, "RATTR_APLANE" },
{ 0x00004000, "TRAST" },
{ 0x00008000, "CLIPID" },
{ 0x00010000, "ZCULL" },
{ 0x00020000, "ENG2D" },
{ 0x00040000, "RMASK" },
{ 0x00080000, "TPC_RAST" },
{ 0x00100000, "TPC_PROP" },
{ 0x00200000, "TPC_TEX" },
{ 0x00400000, "TPC_GEOM" },
{ 0x00800000, "TPC_MP" },
{ 0x01000000, "ROP" },
{}
};
static const struct nvkm_bitfield
nv50_gr_vstatus_0[] = {
{ 0x01, "VFETCH" },
{ 0x02, "CCACHE" },
{ 0x04, "PREGEOM" },
{ 0x08, "POSTGEOM" },
{ 0x10, "VATTR" },
{ 0x20, "STRMOUT" },
{ 0x40, "VCLIP" },
{}
};
static const struct nvkm_bitfield
nv50_gr_vstatus_1[] = {
{ 0x01, "TPC_RAST" },
{ 0x02, "TPC_PROP" },
{ 0x04, "TPC_TEX" },
{ 0x08, "TPC_GEOM" },
{ 0x10, "TPC_MP" },
{}
};
static const struct nvkm_bitfield
nv50_gr_vstatus_2[] = {
{ 0x01, "RATTR" },
{ 0x02, "APLANE" },
{ 0x04, "TRAST" },
{ 0x08, "CLIPID" },
{ 0x10, "ZCULL" },
{ 0x20, "ENG2D" },
{ 0x40, "RMASK" },
{ 0x80, "ROP" },
{}
};
static void
nvkm_gr_vstatus_print(struct nv50_gr *gr, int r,
const struct nvkm_bitfield *units, u32 status)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
u32 stat = status;
u8 mask = 0x00;
char msg[64];
int i;
for (i = 0; units[i].name && status; i++) {
if ((status & 7) == 1)
mask |= (1 << i);
status >>= 3;
}
nvkm_snprintbf(msg, sizeof(msg), units, mask);
nvkm_error(subdev, "PGRAPH_VSTATUS%d: %08x [%s]\n", r, stat, msg);
}
int
g84_gr_tlb_flush(struct nvkm_gr *base)
{
struct nv50_gr *gr = nv50_gr(base);
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_timer *tmr = device->timer;
bool idle, timeout = false;
unsigned long flags;
char status[128];
u64 start;
u32 tmp;
spin_lock_irqsave(&gr->lock, flags);
nvkm_mask(device, 0x400500, 0x00000001, 0x00000000);
start = nvkm_timer_read(tmr);
do {
idle = true;
for (tmp = nvkm_rd32(device, 0x400380); tmp && idle; tmp >>= 3) {
if ((tmp & 7) == 1)
idle = false;
}
for (tmp = nvkm_rd32(device, 0x400384); tmp && idle; tmp >>= 3) {
if ((tmp & 7) == 1)
idle = false;
}
for (tmp = nvkm_rd32(device, 0x400388); tmp && idle; tmp >>= 3) {
if ((tmp & 7) == 1)
idle = false;
}
} while (!idle &&
!(timeout = nvkm_timer_read(tmr) - start > 2000000000));
if (timeout) {
nvkm_error(subdev, "PGRAPH TLB flush idle timeout fail\n");
tmp = nvkm_rd32(device, 0x400700);
nvkm_snprintbf(status, sizeof(status), nv50_gr_status, tmp);
nvkm_error(subdev, "PGRAPH_STATUS %08x [%s]\n", tmp, status);
nvkm_gr_vstatus_print(gr, 0, nv50_gr_vstatus_0,
nvkm_rd32(device, 0x400380));
nvkm_gr_vstatus_print(gr, 1, nv50_gr_vstatus_1,
nvkm_rd32(device, 0x400384));
nvkm_gr_vstatus_print(gr, 2, nv50_gr_vstatus_2,
nvkm_rd32(device, 0x400388));
}
nvkm_wr32(device, 0x100c80, 0x00000001);
nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x100c80) & 0x00000001))
break;
);
nvkm_mask(device, 0x400500, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&gr->lock, flags);
return timeout ? -EBUSY : 0;
}
static const struct nvkm_gr_func
g84_gr = {
.init = nv50_gr_init,
.intr = nv50_gr_intr,
.chan_new = nv50_gr_chan_new,
.tlb_flush = g84_gr_tlb_flush,
.units = nv50_gr_units,
.sclass = {
{ -1, -1, 0x0030, &nv50_gr_object },
{ -1, -1, 0x502d, &nv50_gr_object },
{ -1, -1, 0x5039, &nv50_gr_object },
{ -1, -1, 0x50c0, &nv50_gr_object },
{ -1, -1, 0x8297, &nv50_gr_object },
{}
}
};
int
g84_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv50_gr_new_(&g84_gr, device, index, pgr);
}
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#ifndef __NVC0_GR_H__ #ifndef __GF100_GR_H__
#define __NVC0_GR_H__ #define __GF100_GR_H__
#define gf100_gr(p) container_of((p), struct gf100_gr, base) #define gf100_gr(p) container_of((p), struct gf100_gr, base)
#include "priv.h" #include "priv.h"
...@@ -71,8 +71,8 @@ struct gf100_gr_zbc_depth { ...@@ -71,8 +71,8 @@ struct gf100_gr_zbc_depth {
}; };
struct gf100_gr { struct gf100_gr {
struct nvkm_gr base;
const struct gf100_gr_func *func; const struct gf100_gr_func *func;
struct nvkm_gr base;
struct gf100_gr_fuc fuc409c; struct gf100_gr_fuc fuc409c;
struct gf100_gr_fuc fuc409d; struct gf100_gr_fuc fuc409d;
...@@ -110,11 +110,40 @@ struct gf100_gr { ...@@ -110,11 +110,40 @@ struct gf100_gr {
u8 magic_not_rop_nr; u8 magic_not_rop_nr;
}; };
int gf100_gr_ctor(const struct gf100_gr_func *, struct nvkm_device *,
int, struct gf100_gr *);
int gf100_gr_new_(const struct gf100_gr_func *, struct nvkm_device *,
int, struct nvkm_gr **);
void *gf100_gr_dtor(struct nvkm_gr *);
struct gf100_gr_func { struct gf100_gr_func {
void (*dtor)(struct gf100_gr *);
int (*init)(struct gf100_gr *);
void (*init_gpc_mmu)(struct gf100_gr *);
void (*set_hww_esr_report_mask)(struct gf100_gr *);
const struct gf100_gr_pack *mmio;
struct {
struct gf100_gr_ucode *ucode;
} fecs;
struct {
struct gf100_gr_ucode *ucode;
} gpccs;
int ppc_nr;
const struct gf100_grctx_func *grctx; const struct gf100_grctx_func *grctx;
struct nvkm_sclass sclass[]; struct nvkm_sclass sclass[];
}; };
int gf100_gr_init(struct gf100_gr *);
int gk104_gr_init(struct gf100_gr *);
int gk20a_gr_new_(const struct gf100_gr_func *, struct nvkm_device *,
int, struct nvkm_gr **);
void gk20a_gr_dtor(struct gf100_gr *);
int gk20a_gr_init(struct gf100_gr *);
int gm204_gr_init(struct gf100_gr *);
#define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object) #define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object)
struct gf100_gr_chan { struct gf100_gr_chan {
...@@ -137,33 +166,10 @@ void gf100_gr_dtor_fw(struct gf100_gr_fuc *); ...@@ -137,33 +166,10 @@ void gf100_gr_dtor_fw(struct gf100_gr_fuc *);
int gf100_gr_ctor_fw(struct gf100_gr *, const char *, int gf100_gr_ctor_fw(struct gf100_gr *, const char *,
struct gf100_gr_fuc *); struct gf100_gr_fuc *);
u64 gf100_gr_units(struct nvkm_gr *); u64 gf100_gr_units(struct nvkm_gr *);
int gf100_gr_ctor(struct nvkm_object *, struct nvkm_object *,
struct nvkm_oclass *, void *data, u32 size,
struct nvkm_object **);
void gf100_gr_dtor(struct nvkm_object *);
int gf100_gr_init(struct nvkm_object *);
void gf100_gr_zbc_init(struct gf100_gr *); void gf100_gr_zbc_init(struct gf100_gr *);
int gk104_gr_ctor(struct nvkm_object *, struct nvkm_object *,
struct nvkm_oclass *, void *data, u32 size,
struct nvkm_object **);
int gk104_gr_init(struct nvkm_object *);
int gk20a_gr_ctor(struct nvkm_object *, struct nvkm_object *,
struct nvkm_oclass *, void *data, u32 size,
struct nvkm_object **);
void gk20a_gr_dtor(struct nvkm_object *);
int gk20a_gr_init(struct nvkm_object *);
int gm204_gr_init(struct nvkm_object *);
extern const struct nvkm_object_func gf100_fermi; extern const struct nvkm_object_func gf100_fermi;
extern struct nvkm_oclass gf100_gr_sclass[];
extern struct nvkm_oclass gf110_gr_sclass[];
extern struct nvkm_oclass gk110_gr_sclass[];
extern struct nvkm_oclass gm204_gr_sclass[];
struct gf100_gr_init { struct gf100_gr_init {
u32 addr; u32 addr;
u8 count; u8 count;
...@@ -191,19 +197,6 @@ extern struct gf100_gr_ucode gf100_gr_gpccs_ucode; ...@@ -191,19 +197,6 @@ extern struct gf100_gr_ucode gf100_gr_gpccs_ucode;
extern struct gf100_gr_ucode gk110_gr_fecs_ucode; extern struct gf100_gr_ucode gk110_gr_fecs_ucode;
extern struct gf100_gr_ucode gk110_gr_gpccs_ucode; extern struct gf100_gr_ucode gk110_gr_gpccs_ucode;
struct gf100_gr_oclass {
struct nvkm_oclass base;
const struct gf100_gr_func *func;
const struct gf100_gr_pack *mmio;
struct {
struct gf100_gr_ucode *ucode;
} fecs;
struct {
struct gf100_gr_ucode *ucode;
} gpccs;
int ppc_nr;
};
int gf100_gr_wait_idle(struct gf100_gr *); int gf100_gr_wait_idle(struct gf100_gr *);
void gf100_gr_mmio(struct gf100_gr *, const struct gf100_gr_pack *); void gf100_gr_mmio(struct gf100_gr *, const struct gf100_gr_pack *);
void gf100_gr_icmd(struct gf100_gr *, const struct gf100_gr_pack *); void gf100_gr_icmd(struct gf100_gr *, const struct gf100_gr_pack *);
......
...@@ -114,6 +114,10 @@ gf104_gr_pack_mmio[] = { ...@@ -114,6 +114,10 @@ gf104_gr_pack_mmio[] = {
static const struct gf100_gr_func static const struct gf100_gr_func
gf104_gr = { gf104_gr = {
.init = gf100_gr_init,
.mmio = gf104_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
.grctx = &gf104_grctx, .grctx = &gf104_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -124,17 +128,8 @@ gf104_gr = { ...@@ -124,17 +128,8 @@ gf104_gr = {
} }
}; };
struct nvkm_oclass * int
gf104_gr_oclass = &(struct gf100_gr_oclass) { gf104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0xc3), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gf104_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gf100_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gf104_gr,
.mmio = gf104_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
...@@ -105,6 +105,10 @@ gf108_gr_pack_mmio[] = { ...@@ -105,6 +105,10 @@ gf108_gr_pack_mmio[] = {
static const struct gf100_gr_func static const struct gf100_gr_func
gf108_gr = { gf108_gr = {
.init = gf100_gr_init,
.mmio = gf108_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
.grctx = &gf108_grctx, .grctx = &gf108_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -116,17 +120,8 @@ gf108_gr = { ...@@ -116,17 +120,8 @@ gf108_gr = {
} }
}; };
struct nvkm_oclass * int
gf108_gr_oclass = &(struct gf100_gr_oclass) { gf108_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0xc1), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gf108_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gf100_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gf108_gr,
.mmio = gf108_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
...@@ -86,6 +86,10 @@ gf110_gr_pack_mmio[] = { ...@@ -86,6 +86,10 @@ gf110_gr_pack_mmio[] = {
static const struct gf100_gr_func static const struct gf100_gr_func
gf110_gr = { gf110_gr = {
.init = gf100_gr_init,
.mmio = gf110_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
.grctx = &gf110_grctx, .grctx = &gf110_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -98,17 +102,8 @@ gf110_gr = { ...@@ -98,17 +102,8 @@ gf110_gr = {
} }
}; };
struct nvkm_oclass * int
gf110_gr_oclass = &(struct gf100_gr_oclass) { gf110_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0xc8), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gf110_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gf100_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gf110_gr,
.mmio = gf110_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
...@@ -122,6 +122,11 @@ gf117_gr_gpccs_ucode = { ...@@ -122,6 +122,11 @@ gf117_gr_gpccs_ucode = {
static const struct gf100_gr_func static const struct gf100_gr_func
gf117_gr = { gf117_gr = {
.init = gf100_gr_init,
.mmio = gf117_gr_pack_mmio,
.fecs.ucode = &gf117_gr_fecs_ucode,
.gpccs.ucode = &gf117_gr_gpccs_ucode,
.ppc_nr = 1,
.grctx = &gf117_grctx, .grctx = &gf117_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -134,18 +139,8 @@ gf117_gr = { ...@@ -134,18 +139,8 @@ gf117_gr = {
} }
}; };
struct nvkm_oclass * int
gf117_gr_oclass = &(struct gf100_gr_oclass) { gf117_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0xd7), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gf117_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gf100_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gf117_gr,
.mmio = gf117_gr_pack_mmio,
.fecs.ucode = &gf117_gr_fecs_ucode,
.gpccs.ucode = &gf117_gr_gpccs_ucode,
.ppc_nr = 1,
}.base;
...@@ -177,6 +177,10 @@ gf119_gr_pack_mmio[] = { ...@@ -177,6 +177,10 @@ gf119_gr_pack_mmio[] = {
static const struct gf100_gr_func static const struct gf100_gr_func
gf119_gr = { gf119_gr = {
.init = gf100_gr_init,
.mmio = gf119_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
.grctx = &gf119_grctx, .grctx = &gf119_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -189,17 +193,8 @@ gf119_gr = { ...@@ -189,17 +193,8 @@ gf119_gr = {
} }
}; };
struct nvkm_oclass * int
gf119_gr_oclass = &(struct gf100_gr_oclass) { gf119_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0xd9), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gf119_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gf100_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gf119_gr,
.mmio = gf119_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#include "gf100.h" #include "gf100.h"
#include "ctxgf100.h" #include "ctxgf100.h"
#include <subdev/pmu.h>
#include <nvif/class.h> #include <nvif/class.h>
/******************************************************************************* /*******************************************************************************
...@@ -180,22 +178,14 @@ gk104_gr_pack_mmio[] = { ...@@ -180,22 +178,14 @@ gk104_gr_pack_mmio[] = {
******************************************************************************/ ******************************************************************************/
int int
gk104_gr_init(struct nvkm_object *object) gk104_gr_init(struct gf100_gr *gr)
{ {
struct gf100_gr_oclass *oclass = (void *)object->oclass;
struct gf100_gr *gr = (void *)object;
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {}; u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX]; u8 tpcnr[GPC_MAX];
int gpc, tpc, rop; int gpc, tpc, rop;
int ret, i; int i;
nvkm_pmu_pgob(device->pmu, false);
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x08a4), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x08a4), 0x00000000);
...@@ -206,7 +196,7 @@ gk104_gr_init(struct nvkm_object *object) ...@@ -206,7 +196,7 @@ gk104_gr_init(struct nvkm_object *object)
nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8); nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8);
nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8); nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8);
gf100_gr_mmio(gr, oclass->mmio); gf100_gr_mmio(gr, gr->func->mmio);
nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001);
...@@ -296,28 +286,6 @@ gk104_gr_init(struct nvkm_object *object) ...@@ -296,28 +286,6 @@ gk104_gr_init(struct nvkm_object *object)
return gf100_gr_init_ctxctl(gr); return gf100_gr_init_ctxctl(gr);
} }
static const struct gf100_gr_func
gk104_gr = {
.grctx = &gk104_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
{ -1, -1, KEPLER_INLINE_TO_MEMORY_A },
{ -1, -1, KEPLER_A, &gf100_fermi },
{ -1, -1, KEPLER_COMPUTE_A },
{}
}
};
int
gk104_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
struct nvkm_device *device = (void *)parent;
nvkm_pmu_pgob(device->pmu, false);
return gf100_gr_ctor(parent, engine, oclass, data, size, pobject);
}
#include "fuc/hubgk104.fuc3.h" #include "fuc/hubgk104.fuc3.h"
static struct gf100_gr_ucode static struct gf100_gr_ucode
...@@ -338,18 +306,25 @@ gk104_gr_gpccs_ucode = { ...@@ -338,18 +306,25 @@ gk104_gr_gpccs_ucode = {
.data.size = sizeof(gk104_grgpc_data), .data.size = sizeof(gk104_grgpc_data),
}; };
struct nvkm_oclass * static const struct gf100_gr_func
gk104_gr_oclass = &(struct gf100_gr_oclass) { gk104_gr = {
.base.handle = NV_ENGINE(GR, 0xe4), .init = gk104_gr_init,
.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gk104_gr_ctor,
.dtor = gf100_gr_dtor,
.init = gk104_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gk104_gr,
.mmio = gk104_gr_pack_mmio, .mmio = gk104_gr_pack_mmio,
.fecs.ucode = &gk104_gr_fecs_ucode, .fecs.ucode = &gk104_gr_fecs_ucode,
.gpccs.ucode = &gk104_gr_gpccs_ucode, .gpccs.ucode = &gk104_gr_gpccs_ucode,
.ppc_nr = 1, .ppc_nr = 1,
}.base; .grctx = &gk104_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
{ -1, -1, KEPLER_INLINE_TO_MEMORY_A },
{ -1, -1, KEPLER_A, &gf100_fermi },
{ -1, -1, KEPLER_COMPUTE_A },
{}
}
};
int
gk104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk104_gr, device, index, pgr);
}
...@@ -182,6 +182,11 @@ gk110_gr_gpccs_ucode = { ...@@ -182,6 +182,11 @@ gk110_gr_gpccs_ucode = {
static const struct gf100_gr_func static const struct gf100_gr_func
gk110_gr = { gk110_gr = {
.init = gk104_gr_init,
.mmio = gk110_gr_pack_mmio,
.fecs.ucode = &gk110_gr_fecs_ucode,
.gpccs.ucode = &gk110_gr_gpccs_ucode,
.ppc_nr = 2,
.grctx = &gk110_grctx, .grctx = &gk110_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -192,18 +197,8 @@ gk110_gr = { ...@@ -192,18 +197,8 @@ gk110_gr = {
} }
}; };
struct nvkm_oclass * int
gk110_gr_oclass = &(struct gf100_gr_oclass) { gk110_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0xf0), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gk110_gr, device, index, pgr);
.ctor = gk104_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gk104_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gk110_gr,
.mmio = gk110_gr_pack_mmio,
.fecs.ucode = &gk110_gr_fecs_ucode,
.gpccs.ucode = &gk110_gr_gpccs_ucode,
.ppc_nr = 2,
}.base;
...@@ -102,6 +102,11 @@ gk110b_gr_pack_mmio[] = { ...@@ -102,6 +102,11 @@ gk110b_gr_pack_mmio[] = {
static const struct gf100_gr_func static const struct gf100_gr_func
gk110b_gr = { gk110b_gr = {
.init = gk104_gr_init,
.mmio = gk110b_gr_pack_mmio,
.fecs.ucode = &gk110_gr_fecs_ucode,
.gpccs.ucode = &gk110_gr_gpccs_ucode,
.ppc_nr = 2,
.grctx = &gk110b_grctx, .grctx = &gk110b_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -112,18 +117,8 @@ gk110b_gr = { ...@@ -112,18 +117,8 @@ gk110b_gr = {
} }
}; };
struct nvkm_oclass * int
gk110b_gr_oclass = &(struct gf100_gr_oclass) { gk110b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0xf1), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gk110b_gr, device, index, pgr);
.ctor = gk104_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gk104_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gk110b_gr,
.mmio = gk110b_gr_pack_mmio,
.fecs.ucode = &gk110_gr_fecs_ucode,
.gpccs.ucode = &gk110_gr_gpccs_ucode,
.ppc_nr = 2,
}.base;
...@@ -161,6 +161,11 @@ gk208_gr_gpccs_ucode = { ...@@ -161,6 +161,11 @@ gk208_gr_gpccs_ucode = {
static const struct gf100_gr_func static const struct gf100_gr_func
gk208_gr = { gk208_gr = {
.init = gk104_gr_init,
.mmio = gk208_gr_pack_mmio,
.fecs.ucode = &gk208_gr_fecs_ucode,
.gpccs.ucode = &gk208_gr_gpccs_ucode,
.ppc_nr = 1,
.grctx = &gk208_grctx, .grctx = &gk208_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -171,18 +176,8 @@ gk208_gr = { ...@@ -171,18 +176,8 @@ gk208_gr = {
} }
}; };
struct nvkm_oclass * int
gk208_gr_oclass = &(struct gf100_gr_oclass) { gk208_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0x08), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gk208_gr, device, index, pgr);
.ctor = gk104_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gk104_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gk208_gr,
.mmio = gk208_gr_pack_mmio,
.fecs.ucode = &gk208_gr_fecs_ucode,
.gpccs.ucode = &gk208_gr_gpccs_ucode,
.ppc_nr = 1,
}.base;
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*/ */
#include "gk20a.h" #include "gf100.h"
#include "ctxgf100.h" #include "ctxgf100.h"
#include <subdev/timer.h> #include <subdev/timer.h>
...@@ -146,69 +146,6 @@ gk20a_gr_av_to_method(struct gf100_gr_fuc *fuc) ...@@ -146,69 +146,6 @@ gk20a_gr_av_to_method(struct gf100_gr_fuc *fuc)
return pack; return pack;
} }
int
gk20a_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
int err;
struct gf100_gr *gr;
struct gf100_gr_fuc fuc;
err = gf100_gr_ctor(parent, engine, oclass, data, size, pobject);
if (err)
return err;
gr = (void *)*pobject;
err = gf100_gr_ctor_fw(gr, "sw_nonctx", &fuc);
if (err)
return err;
gr->fuc_sw_nonctx = gk20a_gr_av_to_init(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_sw_nonctx))
return PTR_ERR(gr->fuc_sw_nonctx);
err = gf100_gr_ctor_fw(gr, "sw_ctx", &fuc);
if (err)
return err;
gr->fuc_sw_ctx = gk20a_gr_aiv_to_init(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_sw_ctx))
return PTR_ERR(gr->fuc_sw_ctx);
err = gf100_gr_ctor_fw(gr, "sw_bundle_init", &fuc);
if (err)
return err;
gr->fuc_bundle = gk20a_gr_av_to_init(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_bundle))
return PTR_ERR(gr->fuc_bundle);
err = gf100_gr_ctor_fw(gr, "sw_method_init", &fuc);
if (err)
return err;
gr->fuc_method = gk20a_gr_av_to_method(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_method))
return PTR_ERR(gr->fuc_method);
return 0;
}
void
gk20a_gr_dtor(struct nvkm_object *object)
{
struct gf100_gr *gr = (void *)object;
gk20a_gr_init_dtor(gr->fuc_method);
gk20a_gr_init_dtor(gr->fuc_bundle);
gk20a_gr_init_dtor(gr->fuc_sw_ctx);
gk20a_gr_init_dtor(gr->fuc_sw_nonctx);
gf100_gr_dtor(object);
}
static int static int
gk20a_gr_wait_mem_scrubbing(struct gf100_gr *gr) gk20a_gr_wait_mem_scrubbing(struct gf100_gr *gr)
{ {
...@@ -243,10 +180,8 @@ gk20a_gr_set_hww_esr_report_mask(struct gf100_gr *gr) ...@@ -243,10 +180,8 @@ gk20a_gr_set_hww_esr_report_mask(struct gf100_gr *gr)
} }
int int
gk20a_gr_init(struct nvkm_object *object) gk20a_gr_init(struct gf100_gr *gr)
{ {
struct gk20a_gr_oclass *oclass = (void *)object->oclass;
struct gf100_gr *gr = (void *)object;
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {}; u32 data[TPC_MAX / 8] = {};
...@@ -254,10 +189,6 @@ gk20a_gr_init(struct nvkm_object *object) ...@@ -254,10 +189,6 @@ gk20a_gr_init(struct nvkm_object *object)
int gpc, tpc; int gpc, tpc;
int ret, i; int ret, i;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
/* Clear SCC RAM */ /* Clear SCC RAM */
nvkm_wr32(device, 0x40802c, 0x1); nvkm_wr32(device, 0x40802c, 0x1);
...@@ -275,8 +206,8 @@ gk20a_gr_init(struct nvkm_object *object) ...@@ -275,8 +206,8 @@ gk20a_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(gr->unk4188b4) >> 8); nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(gr->unk4188b4) >> 8);
nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8); nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8);
if (oclass->init_gpc_mmu) if (gr->func->init_gpc_mmu)
oclass->init_gpc_mmu(gr); gr->func->init_gpc_mmu(gr);
/* Set the PE as stream master */ /* Set the PE as stream master */
nvkm_mask(device, 0x503018, 0x1, 0x1); nvkm_mask(device, 0x503018, 0x1, 0x1);
...@@ -322,8 +253,8 @@ gk20a_gr_init(struct nvkm_object *object) ...@@ -322,8 +253,8 @@ gk20a_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404000, 0xc0000000);
nvkm_wr32(device, 0x404600, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000);
if (oclass->set_hww_esr_report_mask) if (gr->func->set_hww_esr_report_mask)
oclass->set_hww_esr_report_mask(gr); gr->func->set_hww_esr_report_mask(gr);
/* Enable TPC exceptions per GPC */ /* Enable TPC exceptions per GPC */
nvkm_wr32(device, 0x419d0c, 0x2); nvkm_wr32(device, 0x419d0c, 0x2);
...@@ -342,8 +273,72 @@ gk20a_gr_init(struct nvkm_object *object) ...@@ -342,8 +273,72 @@ gk20a_gr_init(struct nvkm_object *object)
return gf100_gr_init_ctxctl(gr); return gf100_gr_init_ctxctl(gr);
} }
void
gk20a_gr_dtor(struct gf100_gr *gr)
{
gk20a_gr_init_dtor(gr->fuc_method);
gk20a_gr_init_dtor(gr->fuc_bundle);
gk20a_gr_init_dtor(gr->fuc_sw_ctx);
gk20a_gr_init_dtor(gr->fuc_sw_nonctx);
}
int
gk20a_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
int index, struct nvkm_gr **pgr)
{
struct gf100_gr_fuc fuc;
struct gf100_gr *gr;
int ret;
if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
return -ENOMEM;
*pgr = &gr->base;
ret = gf100_gr_ctor(func, device, index, gr);
if (ret)
return ret;
ret = gf100_gr_ctor_fw(gr, "sw_nonctx", &fuc);
if (ret)
return ret;
gr->fuc_sw_nonctx = gk20a_gr_av_to_init(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_sw_nonctx))
return PTR_ERR(gr->fuc_sw_nonctx);
ret = gf100_gr_ctor_fw(gr, "sw_ctx", &fuc);
if (ret)
return ret;
gr->fuc_sw_ctx = gk20a_gr_aiv_to_init(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_sw_ctx))
return PTR_ERR(gr->fuc_sw_ctx);
ret = gf100_gr_ctor_fw(gr, "sw_bundle_init", &fuc);
if (ret)
return ret;
gr->fuc_bundle = gk20a_gr_av_to_init(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_bundle))
return PTR_ERR(gr->fuc_bundle);
ret = gf100_gr_ctor_fw(gr, "sw_method_init", &fuc);
if (ret)
return ret;
gr->fuc_method = gk20a_gr_av_to_method(&fuc);
gf100_gr_dtor_fw(&fuc);
if (IS_ERR(gr->fuc_method))
return PTR_ERR(gr->fuc_method);
return 0;
}
static const struct gf100_gr_func static const struct gf100_gr_func
gk20a_gr = { gk20a_gr = {
.dtor = gk20a_gr_dtor,
.init = gk20a_gr_init,
.set_hww_esr_report_mask = gk20a_gr_set_hww_esr_report_mask,
.ppc_nr = 1,
.grctx = &gk20a_grctx, .grctx = &gk20a_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -354,18 +349,8 @@ gk20a_gr = { ...@@ -354,18 +349,8 @@ gk20a_gr = {
} }
}; };
struct nvkm_oclass * int
gk20a_gr_oclass = &(struct gk20a_gr_oclass) { gk20a_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.gf100 = { {
.base.handle = NV_ENGINE(GR, 0xea), return gk20a_gr_new_(&gk20a_gr, device, index, pgr);
.base.ofuncs = &(struct nvkm_ofuncs) { }
.ctor = gk20a_gr_ctor,
.dtor = gk20a_gr_dtor,
.init = gk20a_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gk20a_gr,
.ppc_nr = 1,
},
.set_hww_esr_report_mask = gk20a_gr_set_hww_esr_report_mask,
}.gf100.base;
...@@ -308,20 +308,14 @@ gm107_gr_init_bios(struct gf100_gr *gr) ...@@ -308,20 +308,14 @@ gm107_gr_init_bios(struct gf100_gr *gr)
} }
int int
gm107_gr_init(struct nvkm_object *object) gm107_gr_init(struct gf100_gr *gr)
{ {
struct gf100_gr_oclass *oclass = (void *)object->oclass;
struct gf100_gr *gr = (void *)object;
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {}; u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX]; u8 tpcnr[GPC_MAX];
int gpc, tpc, ppc, rop; int gpc, tpc, ppc, rop;
int ret, i; int i;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000);
...@@ -329,7 +323,7 @@ gm107_gr_init(struct nvkm_object *object) ...@@ -329,7 +323,7 @@ gm107_gr_init(struct nvkm_object *object)
nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8); nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8);
nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8); nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8);
gf100_gr_mmio(gr, oclass->mmio); gf100_gr_mmio(gr, gr->func->mmio);
gm107_gr_init_bios(gr); gm107_gr_init_bios(gr);
...@@ -443,6 +437,11 @@ gm107_gr_gpccs_ucode = { ...@@ -443,6 +437,11 @@ gm107_gr_gpccs_ucode = {
static const struct gf100_gr_func static const struct gf100_gr_func
gm107_gr = { gm107_gr = {
.init = gm107_gr_init,
.mmio = gm107_gr_pack_mmio,
.fecs.ucode = &gm107_gr_fecs_ucode,
.gpccs.ucode = &gm107_gr_gpccs_ucode,
.ppc_nr = 2,
.grctx = &gm107_grctx, .grctx = &gm107_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -453,18 +452,8 @@ gm107_gr = { ...@@ -453,18 +452,8 @@ gm107_gr = {
} }
}; };
struct nvkm_oclass * int
gm107_gr_oclass = &(struct gf100_gr_oclass) { gm107_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0x07), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gm107_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gm107_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gm107_gr,
.mmio = gm107_gr_pack_mmio,
.fecs.ucode = &gm107_gr_fecs_ucode,
.gpccs.ucode = &gm107_gr_gpccs_ucode,
.ppc_nr = 2,
}.base;
...@@ -236,21 +236,14 @@ gm204_gr_init_ctxctl(struct gf100_gr *gr) ...@@ -236,21 +236,14 @@ gm204_gr_init_ctxctl(struct gf100_gr *gr)
} }
int int
gm204_gr_init(struct nvkm_object *object) gm204_gr_init(struct gf100_gr *gr)
{ {
struct gf100_gr_oclass *oclass = (void *)object->oclass;
struct gf100_gr *gr = (void *)object;
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {}; u32 data[TPC_MAX / 8] = {}, tmp;
u8 tpcnr[GPC_MAX]; u8 tpcnr[GPC_MAX];
int gpc, tpc, ppc, rop; int gpc, tpc, ppc, rop;
int ret, i; int i;
u32 tmp;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
tmp = nvkm_rd32(device, 0x100c80); /*XXX: mask? */ tmp = nvkm_rd32(device, 0x100c80); /*XXX: mask? */
nvkm_wr32(device, 0x418880, 0x00001000 | (tmp & 0x00000fff)); nvkm_wr32(device, 0x418880, 0x00001000 | (tmp & 0x00000fff));
...@@ -265,7 +258,7 @@ gm204_gr_init(struct nvkm_object *object) ...@@ -265,7 +258,7 @@ gm204_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8); nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8);
nvkm_mask(device, 0x100cc4, 0x00040000, 0x00040000); nvkm_mask(device, 0x100cc4, 0x00040000, 0x00040000);
gf100_gr_mmio(gr, oclass->mmio); gf100_gr_mmio(gr, gr->func->mmio);
gm107_gr_init_bios(gr); gm107_gr_init_bios(gr);
...@@ -360,6 +353,9 @@ gm204_gr_init(struct nvkm_object *object) ...@@ -360,6 +353,9 @@ gm204_gr_init(struct nvkm_object *object)
static const struct gf100_gr_func static const struct gf100_gr_func
gm204_gr = { gm204_gr = {
.init = gm204_gr_init,
.mmio = gm204_gr_pack_mmio,
.ppc_nr = 2,
.grctx = &gm204_grctx, .grctx = &gm204_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -370,16 +366,8 @@ gm204_gr = { ...@@ -370,16 +366,8 @@ gm204_gr = {
} }
}; };
struct nvkm_oclass * int
gm204_gr_oclass = &(struct gf100_gr_oclass) { gm204_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0x24), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gm204_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gm204_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gm204_gr,
.mmio = gm204_gr_pack_mmio,
.ppc_nr = 2,
}.base;
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
static const struct gf100_gr_func static const struct gf100_gr_func
gm206_gr = { gm206_gr = {
.init = gm204_gr_init,
.mmio = gm204_gr_pack_mmio,
.ppc_nr = 2,
.grctx = &gm206_grctx, .grctx = &gm206_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -38,16 +41,8 @@ gm206_gr = { ...@@ -38,16 +41,8 @@ gm206_gr = {
} }
}; };
struct nvkm_oclass * int
gm206_gr_oclass = &(struct gf100_gr_oclass) { gm206_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.base.handle = NV_ENGINE(GR, 0x26), {
.base.ofuncs = &(struct nvkm_ofuncs) { return gf100_gr_new_(&gm206_gr, device, index, pgr);
.ctor = gf100_gr_ctor, }
.dtor = gf100_gr_dtor,
.init = gm204_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gm206_gr,
.mmio = gm204_gr_pack_mmio,
.ppc_nr = 2,
}.base;
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*/ */
#include "gk20a.h" #include "gf100.h"
#include "ctxgf100.h" #include "ctxgf100.h"
#include <subdev/timer.h> #include <subdev/timer.h>
...@@ -61,6 +61,11 @@ gm20b_gr_set_hww_esr_report_mask(struct gf100_gr *gr) ...@@ -61,6 +61,11 @@ gm20b_gr_set_hww_esr_report_mask(struct gf100_gr *gr)
static const struct gf100_gr_func static const struct gf100_gr_func
gm20b_gr = { gm20b_gr = {
.dtor = gk20a_gr_dtor,
.init = gk20a_gr_init,
.init_gpc_mmu = gm20b_gr_init_gpc_mmu,
.set_hww_esr_report_mask = gm20b_gr_set_hww_esr_report_mask,
.ppc_nr = 1,
.grctx = &gm20b_grctx, .grctx = &gm20b_grctx,
.sclass = { .sclass = {
{ -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_TWOD_A },
...@@ -71,19 +76,8 @@ gm20b_gr = { ...@@ -71,19 +76,8 @@ gm20b_gr = {
} }
}; };
struct nvkm_oclass * int
gm20b_gr_oclass = &(struct gk20a_gr_oclass) { gm20b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
.gf100 = { {
.base.handle = NV_ENGINE(GR, 0x2b), return gk20a_gr_new_(&gm20b_gr, device, index, pgr);
.base.ofuncs = &(struct nvkm_ofuncs) { }
.ctor = gk20a_gr_ctor,
.dtor = gf100_gr_dtor,
.init = gk20a_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gm20b_gr,
.ppc_nr = 1,
},
.init_gpc_mmu = gm20b_gr_init_gpc_mmu,
.set_hww_esr_report_mask = gm20b_gr_set_hww_esr_report_mask,
}.gf100.base;
/*
* Copyright 2012 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 "nv50.h"
static const struct nvkm_gr_func
gt200_gr = {
.init = nv50_gr_init,
.intr = nv50_gr_intr,
.chan_new = nv50_gr_chan_new,
.tlb_flush = g84_gr_tlb_flush,
.units = nv50_gr_units,
.sclass = {
{ -1, -1, 0x0030, &nv50_gr_object },
{ -1, -1, 0x502d, &nv50_gr_object },
{ -1, -1, 0x5039, &nv50_gr_object },
{ -1, -1, 0x50c0, &nv50_gr_object },
{ -1, -1, 0x8397, &nv50_gr_object },
{}
}
};
int
gt200_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv50_gr_new_(&gt200_gr, device, index, pgr);
}
/*
* Copyright 2012 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 "nv50.h"
static const struct nvkm_gr_func
gt215_gr = {
.init = nv50_gr_init,
.intr = nv50_gr_intr,
.chan_new = nv50_gr_chan_new,
.tlb_flush = g84_gr_tlb_flush,
.units = nv50_gr_units,
.sclass = {
{ -1, -1, 0x0030, &nv50_gr_object },
{ -1, -1, 0x502d, &nv50_gr_object },
{ -1, -1, 0x5039, &nv50_gr_object },
{ -1, -1, 0x50c0, &nv50_gr_object },
{ -1, -1, 0x8597, &nv50_gr_object },
{ -1, -1, 0x85c0, &nv50_gr_object },
{}
}
};
int
gt215_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv50_gr_new_(&gt215_gr, device, index, pgr);
}
/* /*
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. * Copyright 2012 Red Hat Inc.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
...@@ -14,22 +14,33 @@ ...@@ -14,22 +14,33 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/ */
#include "nv50.h"
#ifndef __GK20A_GR_H__ static const struct nvkm_gr_func
#define __GK20A_GR_H__ mcp79_gr = {
.init = nv50_gr_init,
#include "gf100.h" .intr = nv50_gr_intr,
.chan_new = nv50_gr_chan_new,
struct gk20a_gr_oclass { .units = nv50_gr_units,
struct gf100_gr_oclass gf100; .sclass = {
{ -1, -1, 0x0030, &nv50_gr_object },
void (*init_gpc_mmu)(struct gf100_gr *); { -1, -1, 0x502d, &nv50_gr_object },
void (*set_hww_esr_report_mask)(struct gf100_gr *); { -1, -1, 0x5039, &nv50_gr_object },
{ -1, -1, 0x50c0, &nv50_gr_object },
{ -1, -1, 0x8397, &nv50_gr_object },
{}
}
}; };
#endif int
mcp79_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv50_gr_new_(&mcp79_gr, device, index, pgr);
}
/*
* Copyright 2012 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 "nv50.h"
static const struct nvkm_gr_func
mcp89_gr = {
.init = nv50_gr_init,
.intr = nv50_gr_intr,
.chan_new = nv50_gr_chan_new,
.tlb_flush = g84_gr_tlb_flush,
.units = nv50_gr_units,
.sclass = {
{ -1, -1, 0x0030, &nv50_gr_object },
{ -1, -1, 0x502d, &nv50_gr_object },
{ -1, -1, 0x5039, &nv50_gr_object },
{ -1, -1, 0x50c0, &nv50_gr_object },
{ -1, -1, 0x85c0, &nv50_gr_object },
{ -1, -1, 0x8697, &nv50_gr_object },
{}
}
};
int
mcp89_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv50_gr_new_(&mcp89_gr, device, index, pgr);
}
...@@ -1269,11 +1269,11 @@ nv04_gr_nsource[] = { ...@@ -1269,11 +1269,11 @@ nv04_gr_nsource[] = {
}; };
static void static void
nv04_gr_intr(struct nvkm_subdev *subdev) nv04_gr_intr(struct nvkm_gr *base)
{ {
struct nv04_gr *gr = (void *)subdev; struct nv04_gr *gr = nv04_gr(base);
struct nv04_gr_chan *chan = NULL; struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = subdev->device;
u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR); u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE); u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
u32 nstatus = nvkm_rd32(device, NV03_PGRAPH_NSTATUS); u32 nstatus = nvkm_rd32(device, NV03_PGRAPH_NSTATUS);
...@@ -1286,6 +1286,7 @@ nv04_gr_intr(struct nvkm_subdev *subdev) ...@@ -1286,6 +1286,7 @@ nv04_gr_intr(struct nvkm_subdev *subdev)
u32 inst = (nvkm_rd32(device, 0x40016c) & 0xffff) << 4; u32 inst = (nvkm_rd32(device, 0x40016c) & 0xffff) << 4;
u32 show = stat; u32 show = stat;
char msg[128], src[128], sta[128]; char msg[128], src[128], sta[128];
struct nv04_gr_chan *chan;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&gr->lock, flags); spin_lock_irqsave(&gr->lock, flags);
...@@ -1323,8 +1324,47 @@ nv04_gr_intr(struct nvkm_subdev *subdev) ...@@ -1323,8 +1324,47 @@ nv04_gr_intr(struct nvkm_subdev *subdev)
spin_unlock_irqrestore(&gr->lock, flags); spin_unlock_irqrestore(&gr->lock, flags);
} }
static int
nv04_gr_init(struct nvkm_gr *base)
{
struct nv04_gr *gr = nv04_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device;
/* Enable PGRAPH interrupts */
nvkm_wr32(device, NV03_PGRAPH_INTR, 0xFFFFFFFF);
nvkm_wr32(device, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
nvkm_wr32(device, NV04_PGRAPH_VALID1, 0);
nvkm_wr32(device, NV04_PGRAPH_VALID2, 0);
/*nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x000001FF);
nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x1231c000);
/*1231C000 blob, 001 haiku*/
/*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_1, 0x72111100);
/*0x72111100 blob , 01 haiku*/
/*nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
/*haiku same*/
/*nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
/*haiku and blob 10d4*/
nvkm_wr32(device, NV04_PGRAPH_STATE , 0xFFFFFFFF);
nvkm_wr32(device, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
nvkm_mask(device, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000);
/* These don't belong here, they're part of a per-channel context */
nvkm_wr32(device, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
nvkm_wr32(device, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
return 0;
}
static const struct nvkm_gr_func static const struct nvkm_gr_func
nv04_gr = { nv04_gr = {
.init = nv04_gr_init,
.intr = nv04_gr_intr,
.chan_new = nv04_gr_chan_new, .chan_new = nv04_gr_chan_new,
.sclass = { .sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */ { -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
...@@ -1372,76 +1412,16 @@ nv04_gr = { ...@@ -1372,76 +1412,16 @@ nv04_gr = {
} }
}; };
static int int
nv04_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, nv04_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{ {
struct nv04_gr *gr; struct nv04_gr *gr;
int ret;
ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
*pobject = nv_object(gr);
if (ret)
return ret;
gr->base.func = &nv04_gr; if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
nv_subdev(gr)->unit = 0x00001000; return -ENOMEM;
nv_subdev(gr)->intr = nv04_gr_intr;
spin_lock_init(&gr->lock); spin_lock_init(&gr->lock);
return 0; *pgr = &gr->base;
}
static int return nvkm_gr_ctor(&nv04_gr, device, index, 0x00001000,
nv04_gr_init(struct nvkm_object *object) true, &gr->base);
{
struct nvkm_engine *engine = nv_engine(object);
struct nv04_gr *gr = (void *)engine;
struct nvkm_device *device = gr->base.engine.subdev.device;
int ret;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
/* Enable PGRAPH interrupts */
nvkm_wr32(device, NV03_PGRAPH_INTR, 0xFFFFFFFF);
nvkm_wr32(device, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
nvkm_wr32(device, NV04_PGRAPH_VALID1, 0);
nvkm_wr32(device, NV04_PGRAPH_VALID2, 0);
/*nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x000001FF);
nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x1231c000);
/*1231C000 blob, 001 haiku*/
/*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_1, 0x72111100);
/*0x72111100 blob , 01 haiku*/
/*nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
/*haiku same*/
/*nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
/*haiku and blob 10d4*/
nvkm_wr32(device, NV04_PGRAPH_STATE , 0xFFFFFFFF);
nvkm_wr32(device, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
nvkm_mask(device, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000);
/* These don't belong here, they're part of a per-channel context */
nvkm_wr32(device, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
nvkm_wr32(device, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
return 0;
} }
struct nvkm_oclass
nv04_gr_oclass = {
.handle = NV_ENGINE(GR, 0x04),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_gr_ctor,
.dtor = _nvkm_gr_dtor,
.init = nv04_gr_init,
.fini = _nvkm_gr_fini,
},
};
#ifndef __NV10_GR_H__
#define __NV10_GR_H__
#include "priv.h"
int nv10_gr_new_(const struct nvkm_gr_func *, struct nvkm_device *, int index,
struct nvkm_gr **);
int nv10_gr_init(struct nvkm_gr *);
void nv10_gr_intr(struct nvkm_gr *);
void nv10_gr_tile(struct nvkm_gr *, int, struct nvkm_fb_tile *);
int nv10_gr_chan_new(struct nvkm_gr *, struct nvkm_fifo_chan *,
const struct nvkm_oclass *, struct nvkm_object **);
#endif
/*
* Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
* All Rights Reserved.
*
* 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 (including the next
* paragr) 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
* PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
*/
#include "nv10.h"
static const struct nvkm_gr_func
nv15_gr = {
.init = nv10_gr_init,
.intr = nv10_gr_intr,
.tile = nv10_gr_tile,
.chan_new = nv10_gr_chan_new,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
{ -1, -1, 0x0019, &nv04_gr_object }, /* clip */
{ -1, -1, 0x0030, &nv04_gr_object }, /* null */
{ -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */
{ -1, -1, 0x0043, &nv04_gr_object }, /* rop */
{ -1, -1, 0x0044, &nv04_gr_object }, /* pattern */
{ -1, -1, 0x004a, &nv04_gr_object }, /* gdi */
{ -1, -1, 0x0052, &nv04_gr_object }, /* swzsurf */
{ -1, -1, 0x005f, &nv04_gr_object }, /* blit */
{ -1, -1, 0x0062, &nv04_gr_object }, /* surf2d */
{ -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */
{ -1, -1, 0x0089, &nv04_gr_object }, /* sifm */
{ -1, -1, 0x008a, &nv04_gr_object }, /* ifc */
{ -1, -1, 0x009f, &nv04_gr_object }, /* blit */
{ -1, -1, 0x0093, &nv04_gr_object }, /* surf3d */
{ -1, -1, 0x0094, &nv04_gr_object }, /* ttri */
{ -1, -1, 0x0095, &nv04_gr_object }, /* mtri */
{ -1, -1, 0x0096, &nv04_gr_object }, /* celcius */
{}
}
};
int
nv15_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv10_gr_new_(&nv15_gr, device, index, pgr);
}
/*
* Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
* All Rights Reserved.
*
* 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 (including the next
* paragr) 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
* PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
*/
#include "nv10.h"
static const struct nvkm_gr_func
nv17_gr = {
.init = nv10_gr_init,
.intr = nv10_gr_intr,
.tile = nv10_gr_tile,
.chan_new = nv10_gr_chan_new,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
{ -1, -1, 0x0019, &nv04_gr_object }, /* clip */
{ -1, -1, 0x0030, &nv04_gr_object }, /* null */
{ -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */
{ -1, -1, 0x0043, &nv04_gr_object }, /* rop */
{ -1, -1, 0x0044, &nv04_gr_object }, /* pattern */
{ -1, -1, 0x004a, &nv04_gr_object }, /* gdi */
{ -1, -1, 0x0052, &nv04_gr_object }, /* swzsurf */
{ -1, -1, 0x005f, &nv04_gr_object }, /* blit */
{ -1, -1, 0x0062, &nv04_gr_object }, /* surf2d */
{ -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */
{ -1, -1, 0x0089, &nv04_gr_object }, /* sifm */
{ -1, -1, 0x008a, &nv04_gr_object }, /* ifc */
{ -1, -1, 0x009f, &nv04_gr_object }, /* blit */
{ -1, -1, 0x0093, &nv04_gr_object }, /* surf3d */
{ -1, -1, 0x0094, &nv04_gr_object }, /* ttri */
{ -1, -1, 0x0095, &nv04_gr_object }, /* mtri */
{ -1, -1, 0x0099, &nv04_gr_object },
{}
}
};
int
nv17_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv10_gr_new_(&nv17_gr, device, index, pgr);
}
...@@ -145,12 +145,11 @@ nv20_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, ...@@ -145,12 +145,11 @@ nv20_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
******************************************************************************/ ******************************************************************************/
void void
nv20_gr_tile_prog(struct nvkm_engine *engine, int i) nv20_gr_tile(struct nvkm_gr *base, int i, struct nvkm_fb_tile *tile)
{ {
struct nv20_gr *gr = (void *)engine; struct nv20_gr *gr = nv20_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
struct nvkm_fifo *fifo = device->fifo; struct nvkm_fifo *fifo = device->fifo;
struct nvkm_fb_tile *tile = &device->fb->tile.region[i];
unsigned long flags; unsigned long flags;
nvkm_fifo_pause(fifo, &flags); nvkm_fifo_pause(fifo, &flags);
...@@ -167,7 +166,7 @@ nv20_gr_tile_prog(struct nvkm_engine *engine, int i) ...@@ -167,7 +166,7 @@ nv20_gr_tile_prog(struct nvkm_engine *engine, int i)
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i);
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, tile->addr); nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, tile->addr);
if (nv_device(engine)->chipset != 0x34) { if (device->chipset != 0x34) {
nvkm_wr32(device, NV20_PGRAPH_ZCOMP(i), tile->zcomp); nvkm_wr32(device, NV20_PGRAPH_ZCOMP(i), tile->zcomp);
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i);
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, tile->zcomp); nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, tile->zcomp);
...@@ -177,10 +176,11 @@ nv20_gr_tile_prog(struct nvkm_engine *engine, int i) ...@@ -177,10 +176,11 @@ nv20_gr_tile_prog(struct nvkm_engine *engine, int i)
} }
void void
nv20_gr_intr(struct nvkm_subdev *subdev) nv20_gr_intr(struct nvkm_gr *base)
{ {
struct nv20_gr *gr = (void *)subdev; struct nv20_gr *gr = nv20_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_fifo_chan *chan; struct nvkm_fifo_chan *chan;
u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR); u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE); u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
...@@ -215,82 +215,27 @@ nv20_gr_intr(struct nvkm_subdev *subdev) ...@@ -215,82 +215,27 @@ nv20_gr_intr(struct nvkm_subdev *subdev)
nvkm_fifo_chan_put(device->fifo, flags, &chan); nvkm_fifo_chan_put(device->fifo, flags, &chan);
} }
static const struct nvkm_gr_func int
nv20_gr = { nv20_gr_oneinit(struct nvkm_gr *base)
.chan_new = nv20_gr_chan_new,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
{ -1, -1, 0x0019, &nv04_gr_object }, /* clip */
{ -1, -1, 0x0030, &nv04_gr_object }, /* null */
{ -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */
{ -1, -1, 0x0043, &nv04_gr_object }, /* rop */
{ -1, -1, 0x0044, &nv04_gr_object }, /* patt */
{ -1, -1, 0x004a, &nv04_gr_object }, /* gdi */
{ -1, -1, 0x0062, &nv04_gr_object }, /* surf2d */
{ -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */
{ -1, -1, 0x0089, &nv04_gr_object }, /* sifm */
{ -1, -1, 0x008a, &nv04_gr_object }, /* ifc */
{ -1, -1, 0x0096, &nv04_gr_object }, /* celcius */
{ -1, -1, 0x0097, &nv04_gr_object }, /* kelvin */
{ -1, -1, 0x009e, &nv04_gr_object }, /* swzsurf */
{ -1, -1, 0x009f, &nv04_gr_object }, /* imageblit */
{}
}
};
static int
nv20_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
struct nvkm_device *device = (void *)parent;
struct nv20_gr *gr;
int ret;
ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
*pobject = nv_object(gr);
if (ret)
return ret;
gr->base.func = &nv20_gr;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 32 * 4, 16, true,
&gr->ctxtab);
if (ret)
return ret;
nv_subdev(gr)->unit = 0x00001000;
nv_subdev(gr)->intr = nv20_gr_intr;
nv_engine(gr)->tile_prog = nv20_gr_tile_prog;
return 0;
}
void
nv20_gr_dtor(struct nvkm_object *object)
{ {
struct nv20_gr *gr = (void *)object; struct nv20_gr *gr = nv20_gr(base);
nvkm_memory_del(&gr->ctxtab); return nvkm_memory_new(gr->base.engine.subdev.device,
nvkm_gr_destroy(&gr->base); NVKM_MEM_TARGET_INST, 32 * 4, 16,
true, &gr->ctxtab);
} }
int int
nv20_gr_init(struct nvkm_object *object) nv20_gr_init(struct nvkm_gr *base)
{ {
struct nvkm_engine *engine = nv_engine(object); struct nv20_gr *gr = nv20_gr(base);
struct nv20_gr *gr = (void *)engine;
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
struct nvkm_fb *fb = device->fb;
u32 tmp, vramsz; u32 tmp, vramsz;
int ret, i; int i;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
nvkm_wr32(device, NV20_PGRAPH_CHANNEL_CTX_TABLE, nvkm_wr32(device, NV20_PGRAPH_CHANNEL_CTX_TABLE,
nvkm_memory_addr(gr->ctxtab) >> 4); nvkm_memory_addr(gr->ctxtab) >> 4);
if (nv_device(gr)->chipset == 0x20) { if (device->chipset == 0x20) {
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x003d0000); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x003d0000);
for (i = 0; i < 15; i++) for (i = 0; i < 15; i++)
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, 0x00000000); nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, 0x00000000);
...@@ -318,7 +263,7 @@ nv20_gr_init(struct nvkm_object *object) ...@@ -318,7 +263,7 @@ nv20_gr_init(struct nvkm_object *object)
nvkm_wr32(device, NV10_PGRAPH_DEBUG_4, 0x00000000); nvkm_wr32(device, NV10_PGRAPH_DEBUG_4, 0x00000000);
nvkm_wr32(device, 0x40009C , 0x00000040); nvkm_wr32(device, 0x40009C , 0x00000040);
if (nv_device(gr)->chipset >= 0x25) { if (device->chipset >= 0x25) {
nvkm_wr32(device, 0x400890, 0x00a8cfff); nvkm_wr32(device, 0x400890, 0x00a8cfff);
nvkm_wr32(device, 0x400610, 0x304B1FB6); nvkm_wr32(device, 0x400610, 0x304B1FB6);
nvkm_wr32(device, 0x400B80, 0x1cbd3883); nvkm_wr32(device, 0x400B80, 0x1cbd3883);
...@@ -338,10 +283,6 @@ nv20_gr_init(struct nvkm_object *object) ...@@ -338,10 +283,6 @@ nv20_gr_init(struct nvkm_object *object)
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA , 0x00000030); nvkm_wr32(device, NV10_PGRAPH_RDI_DATA , 0x00000030);
} }
/* Turn all the tiling regions off. */
for (i = 0; i < fb->tile.regions; i++)
engine->tile_prog(engine, i);
nvkm_wr32(device, 0x4009a0, nvkm_rd32(device, 0x100324)); nvkm_wr32(device, 0x4009a0, nvkm_rd32(device, 0x100324));
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA000C); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, nvkm_rd32(device, 0x100324)); nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, nvkm_rd32(device, 0x100324));
...@@ -355,7 +296,7 @@ nv20_gr_init(struct nvkm_object *object) ...@@ -355,7 +296,7 @@ nv20_gr_init(struct nvkm_object *object)
nvkm_wr32(device, NV10_PGRAPH_SURFACE, tmp); nvkm_wr32(device, NV10_PGRAPH_SURFACE, tmp);
/* begin RAM config */ /* begin RAM config */
vramsz = nv_device_resource_len(nv_device(gr), 1) - 1; vramsz = nv_device_resource_len(device, 1) - 1;
nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200)); nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200));
nvkm_wr32(device, 0x4009A8, nvkm_rd32(device, 0x100204)); nvkm_wr32(device, 0x4009A8, nvkm_rd32(device, 0x100204));
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
...@@ -378,13 +319,57 @@ nv20_gr_init(struct nvkm_object *object) ...@@ -378,13 +319,57 @@ nv20_gr_init(struct nvkm_object *object)
return 0; return 0;
} }
struct nvkm_oclass void *
nv20_gr_oclass = { nv20_gr_dtor(struct nvkm_gr *base)
.handle = NV_ENGINE(GR, 0x20), {
.ofuncs = &(struct nvkm_ofuncs) { struct nv20_gr *gr = nv20_gr(base);
.ctor = nv20_gr_ctor, nvkm_memory_del(&gr->ctxtab);
.dtor = nv20_gr_dtor, return gr;
.init = nv20_gr_init, }
.fini = _nvkm_gr_fini,
}, int
nv20_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
int index, struct nvkm_gr **pgr)
{
struct nv20_gr *gr;
if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
return -ENOMEM;
*pgr = &gr->base;
return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base);
}
static const struct nvkm_gr_func
nv20_gr = {
.dtor = nv20_gr_dtor,
.oneinit = nv20_gr_oneinit,
.init = nv20_gr_init,
.intr = nv20_gr_intr,
.tile = nv20_gr_tile,
.chan_new = nv20_gr_chan_new,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
{ -1, -1, 0x0019, &nv04_gr_object }, /* clip */
{ -1, -1, 0x0030, &nv04_gr_object }, /* null */
{ -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */
{ -1, -1, 0x0043, &nv04_gr_object }, /* rop */
{ -1, -1, 0x0044, &nv04_gr_object }, /* patt */
{ -1, -1, 0x004a, &nv04_gr_object }, /* gdi */
{ -1, -1, 0x0062, &nv04_gr_object }, /* surf2d */
{ -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */
{ -1, -1, 0x0089, &nv04_gr_object }, /* sifm */
{ -1, -1, 0x008a, &nv04_gr_object }, /* ifc */
{ -1, -1, 0x0096, &nv04_gr_object }, /* celcius */
{ -1, -1, 0x0097, &nv04_gr_object }, /* kelvin */
{ -1, -1, 0x009e, &nv04_gr_object }, /* swzsurf */
{ -1, -1, 0x009f, &nv04_gr_object }, /* imageblit */
{}
}
}; };
int
nv20_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv20_gr_new_(&nv20_gr, device, index, pgr);
}
...@@ -8,6 +8,16 @@ struct nv20_gr { ...@@ -8,6 +8,16 @@ struct nv20_gr {
struct nvkm_memory *ctxtab; struct nvkm_memory *ctxtab;
}; };
int nv20_gr_new_(const struct nvkm_gr_func *, struct nvkm_device *,
int, struct nvkm_gr **);
void *nv20_gr_dtor(struct nvkm_gr *);
int nv20_gr_oneinit(struct nvkm_gr *);
int nv20_gr_init(struct nvkm_gr *);
void nv20_gr_intr(struct nvkm_gr *);
void nv20_gr_tile(struct nvkm_gr *, int, struct nvkm_fb_tile *);
int nv30_gr_init(struct nvkm_gr *);
#define nv20_gr_chan(p) container_of((p), struct nv20_gr_chan, object) #define nv20_gr_chan(p) container_of((p), struct nv20_gr_chan, object)
struct nv20_gr_chan { struct nv20_gr_chan {
...@@ -18,14 +28,6 @@ struct nv20_gr_chan { ...@@ -18,14 +28,6 @@ struct nv20_gr_chan {
}; };
void *nv20_gr_chan_dtor(struct nvkm_object *); void *nv20_gr_chan_dtor(struct nvkm_object *);
int nv20_gr_chan_init(struct nvkm_object *); int nv20_gr_chan_init(struct nvkm_object *);
int nv20_gr_chan_fini(struct nvkm_object *, bool); int nv20_gr_chan_fini(struct nvkm_object *, bool);
void nv20_gr_tile_prog(struct nvkm_engine *, int);
void nv20_gr_intr(struct nvkm_subdev *);
void nv20_gr_dtor(struct nvkm_object *);
int nv20_gr_init(struct nvkm_object *);
int nv30_gr_init(struct nvkm_object *);
#endif #endif
...@@ -101,6 +101,11 @@ nv25_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, ...@@ -101,6 +101,11 @@ nv25_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
static const struct nvkm_gr_func static const struct nvkm_gr_func
nv25_gr = { nv25_gr = {
.dtor = nv20_gr_dtor,
.oneinit = nv20_gr_oneinit,
.init = nv20_gr_init,
.intr = nv20_gr_intr,
.tile = nv20_gr_tile,
.chan_new = nv25_gr_chan_new, .chan_new = nv25_gr_chan_new,
.sclass = { .sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */ { -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
...@@ -122,40 +127,8 @@ nv25_gr = { ...@@ -122,40 +127,8 @@ nv25_gr = {
} }
}; };
static int int
nv25_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, nv25_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{ {
struct nvkm_device *device = (void *)parent; return nv20_gr_new_(&nv25_gr, device, index, pgr);
struct nv20_gr *gr;
int ret;
ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
*pobject = nv_object(gr);
if (ret)
return ret;
gr->base.func = &nv25_gr;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 32 * 4, 16, true,
&gr->ctxtab);
if (ret)
return ret;
nv_subdev(gr)->unit = 0x00001000;
nv_subdev(gr)->intr = nv20_gr_intr;
nv_engine(gr)->tile_prog = nv20_gr_tile_prog;
return 0;
} }
struct nvkm_oclass
nv25_gr_oclass = {
.handle = NV_ENGINE(GR, 0x25),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv25_gr_ctor,
.dtor = nv20_gr_dtor,
.init = nv20_gr_init,
.fini = _nvkm_gr_fini,
},
};
...@@ -92,6 +92,11 @@ nv2a_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, ...@@ -92,6 +92,11 @@ nv2a_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
static const struct nvkm_gr_func static const struct nvkm_gr_func
nv2a_gr = { nv2a_gr = {
.dtor = nv20_gr_dtor,
.oneinit = nv20_gr_oneinit,
.init = nv20_gr_init,
.intr = nv20_gr_intr,
.tile = nv20_gr_tile,
.chan_new = nv2a_gr_chan_new, .chan_new = nv2a_gr_chan_new,
.sclass = { .sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */ { -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
...@@ -113,40 +118,8 @@ nv2a_gr = { ...@@ -113,40 +118,8 @@ nv2a_gr = {
} }
}; };
static int int
nv2a_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, nv2a_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{ {
struct nvkm_device *device = (void *)parent; return nv20_gr_new_(&nv2a_gr, device, index, pgr);
struct nv20_gr *gr;
int ret;
ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
*pobject = nv_object(gr);
if (ret)
return ret;
gr->base.func = &nv2a_gr;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 32 * 4, 16, true,
&gr->ctxtab);
if (ret)
return ret;
nv_subdev(gr)->unit = 0x00001000;
nv_subdev(gr)->intr = nv20_gr_intr;
nv_engine(gr)->tile_prog = nv20_gr_tile_prog;
return 0;
} }
struct nvkm_oclass
nv2a_gr_oclass = {
.handle = NV_ENGINE(GR, 0x2a),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv2a_gr_ctor,
.dtor = nv20_gr_dtor,
.init = nv20_gr_init,
.fini = _nvkm_gr_fini,
},
};
...@@ -99,70 +99,11 @@ nv30_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, ...@@ -99,70 +99,11 @@ nv30_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
* PGRAPH engine/subdev functions * PGRAPH engine/subdev functions
******************************************************************************/ ******************************************************************************/
static const struct nvkm_gr_func
nv30_gr = {
.chan_new = nv30_gr_chan_new,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
{ -1, -1, 0x0019, &nv04_gr_object }, /* clip */
{ -1, -1, 0x0030, &nv04_gr_object }, /* null */
{ -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */
{ -1, -1, 0x0043, &nv04_gr_object }, /* rop */
{ -1, -1, 0x0044, &nv04_gr_object }, /* patt */
{ -1, -1, 0x004a, &nv04_gr_object }, /* gdi */
{ -1, -1, 0x0062, &nv04_gr_object }, /* surf2d */
{ -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */
{ -1, -1, 0x0089, &nv04_gr_object }, /* sifm */
{ -1, -1, 0x008a, &nv04_gr_object }, /* ifc */
{ -1, -1, 0x009f, &nv04_gr_object }, /* imageblit */
{ -1, -1, 0x0362, &nv04_gr_object }, /* surf2d (nv30) */
{ -1, -1, 0x0389, &nv04_gr_object }, /* sifm (nv30) */
{ -1, -1, 0x038a, &nv04_gr_object }, /* ifc (nv30) */
{ -1, -1, 0x039e, &nv04_gr_object }, /* swzsurf (nv30) */
{ -1, -1, 0x0397, &nv04_gr_object }, /* rankine */
{}
}
};
static int
nv30_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
struct nvkm_device *device = (void *)parent;
struct nv20_gr *gr;
int ret;
ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
*pobject = nv_object(gr);
if (ret)
return ret;
gr->base.func = &nv30_gr;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 32 * 4, 16, true,
&gr->ctxtab);
if (ret)
return ret;
nv_subdev(gr)->unit = 0x00001000;
nv_subdev(gr)->intr = nv20_gr_intr;
nv_engine(gr)->tile_prog = nv20_gr_tile_prog;
return 0;
}
int int
nv30_gr_init(struct nvkm_object *object) nv30_gr_init(struct nvkm_gr *base)
{ {
struct nvkm_engine *engine = nv_engine(object); struct nv20_gr *gr = nv20_gr(base);
struct nv20_gr *gr = (void *)engine;
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
struct nvkm_fb *fb = device->fb;
int ret, i;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
nvkm_wr32(device, NV20_PGRAPH_CHANNEL_CTX_TABLE, nvkm_wr32(device, NV20_PGRAPH_CHANNEL_CTX_TABLE,
nvkm_memory_addr(gr->ctxtab) >> 4); nvkm_memory_addr(gr->ctxtab) >> 4);
...@@ -189,7 +130,7 @@ nv30_gr_init(struct nvkm_object *object) ...@@ -189,7 +130,7 @@ nv30_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x400ba4, 0x00231f3f); nvkm_wr32(device, 0x400ba4, 0x00231f3f);
nvkm_wr32(device, 0x4008a4, 0x40000020); nvkm_wr32(device, 0x4008a4, 0x40000020);
if (nv_device(gr)->chipset == 0x34) { if (device->chipset == 0x34) {
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0004); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA , 0x00200201); nvkm_wr32(device, NV10_PGRAPH_RDI_DATA , 0x00200201);
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0008); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0008);
...@@ -202,10 +143,6 @@ nv30_gr_init(struct nvkm_object *object) ...@@ -202,10 +143,6 @@ nv30_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x4000c0, 0x00000016); nvkm_wr32(device, 0x4000c0, 0x00000016);
/* Turn all the tiling regions off. */
for (i = 0; i < fb->tile.regions; i++)
engine->tile_prog(engine, i);
nvkm_wr32(device, NV10_PGRAPH_CTX_CONTROL, 0x10000100); nvkm_wr32(device, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
nvkm_wr32(device, NV10_PGRAPH_STATE , 0xFFFFFFFF); nvkm_wr32(device, NV10_PGRAPH_STATE , 0xFFFFFFFF);
nvkm_wr32(device, 0x0040075c , 0x00000001); nvkm_wr32(device, 0x0040075c , 0x00000001);
...@@ -214,22 +151,48 @@ nv30_gr_init(struct nvkm_object *object) ...@@ -214,22 +151,48 @@ nv30_gr_init(struct nvkm_object *object)
/* vramsz = pci_resource_len(gr->dev->pdev, 1) - 1; */ /* vramsz = pci_resource_len(gr->dev->pdev, 1) - 1; */
nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200)); nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200));
nvkm_wr32(device, 0x4009A8, nvkm_rd32(device, 0x100204)); nvkm_wr32(device, 0x4009A8, nvkm_rd32(device, 0x100204));
if (nv_device(gr)->chipset != 0x34) { if (device->chipset != 0x34) {
nvkm_wr32(device, 0x400750, 0x00EA0000); nvkm_wr32(device, 0x400750, 0x00EA0000);
nvkm_wr32(device, 0x400754, nvkm_rd32(device, 0x100200)); nvkm_wr32(device, 0x400754, nvkm_rd32(device, 0x100200));
nvkm_wr32(device, 0x400750, 0x00EA0004); nvkm_wr32(device, 0x400750, 0x00EA0004);
nvkm_wr32(device, 0x400754, nvkm_rd32(device, 0x100204)); nvkm_wr32(device, 0x400754, nvkm_rd32(device, 0x100204));
} }
return 0; return 0;
} }
struct nvkm_oclass static const struct nvkm_gr_func
nv30_gr_oclass = { nv30_gr = {
.handle = NV_ENGINE(GR, 0x30), .dtor = nv20_gr_dtor,
.ofuncs = &(struct nvkm_ofuncs) { .oneinit = nv20_gr_oneinit,
.ctor = nv30_gr_ctor, .init = nv30_gr_init,
.dtor = nv20_gr_dtor, .intr = nv20_gr_intr,
.init = nv30_gr_init, .tile = nv20_gr_tile,
.fini = _nvkm_gr_fini, .chan_new = nv30_gr_chan_new,
}, .sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
{ -1, -1, 0x0019, &nv04_gr_object }, /* clip */
{ -1, -1, 0x0030, &nv04_gr_object }, /* null */
{ -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */
{ -1, -1, 0x0043, &nv04_gr_object }, /* rop */
{ -1, -1, 0x0044, &nv04_gr_object }, /* patt */
{ -1, -1, 0x004a, &nv04_gr_object }, /* gdi */
{ -1, -1, 0x0062, &nv04_gr_object }, /* surf2d */
{ -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */
{ -1, -1, 0x0089, &nv04_gr_object }, /* sifm */
{ -1, -1, 0x008a, &nv04_gr_object }, /* ifc */
{ -1, -1, 0x009f, &nv04_gr_object }, /* imageblit */
{ -1, -1, 0x0362, &nv04_gr_object }, /* surf2d (nv30) */
{ -1, -1, 0x0389, &nv04_gr_object }, /* sifm (nv30) */
{ -1, -1, 0x038a, &nv04_gr_object }, /* ifc (nv30) */
{ -1, -1, 0x039e, &nv04_gr_object }, /* swzsurf (nv30) */
{ -1, -1, 0x0397, &nv04_gr_object }, /* rankine */
{}
}
}; };
int
nv30_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv20_gr_new_(&nv30_gr, device, index, pgr);
}
...@@ -100,6 +100,11 @@ nv34_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, ...@@ -100,6 +100,11 @@ nv34_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
static const struct nvkm_gr_func static const struct nvkm_gr_func
nv34_gr = { nv34_gr = {
.dtor = nv20_gr_dtor,
.oneinit = nv20_gr_oneinit,
.init = nv30_gr_init,
.intr = nv20_gr_intr,
.tile = nv20_gr_tile,
.chan_new = nv34_gr_chan_new, .chan_new = nv34_gr_chan_new,
.sclass = { .sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */ { -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
...@@ -123,40 +128,8 @@ nv34_gr = { ...@@ -123,40 +128,8 @@ nv34_gr = {
} }
}; };
static int int
nv34_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, nv34_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{ {
struct nvkm_device *device = (void *)parent; return nv20_gr_new_(&nv34_gr, device, index, pgr);
struct nv20_gr *gr;
int ret;
ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
*pobject = nv_object(gr);
if (ret)
return ret;
gr->base.func = &nv34_gr;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 32 * 4, 16, true,
&gr->ctxtab);
if (ret)
return ret;
nv_subdev(gr)->unit = 0x00001000;
nv_subdev(gr)->intr = nv20_gr_intr;
nv_engine(gr)->tile_prog = nv20_gr_tile_prog;
return 0;
} }
struct nvkm_oclass
nv34_gr_oclass = {
.handle = NV_ENGINE(GR, 0x34),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv34_gr_ctor,
.dtor = nv20_gr_dtor,
.init = nv30_gr_init,
.fini = _nvkm_gr_fini,
},
};
...@@ -100,6 +100,11 @@ nv35_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, ...@@ -100,6 +100,11 @@ nv35_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
static const struct nvkm_gr_func static const struct nvkm_gr_func
nv35_gr = { nv35_gr = {
.dtor = nv20_gr_dtor,
.oneinit = nv20_gr_oneinit,
.init = nv30_gr_init,
.intr = nv20_gr_intr,
.tile = nv20_gr_tile,
.chan_new = nv35_gr_chan_new, .chan_new = nv35_gr_chan_new,
.sclass = { .sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */ { -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
...@@ -123,40 +128,8 @@ nv35_gr = { ...@@ -123,40 +128,8 @@ nv35_gr = {
} }
}; };
static int int
nv35_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, nv35_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{ {
struct nvkm_device *device = (void *)parent; return nv20_gr_new_(&nv35_gr, device, index, pgr);
struct nv20_gr *gr;
int ret;
ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
*pobject = nv_object(gr);
if (ret)
return ret;
gr->base.func = &nv35_gr;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 32 * 4, 16, true,
&gr->ctxtab);
if (ret)
return ret;
nv_subdev(gr)->unit = 0x00001000;
nv_subdev(gr)->intr = nv20_gr_intr;
nv_engine(gr)->tile_prog = nv20_gr_tile_prog;
return 0;
} }
struct nvkm_oclass
nv35_gr_oclass = {
.handle = NV_ENGINE(GR, 0x35),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv35_gr_ctor,
.dtor = nv20_gr_dtor,
.init = nv30_gr_init,
.fini = _nvkm_gr_fini,
},
};
...@@ -9,6 +9,12 @@ struct nv40_gr { ...@@ -9,6 +9,12 @@ struct nv40_gr {
struct list_head chan; struct list_head chan;
}; };
int nv40_gr_new_(const struct nvkm_gr_func *, struct nvkm_device *, int index,
struct nvkm_gr **);
int nv40_gr_init(struct nvkm_gr *);
void nv40_gr_intr(struct nvkm_gr *);
u64 nv40_gr_units(struct nvkm_gr *);
#define nv40_gr_chan(p) container_of((p), struct nv40_gr_chan, object) #define nv40_gr_chan(p) container_of((p), struct nv40_gr_chan, object)
struct nv40_gr_chan { struct nv40_gr_chan {
...@@ -19,6 +25,11 @@ struct nv40_gr_chan { ...@@ -19,6 +25,11 @@ struct nv40_gr_chan {
struct list_head head; struct list_head head;
}; };
int nv40_gr_chan_new(struct nvkm_gr *, struct nvkm_fifo_chan *,
const struct nvkm_oclass *, struct nvkm_object **);
extern const struct nvkm_object_func nv40_gr_object;
/* returns 1 if device is one of the nv4x using the 0x4497 object class, /* returns 1 if device is one of the nv4x using the 0x4497 object class,
* helpful to determine a number of other hardware features * helpful to determine a number of other hardware features
*/ */
...@@ -28,7 +39,7 @@ nv44_gr_class(struct nvkm_device *device) ...@@ -28,7 +39,7 @@ nv44_gr_class(struct nvkm_device *device)
if ((device->chipset & 0xf0) == 0x60) if ((device->chipset & 0xf0) == 0x60)
return 1; return 1;
return !(0x0baf & (1 << (device->chipset & 0x0f))); return !(0x0aaf & (1 << (device->chipset & 0x0f)));
} }
int nv40_grctx_init(struct nvkm_device *, u32 *size); int nv40_grctx_init(struct nvkm_device *, u32 *size);
......
/*
* Copyright 2012 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 "nv40.h"
#include "regs.h"
#include <subdev/fb.h>
#include <engine/fifo.h>
static void
nv44_gr_tile(struct nvkm_gr *base, int i, struct nvkm_fb_tile *tile)
{
struct nv40_gr *gr = nv40_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device;
struct nvkm_fifo *fifo = device->fifo;
unsigned long flags;
nvkm_fifo_pause(fifo, &flags);
nv04_gr_idle(&gr->base);
switch (device->chipset) {
case 0x44:
case 0x4a:
nvkm_wr32(device, NV20_PGRAPH_TSIZE(i), tile->pitch);
nvkm_wr32(device, NV20_PGRAPH_TLIMIT(i), tile->limit);
nvkm_wr32(device, NV20_PGRAPH_TILE(i), tile->addr);
break;
case 0x46:
case 0x4c:
case 0x63:
case 0x67:
case 0x68:
nvkm_wr32(device, NV47_PGRAPH_TSIZE(i), tile->pitch);
nvkm_wr32(device, NV47_PGRAPH_TLIMIT(i), tile->limit);
nvkm_wr32(device, NV47_PGRAPH_TILE(i), tile->addr);
nvkm_wr32(device, NV40_PGRAPH_TSIZE1(i), tile->pitch);
nvkm_wr32(device, NV40_PGRAPH_TLIMIT1(i), tile->limit);
nvkm_wr32(device, NV40_PGRAPH_TILE1(i), tile->addr);
break;
case 0x4e:
nvkm_wr32(device, NV20_PGRAPH_TSIZE(i), tile->pitch);
nvkm_wr32(device, NV20_PGRAPH_TLIMIT(i), tile->limit);
nvkm_wr32(device, NV20_PGRAPH_TILE(i), tile->addr);
nvkm_wr32(device, NV40_PGRAPH_TSIZE1(i), tile->pitch);
nvkm_wr32(device, NV40_PGRAPH_TLIMIT1(i), tile->limit);
nvkm_wr32(device, NV40_PGRAPH_TILE1(i), tile->addr);
break;
default:
WARN_ON(1);
break;
}
nvkm_fifo_start(fifo, &flags);
}
static const struct nvkm_gr_func
nv44_gr = {
.init = nv40_gr_init,
.intr = nv40_gr_intr,
.tile = nv44_gr_tile,
.units = nv40_gr_units,
.chan_new = nv40_gr_chan_new,
.sclass = {
{ -1, -1, 0x0012, &nv40_gr_object }, /* beta1 */
{ -1, -1, 0x0019, &nv40_gr_object }, /* clip */
{ -1, -1, 0x0030, &nv40_gr_object }, /* null */
{ -1, -1, 0x0039, &nv40_gr_object }, /* m2mf */
{ -1, -1, 0x0043, &nv40_gr_object }, /* rop */
{ -1, -1, 0x0044, &nv40_gr_object }, /* patt */
{ -1, -1, 0x004a, &nv40_gr_object }, /* gdi */
{ -1, -1, 0x0062, &nv40_gr_object }, /* surf2d */
{ -1, -1, 0x0072, &nv40_gr_object }, /* beta4 */
{ -1, -1, 0x0089, &nv40_gr_object }, /* sifm */
{ -1, -1, 0x008a, &nv40_gr_object }, /* ifc */
{ -1, -1, 0x009f, &nv40_gr_object }, /* imageblit */
{ -1, -1, 0x3062, &nv40_gr_object }, /* surf2d (nv40) */
{ -1, -1, 0x3089, &nv40_gr_object }, /* sifm (nv40) */
{ -1, -1, 0x309e, &nv40_gr_object }, /* swzsurf (nv40) */
{ -1, -1, 0x4497, &nv40_gr_object }, /* curie */
{}
}
};
int
nv44_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return nv40_gr_new_(&nv44_gr, device, index, pgr);
}
...@@ -10,10 +10,13 @@ struct nv50_gr { ...@@ -10,10 +10,13 @@ struct nv50_gr {
u32 size; u32 size;
}; };
struct nv50_gr_func { int nv50_gr_new_(const struct nvkm_gr_func *, struct nvkm_device *, int index,
void *(*dtor)(struct nv50_gr *); struct nvkm_gr **);
struct nvkm_sclass sclass[]; int nv50_gr_init(struct nvkm_gr *);
}; void nv50_gr_intr(struct nvkm_gr *);
u64 nv50_gr_units(struct nvkm_gr *);
int g84_gr_tlb_flush(struct nvkm_gr *);
#define nv50_gr_chan(p) container_of((p), struct nv50_gr_chan, object) #define nv50_gr_chan(p) container_of((p), struct nv50_gr_chan, object)
...@@ -22,6 +25,11 @@ struct nv50_gr_chan { ...@@ -22,6 +25,11 @@ struct nv50_gr_chan {
struct nv50_gr *gr; struct nv50_gr *gr;
}; };
int nv50_gr_chan_new(struct nvkm_gr *, struct nvkm_fifo_chan *,
const struct nvkm_oclass *, struct nvkm_object **);
extern const struct nvkm_object_func nv50_gr_object;
int nv50_grctx_init(struct nvkm_device *, u32 *size); int nv50_grctx_init(struct nvkm_device *, u32 *size);
void nv50_grctx_fill(struct nvkm_device *, struct nvkm_gpuobj *); void nv50_grctx_fill(struct nvkm_device *, struct nvkm_gpuobj *);
#endif #endif
...@@ -2,14 +2,37 @@ ...@@ -2,14 +2,37 @@
#define __NVKM_GR_PRIV_H__ #define __NVKM_GR_PRIV_H__
#define nvkm_gr(p) container_of((p), struct nvkm_gr, engine) #define nvkm_gr(p) container_of((p), struct nvkm_gr, engine)
#include <engine/gr.h> #include <engine/gr.h>
#include <core/enum.h>
struct nvkm_fb_tile;
struct nvkm_fifo_chan; struct nvkm_fifo_chan;
int nvkm_gr_ctor(const struct nvkm_gr_func *, struct nvkm_device *,
int index, u32 pmc_enable, bool enable,
struct nvkm_gr *);
bool nv04_gr_idle(struct nvkm_gr *);
struct nvkm_gr_func { struct nvkm_gr_func {
void *(*dtor)(struct nvkm_gr *);
int (*oneinit)(struct nvkm_gr *);
int (*init)(struct nvkm_gr *);
void (*intr)(struct nvkm_gr *);
void (*tile)(struct nvkm_gr *, int region, struct nvkm_fb_tile *);
int (*tlb_flush)(struct nvkm_gr *);
int (*chan_new)(struct nvkm_gr *, struct nvkm_fifo_chan *, int (*chan_new)(struct nvkm_gr *, struct nvkm_fifo_chan *,
const struct nvkm_oclass *, struct nvkm_object **); const struct nvkm_oclass *, struct nvkm_object **);
int (*object_get)(struct nvkm_gr *, int, struct nvkm_sclass *); int (*object_get)(struct nvkm_gr *, int, struct nvkm_sclass *);
/* Returns chipset-specific counts of units packed into an u64.
*/
u64 (*units)(struct nvkm_gr *);
struct nvkm_sclass sclass[]; struct nvkm_sclass sclass[];
}; };
extern const struct nvkm_bitfield nv04_gr_nsource[];
extern const struct nvkm_object_func nv04_gr_object; extern const struct nvkm_object_func nv04_gr_object;
extern const struct nvkm_bitfield nv10_gr_intr_name[];
extern const struct nvkm_bitfield nv10_gr_nstatus[];
extern const struct nvkm_enum nv50_data_error_names[];
#endif #endif
...@@ -52,11 +52,13 @@ void ...@@ -52,11 +52,13 @@ void
nvkm_fb_tile_prog(struct nvkm_fb *fb, int region, struct nvkm_fb_tile *tile) nvkm_fb_tile_prog(struct nvkm_fb *fb, int region, struct nvkm_fb_tile *tile)
{ {
struct nvkm_device *device = fb->subdev.device; struct nvkm_device *device = fb->subdev.device;
fb->func->tile.prog(fb, region, tile); if (fb->func->tile.prog) {
if (likely(device->gr)) fb->func->tile.prog(fb, region, tile);
device->gr->engine.tile_prog(&device->gr->engine, region); if (device->gr)
if (likely(device->mpeg)) nvkm_engine_tile(&device->gr->engine, region);
device->mpeg->tile_prog(device->mpeg, region); if (likely(device->mpeg))
device->mpeg->tile_prog(device->mpeg, region);
}
} }
int int
......
...@@ -23,11 +23,10 @@ ...@@ -23,11 +23,10 @@
*/ */
#include "priv.h" #include "priv.h"
#include <core/gpuobj.h>
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <engine/gr.h>
#include <core/engine.h>
#include <core/gpuobj.h>
static void static void
nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]) nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2])
...@@ -167,13 +166,10 @@ nv50_vm_flush(struct nvkm_vm *vm) ...@@ -167,13 +166,10 @@ nv50_vm_flush(struct nvkm_vm *vm)
continue; continue;
/* unfortunate hw bug workaround... */ /* unfortunate hw bug workaround... */
if (i == NVDEV_ENGINE_GR) { if (i == NVDEV_ENGINE_GR && device->gr) {
struct nvkm_engine *engine = int ret = nvkm_gr_tlb_flush(device->gr);
nvkm_device_engine(device, i); if (ret != -ENODEV)
if (engine && engine->tlb_flush) {
engine->tlb_flush(engine);
continue; continue;
}
} }
switch (i) { switch (i) {
......
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