From 5a5c7432bbbd2e318dff107b4ff960ab543a7cef Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 11 Jul 2012 16:08:25 +1000 Subject: drm/nouveau/timer: port to subdev interfaces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 1 + drivers/gpu/drm/nouveau/core/engine/graph/nv50.c | 5 +- .../gpu/drm/nouveau/core/include/subdev/timer.h | 53 +++++ drivers/gpu/drm/nouveau/core/subdev/device/nv04.c | 3 + drivers/gpu/drm/nouveau/core/subdev/device/nv10.c | 9 + drivers/gpu/drm/nouveau/core/subdev/device/nv20.c | 5 + drivers/gpu/drm/nouveau/core/subdev/device/nv30.c | 6 + drivers/gpu/drm/nouveau/core/subdev/device/nv40.c | 17 ++ drivers/gpu/drm/nouveau/core/subdev/device/nv50.c | 15 ++ drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c | 9 + drivers/gpu/drm/nouveau/core/subdev/device/nve0.c | 3 + drivers/gpu/drm/nouveau/core/subdev/timer/base.c | 87 ++++++++ drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c | 243 +++++++++++++++++---- drivers/gpu/drm/nouveau/nouveau_abi16.c | 2 +- drivers/gpu/drm/nouveau/nouveau_compat.c | 32 ++- drivers/gpu/drm/nouveau/nouveau_compat.h | 9 + drivers/gpu/drm/nouveau/nouveau_drv.c | 1 - drivers/gpu/drm/nouveau/nouveau_drv.h | 18 -- drivers/gpu/drm/nouveau/nouveau_pm.c | 11 +- drivers/gpu/drm/nouveau/nouveau_state.c | 88 +------- drivers/gpu/drm/nouveau/nv04_pm.c | 3 +- drivers/gpu/drm/nouveau/nv50_display.c | 6 +- 22 files changed, 464 insertions(+), 162 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/core/include/subdev/timer.h create mode 100644 drivers/gpu/drm/nouveau/core/subdev/timer/base.c (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 3ce81e5244a0..0615e954d238 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -75,6 +75,7 @@ nouveau-y += core/subdev/mc/nv44.o nouveau-y += core/subdev/mc/nv50.o nouveau-y += core/subdev/mc/nv98.o nouveau-y += core/subdev/mc/nvc0.o +nouveau-y += core/subdev/timer/base.o nouveau-y += core/subdev/timer/nv04.o nouveau-y += core/subdev/vm/base.o nouveau-y += core/subdev/vm/nv50.o diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index c22e3a0bca76..b2e9ad4dda06 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c @@ -224,7 +224,6 @@ static void nv84_graph_tlb_flush(struct drm_device *dev, int engine) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; bool idle, timeout = false; unsigned long flags; u64 start; @@ -233,7 +232,7 @@ nv84_graph_tlb_flush(struct drm_device *dev, int engine) spin_lock_irqsave(&dev_priv->context_switch_lock, flags); nv_mask(dev, 0x400500, 0x00000001, 0x00000000); - start = ptimer->read(dev); + start = nv_timer_read(dev); do { idle = true; @@ -251,7 +250,7 @@ nv84_graph_tlb_flush(struct drm_device *dev, int engine) if ((tmp & 7) == 1) idle = false; } - } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000)); + } while (!idle && !(timeout = nv_timer_read(dev) - start > 2000000000)); if (timeout) { NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: " diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h new file mode 100644 index 000000000000..d971b83caebe --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h @@ -0,0 +1,53 @@ +#ifndef __NOUVEAU_TIMER_H__ +#define __NOUVEAU_TIMER_H__ + +#include +#include + +struct nouveau_alarm { + struct list_head head; + u64 timestamp; + void (*func)(struct nouveau_alarm *); +}; + +bool nouveau_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data); +bool nouveau_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data); +bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data); +void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *); + +#define NV_WAIT_DEFAULT 2000000000ULL +#define nv_wait(o,a,m,v) \ + nouveau_timer_wait_eq((o), NV_WAIT_DEFAULT, (a), (m), (v)) +#define nv_wait_ne(o,a,m,v) \ + nouveau_timer_wait_ne((o), NV_WAIT_DEFAULT, (a), (m), (v)) +#define nv_wait_cb(o,a,m,v) \ + nouveau_timer_wait_cb((o), NV_WAIT_DEFAULT, (a), (m), (v)) + +struct nouveau_timer { + struct nouveau_subdev base; + u64 (*read)(struct nouveau_timer *); + void (*alarm)(struct nouveau_timer *, u32 time, struct nouveau_alarm *); +}; + +static inline struct nouveau_timer * +nouveau_timer(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_TIMER]; +} + +#define nouveau_timer_create(p,e,o,d) \ + nouveau_subdev_create_((p), (e), (o), 0, "PTIMER", "timer", \ + sizeof(**d), (void **)d) +#define nouveau_timer_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_timer_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_timer_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +int nouveau_timer_create_(struct nouveau_object *, struct nouveau_engine *, + struct nouveau_oclass *, int size, void **); + +extern struct nouveau_oclass nv04_timer_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c index c3820a8e93e9..aa43bd5c2374 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c @@ -28,6 +28,7 @@ #include #include #include +#include int nv04_identify(struct nouveau_device *device) @@ -39,6 +40,7 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv04_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x05: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -46,6 +48,7 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv05_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown RIVA chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c index 94686f43118d..1926c33fb6f8 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c @@ -29,6 +29,7 @@ #include #include #include +#include int nv10_identify(struct nouveau_device *device) @@ -41,6 +42,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x15: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -49,6 +51,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x16: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -57,6 +60,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x1a: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -65,6 +69,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x11: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -73,6 +78,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x17: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -81,6 +87,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x1f: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -89,6 +96,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x18: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -97,6 +105,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown Celsius chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c index d14041eb5637..88729c308565 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c @@ -29,6 +29,7 @@ #include #include #include +#include int nv20_identify(struct nouveau_device *device) @@ -41,6 +42,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x25: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -49,6 +51,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x28: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -57,6 +60,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x2a: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -65,6 +69,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown Kelvin chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c index a04a20d46728..4feea8804a78 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c @@ -29,6 +29,7 @@ #include #include #include +#include int nv30_identify(struct nouveau_device *device) @@ -41,6 +42,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x35: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -49,6 +51,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x31: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -57,6 +60,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x36: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -65,6 +69,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x34: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -73,6 +78,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown Rankine chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c index a8cc40898c64..8f683613788d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c @@ -29,6 +29,7 @@ #include #include #include +#include int nv40_identify(struct nouveau_device *device) @@ -41,6 +42,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x41: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -49,6 +51,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x42: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -57,6 +60,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x43: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -65,6 +69,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x45: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -73,6 +78,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x47: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -81,6 +87,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x49: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -89,6 +96,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x4b: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -97,6 +105,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x44: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -105,6 +114,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x46: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -113,6 +123,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x4a: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -121,6 +132,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x4c: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -129,6 +141,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x4e: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -137,6 +150,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x63: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -145,6 +159,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x67: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -153,6 +168,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x68: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -161,6 +177,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown Curie chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c index eb5dfba7c74f..e844525d5694 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c @@ -29,6 +29,7 @@ #include #include #include +#include int nv50_identify(struct nouveau_device *device) @@ -41,6 +42,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x84: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -49,6 +51,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x86: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -57,6 +60,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x92: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -65,6 +69,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x94: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -73,6 +78,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x96: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -81,6 +87,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0x98: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -89,6 +96,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xa0: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -97,6 +105,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xaa: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -105,6 +114,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xac: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -113,6 +123,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xa3: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -121,6 +132,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xa5: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -129,6 +141,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xa8: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -137,6 +150,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xaf: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -145,6 +159,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown Tesla chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c index 5efb4aa7ebcb..56d1950c9b77 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c @@ -29,6 +29,7 @@ #include #include #include +#include int nvc0_identify(struct nouveau_device *device) @@ -41,6 +42,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xc4: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -49,6 +51,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xc3: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -57,6 +60,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xce: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -65,6 +69,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xcf: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -73,6 +78,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xc1: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -81,6 +87,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xc8: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -89,6 +96,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xd9: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -97,6 +105,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown Fermi chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c index eb6ccba9fca2..ab5e05291465 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c @@ -29,6 +29,7 @@ #include #include #include +#include int nve0_identify(struct nouveau_device *device) @@ -41,6 +42,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; case 0xe7: device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; @@ -49,6 +51,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; break; default: nv_fatal(device, "unknown Kepler chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/base.c b/drivers/gpu/drm/nouveau/core/subdev/timer/base.c new file mode 100644 index 000000000000..5d417cc9949b --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/base.c @@ -0,0 +1,87 @@ +/* + * 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 "subdev/timer.h" + +bool +nouveau_timer_wait_eq(void *obj, u64 nsec, u32 addr, u32 mask, u32 data) +{ + struct nouveau_timer *ptimer = nouveau_timer(obj); + u64 time0; + + time0 = ptimer->read(ptimer); + do { + if (nv_iclass(obj, NV_SUBDEV_CLASS)) { + if ((nv_rd32(obj, addr) & mask) == data) + return true; + } else { + if ((nv_ro32(obj, addr) & mask) == data) + return true; + } + } while (ptimer->read(ptimer) - time0 < nsec); + + return false; +} + +bool +nouveau_timer_wait_ne(void *obj, u64 nsec, u32 addr, u32 mask, u32 data) +{ + struct nouveau_timer *ptimer = nouveau_timer(obj); + u64 time0; + + time0 = ptimer->read(ptimer); + do { + if (nv_iclass(obj, NV_SUBDEV_CLASS)) { + if ((nv_rd32(obj, addr) & mask) != data) + return true; + } else { + if ((nv_ro32(obj, addr) & mask) != data) + return true; + } + } while (ptimer->read(ptimer) - time0 < nsec); + + return false; +} + +bool +nouveau_timer_wait_cb(void *obj, u64 nsec, bool (*func)(void *), void *data) +{ + struct nouveau_timer *ptimer = nouveau_timer(obj); + u64 time0; + + time0 = ptimer->read(ptimer); + do { + if (func(data) == true) + return true; + } while (ptimer->read(ptimer) - time0 < nsec); + + return false; +} + +void +nouveau_timer_alarm(void *obj, u32 nsec, struct nouveau_alarm *alarm) +{ + struct nouveau_timer *ptimer = nouveau_timer(obj); + ptimer->alarm(ptimer, nsec, alarm); +} diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c index 63333dc9ece0..49976be4d73b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c @@ -1,45 +1,201 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include -#include "nouveau_hw.h" - -int -nv04_timer_init(struct drm_device *dev) +/* + * 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 + +#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_priv { + struct nouveau_timer base; + struct list_head alarms; + spinlock_t lock; +}; + +static u64 +nv04_timer_read(struct nouveau_timer *ptimer) +{ + struct nv04_timer_priv *priv = (void *)ptimer; + u32 hi, lo; + + do { + hi = nv_rd32(priv, NV04_PTIMER_TIME_1); + lo = nv_rd32(priv, NV04_PTIMER_TIME_0); + } while (hi != nv_rd32(priv, NV04_PTIMER_TIME_1)); + + return ((u64)hi << 32 | lo); +} + +static void +nv04_timer_alarm_trigger(struct nouveau_timer *ptimer) +{ + struct nv04_timer_priv *priv = (void *)ptimer; + struct nouveau_alarm *alarm, *atemp; + unsigned long flags; + LIST_HEAD(exec); + + /* move any due alarms off the pending list */ + spin_lock_irqsave(&priv->lock, flags); + list_for_each_entry_safe(alarm, atemp, &priv->alarms, head) { + if (alarm->timestamp <= ptimer->read(ptimer)) + list_move_tail(&alarm->head, &exec); + } + + /* reschedule interrupt for next alarm time */ + if (!list_empty(&priv->alarms)) { + alarm = list_first_entry(&priv->alarms, typeof(*alarm), head); + nv_wr32(priv, NV04_PTIMER_ALARM_0, alarm->timestamp); + nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000001); + } else { + nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); + } + spin_unlock_irqrestore(&priv->lock, flags); + + /* execute any pending alarm handlers */ + list_for_each_entry_safe(alarm, atemp, &exec, head) { + list_del(&alarm->head); + alarm->func(alarm); + } +} + +static void +nv04_timer_alarm(struct nouveau_timer *ptimer, u32 time, + struct nouveau_alarm *alarm) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 m, n, d; + struct nv04_timer_priv *priv = (void *)ptimer; + struct nouveau_alarm *list; + unsigned long flags; + + alarm->timestamp = ptimer->read(ptimer) + time; + + /* append new alarm to list, in soonest-alarm-first order */ + spin_lock_irqsave(&priv->lock, flags); + list_for_each_entry(list, &priv->alarms, head) { + if (list->timestamp > alarm->timestamp) + break; + } + list_add_tail(&alarm->head, &list->head); + spin_unlock_irqrestore(&priv->lock, flags); - nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000); - nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF); + /* process pending alarms */ + nv04_timer_alarm_trigger(ptimer); +} + +static void +nv04_timer_intr(struct nouveau_subdev *subdev) +{ + struct nv04_timer_priv *priv = (void *)subdev; + u32 stat = nv_rd32(priv, NV04_PTIMER_INTR_0); + + if (stat & 0x00000001) { + nv04_timer_alarm_trigger(&priv->base); + nv_wr32(priv, NV04_PTIMER_INTR_0, 0x00000001); + stat &= ~0x00000001; + } + + if (stat) { + nv_error(priv, "unknown stat 0x%08x\n", stat); + nv_wr32(priv, NV04_PTIMER_INTR_0, stat); + } +} + +static int +nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv04_timer_priv *priv; + int ret; + + ret = nouveau_timer_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.base.intr = nv04_timer_intr; + priv->base.read = nv04_timer_read; + priv->base.alarm = nv04_timer_alarm; + + INIT_LIST_HEAD(&priv->alarms); + spin_lock_init(&priv->lock); + return 0; +} + +static void +nv04_timer_dtor(struct nouveau_object *object) +{ + struct nv04_timer_priv *priv = (void *)object; + return nouveau_timer_destroy(&priv->base); +} + +static int +nv04_timer_init(struct nouveau_object *object) +{ + struct nouveau_device *device = nv_device(object); + struct nv04_timer_priv *priv = (void *)object; + u32 m = 1, f, n, d; + int ret; + + ret = nouveau_timer_init(&priv->base); + if (ret) + return ret; /* aim for 31.25MHz, which gives us nanosecond timestamps */ d = 1000000 / 32; /* determine base clock for timer source */ - if (dev_priv->chipset < 0x40) { - n = nouveau_hw_get_clock(dev, PLL_CORE); +#if 0 /*XXX*/ + if (device->chipset < 0x40) { + n = nouveau_hw_get_clock(device, PLL_CORE); } else - if (dev_priv->chipset == 0x40) { +#endif + if (device->chipset <= 0x40) { /*XXX: figure this out */ + f = -1; n = 0; } else { - n = dev_priv->crystal; - m = 1; + f = device->crystal; + n = f; while (n < (d * 2)) { n += (n / m); m++; } - nv_wr32(dev, 0x009220, m - 1); + nv_wr32(priv, 0x009220, m - 1); } if (!n) { - NV_WARN(dev, "PTIMER: unknown input clock freq\n"); - if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) || - !nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) { - nv_wr32(dev, NV04_PTIMER_NUMERATOR, 1); - nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 1); + nv_warn(priv, "unknown input clock freq\n"); + if (!nv_rd32(priv, NV04_PTIMER_NUMERATOR) || + !nv_rd32(priv, NV04_PTIMER_DENOMINATOR)) { + nv_wr32(priv, NV04_PTIMER_NUMERATOR, 1); + nv_wr32(priv, NV04_PTIMER_DENOMINATOR, 1); } return 0; } @@ -60,25 +216,34 @@ nv04_timer_init(struct drm_device *dev) d >>= 1; } - nv_wr32(dev, NV04_PTIMER_NUMERATOR, n); - nv_wr32(dev, NV04_PTIMER_DENOMINATOR, d); + nv_debug(priv, "input frequency : %dHz\n", f); + nv_debug(priv, "input multiplier: %d\n", m); + nv_debug(priv, "numerator : 0x%08x\n", n); + nv_debug(priv, "denominator : 0x%08x\n", d); + nv_debug(priv, "timer frequency : %dHz\n", (f * m) * d / n); + + nv_wr32(priv, NV04_PTIMER_NUMERATOR, n); + nv_wr32(priv, NV04_PTIMER_DENOMINATOR, d); + nv_wr32(priv, NV04_PTIMER_INTR_0, 0xffffffff); + nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); return 0; } -u64 -nv04_timer_read(struct drm_device *dev) +static int +nv04_timer_fini(struct nouveau_object *object, bool suspend) { - u32 hi, lo; - - do { - hi = nv_rd32(dev, NV04_PTIMER_TIME_1); - lo = nv_rd32(dev, NV04_PTIMER_TIME_0); - } while (hi != nv_rd32(dev, NV04_PTIMER_TIME_1)); - - return ((u64)hi << 32 | lo); + struct nv04_timer_priv *priv = (void *)object; + nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); + return nouveau_timer_fini(&priv->base, suspend); } -void -nv04_timer_takedown(struct drm_device *dev) -{ -} +struct nouveau_oclass +nv04_timer_oclass = { + .handle = NV_SUBDEV(TIMER, 0x04), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv04_timer_ctor, + .dtor = nv04_timer_dtor, + .init = nv04_timer_init, + .fini = nv04_timer_fini, + } +}; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 1b9db808a855..9b3a4617bffa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -64,7 +64,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) getparam->value = 0; /* deprecated */ break; case NOUVEAU_GETPARAM_PTIMER_TIME: - getparam->value = dev_priv->engine.timer.read(dev); + getparam->value = nv_timer_read(dev); break; case NOUVEAU_GETPARAM_HAS_BO_USAGE: getparam->value = 1; diff --git a/drivers/gpu/drm/nouveau/nouveau_compat.c b/drivers/gpu/drm/nouveau/nouveau_compat.c index cfdc45c86e12..7880ebb9a7d9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_compat.c +++ b/drivers/gpu/drm/nouveau/nouveau_compat.c @@ -9,6 +9,7 @@ #include #include #include +#include void *nouveau_newpriv(struct drm_device *); @@ -300,5 +301,34 @@ nv_intr(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_newpriv(dev); struct nouveau_mc *pmc = nouveau_mc(drm->device); - nv_subdev(pmc)->intr(pmc); + nv_subdev(pmc)->intr(&pmc->base); +} + +bool nouveau_wait_eq(struct drm_device *dev, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val) +{ + struct nouveau_drm *drm = nouveau_newpriv(dev); + return nouveau_timer_wait_eq(drm->device, timeout, reg, mask, val); +} + +bool nouveau_wait_ne(struct drm_device *dev, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val) +{ + struct nouveau_drm *drm = nouveau_newpriv(dev); + return nouveau_timer_wait_ne(drm->device, timeout, reg, mask, val); +} + +bool nouveau_wait_cb(struct drm_device *dev, u64 timeout, + bool (*cond)(void *), void *data) +{ + struct nouveau_drm *drm = nouveau_newpriv(dev); + return nouveau_timer_wait_cb(drm->device, timeout, cond, data); +} + +u64 +nv_timer_read(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_newpriv(dev); + struct nouveau_timer *ptimer = nouveau_timer(drm->device); + return ptimer->read(ptimer); } diff --git a/drivers/gpu/drm/nouveau/nouveau_compat.h b/drivers/gpu/drm/nouveau/nouveau_compat.h index 19995cdc8bb0..c9622ebf5cbe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_compat.h +++ b/drivers/gpu/drm/nouveau/nouveau_compat.h @@ -53,4 +53,13 @@ void nouveau_bios_init_exec(struct drm_device *, u16); void nv_intr(struct drm_device *); +bool nouveau_wait_eq(struct drm_device *, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val); +bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val); +bool nouveau_wait_cb(struct drm_device *, u64 timeout, + bool (*cond)(void *), void *); + +u64 nv_timer_read(struct drm_device *); + #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index d1251d8772e8..7223a4f69231 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -252,7 +252,6 @@ nouveau_pci_resume(struct pci_dev *pdev) NV_INFO(dev, "Reinitialising engines...\n"); engine->instmem.resume(dev); - engine->timer.init(dev); engine->fb.init(dev); for (i = 0; i < NVOBJ_ENGINE_NR; i++) { if (dev_priv->eng[i]) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 7722b03d8d35..b4595990f5e8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -324,12 +324,6 @@ struct nouveau_instmem_engine { void (*flush)(struct drm_device *); }; -struct nouveau_timer_engine { - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); - uint64_t (*read)(struct drm_device *dev); -}; - struct nouveau_fb_engine { int num_tiles; struct drm_mm tag_heap; @@ -539,7 +533,6 @@ struct nouveau_vram_engine { struct nouveau_engine { struct nouveau_instmem_engine instmem; - struct nouveau_timer_engine timer; struct nouveau_fb_engine fb; struct nouveau_display_engine display; struct nouveau_pm_engine pm; @@ -836,12 +829,6 @@ extern int nouveau_load(struct drm_device *, unsigned long flags); extern int nouveau_firstopen(struct drm_device *); extern void nouveau_lastclose(struct drm_device *); extern int nouveau_unload(struct drm_device *); -extern bool nouveau_wait_eq(struct drm_device *, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val); -extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val); -extern bool nouveau_wait_cb(struct drm_device *, u64 timeout, - bool (*cond)(void *), void *); extern bool nouveau_wait_for_idle(struct drm_device *); extern int nouveau_card_init(struct drm_device *); @@ -1204,11 +1191,6 @@ extern void nvc0_instmem_takedown(struct drm_device *); extern int nvc0_instmem_suspend(struct drm_device *); extern void nvc0_instmem_resume(struct drm_device *); -/* nv04_timer.c */ -extern int nv04_timer_init(struct drm_device *); -extern uint64_t nv04_timer_read(struct drm_device *); -extern void nv04_timer_takedown(struct drm_device *); - extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index fd74cbf7ef69..539e81c416cd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -194,8 +194,7 @@ nouveau_pm_trigger(struct drm_device *dev) /* change perflvl, if necessary */ if (perflvl != pm->cur) { - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - u64 time0 = ptimer->read(dev); + u64 time0 = nv_timer_read(dev); NV_INFO(dev, "setting performance level: %d", perflvl->id); ret = nouveau_pm_perflvl_set(dev, perflvl); @@ -203,7 +202,7 @@ nouveau_pm_trigger(struct drm_device *dev) NV_INFO(dev, "> reclocking failed: %d\n\n", ret); NV_INFO(dev, "> reclocking took %lluns\n\n", - ptimer->read(dev) - time0); + nv_timer_read(dev) - time0); } } @@ -553,8 +552,6 @@ nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr, char *buf) { struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; u32 cycles, cur, prev; u64 start; @@ -565,7 +562,7 @@ nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr, * When the fan spins, it changes the value of GPIO FAN_SENSE. * We get 4 changes (0 -> 1 -> 0 -> 1 -> [...]) per complete rotation. */ - start = ptimer->read(dev); + start = nv_timer_read(dev); prev = nouveau_gpio_func_get(dev, DCB_GPIO_FAN_SENSE); cycles = 0; do { @@ -576,7 +573,7 @@ nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr, } usleep_range(500, 1000); /* supports 0 < rpm < 7500 */ - } while (ptimer->read(dev) - start < 250000000); + } while (nv_timer_read(dev) - start < 250000000); /* interpolate to get rpm */ return sprintf(buf, "%i\n", cycles / 4 * 4 * 60); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e487747d70d8..3b11962d7d6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -61,9 +61,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv04_instmem_map; engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv04_fb_init; engine->fb.takedown = nv04_fb_takedown; engine->display.early_init = nv04_display_early_init; @@ -89,9 +86,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv04_instmem_map; engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; engine->fb.init_tile_region = nv10_fb_init_tile_region; @@ -124,9 +118,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv04_instmem_map; engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv20_fb_init; engine->fb.takedown = nv20_fb_takedown; engine->fb.init_tile_region = nv20_fb_init_tile_region; @@ -155,9 +146,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv04_instmem_map; engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv30_fb_init; engine->fb.takedown = nv30_fb_takedown; engine->fb.init_tile_region = nv30_fb_init_tile_region; @@ -189,9 +177,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv04_instmem_map; engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv40_fb_init; engine->fb.takedown = nv40_fb_takedown; engine->fb.init_tile_region = nv30_fb_init_tile_region; @@ -231,9 +216,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.flush = nv50_instmem_flush; else engine->instmem.flush = nv84_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv50_fb_init; engine->fb.takedown = nv50_fb_takedown; engine->display.early_init = nv50_display_early_init; @@ -287,9 +269,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv50_instmem_map; engine->instmem.unmap = nv50_instmem_unmap; engine->instmem.flush = nv84_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; engine->display.early_init = nv50_display_early_init; @@ -322,9 +301,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv50_instmem_map; engine->instmem.unmap = nv50_instmem_unmap; engine->instmem.flush = nv84_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; engine->display.early_init = nouveau_stub_init; @@ -355,9 +331,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.map = nv50_instmem_map; engine->instmem.unmap = nv50_instmem_unmap; engine->instmem.flush = nv84_instmem_flush; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; engine->display.early_init = nouveau_stub_init; @@ -515,15 +488,10 @@ nouveau_card_init(struct drm_device *dev) nv_mask(dev, 0x00088080, 0x00000800, 0x00000000); } - /* PTIMER */ - ret = engine->timer.init(dev); - if (ret) - goto out_bios; - /* PFB */ ret = engine->fb.init(dev); if (ret) - goto out_timer; + goto out_bios; ret = engine->vram.init(dev); if (ret) @@ -770,8 +738,6 @@ out_vram: engine->vram.takedown(dev); out_fb: engine->fb.takedown(dev); -out_timer: - engine->timer.takedown(dev); out_bios: nouveau_bios_takedown(dev); out_display_early: @@ -824,7 +790,6 @@ static void nouveau_card_takedown(struct drm_device *dev) engine->vram.takedown(dev); engine->fb.takedown(dev); - engine->timer.takedown(dev); nouveau_bios_takedown(dev); engine->display.late_takedown(dev); @@ -1143,57 +1108,6 @@ int nouveau_unload(struct drm_device *dev) return 0; } -/* Wait until (value(reg) & mask) == val, up until timeout has hit */ -bool -nouveau_wait_eq(struct drm_device *dev, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - uint64_t start = ptimer->read(dev); - - do { - if ((nv_rd32(dev, reg) & mask) == val) - return true; - } while (ptimer->read(dev) - start < timeout); - - return false; -} - -/* Wait until (value(reg) & mask) != val, up until timeout has hit */ -bool -nouveau_wait_ne(struct drm_device *dev, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - uint64_t start = ptimer->read(dev); - - do { - if ((nv_rd32(dev, reg) & mask) != val) - return true; - } while (ptimer->read(dev) - start < timeout); - - return false; -} - -/* Wait until cond(data) == true, up until timeout has hit */ -bool -nouveau_wait_cb(struct drm_device *dev, u64 timeout, - bool (*cond)(void *), void *data) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - u64 start = ptimer->read(dev); - - do { - if (cond(data) == true) - return true; - } while (ptimer->read(dev) - start < timeout); - - return false; -} - /* Waits for PGRAPH to go completely idle */ bool nouveau_wait_for_idle(struct drm_device *dev) { diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c index 4528d48dc52b..76b5340603a9 100644 --- a/drivers/gpu/drm/nouveau/nv04_pm.c +++ b/drivers/gpu/drm/nouveau/nv04_pm.c @@ -114,7 +114,6 @@ int nv04_pm_clocks_set(struct drm_device *dev, void *pre_state) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; struct nv04_pm_state *state = pre_state; prog_pll(dev, &state->core); @@ -130,7 +129,9 @@ nv04_pm_clocks_set(struct drm_device *dev, void *pre_state) } } +#if 0 /*XXX*/ ptimer->init(dev); +#endif kfree(state); return 0; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index e7cd8216d114..ccbb03ead8eb 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -88,8 +88,6 @@ nv50_display_late_takedown(struct drm_device *dev) int nv50_display_sync(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; struct nv50_display *disp = nv50_display(dev); struct nouveau_channel *evo = disp->master; u64 start; @@ -107,11 +105,11 @@ nv50_display_sync(struct drm_device *dev) nv_wo32(disp->ntfy, 0x000, 0x00000000); FIRE_RING (evo); - start = ptimer->read(dev); + start = nv_timer_read(dev); do { if (nv_ro32(disp->ntfy, 0x000)) return 0; - } while (ptimer->read(dev) - start < 2000000000ULL); + } while (nv_timer_read(dev) - start < 2000000000ULL); } return -EBUSY; -- cgit v1.2.3-59-g8ed1b