};
static inline void
-nvkm_alarm_init(struct nvkm_alarm *alarm,
- void (*func)(struct nvkm_alarm *))
+nvkm_alarm_init(struct nvkm_alarm *alarm, void (*func)(struct nvkm_alarm *))
{
INIT_LIST_HEAD(&alarm->head);
alarm->func = func;
}
-void nvkm_timer_alarm(void *, u32 nsec, struct nvkm_alarm *);
-void nvkm_timer_alarm_cancel(void *, struct nvkm_alarm *);
+struct nvkm_timer {
+ const struct nvkm_timer_func *func;
+ struct nvkm_subdev subdev;
+
+ struct list_head alarms;
+ spinlock_t lock;
+};
+
+u64 nvkm_timer_read(struct nvkm_timer *);
+void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *);
+void nvkm_timer_alarm_cancel(struct nvkm_timer *, struct nvkm_alarm *);
/* Delay based on GPU time (ie. PTIMER).
*
#define nvkm_nsec(d,n,cond...) ({ \
struct nvkm_device *_device = (d); \
struct nvkm_timer *_tmr = _device->timer; \
- u64 _nsecs = (n), _time0 = _tmr->read(_tmr); \
+ u64 _nsecs = (n), _time0 = nvkm_timer_read(_tmr); \
s64 _taken = 0; \
- bool _warn = true; \
+ bool _warn = true; \
\
do { \
cond \
- } while (_taken = _tmr->read(_tmr) - _time0, _taken < _nsecs); \
+ } while (_taken = nvkm_timer_read(_tmr) - _time0, _taken < _nsecs); \
\
if (_taken >= _nsecs) { \
if (_warn) { \
#define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond)
#define nvkm_msec(d,m,cond...) nvkm_usec((d), (m) * 1000, ##cond)
-struct nvkm_timer {
- struct nvkm_subdev subdev;
- u64 (*read)(struct nvkm_timer *);
- void (*alarm)(struct nvkm_timer *, u64 time, struct nvkm_alarm *);
- void (*alarm_cancel)(struct nvkm_timer *, struct nvkm_alarm *);
-};
-
-static inline struct nvkm_timer *
-nvkm_timer(void *obj)
-{
- return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_TIMER);
-}
-
-#define nvkm_timer_create(p,e,o,d) \
- nvkm_subdev_create_((p), (e), (o), 0, "PTIMER", "timer", \
- sizeof(**d), (void **)d)
-#define nvkm_timer_destroy(p) \
- nvkm_subdev_destroy(&(p)->subdev)
-#define nvkm_timer_init(p) \
- nvkm_subdev_init_old(&(p)->subdev)
-#define nvkm_timer_fini(p,s) \
- nvkm_subdev_fini_old(&(p)->subdev, (s))
-
-int nvkm_timer_create_(struct nvkm_object *, struct nvkm_engine *,
- struct nvkm_oclass *, int size, void **);
-
-extern struct nvkm_oclass nv04_timer_oclass;
-extern struct nvkm_oclass gk20a_timer_oclass;
+int nv04_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
+int nv40_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
+int nv41_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
+int gk20a_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
#endif
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv04_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv04_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .gr = nv10_gr_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv10_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv10_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv10_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.imem = nv04_instmem_new,
.mc = nv04_mc_new,
.mmu = nv04_mmu_new,
-// .timer = nv04_timer_new,
+ .timer = nv04_timer_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
// .fifo = nv17_fifo_new,
.mc = nv40_mc_new,
.mmu = nv04_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv40_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv40_mc_new,
.mmu = nv41_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv40_mc_new,
.mmu = nv41_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv40_mc_new,
.mmu = nv41_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv44_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv40_mc_new,
.mmu = nv04_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv44_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv40_mc_new,
.mmu = nv41_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv40_mc_new,
.mmu = nv41_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv44_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv40_mc_new,
.mmu = nv41_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv4c_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv4c_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = nv50_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv50_disp_new,
// .dma = nv50_dma_new,
.mc = nv4c_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv4c_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mc = nv4c_mc_new,
.mmu = nv44_mmu_new,
.therm = nv40_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = nv04_disp_new,
// .dma = nv04_dma_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = g84_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .bsp = g84_bsp_new,
// .cipher = g84_cipher_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = g84_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .bsp = g84_bsp_new,
// .cipher = g84_cipher_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = g84_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .bsp = g84_bsp_new,
// .cipher = g84_cipher_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = g84_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .bsp = g84_bsp_new,
// .cipher = g84_cipher_new,
.devinit = g84_devinit_new,
.mc = g94_mc_new,
.bus = g94_bus_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
.fb = g84_fb_new,
.imem = nv50_instmem_new,
.mmu = nv50_mmu_new,
.devinit = g98_devinit_new,
.mc = g98_mc_new,
.bus = g94_bus_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
.fb = g84_fb_new,
.imem = nv50_instmem_new,
.mmu = nv50_mmu_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = g84_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .bsp = g84_bsp_new,
// .cipher = g84_cipher_new,
.mxm = nv50_mxm_new,
.pmu = gt215_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gt215_ce_new,
// .disp = gt215_disp_new,
.mxm = nv50_mxm_new,
.pmu = gt215_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gt215_ce_new,
// .disp = gt215_disp_new,
.mxm = nv50_mxm_new,
.pmu = gt215_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gt215_ce_new,
// .disp = gt215_disp_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = g84_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = g94_disp_new,
// .dma = nv50_dma_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.therm = g84_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .disp = g94_disp_new,
// .dma = nv50_dma_new,
.mxm = nv50_mxm_new,
.pmu = gt215_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gt215_ce_new,
// .disp = gt215_disp_new,
.mxm = nv50_mxm_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .ce[1] = gf100_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .disp = gt215_disp_new,
.mxm = nv50_mxm_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .disp = gt215_disp_new,
.mxm = nv50_mxm_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .ce[1] = gf100_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .ce[1] = gf100_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .ce[1] = gf100_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .disp = gt215_disp_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .ce[0] = gf100_ce0_new,
// .disp = gf119_disp_new,
// .dma = gf119_dma_new,
.mxm = nv50_mxm_new,
.pmu = gf119_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gf100_ce0_new,
// .disp = gf119_disp_new,
.mxm = nv50_mxm_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gk104_ce0_new,
// .ce[1] = gk104_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gk104_ce0_new,
// .ce[1] = gk104_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gf119_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gk104_ce0_new,
// .ce[1] = gk104_ce1_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.pmu = gk20a_pmu_new,
-// .timer = gk20a_timer_new,
+ .timer = gk20a_timer_new,
// .volt = gk20a_volt_new,
// .ce[2] = gk104_ce2_new,
// .dma = gf119_dma_new,
.mxm = nv50_mxm_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gk104_ce0_new,
// .ce[1] = gk104_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gk104_ce0_new,
// .ce[1] = gk104_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gk104_ce0_new,
// .ce[1] = gk104_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
-// .timer = nv04_timer_new,
+ .timer = nv41_timer_new,
// .volt = nv40_volt_new,
// .ce[0] = gk104_ce0_new,
// .ce[1] = gk104_ce1_new,
.mxm = nv50_mxm_new,
.pmu = gm107_pmu_new,
.therm = gm107_therm_new,
-// .timer = gk20a_timer_new,
+ .timer = gk20a_timer_new,
// .ce[0] = gk104_ce0_new,
// .ce[2] = gk104_ce2_new,
// .disp = gm107_disp_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pmu = gm107_pmu_new,
-// .timer = gk20a_timer_new,
+ .timer = gk20a_timer_new,
// .ce[0] = gm204_ce0_new,
// .ce[1] = gm204_ce1_new,
// .ce[2] = gm204_ce2_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pmu = gm107_pmu_new,
-// .timer = gk20a_timer_new,
+ .timer = gk20a_timer_new,
// .ce[0] = gm204_ce0_new,
// .ce[1] = gm204_ce1_new,
// .ce[2] = gm204_ce2_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mmu = gf100_mmu_new,
-// .timer = gk20a_timer_new,
+ .timer = gk20a_timer_new,
// .ce[2] = gm204_ce2_new,
// .dma = gf119_dma_new,
// .fifo = gm20b_fifo_new,
{
switch (device->chipset) {
case 0xc0:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xc4:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xc3:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xce:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xcf:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xc1:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf108_pm_oclass;
break;
case 0xc8:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf100_pm_oclass;
break;
case 0xd9:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gf117_pm_oclass;
break;
case 0xd7:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
{
switch (device->chipset) {
case 0xe4:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break;
case 0xe7:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break;
case 0xe6:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gk104_pm_oclass;
break;
case 0xea:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk20a_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &gk20a_volt_oclass;
break;
case 0xf0:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
break;
case 0xf1:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
break;
case 0x106:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
break;
case 0x108:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
{
switch (device->chipset) {
case 0x117:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
/* looks to be some non-trivial changes */
/* priv ring says no to 0x10eb14 writes */
#endif
- device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
#endif
/* looks to be some non-trivial changes */
/* priv ring says no to 0x10eb14 writes */
#endif
- device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
#endif
break;
case 0x12b:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gm20b_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
{
switch (device->chipset) {
case 0x04:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x05:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
{
switch (device->chipset) {
case 0x10:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x15:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x16:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x1a:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x11:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x17:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x1f:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x18:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
{
switch (device->chipset) {
case 0x20:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x25:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x28:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x2a:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
{
switch (device->chipset) {
case 0x30:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x35:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x31:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x36:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x34:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
{
switch (device->chipset) {
case 0x40:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x41:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x42:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x43:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x45:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x47:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x49:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4b:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x44:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x46:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4a:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4c:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4e:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x63:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x67:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x68:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
{
switch (device->chipset) {
case 0x50:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv50_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = nv50_pm_oclass;
break;
case 0x84:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0x86:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0x92:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0x94:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0x96:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0x98:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0xa0:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt200_pm_oclass;
break;
case 0xaa:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0xac:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
break;
case 0xa3:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break;
case 0xa5:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break;
case 0xa8:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
break;
case 0xaf:
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
nvkm_udevice_time(struct nvkm_udevice *udev, void *data, u32 size)
{
struct nvkm_device *device = udev->device;
- struct nvkm_timer *tmr = device->timer;
union {
struct nv_device_time_v0 v0;
} *args = data;
int ret;
if (nvif_unpack(args->v0, 0, 0, false)) {
- args->v0.time = tmr->read(tmr);
+ args->v0.time = nvkm_timer_read(device->timer);
}
return ret;
spin_lock_irqsave(&gr->lock, flags);
nvkm_mask(device, 0x400500, 0x00000001, 0x00000000);
- start = tmr->read(tmr);
+ start = nvkm_timer_read(tmr);
do {
idle = true;
idle = false;
}
} while (!idle &&
- !(timeout = tmr->read(tmr) - start > 2000000000));
+ !(timeout = nvkm_timer_read(tmr) - start > 2000000000));
if (timeout) {
nvkm_error(subdev, "PGRAPH TLB flush idle timeout fail\n");
struct nvkm_subdev *subdev = &pmu->base.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_clk *clk = device->clk;
+ struct nvkm_timer *tmr = device->timer;
struct nvkm_volt *volt = device->volt;
u32 utilization = 0;
int state, ret;
resched:
gk20a_pmu_dvfs_reset_dev_status(pmu);
- nvkm_timer_alarm(pmu, 100000000, alarm);
+ nvkm_timer_alarm(tmr, 100000000, alarm);
}
static int
gk20a_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
{
struct gk20a_pmu *pmu = gk20a_pmu(subdev);
- nvkm_timer_alarm_cancel(pmu, &pmu->alarm);
+ nvkm_timer_alarm_cancel(subdev->device->timer, &pmu->alarm);
return 0;
}
nvkm_wr32(device, 0x10a50c + (BUSY_SLOT * 0x10), 0x00000002);
nvkm_wr32(device, 0x10a50c + (CLK_SLOT * 0x10), 0x00000003);
- nvkm_timer_alarm(pmu, 2000000000, &pmu->alarm);
+ nvkm_timer_alarm(device->timer, 2000000000, &pmu->alarm);
return 0;
}
switch (mode) {
case NVKM_THERM_CTRL_MANUAL:
- tmr->alarm_cancel(tmr, &therm->alarm);
+ nvkm_timer_alarm_cancel(tmr, &therm->alarm);
duty = nvkm_therm_fan_get(therm);
if (duty < 0)
duty = 100;
break;
case NVKM_THERM_CTRL_NONE:
default:
- tmr->alarm_cancel(tmr, &therm->alarm);
+ nvkm_timer_alarm_cancel(tmr, &therm->alarm);
poll = false;
}
if (list_empty(&therm->alarm.head) && poll)
- tmr->alarm(tmr, 1000000000ULL, &therm->alarm);
+ nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm);
spin_unlock_irqrestore(&therm->lock, flags);
if (duty >= 0) {
else
delay = bump_period;
- tmr->alarm(tmr, delay * 1000 * 1000, &fan->alarm);
+ nvkm_timer_alarm(tmr, delay * 1000 * 1000, &fan->alarm);
}
return ret;
* When the fan spins, it changes the value of GPIO FAN_SENSE.
* We get 4 changes (0 -> 1 -> 0 -> 1) per complete rotation.
*/
- start = tmr->read(tmr);
+ start = nvkm_timer_read(tmr);
prev = nvkm_gpio_get(gpio, 0, therm->fan->tach.func,
therm->fan->tach.line);
cycles = 0;
therm->fan->tach.line);
if (prev != cur) {
if (!start)
- start = tmr->read(tmr);
+ start = nvkm_timer_read(tmr);
cycles++;
prev = cur;
}
- } while (cycles < 5 && tmr->read(tmr) - start < 250000000);
- end = tmr->read(tmr);
+ } while (cycles < 5 && nvkm_timer_read(tmr) - start < 250000000);
+ end = nvkm_timer_read(tmr);
if (cycles == 5) {
tach = (u64)60000000000ULL;
{
struct nvkm_timer *tmr = therm->subdev.device->timer;
if (suspend)
- tmr->alarm_cancel(tmr, &therm->fan->alarm);
+ nvkm_timer_alarm_cancel(tmr, &therm->fan->alarm);
return 0;
}
u64 next_change = (percent * fan->period_us) / 100;
if (!duty)
next_change = fan->period_us - next_change;
- tmr->alarm(tmr, next_change * 1000, &fan->alarm);
+ nvkm_timer_alarm(tmr, next_change * 1000, &fan->alarm);
}
spin_unlock_irqrestore(&fan->lock, flags);
}
/* schedule the next poll in one second */
if (therm->func->temp_get(therm) >= 0 && list_empty(&alarm->head))
- tmr->alarm(tmr, 1000000000ULL, alarm);
+ nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
}
void
{
struct nvkm_timer *tmr = therm->subdev.device->timer;
if (suspend)
- tmr->alarm_cancel(tmr, &therm->sensor.therm_poll_alarm);
+ nvkm_timer_alarm_cancel(tmr, &therm->sensor.therm_poll_alarm);
return 0;
}
nvkm-y += nvkm/subdev/timer/base.o
nvkm-y += nvkm/subdev/timer/nv04.o
+nvkm-y += nvkm/subdev/timer/nv40.o
+nvkm-y += nvkm/subdev/timer/nv41.o
nvkm-y += nvkm/subdev/timer/gk20a.o
*
* Authors: Ben Skeggs
*/
-#include <subdev/timer.h>
+#include "priv.h"
+
+u64
+nvkm_timer_read(struct nvkm_timer *tmr)
+{
+ return tmr->func->read(tmr);
+}
+
+void
+nvkm_timer_alarm_trigger(struct nvkm_timer *tmr)
+{
+ struct nvkm_alarm *alarm, *atemp;
+ unsigned long flags;
+ LIST_HEAD(exec);
+
+ /* move any due alarms off the pending list */
+ spin_lock_irqsave(&tmr->lock, flags);
+ list_for_each_entry_safe(alarm, atemp, &tmr->alarms, head) {
+ if (alarm->timestamp <= nvkm_timer_read(tmr))
+ list_move_tail(&alarm->head, &exec);
+ }
+
+ /* reschedule interrupt for next alarm time */
+ if (!list_empty(&tmr->alarms)) {
+ alarm = list_first_entry(&tmr->alarms, typeof(*alarm), head);
+ tmr->func->alarm_init(tmr, alarm->timestamp);
+ } else {
+ tmr->func->alarm_fini(tmr);
+ }
+ spin_unlock_irqrestore(&tmr->lock, flags);
+
+ /* execute any pending alarm handlers */
+ list_for_each_entry_safe(alarm, atemp, &exec, head) {
+ list_del_init(&alarm->head);
+ alarm->func(alarm);
+ }
+}
void
-nvkm_timer_alarm(void *obj, u32 nsec, struct nvkm_alarm *alarm)
+nvkm_timer_alarm(struct nvkm_timer *tmr, u32 nsec, struct nvkm_alarm *alarm)
{
- struct nvkm_timer *tmr = nvkm_timer(obj);
- tmr->alarm(tmr, nsec, alarm);
+ struct nvkm_alarm *list;
+ unsigned long flags;
+
+ alarm->timestamp = nvkm_timer_read(tmr) + nsec;
+
+ /* append new alarm to list, in soonest-alarm-first order */
+ spin_lock_irqsave(&tmr->lock, flags);
+ if (!nsec) {
+ if (!list_empty(&alarm->head))
+ list_del(&alarm->head);
+ } else {
+ list_for_each_entry(list, &tmr->alarms, head) {
+ if (list->timestamp > alarm->timestamp)
+ break;
+ }
+ list_add_tail(&alarm->head, &list->head);
+ }
+ spin_unlock_irqrestore(&tmr->lock, flags);
+
+ /* process pending alarms */
+ nvkm_timer_alarm_trigger(tmr);
}
void
-nvkm_timer_alarm_cancel(void *obj, struct nvkm_alarm *alarm)
+nvkm_timer_alarm_cancel(struct nvkm_timer *tmr, struct nvkm_alarm *alarm)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&tmr->lock, flags);
+ list_del_init(&alarm->head);
+ spin_unlock_irqrestore(&tmr->lock, flags);
+}
+
+static void
+nvkm_timer_intr(struct nvkm_subdev *subdev)
{
- struct nvkm_timer *tmr = nvkm_timer(obj);
- tmr->alarm_cancel(tmr, alarm);
+ struct nvkm_timer *tmr = nvkm_timer(subdev);
+ tmr->func->intr(tmr);
+}
+
+static int
+nvkm_timer_fini(struct nvkm_subdev *subdev, bool suspend)
+{
+ struct nvkm_timer *tmr = nvkm_timer(subdev);
+ tmr->func->alarm_fini(tmr);
+ return 0;
+}
+
+static int
+nvkm_timer_init(struct nvkm_subdev *subdev)
+{
+ struct nvkm_timer *tmr = nvkm_timer(subdev);
+ if (tmr->func->init)
+ tmr->func->init(tmr);
+ tmr->func->time(tmr, ktime_to_ns(ktime_get()));
+ nvkm_timer_alarm_trigger(tmr);
+ return 0;
+}
+
+static void *
+nvkm_timer_dtor(struct nvkm_subdev *subdev)
+{
+ return nvkm_timer(subdev);
+}
+
+static const struct nvkm_subdev_func
+nvkm_timer = {
+ .dtor = nvkm_timer_dtor,
+ .init = nvkm_timer_init,
+ .fini = nvkm_timer_fini,
+ .intr = nvkm_timer_intr,
+};
+
+int
+nvkm_timer_new_(const struct nvkm_timer_func *func, struct nvkm_device *device,
+ int index, struct nvkm_timer **ptmr)
+{
+ struct nvkm_timer *tmr;
+
+ if (!(tmr = *ptmr = kzalloc(sizeof(*tmr), GFP_KERNEL)))
+ return -ENOMEM;
+
+ nvkm_subdev_ctor(&nvkm_timer, device, index, 0, &tmr->subdev);
+ tmr->func = func;
+ INIT_LIST_HEAD(&tmr->alarms);
+ spin_lock_init(&tmr->lock);
+ return 0;
}
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
-static int
-gk20a_timer_init(struct nvkm_object *object)
-{
- struct nv04_timer *tmr = (void *)object;
- struct nvkm_subdev *subdev = &tmr->base.subdev;
- struct nvkm_device *device = subdev->device;
- u32 hi = upper_32_bits(tmr->suspend_time);
- u32 lo = lower_32_bits(tmr->suspend_time);
- int ret;
-
- ret = nvkm_timer_init(&tmr->base);
- if (ret)
- return ret;
-
- nvkm_debug(subdev, "time low : %08x\n", lo);
- nvkm_debug(subdev, "time high : %08x\n", hi);
+static const struct nvkm_timer_func
+gk20a_timer = {
+ .intr = nv04_timer_intr,
+ .read = nv04_timer_read,
+ .time = nv04_timer_time,
+ .alarm_init = nv04_timer_alarm_init,
+ .alarm_fini = nv04_timer_alarm_fini,
+};
- /* restore the time before suspend */
- nvkm_wr32(device, NV04_PTIMER_TIME_1, hi);
- nvkm_wr32(device, NV04_PTIMER_TIME_0, lo);
- return 0;
+int
+gk20a_timer_new(struct nvkm_device *device, int index, struct nvkm_timer **ptmr)
+{
+ return nvkm_timer_new_(&gk20a_timer, device, index, ptmr);
}
-
-struct nvkm_oclass
-gk20a_timer_oclass = {
- .handle = NV_SUBDEV(TIMER, 0xff),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_timer_ctor,
- .dtor = nv04_timer_dtor,
- .init = gk20a_timer_init,
- .fini = nv04_timer_fini,
- }
-};
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
+#include "regsnv04.h"
-static u64
+void
+nv04_timer_time(struct nvkm_timer *tmr, u64 time)
+{
+ struct nvkm_subdev *subdev = &tmr->subdev;
+ struct nvkm_device *device = subdev->device;
+ u32 hi = upper_32_bits(time);
+ u32 lo = lower_32_bits(time);
+
+ nvkm_debug(subdev, "time low : %08x\n", lo);
+ nvkm_debug(subdev, "time high : %08x\n", hi);
+
+ nvkm_wr32(device, NV04_PTIMER_TIME_1, hi);
+ nvkm_wr32(device, NV04_PTIMER_TIME_0, lo);
+}
+
+u64
nv04_timer_read(struct nvkm_timer *tmr)
{
struct nvkm_device *device = tmr->subdev.device;
return ((u64)hi << 32 | lo);
}
-static void
-nv04_timer_alarm_trigger(struct nvkm_timer *obj)
-{
- struct nv04_timer *tmr = container_of(obj, typeof(*tmr), base);
- struct nvkm_device *device = tmr->base.subdev.device;
- struct nvkm_alarm *alarm, *atemp;
- unsigned long flags;
- LIST_HEAD(exec);
-
- /* move any due alarms off the pending list */
- spin_lock_irqsave(&tmr->lock, flags);
- list_for_each_entry_safe(alarm, atemp, &tmr->alarms, head) {
- if (alarm->timestamp <= tmr->base.read(&tmr->base))
- list_move_tail(&alarm->head, &exec);
- }
-
- /* reschedule interrupt for next alarm time */
- if (!list_empty(&tmr->alarms)) {
- alarm = list_first_entry(&tmr->alarms, typeof(*alarm), head);
- nvkm_wr32(device, NV04_PTIMER_ALARM_0, alarm->timestamp);
- nvkm_wr32(device, NV04_PTIMER_INTR_EN_0, 0x00000001);
- } else {
- nvkm_wr32(device, NV04_PTIMER_INTR_EN_0, 0x00000000);
- }
- spin_unlock_irqrestore(&tmr->lock, flags);
-
- /* execute any pending alarm handlers */
- list_for_each_entry_safe(alarm, atemp, &exec, head) {
- list_del_init(&alarm->head);
- alarm->func(alarm);
- }
-}
-
-static void
-nv04_timer_alarm(struct nvkm_timer *obj, u64 time, struct nvkm_alarm *alarm)
+void
+nv04_timer_alarm_fini(struct nvkm_timer *tmr)
{
- struct nv04_timer *tmr = container_of(obj, typeof(*tmr), base);
- struct nvkm_alarm *list;
- unsigned long flags;
-
- alarm->timestamp = tmr->base.read(&tmr->base) + time;
-
- /* append new alarm to list, in soonest-alarm-first order */
- spin_lock_irqsave(&tmr->lock, flags);
- if (!time) {
- if (!list_empty(&alarm->head))
- list_del(&alarm->head);
- } else {
- list_for_each_entry(list, &tmr->alarms, head) {
- if (list->timestamp > alarm->timestamp)
- break;
- }
- list_add_tail(&alarm->head, &list->head);
- }
- spin_unlock_irqrestore(&tmr->lock, flags);
-
- /* process pending alarms */
- nv04_timer_alarm_trigger(&tmr->base);
+ struct nvkm_device *device = tmr->subdev.device;
+ nvkm_wr32(device, NV04_PTIMER_INTR_EN_0, 0x00000000);
}
-static void
-nv04_timer_alarm_cancel(struct nvkm_timer *obj, struct nvkm_alarm *alarm)
+void
+nv04_timer_alarm_init(struct nvkm_timer *tmr, u32 time)
{
- struct nv04_timer *tmr = container_of(obj, typeof(*tmr), base);
- unsigned long flags;
- spin_lock_irqsave(&tmr->lock, flags);
- list_del_init(&alarm->head);
- spin_unlock_irqrestore(&tmr->lock, flags);
+ struct nvkm_device *device = tmr->subdev.device;
+ nvkm_wr32(device, NV04_PTIMER_ALARM_0, time);
+ nvkm_wr32(device, NV04_PTIMER_INTR_EN_0, 0x00000001);
}
-static void
-nv04_timer_intr(struct nvkm_subdev *subdev)
+void
+nv04_timer_intr(struct nvkm_timer *tmr)
{
- struct nv04_timer *tmr = (void *)subdev;
- struct nvkm_device *device = tmr->base.subdev.device;
+ struct nvkm_subdev *subdev = &tmr->subdev;
+ struct nvkm_device *device = subdev->device;
u32 stat = nvkm_rd32(device, NV04_PTIMER_INTR_0);
if (stat & 0x00000001) {
- nv04_timer_alarm_trigger(&tmr->base);
+ nvkm_timer_alarm_trigger(tmr);
nvkm_wr32(device, NV04_PTIMER_INTR_0, 0x00000001);
stat &= ~0x00000001;
}
}
}
-int
-nv04_timer_fini(struct nvkm_object *object, bool suspend)
-{
- struct nv04_timer *tmr = (void *)object;
- struct nvkm_device *device = tmr->base.subdev.device;
- if (suspend)
- tmr->suspend_time = nv04_timer_read(&tmr->base);
- nvkm_wr32(device, NV04_PTIMER_INTR_EN_0, 0x00000000);
- return nvkm_timer_fini(&tmr->base, suspend);
-}
-
-static int
-nv04_timer_init(struct nvkm_object *object)
+static void
+nv04_timer_init(struct nvkm_timer *tmr)
{
- struct nv04_timer *tmr = (void *)object;
- struct nvkm_subdev *subdev = &tmr->base.subdev;
+ struct nvkm_subdev *subdev = &tmr->subdev;
struct nvkm_device *device = subdev->device;
- u32 m = 1, f, n, d, lo, hi;
- int ret;
-
- ret = nvkm_timer_init(&tmr->base);
- if (ret)
- return ret;
+ u32 f = 0; /*XXX: nvclk */
+ u32 n, d;
/* aim for 31.25MHz, which gives us nanosecond timestamps */
d = 1000000 / 32;
-
- /* determine base clock for timer source */
-#if 0 /*XXX*/
- if (device->chipset < 0x40) {
- n = nvkm_hw_get_clock(device, PLL_CORE);
- } else
-#endif
- if (device->chipset <= 0x40) {
- /*XXX: figure this out */
- f = -1;
- n = 0;
- } else {
- f = device->crystal;
- n = f;
- while (n < (d * 2)) {
- n += (n / m);
- m++;
+ n = f;
+
+ if (!f) {
+ n = nvkm_rd32(device, NV04_PTIMER_NUMERATOR);
+ d = nvkm_rd32(device, NV04_PTIMER_DENOMINATOR);
+ if (!n || !d) {
+ n = 1;
+ d = 1;
}
-
- nvkm_wr32(device, 0x009220, m - 1);
- }
-
- if (!n) {
nvkm_warn(subdev, "unknown input clock freq\n");
- if (!nvkm_rd32(device, NV04_PTIMER_NUMERATOR) ||
- !nvkm_rd32(device, NV04_PTIMER_DENOMINATOR)) {
- nvkm_wr32(device, NV04_PTIMER_NUMERATOR, 1);
- nvkm_wr32(device, NV04_PTIMER_DENOMINATOR, 1);
- }
- return 0;
}
/* reduce ratio to acceptable values */
d >>= 1;
}
- /* restore the time before suspend */
- lo = tmr->suspend_time;
- hi = (tmr->suspend_time >> 32);
-
nvkm_debug(subdev, "input frequency : %dHz\n", f);
- nvkm_debug(subdev, "input multiplier: %d\n", m);
nvkm_debug(subdev, "numerator : %08x\n", n);
nvkm_debug(subdev, "denominator : %08x\n", d);
- nvkm_debug(subdev, "timer frequency : %dHz\n", (f * m) * d / n);
- nvkm_debug(subdev, "time low : %08x\n", lo);
- nvkm_debug(subdev, "time high : %08x\n", hi);
+ nvkm_debug(subdev, "timer frequency : %dHz\n", f * d / n);
nvkm_wr32(device, NV04_PTIMER_NUMERATOR, n);
nvkm_wr32(device, NV04_PTIMER_DENOMINATOR, d);
- nvkm_wr32(device, NV04_PTIMER_INTR_0, 0xffffffff);
- nvkm_wr32(device, NV04_PTIMER_INTR_EN_0, 0x00000000);
- nvkm_wr32(device, NV04_PTIMER_TIME_1, hi);
- nvkm_wr32(device, NV04_PTIMER_TIME_0, lo);
- return 0;
}
-void
-nv04_timer_dtor(struct nvkm_object *object)
-{
- struct nv04_timer *tmr = (void *)object;
- return nvkm_timer_destroy(&tmr->base);
-}
+static const struct nvkm_timer_func
+nv04_timer = {
+ .init = nv04_timer_init,
+ .intr = nv04_timer_intr,
+ .read = nv04_timer_read,
+ .time = nv04_timer_time,
+ .alarm_init = nv04_timer_alarm_init,
+ .alarm_fini = nv04_timer_alarm_fini,
+};
int
-nv04_timer_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+nv04_timer_new(struct nvkm_device *device, int index, struct nvkm_timer **ptmr)
{
- struct nv04_timer *tmr;
- int ret;
-
- ret = nvkm_timer_create(parent, engine, oclass, &tmr);
- *pobject = nv_object(tmr);
- if (ret)
- return ret;
-
- tmr->base.subdev.intr = nv04_timer_intr;
- tmr->base.read = nv04_timer_read;
- tmr->base.alarm = nv04_timer_alarm;
- tmr->base.alarm_cancel = nv04_timer_alarm_cancel;
- tmr->suspend_time = 0;
-
- INIT_LIST_HEAD(&tmr->alarms);
- spin_lock_init(&tmr->lock);
- return 0;
+ return nvkm_timer_new_(&nv04_timer, device, index, ptmr);
}
-
-struct nvkm_oclass
-nv04_timer_oclass = {
- .handle = NV_SUBDEV(TIMER, 0x04),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_timer_ctor,
- .dtor = nv04_timer_dtor,
- .init = nv04_timer_init,
- .fini = nv04_timer_fini,
- }
-};
+++ /dev/null
-#ifndef __NVKM_TIMER_NV04_H__
-#define __NVKM_TIMER_NV04_H__
-#include "priv.h"
-
-#define NV04_PTIMER_INTR_0 0x009100
-#define NV04_PTIMER_INTR_EN_0 0x009140
-#define NV04_PTIMER_NUMERATOR 0x009200
-#define NV04_PTIMER_DENOMINATOR 0x009210
-#define NV04_PTIMER_TIME_0 0x009400
-#define NV04_PTIMER_TIME_1 0x009410
-#define NV04_PTIMER_ALARM_0 0x009420
-
-struct nv04_timer {
- struct nvkm_timer base;
- struct list_head alarms;
- spinlock_t lock;
- u64 suspend_time;
-};
-
-int nv04_timer_ctor(struct nvkm_object *, struct nvkm_object *,
- struct nvkm_oclass *, void *, u32,
- struct nvkm_object **);
-void nv04_timer_dtor(struct nvkm_object *);
-int nv04_timer_fini(struct nvkm_object *, bool);
-#endif
--- /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 "priv.h"
+#include "regsnv04.h"
+
+static void
+nv40_timer_init(struct nvkm_timer *tmr)
+{
+ struct nvkm_subdev *subdev = &tmr->subdev;
+ struct nvkm_device *device = subdev->device;
+ u32 f = 0; /*XXX: figure this out */
+ u32 n, d;
+
+ /* aim for 31.25MHz, which gives us nanosecond timestamps */
+ d = 1000000 / 32;
+ n = f;
+
+ if (!f) {
+ n = nvkm_rd32(device, NV04_PTIMER_NUMERATOR);
+ d = nvkm_rd32(device, NV04_PTIMER_DENOMINATOR);
+ if (!n || !d) {
+ n = 1;
+ d = 1;
+ }
+ nvkm_warn(subdev, "unknown input clock freq\n");
+ }
+
+ /* reduce ratio to acceptable values */
+ while (((n % 5) == 0) && ((d % 5) == 0)) {
+ n /= 5;
+ d /= 5;
+ }
+
+ while (((n % 2) == 0) && ((d % 2) == 0)) {
+ n /= 2;
+ d /= 2;
+ }
+
+ while (n > 0xffff || d > 0xffff) {
+ n >>= 1;
+ d >>= 1;
+ }
+
+ nvkm_debug(subdev, "input frequency : %dHz\n", f);
+ nvkm_debug(subdev, "numerator : %08x\n", n);
+ nvkm_debug(subdev, "denominator : %08x\n", d);
+ nvkm_debug(subdev, "timer frequency : %dHz\n", f * d / n);
+
+ nvkm_wr32(device, NV04_PTIMER_NUMERATOR, n);
+ nvkm_wr32(device, NV04_PTIMER_DENOMINATOR, d);
+}
+
+static const struct nvkm_timer_func
+nv40_timer = {
+ .init = nv40_timer_init,
+ .intr = nv04_timer_intr,
+ .read = nv04_timer_read,
+ .time = nv04_timer_time,
+ .alarm_init = nv04_timer_alarm_init,
+ .alarm_fini = nv04_timer_alarm_fini,
+};
+
+int
+nv40_timer_new(struct nvkm_device *device, int index, struct nvkm_timer **ptmr)
+{
+ return nvkm_timer_new_(&nv40_timer, device, index, ptmr);
+}
--- /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 "priv.h"
+#include "regsnv04.h"
+
+static void
+nv41_timer_init(struct nvkm_timer *tmr)
+{
+ struct nvkm_subdev *subdev = &tmr->subdev;
+ struct nvkm_device *device = subdev->device;
+ u32 f = device->crystal;
+ u32 m = 1, n, d;
+
+ /* aim for 31.25MHz, which gives us nanosecond timestamps */
+ d = 1000000 / 32;
+ n = f;
+
+ while (n < (d * 2)) {
+ n += (n / m);
+ m++;
+ }
+
+ /* reduce ratio to acceptable values */
+ while (((n % 5) == 0) && ((d % 5) == 0)) {
+ n /= 5;
+ d /= 5;
+ }
+
+ while (((n % 2) == 0) && ((d % 2) == 0)) {
+ n /= 2;
+ d /= 2;
+ }
+
+ while (n > 0xffff || d > 0xffff) {
+ n >>= 1;
+ d >>= 1;
+ }
+
+ nvkm_debug(subdev, "input frequency : %dHz\n", f);
+ nvkm_debug(subdev, "input multiplier: %d\n", m);
+ nvkm_debug(subdev, "numerator : %08x\n", n);
+ nvkm_debug(subdev, "denominator : %08x\n", d);
+ nvkm_debug(subdev, "timer frequency : %dHz\n", (f * m) * d / n);
+
+ nvkm_wr32(device, 0x009220, m - 1);
+ nvkm_wr32(device, NV04_PTIMER_NUMERATOR, n);
+ nvkm_wr32(device, NV04_PTIMER_DENOMINATOR, d);
+}
+
+static const struct nvkm_timer_func
+nv41_timer = {
+ .init = nv41_timer_init,
+ .intr = nv04_timer_intr,
+ .read = nv04_timer_read,
+ .time = nv04_timer_time,
+ .alarm_init = nv04_timer_alarm_init,
+ .alarm_fini = nv04_timer_alarm_fini,
+};
+
+int
+nv41_timer_new(struct nvkm_device *device, int index, struct nvkm_timer **ptmr)
+{
+ return nvkm_timer_new_(&nv41_timer, device, index, ptmr);
+}
#ifndef __NVKM_TIMER_PRIV_H__
#define __NVKM_TIMER_PRIV_H__
+#define nvkm_timer(p) container_of((p), struct nvkm_timer, subdev)
#include <subdev/timer.h>
+
+int nvkm_timer_new_(const struct nvkm_timer_func *, struct nvkm_device *,
+ int index, struct nvkm_timer **);
+
+struct nvkm_timer_func {
+ void (*init)(struct nvkm_timer *);
+ void (*intr)(struct nvkm_timer *);
+ u64 (*read)(struct nvkm_timer *);
+ void (*time)(struct nvkm_timer *, u64 time);
+ void (*alarm_init)(struct nvkm_timer *, u32 time);
+ void (*alarm_fini)(struct nvkm_timer *);
+};
+
+void nvkm_timer_alarm_trigger(struct nvkm_timer *);
+
+void nv04_timer_fini(struct nvkm_timer *);
+void nv04_timer_intr(struct nvkm_timer *);
+void nv04_timer_time(struct nvkm_timer *, u64);
+u64 nv04_timer_read(struct nvkm_timer *);
+void nv04_timer_alarm_init(struct nvkm_timer *, u32);
+void nv04_timer_alarm_fini(struct nvkm_timer *);
#endif
--- /dev/null
+#define NV04_PTIMER_INTR_0 0x009100
+#define NV04_PTIMER_INTR_EN_0 0x009140
+#define NV04_PTIMER_NUMERATOR 0x009200
+#define NV04_PTIMER_DENOMINATOR 0x009210
+#define NV04_PTIMER_TIME_0 0x009400
+#define NV04_PTIMER_TIME_1 0x009410
+#define NV04_PTIMER_ALARM_0 0x009420