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 @@
#include <core/subdev.h>
struct nvkm_device_oclass; /*XXX: DEV!ENG */
struct nvkm_fifo_chan;
struct nvkm_fb_tile;
#define NV_ENGINE_(eng,var) (((var) << 8) | (eng))
#define NV_ENGINE(name,var) NV_ENGINE_(NVDEV_ENGINE_##name, (var))
......@@ -20,7 +21,6 @@ struct nvkm_engine {
spinlock_t lock;
void (*tile_prog)(struct nvkm_engine *, int region);
int (*tlb_flush)(struct nvkm_engine *);
};
struct nvkm_engine_func {
......@@ -29,6 +29,7 @@ struct nvkm_engine_func {
int (*init)(struct nvkm_engine *);
int (*fini)(struct nvkm_engine *, bool suspend);
void (*intr)(struct nvkm_engine *);
void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
struct {
int (*sclass)(struct nvkm_oclass *, int index,
......@@ -54,6 +55,7 @@ int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *,
struct nvkm_engine **);
struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *);
void nvkm_engine_unref(struct nvkm_engine **);
void nvkm_engine_tile(struct nvkm_engine *, int region);
static inline struct nvkm_engine *
nv_engine(void *obj)
......
......@@ -3,64 +3,44 @@
#include <core/engine.h>
struct nvkm_gr {
struct nvkm_engine engine;
const struct nvkm_gr_func *func;
/* Returns chipset-specific counts of units packed into an u64.
*/
u64 (*units)(struct nvkm_gr *);
struct nvkm_engine engine;
};
#define nvkm_gr_create(p,e,c,y,d) \
nvkm_gr_create_((p), (e), (c), (y), sizeof(**d), (void **)(d))
int
nvkm_gr_create_(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, bool enable,
int length, void **pobject);
#define nvkm_gr_destroy(d) \
nvkm_engine_destroy(&(d)->engine)
#define nvkm_gr_init(d) \
nvkm_engine_init_old(&(d)->engine)
#define nvkm_gr_fini(d,s) \
nvkm_engine_fini_old(&(d)->engine, (s))
#define _nvkm_gr_dtor _nvkm_engine_dtor
#define _nvkm_gr_init _nvkm_engine_init
#define _nvkm_gr_fini _nvkm_engine_fini
extern struct nvkm_oclass nv04_gr_oclass;
extern struct nvkm_oclass nv10_gr_oclass;
extern struct nvkm_oclass nv20_gr_oclass;
extern struct nvkm_oclass nv25_gr_oclass;
extern struct nvkm_oclass nv2a_gr_oclass;
extern struct nvkm_oclass nv30_gr_oclass;
extern struct nvkm_oclass nv34_gr_oclass;
extern struct nvkm_oclass nv35_gr_oclass;
extern struct nvkm_oclass nv40_gr_oclass;
extern struct nvkm_oclass nv50_gr_oclass;
extern struct nvkm_oclass *gf100_gr_oclass;
extern struct nvkm_oclass *gf108_gr_oclass;
extern struct nvkm_oclass *gf104_gr_oclass;
extern struct nvkm_oclass *gf110_gr_oclass;
extern struct nvkm_oclass *gf117_gr_oclass;
extern struct nvkm_oclass *gf119_gr_oclass;
extern struct nvkm_oclass *gk104_gr_oclass;
extern struct nvkm_oclass *gk20a_gr_oclass;
extern struct nvkm_oclass *gk110_gr_oclass;
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[];
u64 nvkm_gr_units(struct nvkm_gr *);
int nvkm_gr_tlb_flush(struct nvkm_gr *);
int nv04_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv15_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv17_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv20_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv25_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv2a_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv30_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv34_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv35_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv40_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv44_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv50_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int g84_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gt200_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int mcp79_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gt215_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int mcp89_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gf100_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gf104_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gf108_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gf110_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gf117_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gf119_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gk104_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gk110_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gk110b_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gk208_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gk20a_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm107_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm204_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm206_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm20b_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#endif
......@@ -215,7 +215,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
getparam->value = 1;
break;
case NOUVEAU_GETPARAM_GRAPH_UNITS:
getparam->value = gr->units ? gr->units(gr) : 0;
getparam->value = nvkm_gr_units(gr);
break;
default:
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,
{
struct nouveau_drm *drm = nouveau_drm(dev);
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];
nouveau_fence_unref(&reg->fence);
......
......@@ -25,6 +25,8 @@
#include <core/device.h>
#include <core/option.h>
#include <subdev/fb.h>
void
nvkm_engine_unref(struct nvkm_engine **pengine)
{
......@@ -56,6 +58,14 @@ nvkm_engine_ref(struct nvkm_engine *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
nvkm_engine_intr(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_subdev *subdev = &engine->subdev;
int ret = 0;
struct nvkm_fb *fb = subdev->device->fb;
int ret = 0, i;
s64 time;
if (!engine->usecount) {
......@@ -108,6 +119,8 @@ nvkm_engine_init(struct nvkm_subdev *obj)
if (engine->func->init)
ret = engine->func->init(engine);
for (i = 0; fb && i < fb->tile.regions; i++)
nvkm_engine_tile(engine, i);
return ret;
}
......
......@@ -29,47 +29,38 @@ gf100_identify(struct nvkm_device *device)
switch (device->chipset) {
case 0xc0:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf100_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xc4:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xc3:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xce:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xcf:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xc1:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf108_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf108_pm_oclass;
break;
case 0xc8:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf110_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xd9:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf119_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf117_pm_oclass;
break;
case 0xd7:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gf117_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf117_pm_oclass;
break;
default:
......
......@@ -29,41 +29,33 @@ gk104_identify(struct nvkm_device *device)
switch (device->chipset) {
case 0xe4:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break;
case 0xe7:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break;
case 0xe6:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break;
case 0xea:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk20a_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break;
case 0xf0:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk110_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
break;
case 0xf1:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk110b_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
break;
case 0x106:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk208_gr_oclass;
break;
case 0x108:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk208_gr_oclass;
break;
default:
return -EINVAL;
......
......@@ -32,7 +32,6 @@ gm100_identify(struct nvkm_device *device)
#if 0
#endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass;
#if 0
#endif
#if 0
......@@ -46,7 +45,6 @@ gm100_identify(struct nvkm_device *device)
#if 0
#endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm204_gr_oclass;
#if 0
#endif
break;
......@@ -58,14 +56,12 @@ gm100_identify(struct nvkm_device *device)
#if 0
#endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm206_gr_oclass;
#if 0
#endif
break;
case 0x12b:
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm20b_gr_oclass;
break;
default:
return -EINVAL;
......
......@@ -29,11 +29,9 @@ nv04_identify(struct nvkm_device *device)
switch (device->chipset) {
case 0x04:
device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_gr_oclass;
break;
case 0x05:
device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_gr_oclass;
break;
default:
return -EINVAL;
......
......@@ -28,35 +28,27 @@ nv10_identify(struct nvkm_device *device)
{
switch (device->chipset) {
case 0x10:
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
case 0x15:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
case 0x16:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
case 0x1a:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
case 0x11:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
case 0x17:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
case 0x1f:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
case 0x18:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
break;
default:
return -EINVAL;
......
......@@ -29,19 +29,15 @@ nv20_identify(struct nvkm_device *device)
switch (device->chipset) {
case 0x20:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv20_gr_oclass;
break;
case 0x25:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_gr_oclass;
break;
case 0x28:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_gr_oclass;
break;
case 0x2a:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv2a_gr_oclass;
break;
default:
return -EINVAL;
......
......@@ -29,25 +29,20 @@ nv30_identify(struct nvkm_device *device)
switch (device->chipset) {
case 0x30:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_gr_oclass;
break;
case 0x35:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_gr_oclass;
break;
case 0x31:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
break;
case 0x36:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
break;
case 0x34:
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv34_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
break;
default:
......
......@@ -29,97 +29,81 @@ nv40_identify(struct nvkm_device *device)
switch (device->chipset) {
case 0x40:
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_PM ] = nv40_pm_oclass;
break;
case 0x41:
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_PM ] = nv40_pm_oclass;
break;
case 0x42:
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_PM ] = nv40_pm_oclass;
break;
case 0x43:
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_PM ] = nv40_pm_oclass;
break;
case 0x45:
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_PM ] = nv40_pm_oclass;
break;
case 0x47:
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_PM ] = nv40_pm_oclass;
break;
case 0x49:
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_PM ] = nv40_pm_oclass;
break;
case 0x4b:
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_PM ] = nv40_pm_oclass;
break;
case 0x44:
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_PM ] = nv40_pm_oclass;
break;
case 0x46:
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_PM ] = nv40_pm_oclass;
break;
case 0x4a:
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_PM ] = nv40_pm_oclass;
break;
case 0x4c:
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_PM ] = nv40_pm_oclass;
break;
case 0x4e:
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_PM ] = nv40_pm_oclass;
break;
case 0x63:
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_PM ] = nv40_pm_oclass;
break;
case 0x67:
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_PM ] = nv40_pm_oclass;
break;
case 0x68:
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_PM ] = nv40_pm_oclass;
break;
......
......@@ -29,80 +29,66 @@ nv50_identify(struct nvkm_device *device)
switch (device->chipset) {
case 0x50:
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_PM ] = nv50_pm_oclass;
break;
case 0x84:
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_PM ] = g84_pm_oclass;
break;
case 0x86:
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_PM ] = g84_pm_oclass;
break;
case 0x92:
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_PM ] = g84_pm_oclass;
break;
case 0x94:
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_PM ] = g84_pm_oclass;
break;
case 0x96:
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_PM ] = g84_pm_oclass;
break;
case 0x98:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0xa0:
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_PM ] = gt200_pm_oclass;
break;
case 0xaa:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0xac:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0xa3:
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_PM ] = gt215_pm_oclass;
break;
case 0xa5:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break;
case 0xa8:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break;
case 0xaf:
device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break;
default:
......
nvkm-y += nvkm/engine/gr/base.o
nvkm-y += nvkm/engine/gr/nv04.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/nv25.o
nvkm-y += nvkm/engine/gr/nv2a.o
......@@ -8,18 +10,24 @@ nvkm-y += nvkm/engine/gr/nv30.o
nvkm-y += nvkm/engine/gr/nv34.o
nvkm-y += nvkm/engine/gr/nv35.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/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/gf108.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/gf117.o
nvkm-y += nvkm/engine/gr/gf119.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/gk110b.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/gm204.o
nvkm-y += nvkm/engine/gr/gm206.o
......@@ -28,16 +36,16 @@ nvkm-y += nvkm/engine/gr/gm20b.o
nvkm-y += nvkm/engine/gr/ctxnv40.o
nvkm-y += nvkm/engine/gr/ctxnv50.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/ctxgf108.o
nvkm-y += nvkm/engine/gr/ctxgf110.o
nvkm-y += nvkm/engine/gr/ctxgf117.o
nvkm-y += nvkm/engine/gr/ctxgf119.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/ctxgk110b.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/ctxgm204.o
nvkm-y += nvkm/engine/gr/ctxgm206.o
......
......@@ -25,6 +25,30 @@
#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
nvkm_gr_oclass_get(struct nvkm_oclass *oclass, int index)
{
......@@ -59,26 +83,54 @@ nvkm_gr_cclass_new(struct nvkm_fifo_chan *chan,
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 = {
.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.sclass = nvkm_gr_oclass_get,
};
int
nvkm_gr_create_(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, bool enable,
int length, void **pobject)
nvkm_gr_ctor(const struct nvkm_gr_func *func, struct nvkm_device *device,
int index, u32 pmc_enable, bool enable, struct nvkm_gr *gr)
{
struct nvkm_gr *gr;
int ret;
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;
gr->func = func;
return nvkm_engine_ctor(&nvkm_gr, device, index, pmc_enable,
enable, &gr->engine);
}
......@@ -19,9 +19,8 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "ctxgf100.h"
#include "gk20a.h"
#include "gf100.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 @@
*
* Authors: Ben Skeggs
*/
#ifndef __NVC0_GR_H__
#define __NVC0_GR_H__
#ifndef __GF100_GR_H__
#define __GF100_GR_H__
#define gf100_gr(p) container_of((p), struct gf100_gr, base)
#include "priv.h"
......@@ -71,8 +71,8 @@ struct gf100_gr_zbc_depth {
};
struct gf100_gr {
struct nvkm_gr base;
const struct gf100_gr_func *func;
struct nvkm_gr base;
struct gf100_gr_fuc fuc409c;
struct gf100_gr_fuc fuc409d;
......@@ -110,11 +110,40 @@ struct gf100_gr {
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 {
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;
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)
struct gf100_gr_chan {
......@@ -137,33 +166,10 @@ void gf100_gr_dtor_fw(struct gf100_gr_fuc *);
int gf100_gr_ctor_fw(struct gf100_gr *, const char *,
struct gf100_gr_fuc *);
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 *);
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 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 {
u32 addr;
u8 count;
......@@ -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_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 *);
void gf100_gr_mmio(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[] = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -124,17 +128,8 @@ gf104_gr = {
}
};
struct nvkm_oclass *
gf104_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xc3),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gf104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf104_gr, device, index, pgr);
}
......@@ -105,6 +105,10 @@ gf108_gr_pack_mmio[] = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -116,17 +120,8 @@ gf108_gr = {
}
};
struct nvkm_oclass *
gf108_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xc1),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gf108_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf108_gr, device, index, pgr);
}
......@@ -86,6 +86,10 @@ gf110_gr_pack_mmio[] = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -98,17 +102,8 @@ gf110_gr = {
}
};
struct nvkm_oclass *
gf110_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xc8),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gf110_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf110_gr, device, index, pgr);
}
......@@ -122,6 +122,11 @@ gf117_gr_gpccs_ucode = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -134,18 +139,8 @@ gf117_gr = {
}
};
struct nvkm_oclass *
gf117_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xd7),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gf117_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf117_gr, device, index, pgr);
}
......@@ -177,6 +177,10 @@ gf119_gr_pack_mmio[] = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -189,17 +193,8 @@ gf119_gr = {
}
};
struct nvkm_oclass *
gf119_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xd9),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gf119_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf119_gr, device, index, pgr);
}
......@@ -24,8 +24,6 @@
#include "gf100.h"
#include "ctxgf100.h"
#include <subdev/pmu.h>
#include <nvif/class.h>
/*******************************************************************************
......@@ -180,22 +178,14 @@ gk104_gr_pack_mmio[] = {
******************************************************************************/
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;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
int gpc, tpc, rop;
int ret, i;
nvkm_pmu_pgob(device->pmu, false);
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
int i;
nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x08a4), 0x00000000);
......@@ -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(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);
......@@ -296,28 +286,6 @@ gk104_gr_init(struct nvkm_object *object)
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"
static struct gf100_gr_ucode
......@@ -338,18 +306,25 @@ gk104_gr_gpccs_ucode = {
.data.size = sizeof(gk104_grgpc_data),
};
struct nvkm_oclass *
gk104_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xe4),
.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gk104_gr_ctor,
.dtor = gf100_gr_dtor,
.init = gk104_gr_init,
.fini = _nvkm_gr_fini,
},
.func = &gk104_gr,
static const struct gf100_gr_func
gk104_gr = {
.init = gk104_gr_init,
.mmio = gk104_gr_pack_mmio,
.fecs.ucode = &gk104_gr_fecs_ucode,
.gpccs.ucode = &gk104_gr_gpccs_ucode,
.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 = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -192,18 +197,8 @@ gk110_gr = {
}
};
struct nvkm_oclass *
gk110_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xf0),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gk110_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk110_gr, device, index, pgr);
}
......@@ -102,6 +102,11 @@ gk110b_gr_pack_mmio[] = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -112,18 +117,8 @@ gk110b_gr = {
}
};
struct nvkm_oclass *
gk110b_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xf1),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gk110b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk110b_gr, device, index, pgr);
}
......@@ -161,6 +161,11 @@ gk208_gr_gpccs_ucode = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -171,18 +176,8 @@ gk208_gr = {
}
};
struct nvkm_oclass *
gk208_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0x08),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gk208_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk208_gr, device, index, pgr);
}
......@@ -19,7 +19,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "gk20a.h"
#include "gf100.h"
#include "ctxgf100.h"
#include <subdev/timer.h>
......@@ -146,69 +146,6 @@ gk20a_gr_av_to_method(struct gf100_gr_fuc *fuc)
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
gk20a_gr_wait_mem_scrubbing(struct gf100_gr *gr)
{
......@@ -243,10 +180,8 @@ gk20a_gr_set_hww_esr_report_mask(struct gf100_gr *gr)
}
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;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {};
......@@ -254,10 +189,6 @@ gk20a_gr_init(struct nvkm_object *object)
int gpc, tpc;
int ret, i;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
/* Clear SCC RAM */
nvkm_wr32(device, 0x40802c, 0x1);
......@@ -275,8 +206,8 @@ gk20a_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(gr->unk4188b4) >> 8);
nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8);
if (oclass->init_gpc_mmu)
oclass->init_gpc_mmu(gr);
if (gr->func->init_gpc_mmu)
gr->func->init_gpc_mmu(gr);
/* Set the PE as stream master */
nvkm_mask(device, 0x503018, 0x1, 0x1);
......@@ -322,8 +253,8 @@ gk20a_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x404000, 0xc0000000);
nvkm_wr32(device, 0x404600, 0xc0000000);
if (oclass->set_hww_esr_report_mask)
oclass->set_hww_esr_report_mask(gr);
if (gr->func->set_hww_esr_report_mask)
gr->func->set_hww_esr_report_mask(gr);
/* Enable TPC exceptions per GPC */
nvkm_wr32(device, 0x419d0c, 0x2);
......@@ -342,8 +273,72 @@ gk20a_gr_init(struct nvkm_object *object)
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
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -354,18 +349,8 @@ gk20a_gr = {
}
};
struct nvkm_oclass *
gk20a_gr_oclass = &(struct gk20a_gr_oclass) {
.gf100 = {
.base.handle = NV_ENGINE(GR, 0xea),
.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;
int
gk20a_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gk20a_gr_new_(&gk20a_gr, device, index, pgr);
}
......@@ -308,20 +308,14 @@ gm107_gr_init_bios(struct gf100_gr *gr)
}
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;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
int gpc, tpc, ppc, rop;
int ret, i;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
int i;
nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000);
......@@ -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(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);
......@@ -443,6 +437,11 @@ gm107_gr_gpccs_ucode = {
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -453,18 +452,8 @@ gm107_gr = {
}
};
struct nvkm_oclass *
gm107_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0x07),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gm107_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gm107_gr, device, index, pgr);
}
......@@ -236,21 +236,14 @@ gm204_gr_init_ctxctl(struct gf100_gr *gr)
}
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;
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];
int gpc, tpc, ppc, rop;
int ret, i;
u32 tmp;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
int i;
tmp = nvkm_rd32(device, 0x100c80); /*XXX: mask? */
nvkm_wr32(device, 0x418880, 0x00001000 | (tmp & 0x00000fff));
......@@ -265,7 +258,7 @@ gm204_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8);
nvkm_mask(device, 0x100cc4, 0x00040000, 0x00040000);
gf100_gr_mmio(gr, oclass->mmio);
gf100_gr_mmio(gr, gr->func->mmio);
gm107_gr_init_bios(gr);
......@@ -360,6 +353,9 @@ gm204_gr_init(struct nvkm_object *object)
static const struct gf100_gr_func
gm204_gr = {
.init = gm204_gr_init,
.mmio = gm204_gr_pack_mmio,
.ppc_nr = 2,
.grctx = &gm204_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -370,16 +366,8 @@ gm204_gr = {
}
};
struct nvkm_oclass *
gm204_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0x24),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gm204_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gm204_gr, device, index, pgr);
}
......@@ -28,6 +28,9 @@
static const struct gf100_gr_func
gm206_gr = {
.init = gm204_gr_init,
.mmio = gm204_gr_pack_mmio,
.ppc_nr = 2,
.grctx = &gm206_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -38,16 +41,8 @@ gm206_gr = {
}
};
struct nvkm_oclass *
gm206_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0x26),
.base.ofuncs = &(struct nvkm_ofuncs) {
.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;
int
gm206_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gm206_gr, device, index, pgr);
}
......@@ -19,7 +19,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "gk20a.h"
#include "gf100.h"
#include "ctxgf100.h"
#include <subdev/timer.h>
......@@ -61,6 +61,11 @@ gm20b_gr_set_hww_esr_report_mask(struct gf100_gr *gr)
static const struct gf100_gr_func
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,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
......@@ -71,19 +76,8 @@ gm20b_gr = {
}
};
struct nvkm_oclass *
gm20b_gr_oclass = &(struct gk20a_gr_oclass) {
.gf100 = {
.base.handle = NV_ENGINE(GR, 0x2b),
.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;
int
gm20b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gk20a_gr_new_(&gm20b_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
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
* copy of this software and associated documentation files (the "Software"),
......@@ -14,22 +14,33 @@
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
* 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"
#ifndef __GK20A_GR_H__
#define __GK20A_GR_H__
#include "gf100.h"
struct gk20a_gr_oclass {
struct gf100_gr_oclass gf100;
void (*init_gpc_mmu)(struct gf100_gr *);
void (*set_hww_esr_report_mask)(struct gf100_gr *);
static const struct nvkm_gr_func
mcp79_gr = {
.init = nv50_gr_init,
.intr = nv50_gr_intr,
.chan_new = nv50_gr_chan_new,
.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 },
{}
}
};
#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[] = {
};
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_chan *chan = NULL;
struct nvkm_device *device = gr->base.engine.subdev.device;
struct nv04_gr *gr = nv04_gr(base);
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
u32 nstatus = nvkm_rd32(device, NV03_PGRAPH_NSTATUS);
......@@ -1286,6 +1286,7 @@ nv04_gr_intr(struct nvkm_subdev *subdev)
u32 inst = (nvkm_rd32(device, 0x40016c) & 0xffff) << 4;
u32 show = stat;
char msg[128], src[128], sta[128];
struct nv04_gr_chan *chan;
unsigned long flags;
spin_lock_irqsave(&gr->lock, flags);
......@@ -1323,8 +1324,47 @@ nv04_gr_intr(struct nvkm_subdev *subdev)
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
nv04_gr = {
.init = nv04_gr_init,
.intr = nv04_gr_intr,
.chan_new = nv04_gr_chan_new,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
......@@ -1372,76 +1412,16 @@ nv04_gr = {
}
};
static int
nv04_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv04_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
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;
nv_subdev(gr)->unit = 0x00001000;
nv_subdev(gr)->intr = nv04_gr_intr;
if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
return -ENOMEM;
spin_lock_init(&gr->lock);
return 0;
}
*pgr = &gr->base;
static int
nv04_gr_init(struct nvkm_object *object)
{
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;
return nvkm_gr_ctor(&nv04_gr, device, index, 0x00001000,
true, &gr->base);
}
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,
******************************************************************************/
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_fifo *fifo = device->fifo;
struct nvkm_fb_tile *tile = &device->fb->tile.region[i];
unsigned long flags;
nvkm_fifo_pause(fifo, &flags);
......@@ -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_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, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i);
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, tile->zcomp);
......@@ -177,10 +176,11 @@ nv20_gr_tile_prog(struct nvkm_engine *engine, int i)
}
void
nv20_gr_intr(struct nvkm_subdev *subdev)
nv20_gr_intr(struct nvkm_gr *base)
{
struct nv20_gr *gr = (void *)subdev;
struct nvkm_device *device = gr->base.engine.subdev.device;
struct nv20_gr *gr = nv20_gr(base);
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_fifo_chan *chan;
u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
......@@ -215,82 +215,27 @@ nv20_gr_intr(struct nvkm_subdev *subdev)
nvkm_fifo_chan_put(device->fifo, flags, &chan);
}
static const struct nvkm_gr_func
nv20_gr = {
.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)
int
nv20_gr_oneinit(struct nvkm_gr *base)
{
struct nv20_gr *gr = (void *)object;
nvkm_memory_del(&gr->ctxtab);
nvkm_gr_destroy(&gr->base);
struct nv20_gr *gr = nv20_gr(base);
return nvkm_memory_new(gr->base.engine.subdev.device,
NVKM_MEM_TARGET_INST, 32 * 4, 16,
true, &gr->ctxtab);
}
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 = (void *)engine;
struct nv20_gr *gr = nv20_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device;
struct nvkm_fb *fb = device->fb;
u32 tmp, vramsz;
int ret, i;
ret = nvkm_gr_init(&gr->base);
if (ret)
return ret;
int i;
nvkm_wr32(device, NV20_PGRAPH_CHANNEL_CTX_TABLE,
nvkm_memory_addr(gr->ctxtab) >> 4);
if (nv_device(gr)->chipset == 0x20) {
if (device->chipset == 0x20) {
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x003d0000);
for (i = 0; i < 15; i++)
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, 0x00000000);
......@@ -318,7 +263,7 @@ nv20_gr_init(struct nvkm_object *object)
nvkm_wr32(device, NV10_PGRAPH_DEBUG_4, 0x00000000);
nvkm_wr32(device, 0x40009C , 0x00000040);
if (nv_device(gr)->chipset >= 0x25) {
if (device->chipset >= 0x25) {
nvkm_wr32(device, 0x400890, 0x00a8cfff);
nvkm_wr32(device, 0x400610, 0x304B1FB6);
nvkm_wr32(device, 0x400B80, 0x1cbd3883);
......@@ -338,10 +283,6 @@ nv20_gr_init(struct nvkm_object *object)
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, NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
nvkm_wr32(device, NV10_PGRAPH_RDI_DATA, nvkm_rd32(device, 0x100324));
......@@ -355,7 +296,7 @@ nv20_gr_init(struct nvkm_object *object)
nvkm_wr32(device, NV10_PGRAPH_SURFACE, tmp);
/* 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, 0x4009A8, nvkm_rd32(device, 0x100204));
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
......@@ -378,13 +319,57 @@ nv20_gr_init(struct nvkm_object *object)
return 0;
}
struct nvkm_oclass
nv20_gr_oclass = {
.handle = NV_ENGINE(GR, 0x20),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv20_gr_ctor,
.dtor = nv20_gr_dtor,
.init = nv20_gr_init,
.fini = _nvkm_gr_fini,
},
void *
nv20_gr_dtor(struct nvkm_gr *base)
{
struct nv20_gr *gr = nv20_gr(base);
nvkm_memory_del(&gr->ctxtab);
return gr;
}
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 {
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)
struct nv20_gr_chan {
......@@ -18,14 +28,6 @@ struct nv20_gr_chan {
};
void *nv20_gr_chan_dtor(struct nvkm_object *);
int nv20_gr_chan_init(struct nvkm_object *);
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 *);
int nv20_gr_chan_init(struct nvkm_object *);
int nv20_gr_chan_fini(struct nvkm_object *, bool);
#endif
......@@ -101,6 +101,11 @@ nv25_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
static const struct nvkm_gr_func
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,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
......@@ -122,40 +127,8 @@ nv25_gr = {
}
};
static int
nv25_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv25_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
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 = &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;
return nv20_gr_new_(&nv25_gr, device, index, pgr);
}
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,
static const struct nvkm_gr_func
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,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
......@@ -113,40 +118,8 @@ nv2a_gr = {
}
};
static int
nv2a_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv2a_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
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 = &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;
return nv20_gr_new_(&nv2a_gr, device, index, pgr);
}
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,
* 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
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 = (void *)engine;
struct nv20_gr *gr = nv20_gr(base);
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_memory_addr(gr->ctxtab) >> 4);
......@@ -189,7 +130,7 @@ nv30_gr_init(struct nvkm_object *object)
nvkm_wr32(device, 0x400ba4, 0x00231f3f);
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_DATA , 0x00200201);
nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0008);
......@@ -202,10 +143,6 @@ nv30_gr_init(struct nvkm_object *object)
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_STATE , 0xFFFFFFFF);
nvkm_wr32(device, 0x0040075c , 0x00000001);
......@@ -214,22 +151,48 @@ nv30_gr_init(struct nvkm_object *object)
/* vramsz = pci_resource_len(gr->dev->pdev, 1) - 1; */
nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200));
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, 0x400754, nvkm_rd32(device, 0x100200));
nvkm_wr32(device, 0x400750, 0x00EA0004);
nvkm_wr32(device, 0x400754, nvkm_rd32(device, 0x100204));
}
return 0;
}
struct nvkm_oclass
nv30_gr_oclass = {
.handle = NV_ENGINE(GR, 0x30),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv30_gr_ctor,
.dtor = nv20_gr_dtor,
.init = nv30_gr_init,
.fini = _nvkm_gr_fini,
},
static const struct nvkm_gr_func
nv30_gr = {
.dtor = nv20_gr_dtor,
.oneinit = nv20_gr_oneinit,
.init = nv30_gr_init,
.intr = nv20_gr_intr,
.tile = nv20_gr_tile,
.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,
static const struct nvkm_gr_func
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,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
......@@ -123,40 +128,8 @@ nv34_gr = {
}
};
static int
nv34_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv34_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
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 = &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;
return nv20_gr_new_(&nv34_gr, device, index, pgr);
}
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,
static const struct nvkm_gr_func
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,
.sclass = {
{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
......@@ -123,40 +128,8 @@ nv35_gr = {
}
};
static int
nv35_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv35_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
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 = &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;
return nv20_gr_new_(&nv35_gr, device, index, pgr);
}
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 {
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)
struct nv40_gr_chan {
......@@ -19,6 +25,11 @@ struct nv40_gr_chan {
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,
* helpful to determine a number of other hardware features
*/
......@@ -28,7 +39,7 @@ nv44_gr_class(struct nvkm_device *device)
if ((device->chipset & 0xf0) == 0x60)
return 1;
return !(0x0baf & (1 << (device->chipset & 0x0f)));
return !(0x0aaf & (1 << (device->chipset & 0x0f)));
}
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 {
u32 size;
};
struct nv50_gr_func {
void *(*dtor)(struct nv50_gr *);
struct nvkm_sclass sclass[];
};
int nv50_gr_new_(const struct nvkm_gr_func *, struct nvkm_device *, int index,
struct nvkm_gr **);
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)
......@@ -22,6 +25,11 @@ struct nv50_gr_chan {
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);
void nv50_grctx_fill(struct nvkm_device *, struct nvkm_gpuobj *);
#endif
......@@ -2,14 +2,37 @@
#define __NVKM_GR_PRIV_H__
#define nvkm_gr(p) container_of((p), struct nvkm_gr, engine)
#include <engine/gr.h>
#include <core/enum.h>
struct nvkm_fb_tile;
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 {
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 *,
const struct nvkm_oclass *, struct nvkm_object **);
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[];
};
extern const struct nvkm_bitfield nv04_gr_nsource[];
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
......@@ -52,11 +52,13 @@ void
nvkm_fb_tile_prog(struct nvkm_fb *fb, int region, struct nvkm_fb_tile *tile)
{
struct nvkm_device *device = fb->subdev.device;
fb->func->tile.prog(fb, region, tile);
if (likely(device->gr))
device->gr->engine.tile_prog(&device->gr->engine, region);
if (likely(device->mpeg))
device->mpeg->tile_prog(device->mpeg, region);
if (fb->func->tile.prog) {
fb->func->tile.prog(fb, region, tile);
if (device->gr)
nvkm_engine_tile(&device->gr->engine, region);
if (likely(device->mpeg))
device->mpeg->tile_prog(device->mpeg, region);
}
}
int
......
......@@ -23,11 +23,10 @@
*/
#include "priv.h"
#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <subdev/timer.h>
#include <core/engine.h>
#include <core/gpuobj.h>
#include <engine/gr.h>
static void
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)
continue;
/* unfortunate hw bug workaround... */
if (i == NVDEV_ENGINE_GR) {
struct nvkm_engine *engine =
nvkm_device_engine(device, i);
if (engine && engine->tlb_flush) {
engine->tlb_flush(engine);
if (i == NVDEV_ENGINE_GR && device->gr) {
int ret = nvkm_gr_tlb_flush(device->gr);
if (ret != -ENODEV)
continue;
}
}
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