#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))
spinlock_t lock;
void (*tile_prog)(struct nvkm_engine *, int region);
- int (*tlb_flush)(struct nvkm_engine *);
};
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,
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)
#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
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);
{
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(®->fence);
#include <core/device.h>
#include <core/option.h>
+#include <subdev/fb.h>
+
void
nvkm_engine_unref(struct nvkm_engine **pengine)
{
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)
{
{
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) {
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;
}
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv04_fifo_new,
-// .gr = nv04_gr_new,
+ .gr = nv04_gr_new,
// .sw = nv04_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv04_fifo_new,
-// .gr = nv04_gr_new,
+ .gr = nv04_gr_new,
// .sw = nv04_sw_new,
};
.timer = nv04_timer_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
-// .gr = nv10_gr_new,
+ .gr = nv10_gr_new,
};
static const struct nvkm_device_chip
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv10_fifo_new,
-// .gr = nv10_gr_new,
+ .gr = nv15_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv10_fifo_new,
-// .gr = nv10_gr_new,
+ .gr = nv15_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv10_gr_new,
+ .gr = nv17_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv10_gr_new,
+ .gr = nv17_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv10_fifo_new,
-// .gr = nv10_gr_new,
+ .gr = nv15_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv10_gr_new,
+ .gr = nv17_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv20_gr_new,
+ .gr = nv20_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv25_gr_new,
+ .gr = nv25_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv25_gr_new,
+ .gr = nv25_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv2a_gr_new,
+ .gr = nv2a_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv30_gr_new,
+ .gr = nv30_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv30_gr_new,
+ .gr = nv30_gr_new,
// .mpeg = nv31_mpeg_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv34_gr_new,
+ .gr = nv34_gr_new,
// .mpeg = nv31_mpeg_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv35_gr_new,
+ .gr = nv35_gr_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv17_fifo_new,
-// .gr = nv35_gr_new,
+ .gr = nv35_gr_new,
// .mpeg = nv31_mpeg_new,
// .sw = nv10_sw_new,
};
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv40_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv40_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv40_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv40_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv40_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv50_disp_new,
.dma = nv50_dma_new,
.fifo = nv50_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = nv50_gr_new,
// .mpeg = nv50_mpeg_new,
// .pm = nv50_pm_new,
// .sw = nv50_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = nv04_disp_new,
.dma = nv04_dma_new,
.fifo = nv40_fifo_new,
-// .gr = nv40_gr_new,
+ .gr = nv44_gr_new,
// .mpeg = nv44_mpeg_new,
// .pm = nv40_pm_new,
// .sw = nv10_sw_new,
.disp = g84_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = g84_gr_new,
// .mpeg = g84_mpeg_new,
// .pm = g84_pm_new,
// .sw = nv50_sw_new,
.disp = g84_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = g84_gr_new,
// .mpeg = g84_mpeg_new,
// .pm = g84_pm_new,
// .sw = nv50_sw_new,
.disp = g84_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = g84_gr_new,
// .mpeg = g84_mpeg_new,
// .pm = g84_pm_new,
// .sw = nv50_sw_new,
.disp = g94_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = g84_gr_new,
// .mpeg = g84_mpeg_new,
// .pm = g84_pm_new,
// .sw = nv50_sw_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
// .sw = nv50_sw_new,
-// .gr = nv50_gr_new,
+ .gr = g84_gr_new,
// .mpeg = g84_mpeg_new,
.vp = g84_vp_new,
.cipher = g84_cipher_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
// .sw = nv50_sw_new,
-// .gr = nv50_gr_new,
+ .gr = g84_gr_new,
.mspdec = g98_mspdec_new,
.sec = g98_sec_new,
.msvld = g98_msvld_new,
.disp = gt200_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = gt200_gr_new,
// .mpeg = g84_mpeg_new,
// .pm = gt200_pm_new,
// .sw = nv50_sw_new,
.disp = gt215_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = gt215_gr_new,
// .mpeg = g84_mpeg_new,
.mspdec = gt215_mspdec_new,
.msppp = gt215_msppp_new,
.disp = gt215_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = gt215_gr_new,
.mspdec = gt215_mspdec_new,
.msppp = gt215_msppp_new,
.msvld = gt215_msvld_new,
.disp = gt215_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = gt215_gr_new,
.mspdec = gt215_mspdec_new,
.msppp = gt215_msppp_new,
.msvld = gt215_msvld_new,
.disp = g94_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = gt200_gr_new,
.mspdec = g98_mspdec_new,
.msppp = g98_msppp_new,
.msvld = g98_msvld_new,
.disp = g94_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = mcp79_gr_new,
.mspdec = g98_mspdec_new,
.msppp = g98_msppp_new,
.msvld = g98_msvld_new,
.disp = gt215_disp_new,
.dma = nv50_dma_new,
.fifo = g84_fifo_new,
-// .gr = nv50_gr_new,
+ .gr = mcp89_gr_new,
.mspdec = gt215_mspdec_new,
.msppp = gt215_msppp_new,
.msvld = mcp89_msvld_new,
.disp = gt215_disp_new,
.dma = gf100_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf100_gr_new,
+ .gr = gf100_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gt215_disp_new,
.dma = gf100_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf108_gr_new,
+ .gr = gf108_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gt215_disp_new,
.dma = gf100_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf104_gr_new,
+ .gr = gf104_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gt215_disp_new,
.dma = gf100_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf104_gr_new,
+ .gr = gf104_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gt215_disp_new,
.dma = gf100_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf110_gr_new,
+ .gr = gf110_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gt215_disp_new,
.dma = gf100_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf104_gr_new,
+ .gr = gf104_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gt215_disp_new,
.dma = gf100_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf104_gr_new,
+ .gr = gf104_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gf119_disp_new,
.dma = gf119_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf117_gr_new,
+ .gr = gf117_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gf119_disp_new,
.dma = gf119_dma_new,
.fifo = gf100_fifo_new,
-// .gr = gf119_gr_new,
+ .gr = gf119_gr_new,
.mspdec = gf100_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gf100_msvld_new,
.disp = gk104_disp_new,
.dma = gf119_dma_new,
.fifo = gk104_fifo_new,
-// .gr = gk104_gr_new,
+ .gr = gk104_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gk104_msvld_new,
.disp = gk104_disp_new,
.dma = gf119_dma_new,
.fifo = gk104_fifo_new,
-// .gr = gk104_gr_new,
+ .gr = gk104_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gk104_msvld_new,
.disp = gk104_disp_new,
.dma = gf119_dma_new,
.fifo = gk104_fifo_new,
-// .gr = gk104_gr_new,
+ .gr = gk104_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gk104_msvld_new,
.ce[2] = gk104_ce_new,
.dma = gf119_dma_new,
.fifo = gk20a_fifo_new,
-// .gr = gk20a_gr_new,
+ .gr = gk20a_gr_new,
// .pm = gk104_pm_new,
// .sw = gf100_sw_new,
};
.disp = gk110_disp_new,
.dma = gf119_dma_new,
.fifo = gk104_fifo_new,
-// .gr = gk110_gr_new,
+ .gr = gk110_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gk104_msvld_new,
.disp = gk110_disp_new,
.dma = gf119_dma_new,
.fifo = gk104_fifo_new,
-// .gr = gk110b_gr_new,
+ .gr = gk110b_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gk104_msvld_new,
.disp = gk110_disp_new,
.dma = gf119_dma_new,
.fifo = gk208_fifo_new,
-// .gr = gk208_gr_new,
+ .gr = gk208_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gk104_msvld_new,
.disp = gk110_disp_new,
.dma = gf119_dma_new,
.fifo = gk208_fifo_new,
-// .gr = gk208_gr_new,
+ .gr = gk208_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
.msvld = gk104_msvld_new,
.disp = gm107_disp_new,
.dma = gf119_dma_new,
.fifo = gk208_fifo_new,
-// .gr = gm107_gr_new,
+ .gr = gm107_gr_new,
// .sw = gf100_sw_new,
};
.disp = gm204_disp_new,
.dma = gf119_dma_new,
.fifo = gm204_fifo_new,
-// .gr = gm204_gr_new,
+ .gr = gm204_gr_new,
// .sw = gf100_sw_new,
};
.disp = gm204_disp_new,
.dma = gf119_dma_new,
.fifo = gm204_fifo_new,
-// .gr = gm206_gr_new,
+ .gr = gm206_gr_new,
// .sw = gf100_sw_new,
};
.ce[2] = gm204_ce_new,
.dma = gf119_dma_new,
.fifo = gm20b_fifo_new,
-// .gr = gm20b_gr_new,
+ .gr = gm20b_gr_new,
// .sw = gf100_sw_new,
};
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:
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;
#if 0
#endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass;
#if 0
#endif
#if 0
#if 0
#endif
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = gm204_gr_oclass;
#if 0
#endif
break;
#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;
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;
{
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;
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;
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:
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;
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
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
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
#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)
{
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);
}
* 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>
--- /dev/null
+/*
+ * 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);
+}
#include <core/option.h>
#include <subdev/fb.h>
#include <subdev/mc.h>
+#include <subdev/pmu.h>
#include <subdev/timer.h>
#include <engine/fifo.h>
}
u64
-gf100_gr_units(struct nvkm_gr *obj)
+gf100_gr_units(struct nvkm_gr *base)
{
- struct gf100_gr *gr = container_of(obj, typeof(*gr), base);
+ struct gf100_gr *gr = gf100_gr(base);
u64 cfg;
cfg = (u32)gr->gpc_nr;
}
static void
-gf100_gr_intr(struct nvkm_subdev *subdev)
+gf100_gr_intr(struct nvkm_gr *base)
{
- struct gf100_gr *gr = (void *)subdev;
- struct nvkm_device *device = gr->base.engine.subdev.device;
+ struct gf100_gr *gr = gf100_gr(base);
+ struct nvkm_subdev *subdev = &gr->base.engine.subdev;
+ struct nvkm_device *device = subdev->device;
struct nvkm_fifo_chan *chan;
unsigned long flags;
u64 inst = nvkm_rd32(device, 0x409b00) & 0x0fffffff;
chid = chan->chid;
}
- if (nv_device(gr)->card_type < NV_E0 || subc < 4)
+ if (device->card_type < NV_E0 || subc < 4)
class = nvkm_rd32(device, 0x404200 + (subc * 4));
else
class = 0x0000;
const struct gf100_grctx_func *grctx = gr->func->grctx;
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
- struct gf100_gr_oclass *oclass = (void *)nv_object(gr)->oclass;
int i;
if (gr->firmware) {
/* load fuc microcode */
nvkm_mc_unk260(device->mc, 0);
- gf100_gr_init_fw(gr, 0x409000, &gr->fuc409c,
- &gr->fuc409d);
- gf100_gr_init_fw(gr, 0x41a000, &gr->fuc41ac,
- &gr->fuc41ad);
+ gf100_gr_init_fw(gr, 0x409000, &gr->fuc409c, &gr->fuc409d);
+ gf100_gr_init_fw(gr, 0x41a000, &gr->fuc41ac, &gr->fuc41ad);
nvkm_mc_unk260(device->mc, 1);
/* start both of them running */
) < 0)
return -EBUSY;
- if (nv_device(gr)->chipset >= 0xe0) {
+ if (device->chipset >= 0xe0) {
nvkm_wr32(device, 0x409800, 0x00000000);
nvkm_wr32(device, 0x409500, 0x00000001);
nvkm_wr32(device, 0x409504, 0x00000030);
return 0;
} else
- if (!oclass->fecs.ucode) {
+ if (!gr->func->fecs.ucode) {
return -ENOSYS;
}
/* load HUB microcode */
nvkm_mc_unk260(device->mc, 0);
nvkm_wr32(device, 0x4091c0, 0x01000000);
- for (i = 0; i < oclass->fecs.ucode->data.size / 4; i++)
- nvkm_wr32(device, 0x4091c4, oclass->fecs.ucode->data.data[i]);
+ for (i = 0; i < gr->func->fecs.ucode->data.size / 4; i++)
+ nvkm_wr32(device, 0x4091c4, gr->func->fecs.ucode->data.data[i]);
nvkm_wr32(device, 0x409180, 0x01000000);
- for (i = 0; i < oclass->fecs.ucode->code.size / 4; i++) {
+ for (i = 0; i < gr->func->fecs.ucode->code.size / 4; i++) {
if ((i & 0x3f) == 0)
nvkm_wr32(device, 0x409188, i >> 6);
- nvkm_wr32(device, 0x409184, oclass->fecs.ucode->code.data[i]);
+ nvkm_wr32(device, 0x409184, gr->func->fecs.ucode->code.data[i]);
}
/* load GPC microcode */
nvkm_wr32(device, 0x41a1c0, 0x01000000);
- for (i = 0; i < oclass->gpccs.ucode->data.size / 4; i++)
- nvkm_wr32(device, 0x41a1c4, oclass->gpccs.ucode->data.data[i]);
+ for (i = 0; i < gr->func->gpccs.ucode->data.size / 4; i++)
+ nvkm_wr32(device, 0x41a1c4, gr->func->gpccs.ucode->data.data[i]);
nvkm_wr32(device, 0x41a180, 0x01000000);
- for (i = 0; i < oclass->gpccs.ucode->code.size / 4; i++) {
+ for (i = 0; i < gr->func->gpccs.ucode->code.size / 4; i++) {
if ((i & 0x3f) == 0)
nvkm_wr32(device, 0x41a188, i >> 6);
- nvkm_wr32(device, 0x41a184, oclass->gpccs.ucode->code.data[i]);
+ nvkm_wr32(device, 0x41a184, gr->func->gpccs.ucode->code.data[i]);
}
nvkm_mc_unk260(device->mc, 1);
return 0;
}
+static int
+gf100_gr_oneinit(struct nvkm_gr *base)
+{
+ struct gf100_gr *gr = gf100_gr(base);
+ struct nvkm_device *device = gr->base.engine.subdev.device;
+ int ret, i, j;
+
+ nvkm_pmu_pgob(device->pmu, false);
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false,
+ &gr->unk4188b4);
+ if (ret)
+ return ret;
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false,
+ &gr->unk4188b8);
+ if (ret)
+ return ret;
+
+ nvkm_kmap(gr->unk4188b4);
+ for (i = 0; i < 0x1000; i += 4)
+ nvkm_wo32(gr->unk4188b4, i, 0x00000010);
+ nvkm_done(gr->unk4188b4);
+
+ nvkm_kmap(gr->unk4188b8);
+ for (i = 0; i < 0x1000; i += 4)
+ nvkm_wo32(gr->unk4188b8, i, 0x00000010);
+ nvkm_done(gr->unk4188b8);
+
+ gr->rop_nr = (nvkm_rd32(device, 0x409604) & 0x001f0000) >> 16;
+ gr->gpc_nr = nvkm_rd32(device, 0x409604) & 0x0000001f;
+ for (i = 0; i < gr->gpc_nr; i++) {
+ gr->tpc_nr[i] = nvkm_rd32(device, GPC_UNIT(i, 0x2608));
+ gr->tpc_total += gr->tpc_nr[i];
+ gr->ppc_nr[i] = gr->func->ppc_nr;
+ for (j = 0; j < gr->ppc_nr[i]; j++) {
+ u8 mask = nvkm_rd32(device, GPC_UNIT(i, 0x0c30 + (j * 4)));
+ gr->ppc_tpc_nr[i][j] = hweight8(mask);
+ }
+ }
+
+ /*XXX: these need figuring out... though it might not even matter */
+ switch (device->chipset) {
+ case 0xc0:
+ if (gr->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
+ gr->magic_not_rop_nr = 0x07;
+ } else
+ if (gr->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
+ gr->magic_not_rop_nr = 0x05;
+ } else
+ if (gr->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
+ gr->magic_not_rop_nr = 0x06;
+ }
+ break;
+ case 0xc3: /* 450, 4/0/0/0, 2 */
+ gr->magic_not_rop_nr = 0x03;
+ break;
+ case 0xc4: /* 460, 3/4/0/0, 4 */
+ gr->magic_not_rop_nr = 0x01;
+ break;
+ case 0xc1: /* 2/0/0/0, 1 */
+ gr->magic_not_rop_nr = 0x01;
+ break;
+ case 0xc8: /* 4/4/3/4, 5 */
+ gr->magic_not_rop_nr = 0x06;
+ break;
+ case 0xce: /* 4/4/0/0, 4 */
+ gr->magic_not_rop_nr = 0x03;
+ break;
+ case 0xcf: /* 4/0/0/0, 3 */
+ gr->magic_not_rop_nr = 0x03;
+ break;
+ case 0xd7:
+ case 0xd9: /* 1/0/0/0, 1 */
+ case 0xea: /* gk20a */
+ case 0x12b: /* gm20b */
+ gr->magic_not_rop_nr = 0x01;
+ break;
+ }
+
+ return 0;
+}
+
+int
+gf100_gr_init_(struct nvkm_gr *base)
+{
+ struct gf100_gr *gr = gf100_gr(base);
+ nvkm_pmu_pgob(gr->base.engine.subdev.device->pmu, false);
+ return gr->func->init(gr);
+}
+
+void
+gf100_gr_dtor_fw(struct gf100_gr_fuc *fuc)
+{
+ kfree(fuc->data);
+ fuc->data = NULL;
+}
+
+void *
+gf100_gr_dtor(struct nvkm_gr *base)
+{
+ struct gf100_gr *gr = gf100_gr(base);
+
+ if (gr->func->dtor)
+ gr->func->dtor(gr);
+ kfree(gr->data);
+
+ gf100_gr_dtor_fw(&gr->fuc409c);
+ gf100_gr_dtor_fw(&gr->fuc409d);
+ gf100_gr_dtor_fw(&gr->fuc41ac);
+ gf100_gr_dtor_fw(&gr->fuc41ad);
+
+ nvkm_memory_del(&gr->unk4188b8);
+ nvkm_memory_del(&gr->unk4188b4);
+ return gr;
+}
+
+static const struct nvkm_gr_func
+gf100_gr_ = {
+ .dtor = gf100_gr_dtor,
+ .oneinit = gf100_gr_oneinit,
+ .init = gf100_gr_init_,
+ .intr = gf100_gr_intr,
+ .units = gf100_gr_units,
+ .chan_new = gf100_gr_chan_new,
+ .object_get = gf100_gr_object_get,
+};
+
+int
+gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
+ struct gf100_gr_fuc *fuc)
+{
+ struct nvkm_subdev *subdev = &gr->base.engine.subdev;
+ struct nvkm_device *device = subdev->device;
+ const struct firmware *fw;
+ char f[64];
+ char cname[16];
+ int ret;
+ int i;
+
+ /* Convert device name to lowercase */
+ strncpy(cname, device->chip->name, sizeof(cname));
+ cname[sizeof(cname) - 1] = '\0';
+ i = strlen(cname);
+ while (i) {
+ --i;
+ cname[i] = tolower(cname[i]);
+ }
+
+ snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
+ ret = request_firmware(&fw, f, nv_device_base(device));
+ if (ret) {
+ nvkm_error(subdev, "failed to load %s\n", fwname);
+ return ret;
+ }
+
+ fuc->size = fw->size;
+ fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
+ release_firmware(fw);
+ return (fuc->data != NULL) ? 0 : -ENOMEM;
+}
+
+int
+gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
+ int index, struct gf100_gr *gr)
+{
+ int ret;
+
+ gr->func = func;
+ gr->firmware = nvkm_boolopt(device->cfgopt, "NvGrUseFW",
+ func->fecs.ucode == NULL);
+
+ ret = nvkm_gr_ctor(&gf100_gr_, device, index, 0x08001000,
+ gr->firmware || func->fecs.ucode != NULL,
+ &gr->base);
+ if (ret)
+ return ret;
+
+ if (gr->firmware) {
+ nvkm_info(&gr->base.engine.subdev, "using external firmware\n");
+ if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) ||
+ gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) ||
+ gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) ||
+ gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad))
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
int
-gf100_gr_init(struct nvkm_object *object)
+gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
+ int index, struct nvkm_gr **pgr)
+{
+ struct gf100_gr *gr;
+ if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
+ return -ENOMEM;
+ *pgr = &gr->base;
+ return gf100_gr_ctor(func, device, index, gr);
+}
+
+int
+gf100_gr_init(struct gf100_gr *gr)
{
- struct gf100_gr *gr = (void *)object;
struct nvkm_device *device = gr->base.engine.subdev.device;
- struct gf100_gr_oclass *oclass = (void *)object->oclass;
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;
-
- 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);
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);
memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr));
for (i = 0, gpc = -1; i < gr->tpc_total; i++) {
nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
}
- if (nv_device(gr)->chipset != 0xd7)
+ if (device->chipset != 0xd7)
nvkm_wr32(device, GPC_BCAST(0x1bd4), magicgpc918);
else
nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918);
return gf100_gr_init_ctxctl(gr);
}
-void
-gf100_gr_dtor_fw(struct gf100_gr_fuc *fuc)
-{
- kfree(fuc->data);
- fuc->data = NULL;
-}
-
-int
-gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
- struct gf100_gr_fuc *fuc)
-{
- struct nvkm_subdev *subdev = &gr->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
- const struct firmware *fw;
- char f[64];
- char cname[16];
- int ret;
- int i;
-
- /* Convert device name to lowercase */
- strncpy(cname, device->chip->name, sizeof(cname));
- cname[sizeof(cname) - 1] = '\0';
- i = strlen(cname);
- while (i) {
- --i;
- cname[i] = tolower(cname[i]);
- }
-
- snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
- ret = request_firmware(&fw, f, nv_device_base(device));
- if (ret) {
- nvkm_error(subdev, "failed to load %s\n", fwname);
- return ret;
- }
-
- fuc->size = fw->size;
- fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
- release_firmware(fw);
- return (fuc->data != NULL) ? 0 : -ENOMEM;
-}
-
-void
-gf100_gr_dtor(struct nvkm_object *object)
-{
- struct gf100_gr *gr = (void *)object;
-
- kfree(gr->data);
-
- gf100_gr_dtor_fw(&gr->fuc409c);
- gf100_gr_dtor_fw(&gr->fuc409d);
- gf100_gr_dtor_fw(&gr->fuc41ac);
- gf100_gr_dtor_fw(&gr->fuc41ad);
-
- nvkm_memory_del(&gr->unk4188b8);
- nvkm_memory_del(&gr->unk4188b4);
-
- nvkm_gr_destroy(&gr->base);
-}
-
-static const struct nvkm_gr_func
-gf100_gr_ = {
- .chan_new = gf100_gr_chan_new,
- .object_get = gf100_gr_object_get,
-};
-
-int
-gf100_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *bclass, void *data, u32 size,
- struct nvkm_object **pobject)
-{
- struct gf100_gr_oclass *oclass = (void *)bclass;
- struct nvkm_device *device = (void *)parent;
- struct gf100_gr *gr;
- bool use_ext_fw, enable;
- int ret, i, j;
-
- use_ext_fw = nvkm_boolopt(device->cfgopt, "NvGrUseFW",
- oclass->fecs.ucode == NULL);
- enable = use_ext_fw || oclass->fecs.ucode != NULL;
-
- ret = nvkm_gr_create(parent, engine, bclass, enable, &gr);
- *pobject = nv_object(gr);
- if (ret)
- return ret;
-
- gr->func = oclass->func;
- gr->base.func = &gf100_gr_;
- nv_subdev(gr)->unit = 0x08001000;
- nv_subdev(gr)->intr = gf100_gr_intr;
-
- gr->base.units = gf100_gr_units;
-
- if (use_ext_fw) {
- nvkm_info(&gr->base.engine.subdev, "using external firmware\n");
- if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) ||
- gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) ||
- gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) ||
- gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad))
- return -ENODEV;
- gr->firmware = true;
- }
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false,
- &gr->unk4188b4);
- if (ret)
- return ret;
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false,
- &gr->unk4188b8);
- if (ret)
- return ret;
-
- nvkm_kmap(gr->unk4188b4);
- for (i = 0; i < 0x1000; i += 4)
- nvkm_wo32(gr->unk4188b4, i, 0x00000010);
- nvkm_done(gr->unk4188b4);
-
- nvkm_kmap(gr->unk4188b8);
- for (i = 0; i < 0x1000; i += 4)
- nvkm_wo32(gr->unk4188b8, i, 0x00000010);
- nvkm_done(gr->unk4188b8);
-
- gr->rop_nr = (nvkm_rd32(device, 0x409604) & 0x001f0000) >> 16;
- gr->gpc_nr = nvkm_rd32(device, 0x409604) & 0x0000001f;
- for (i = 0; i < gr->gpc_nr; i++) {
- gr->tpc_nr[i] = nvkm_rd32(device, GPC_UNIT(i, 0x2608));
- gr->tpc_total += gr->tpc_nr[i];
- gr->ppc_nr[i] = oclass->ppc_nr;
- for (j = 0; j < gr->ppc_nr[i]; j++) {
- u8 mask = nvkm_rd32(device, GPC_UNIT(i, 0x0c30 + (j * 4)));
- gr->ppc_tpc_nr[i][j] = hweight8(mask);
- }
- }
-
- /*XXX: these need figuring out... though it might not even matter */
- switch (nv_device(gr)->chipset) {
- case 0xc0:
- if (gr->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
- gr->magic_not_rop_nr = 0x07;
- } else
- if (gr->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
- gr->magic_not_rop_nr = 0x05;
- } else
- if (gr->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
- gr->magic_not_rop_nr = 0x06;
- }
- break;
- case 0xc3: /* 450, 4/0/0/0, 2 */
- gr->magic_not_rop_nr = 0x03;
- break;
- case 0xc4: /* 460, 3/4/0/0, 4 */
- gr->magic_not_rop_nr = 0x01;
- break;
- case 0xc1: /* 2/0/0/0, 1 */
- gr->magic_not_rop_nr = 0x01;
- break;
- case 0xc8: /* 4/4/3/4, 5 */
- gr->magic_not_rop_nr = 0x06;
- break;
- case 0xce: /* 4/4/0/0, 4 */
- gr->magic_not_rop_nr = 0x03;
- break;
- case 0xcf: /* 4/0/0/0, 3 */
- gr->magic_not_rop_nr = 0x03;
- break;
- case 0xd7:
- case 0xd9: /* 1/0/0/0, 1 */
- case 0xea: /* gk20a */
- case 0x12b: /* gm20b */
- gr->magic_not_rop_nr = 0x01;
- break;
- }
-
- return 0;
-}
-
#include "fuc/hubgf100.fuc3.h"
struct gf100_gr_ucode
static const struct gf100_gr_func
gf100_gr = {
+ .init = gf100_gr_init,
+ .mmio = gf100_gr_pack_mmio,
+ .fecs.ucode = &gf100_gr_fecs_ucode,
+ .gpccs.ucode = &gf100_gr_gpccs_ucode,
.grctx = &gf100_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
}
};
-struct nvkm_oclass *
-gf100_gr_oclass = &(struct gf100_gr_oclass) {
- .base.handle = NV_ENGINE(GR, 0xc0),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = gf100_gr_ctor,
- .dtor = gf100_gr_dtor,
- .init = gf100_gr_init,
- .fini = _nvkm_gr_fini,
- },
- .func = &gf100_gr,
- .mmio = gf100_gr_pack_mmio,
- .fecs.ucode = &gf100_gr_fecs_ucode,
- .gpccs.ucode = &gf100_gr_gpccs_ucode,
-}.base;
+int
+gf100_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
+{
+ return gf100_gr_new_(&gf100_gr, device, index, pgr);
+}
*
* 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"
};
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;
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 {
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;
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 *);
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 },
}
};
-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);
+}
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 },
}
};
-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);
+}
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 },
}
};
-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);
+}
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 },
}
};
-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);
+}
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 },
}
};
-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);
+}
#include "gf100.h"
#include "ctxgf100.h"
-#include <subdev/pmu.h>
-
#include <nvif/class.h>
/*******************************************************************************
******************************************************************************/
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);
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);
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
.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);
+}
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 },
}
};
-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);
+}
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 },
}
};
-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);
+}
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 },
}
};
-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);
+}
* 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>
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)
{
}
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] = {};
int gpc, tpc;
int ret, i;
- ret = nvkm_gr_init(&gr->base);
- if (ret)
- return ret;
-
/* Clear SCC RAM */
nvkm_wr32(device, 0x40802c, 0x1);
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);
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);
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 },
}
};
-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);
+}
+++ /dev/null
-/*
- * Copyright (c) 2015, NVIDIA CORPORATION. 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 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 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.
- */
-
-#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 *);
-};
-
-#endif
}
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);
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);
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 },
}
};
-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);
+}
}
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));
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);
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 },
}
};
-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);
+}
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 },
}
};
-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);
+}
* 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>
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 },
}
};
-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);
+}
--- /dev/null
+/*
+ * 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_(>200_gr, device, index, pgr);
+}
--- /dev/null
+/*
+ * 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_(>215_gr, device, index, pgr);
+}
--- /dev/null
+/*
+ * 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
+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 },
+ {}
+ }
+};
+
+int
+mcp79_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
+{
+ return nv50_gr_new_(&mcp79_gr, device, index, pgr);
+}
--- /dev/null
+/*
+ * 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);
+}
};
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);
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);
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 */
}
};
-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,
- },
-};
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-#include "priv.h"
+#include "nv10.h"
#include "regs.h"
#include <core/client.h>
for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
nvkm_wr32(device, nv10_gr_ctx_regs[i], chan->nv10[i]);
- if (nv_device(gr)->card_type >= NV_11 &&
- nv_device(gr)->chipset >= 0x17) {
+ if (device->card_type >= NV_11 && device->chipset >= 0x17) {
for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
nvkm_wr32(device, nv17_gr_ctx_regs[i], chan->nv17[i]);
}
for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
chan->nv10[i] = nvkm_rd32(device, nv10_gr_ctx_regs[i]);
- if (nv_device(gr)->card_type >= NV_11 &&
- nv_device(gr)->chipset >= 0x17) {
+ if (device->card_type >= NV_11 && device->chipset >= 0x17) {
for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
chan->nv17[i] = nvkm_rd32(device, nv17_gr_ctx_regs[i]);
}
chan->nv17[offset] = val; \
} while (0)
-static int
+int
nv10_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
const struct nvkm_oclass *oclass, struct nvkm_object **pobject)
{
* PGRAPH engine/subdev functions
******************************************************************************/
-static void
-nv10_gr_tile_prog(struct nvkm_engine *engine, int i)
+void
+nv10_gr_tile(struct nvkm_gr *base, int i, struct nvkm_fb_tile *tile)
{
- struct nv10_gr *gr = (void *)engine;
+ struct nv10_gr *gr = nv10_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);
{}
};
-static void
-nv10_gr_intr(struct nvkm_subdev *subdev)
+void
+nv10_gr_intr(struct nvkm_gr *base)
{
- struct nv10_gr *gr = (void *)subdev;
- struct nv10_gr_chan *chan = NULL;
- struct nvkm_device *device = gr->base.engine.subdev.device;
+ struct nv10_gr *gr = nv10_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);
u32 class = nvkm_rd32(device, 0x400160 + subc * 4) & 0xfff;
u32 show = stat;
char msg[128], src[128], sta[128];
+ struct nv10_gr_chan *chan;
unsigned long flags;
spin_lock_irqsave(&gr->lock, flags);
spin_unlock_irqrestore(&gr->lock, flags);
}
-static const struct nvkm_gr_func
-nv10_gr = {
- .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, 0x0056, &nv04_gr_object }, /* celcius */
- {}
- }
-};
-
-static const struct nvkm_gr_func
-nv15_gr = {
- .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 */
- {}
- }
-};
-
-
-static const struct nvkm_gr_func
-nv17_gr = {
- .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 },
- {}
- }
-};
-
-static int
-nv10_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
-{
- struct nv10_gr *gr;
- int ret;
-
- ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
- *pobject = nv_object(gr);
- if (ret)
- return ret;
-
- nv_subdev(gr)->unit = 0x00001000;
- nv_subdev(gr)->intr = nv10_gr_intr;
-
- if (nv_device(gr)->chipset <= 0x10)
- gr->base.func = &nv10_gr;
- else
- if (nv_device(gr)->chipset < 0x17 ||
- nv_device(gr)->card_type < NV_11)
- gr->base.func = &nv15_gr;
- else
- gr->base.func = &nv17_gr;
-
- nv_engine(gr)->tile_prog = nv10_gr_tile_prog;
- spin_lock_init(&gr->lock);
- return 0;
-}
-
-static void
-nv10_gr_dtor(struct nvkm_object *object)
+int
+nv10_gr_init(struct nvkm_gr *base)
{
- struct nv10_gr *gr = (void *)object;
- nvkm_gr_destroy(&gr->base);
-}
-
-static int
-nv10_gr_init(struct nvkm_object *object)
-{
- struct nvkm_engine *engine = nv_engine(object);
- struct nv10_gr *gr = (void *)engine;
+ struct nv10_gr *gr = nv10_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, NV03_PGRAPH_INTR , 0xFFFFFFFF);
nvkm_wr32(device, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31));
- if (nv_device(gr)->card_type >= NV_11 &&
- nv_device(gr)->chipset >= 0x17) {
+ if (device->card_type >= NV_11 && device->chipset >= 0x17) {
nvkm_wr32(device, NV10_PGRAPH_DEBUG_4, 0x1f000000);
nvkm_wr32(device, 0x400a10, 0x03ff3fb6);
nvkm_wr32(device, 0x400838, 0x002f8684);
nvkm_wr32(device, NV10_PGRAPH_DEBUG_4, 0x00000000);
}
- /* 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_SWITCH(0), 0x00000000);
nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
return 0;
}
-static int
-nv10_gr_fini(struct nvkm_object *object, bool suspend)
+int
+nv10_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
+ int index, struct nvkm_gr **pgr)
{
- struct nv10_gr *gr = (void *)object;
- return nvkm_gr_fini(&gr->base, suspend);
+ struct nv10_gr *gr;
+
+ if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
+ return -ENOMEM;
+ spin_lock_init(&gr->lock);
+ *pgr = &gr->base;
+
+ return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base);
}
-struct nvkm_oclass
-nv10_gr_oclass = {
- .handle = NV_ENGINE(GR, 0x10),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv10_gr_ctor,
- .dtor = nv10_gr_dtor,
- .init = nv10_gr_init,
- .fini = nv10_gr_fini,
- },
+static const struct nvkm_gr_func
+nv10_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, 0x0056, &nv04_gr_object }, /* celcius */
+ {}
+ }
};
+
+int
+nv10_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
+{
+ return nv10_gr_new_(&nv10_gr, device, index, pgr);
+}
--- /dev/null
+#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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
******************************************************************************/
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);
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);
}
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);
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);
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);
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));
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);
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);
+}
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 {
};
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
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 */
}
};
-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,
- },
-};
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 */
}
};
-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,
- },
-};
* 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);
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);
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);
/* 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);
+}
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 */
}
};
-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,
- },
-};
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 */
}
};
-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,
- },
-};
#include <subdev/timer.h>
#include <engine/fifo.h>
-static u64
+u64
nv40_gr_units(struct nvkm_gr *gr)
{
return nvkm_rd32(gr->engine.subdev.device, 0x1540);
return ret;
}
-static const struct nvkm_object_func
+const struct nvkm_object_func
nv40_gr_object = {
.bind = nv40_gr_object_bind,
};
.bind = nv40_gr_chan_bind,
};
-static int
+int
nv40_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
const struct nvkm_oclass *oclass, struct nvkm_object **pobject)
{
******************************************************************************/
static void
-nv40_gr_tile_prog(struct nvkm_engine *engine, int i)
+nv40_gr_tile(struct nvkm_gr *base, int i, struct nvkm_fb_tile *tile)
{
- struct nv40_gr *gr = (void *)engine;
+ struct nv40_gr *gr = nv40_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);
nv04_gr_idle(&gr->base);
- switch (nv_device(gr)->chipset) {
+ switch (device->chipset) {
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x45:
- 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);
- switch (nv_device(gr)->chipset) {
+ switch (device->chipset) {
case 0x40:
case 0x45:
nvkm_wr32(device, NV20_PGRAPH_ZCOMP(i), tile->zcomp);
break;
}
break;
- 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 0x47:
case 0x49:
case 0x4b:
- 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);
- switch (nv_device(gr)->chipset) {
- case 0x47:
- case 0x49:
- case 0x4b:
- nvkm_wr32(device, NV47_PGRAPH_ZCOMP0(i), tile->zcomp);
- nvkm_wr32(device, NV47_PGRAPH_ZCOMP1(i), tile->zcomp);
- break;
- default:
- break;
- }
+ nvkm_wr32(device, NV47_PGRAPH_ZCOMP0(i), tile->zcomp);
+ nvkm_wr32(device, NV47_PGRAPH_ZCOMP1(i), tile->zcomp);
break;
default:
+ WARN_ON(1);
break;
}
nvkm_fifo_start(fifo, &flags);
}
-static void
-nv40_gr_intr(struct nvkm_subdev *subdev)
+void
+nv40_gr_intr(struct nvkm_gr *base)
{
- struct nv40_gr *gr = (void *)subdev;
+ struct nv40_gr *gr = nv40_gr(base);
struct nv40_gr_chan *temp, *chan = NULL;
- struct nvkm_device *device = gr->base.engine.subdev.device;
+ 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);
spin_unlock_irqrestore(&gr->base.engine.lock, flags);
}
-static const struct nvkm_gr_func
-nv40_gr = {
- .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, 0x4097, &nv40_gr_object }, /* curie */
- {}
- }
-};
-
-static const struct nvkm_gr_func
-nv44_gr = {
- .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 */
- {}
- }
-};
-
-static int
-nv40_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 nv40_gr *gr;
- int ret;
-
- ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
- *pobject = nv_object(gr);
- if (ret)
- return ret;
-
- INIT_LIST_HEAD(&gr->chan);
-
- nv_subdev(gr)->unit = 0x00001000;
- nv_subdev(gr)->intr = nv40_gr_intr;
- if (nv44_gr_class(device))
- gr->base.func = &nv44_gr;
- else
- gr->base.func = &nv40_gr;
- nv_engine(gr)->tile_prog = nv40_gr_tile_prog;
-
- gr->base.units = nv40_gr_units;
- return 0;
-}
-
-static int
-nv40_gr_init(struct nvkm_object *object)
+int
+nv40_gr_init(struct nvkm_gr *base)
{
- struct nvkm_engine *engine = nv_engine(object);
- struct nv40_gr *gr = (void *)engine;
+ struct nv40_gr *gr = nv40_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device;
- struct nvkm_fb *fb = device->fb;
int ret, i, j;
u32 vramsz;
- ret = nvkm_gr_init(&gr->base);
- if (ret)
- return ret;
-
/* generate and upload context program */
- ret = nv40_grctx_init(nv_device(gr), &gr->size);
+ ret = nv40_grctx_init(device, &gr->size);
if (ret)
return ret;
nvkm_wr32(device, 0x405000, i);
}
- if (nv_device(gr)->chipset == 0x40) {
+ if (device->chipset == 0x40) {
nvkm_wr32(device, 0x4009b0, 0x83280fff);
nvkm_wr32(device, 0x4009b4, 0x000000a0);
} else {
nvkm_wr32(device, 0x400824, 0x000000a0);
}
- switch (nv_device(gr)->chipset) {
+ switch (device->chipset) {
case 0x40:
case 0x45:
nvkm_wr32(device, 0x4009b8, 0x0078e366);
nvkm_wr32(device, 0x400b3c, 0x00006000);
/* Tiling related stuff. */
- switch (nv_device(gr)->chipset) {
+ switch (device->chipset) {
case 0x44:
case 0x4a:
nvkm_wr32(device, 0x400bc4, 0x1003d888);
break;
}
- /* Turn all the tiling regions off. */
- for (i = 0; i < fb->tile.regions; i++)
- engine->tile_prog(engine, i);
-
/* begin RAM config */
- vramsz = nv_device_resource_len(nv_device(gr), 1) - 1;
- switch (nv_device(gr)->chipset) {
+ vramsz = nv_device_resource_len(device, 1) - 1;
+ switch (device->chipset) {
case 0x40:
nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200));
nvkm_wr32(device, 0x4009A8, nvkm_rd32(device, 0x100204));
nvkm_wr32(device, 0x400868, vramsz);
break;
default:
- switch (nv_device(gr)->chipset) {
+ switch (device->chipset) {
case 0x41:
case 0x42:
case 0x43:
return 0;
}
-struct nvkm_oclass
-nv40_gr_oclass = {
- .handle = NV_ENGINE(GR, 0x40),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv40_gr_ctor,
- .dtor = _nvkm_gr_dtor,
- .init = nv40_gr_init,
- .fini = _nvkm_gr_fini,
- },
+int
+nv40_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
+ int index, struct nvkm_gr **pgr)
+{
+ struct nv40_gr *gr;
+
+ if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
+ return -ENOMEM;
+ *pgr = &gr->base;
+ INIT_LIST_HEAD(&gr->chan);
+
+ return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base);
+}
+
+static const struct nvkm_gr_func
+nv40_gr = {
+ .init = nv40_gr_init,
+ .intr = nv40_gr_intr,
+ .tile = nv40_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, 0x4097, &nv40_gr_object }, /* curie */
+ {}
+ }
};
+
+int
+nv40_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
+{
+ return nv40_gr_new_(&nv40_gr, device, index, pgr);
+}
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 {
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
*/
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);
--- /dev/null
+/*
+ * 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);
+}
#include <core/client.h>
#include <core/gpuobj.h>
-#include <subdev/timer.h>
#include <engine/fifo.h>
-static u64
+u64
nv50_gr_units(struct nvkm_gr *gr)
{
return nvkm_rd32(gr->engine.subdev.device, 0x1540);
return ret;
}
-static const struct nvkm_object_func
+const struct nvkm_object_func
nv50_gr_object = {
.bind = nv50_gr_object_bind,
};
-static int
-nv50_gr_object_get(struct nvkm_gr *base, int index, struct nvkm_sclass *sclass)
-{
- struct nv50_gr *gr = nv50_gr(base);
- int c = 0;
-
- while (gr->func->sclass[c].oclass) {
- if (c++ == index) {
- *sclass = gr->func->sclass[index];
- return index;
- }
- }
-
- return c;
-}
-
/*******************************************************************************
* PGRAPH context
******************************************************************************/
.bind = nv50_gr_chan_bind,
};
-static int
+int
nv50_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
const struct nvkm_oclass *oclass, struct nvkm_object **pobject)
{
* PGRAPH engine/subdev functions
******************************************************************************/
-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);
-}
-
-static int
-g84_gr_tlb_flush(struct nvkm_engine *engine)
-{
- struct nv50_gr *gr = (void *)engine;
- 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_bitfield nv50_mp_exec_errors[] = {
{ 0x01, "STACK_UNDERFLOW" },
{ 0x02, "STACK_MISMATCH" },
for (i = 0; i < 4; i++) {
if (!(units & 1 << (i+24)))
continue;
- if (nv_device(gr)->chipset < 0xa0)
+ if (device->chipset < 0xa0)
addr = 0x408200 + (tpid << 12) + (i << 7);
else
addr = 0x408100 + (tpid << 11) + (i << 7);
for (i = 0; i < 16; i++) {
if (!(units & (1 << i)))
continue;
- if (nv_device(gr)->chipset < 0xa0)
+ if (device->chipset < 0xa0)
ustatus_addr = ustatus_old + (i << 12);
else
ustatus_addr = ustatus_new + (i << 11);
return 1;
}
-static void
-nv50_gr_intr(struct nvkm_subdev *subdev)
+void
+nv50_gr_intr(struct nvkm_gr *base)
{
- struct nv50_gr *gr = (void *)subdev;
- struct nvkm_device *device = gr->base.engine.subdev.device;
+ struct nv50_gr *gr = nv50_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, 0x400100);
u32 inst = nvkm_rd32(device, 0x40032c) & 0x0fffffff;
nvkm_fifo_chan_put(device->fifo, flags, &chan);
}
-static const struct nv50_gr_func
-nv50_gr = {
- .sclass = {
- { -1, -1, 0x0030, &nv50_gr_object },
- { -1, -1, 0x502d, &nv50_gr_object },
- { -1, -1, 0x5039, &nv50_gr_object },
- { -1, -1, 0x5097, &nv50_gr_object },
- { -1, -1, 0x50c0, &nv50_gr_object },
- {}
- }
-};
-
-static const struct nv50_gr_func
-g84_gr = {
- .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 },
- {}
- }
-};
-
-static const struct nv50_gr_func
-gt200_gr = {
- .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 },
- {}
- }
-};
-
-static const struct nv50_gr_func
-gt215_gr = {
- .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 },
- {}
- }
-};
-
-static const struct nv50_gr_func
-mcp89_gr = {
- .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 },
- {}
- }
-};
-
-static const struct nvkm_gr_func
-nv50_gr_ = {
- .chan_new = nv50_gr_chan_new,
- .object_get = nv50_gr_object_get,
-};
-
-static int
-nv50_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
-{
- struct nv50_gr *gr;
- int ret;
-
- ret = nvkm_gr_create(parent, engine, oclass, true, &gr);
- *pobject = nv_object(gr);
- if (ret)
- return ret;
-
- nv_subdev(gr)->unit = 0x00201000;
- nv_subdev(gr)->intr = nv50_gr_intr;
-
- gr->base.func = &nv50_gr_;
- gr->base.units = nv50_gr_units;
-
- switch (nv_device(gr)->chipset) {
- case 0x50:
- gr->func = &nv50_gr;
- break;
- case 0x84:
- case 0x86:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0x98:
- gr->func = &g84_gr;
- break;
- case 0xa0:
- case 0xaa:
- case 0xac:
- gr->func = >200_gr;
- break;
- case 0xa3:
- case 0xa5:
- case 0xa8:
- gr->func = >215_gr;
- break;
- case 0xaf:
- gr->func = &mcp89_gr;
- break;
- }
-
- /* unfortunate hw bug workaround... */
- if (nv_device(gr)->chipset != 0x50 &&
- nv_device(gr)->chipset != 0xac)
- nv_engine(gr)->tlb_flush = g84_gr_tlb_flush;
-
- spin_lock_init(&gr->lock);
- return 0;
-}
-
-static int
-nv50_gr_init(struct nvkm_object *object)
+int
+nv50_gr_init(struct nvkm_gr *base)
{
- struct nv50_gr *gr = (void *)object;
+ struct nv50_gr *gr = nv50_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device;
int ret, units, i;
- ret = nvkm_gr_init(&gr->base);
- if (ret)
- return ret;
-
/* NV_PGRAPH_DEBUG_3_HW_CTX_SWITCH_ENABLED */
nvkm_wr32(device, 0x40008c, 0x00000004);
if (!(units & (1 << i)))
continue;
- if (nv_device(gr)->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
nvkm_wr32(device, 0x408900 + (i << 12), 0xc0000000);
nvkm_wr32(device, 0x408e08 + (i << 12), 0xc0000000);
nvkm_wr32(device, 0x408314 + (i << 12), 0xc0000000);
nvkm_wr32(device, 0x400500, 0x00010001);
/* upload context program, initialise ctxctl defaults */
- ret = nv50_grctx_init(nv_device(gr), &gr->size);
+ ret = nv50_grctx_init(device, &gr->size);
if (ret)
return ret;
nvkm_wr32(device, 0x400330, 0x00000000);
/* some unknown zcull magic */
- switch (nv_device(gr)->chipset & 0xf0) {
+ switch (device->chipset & 0xf0) {
case 0x50:
case 0x80:
case 0x90:
break;
case 0xa0:
default:
- if (nv_device(gr)->chipset == 0xa0 ||
- nv_device(gr)->chipset == 0xaa ||
- nv_device(gr)->chipset == 0xac) {
+ if (device->chipset == 0xa0 ||
+ device->chipset == 0xaa ||
+ device->chipset == 0xac) {
nvkm_wr32(device, 0x402ca8, 0x00000802);
} else {
nvkm_wr32(device, 0x402cc0, 0x00000000);
nvkm_wr32(device, 0x402c28 + (i * 0x10), 0x00000000);
nvkm_wr32(device, 0x402c2c + (i * 0x10), 0x00000000);
}
+
return 0;
}
-struct nvkm_oclass
-nv50_gr_oclass = {
- .handle = NV_ENGINE(GR, 0x50),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv50_gr_ctor,
- .dtor = _nvkm_gr_dtor,
- .init = nv50_gr_init,
- .fini = _nvkm_gr_fini,
- },
+int
+nv50_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
+ int index, struct nvkm_gr **pgr)
+{
+ struct nv50_gr *gr;
+
+ if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
+ return -ENOMEM;
+ spin_lock_init(&gr->lock);
+ *pgr = &gr->base;
+
+ return nvkm_gr_ctor(func, device, index, 0x00201000, true, &gr->base);
+}
+
+static const struct nvkm_gr_func
+nv50_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, 0x5097, &nv50_gr_object },
+ { -1, -1, 0x50c0, &nv50_gr_object },
+ {}
+ }
};
+
+int
+nv50_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
+{
+ return nv50_gr_new_(&nv50_gr, device, index, pgr);
+}
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)
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
#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
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
*/
#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])
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) {