aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
index 9469b8275675..49350eaf4df5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
@@ -36,6 +36,7 @@ struct nv04_timer_priv {
36 struct nouveau_timer base; 36 struct nouveau_timer base;
37 struct list_head alarms; 37 struct list_head alarms;
38 spinlock_t lock; 38 spinlock_t lock;
39 u64 suspend_time;
39}; 40};
40 41
41static u64 42static u64
@@ -146,6 +147,7 @@ nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
146 priv->base.base.intr = nv04_timer_intr; 147 priv->base.base.intr = nv04_timer_intr;
147 priv->base.read = nv04_timer_read; 148 priv->base.read = nv04_timer_read;
148 priv->base.alarm = nv04_timer_alarm; 149 priv->base.alarm = nv04_timer_alarm;
150 priv->suspend_time = 0;
149 151
150 INIT_LIST_HEAD(&priv->alarms); 152 INIT_LIST_HEAD(&priv->alarms);
151 spin_lock_init(&priv->lock); 153 spin_lock_init(&priv->lock);
@@ -164,7 +166,7 @@ nv04_timer_init(struct nouveau_object *object)
164{ 166{
165 struct nouveau_device *device = nv_device(object); 167 struct nouveau_device *device = nv_device(object);
166 struct nv04_timer_priv *priv = (void *)object; 168 struct nv04_timer_priv *priv = (void *)object;
167 u32 m = 1, f, n, d; 169 u32 m = 1, f, n, d, lo, hi;
168 int ret; 170 int ret;
169 171
170 ret = nouveau_timer_init(&priv->base); 172 ret = nouveau_timer_init(&priv->base);
@@ -221,16 +223,25 @@ nv04_timer_init(struct nouveau_object *object)
221 d >>= 1; 223 d >>= 1;
222 } 224 }
223 225
226 /* restore the time before suspend */
227 lo = priv->suspend_time;
228 hi = (priv->suspend_time >> 32);
229
224 nv_debug(priv, "input frequency : %dHz\n", f); 230 nv_debug(priv, "input frequency : %dHz\n", f);
225 nv_debug(priv, "input multiplier: %d\n", m); 231 nv_debug(priv, "input multiplier: %d\n", m);
226 nv_debug(priv, "numerator : 0x%08x\n", n); 232 nv_debug(priv, "numerator : 0x%08x\n", n);
227 nv_debug(priv, "denominator : 0x%08x\n", d); 233 nv_debug(priv, "denominator : 0x%08x\n", d);
228 nv_debug(priv, "timer frequency : %dHz\n", (f * m) * d / n); 234 nv_debug(priv, "timer frequency : %dHz\n", (f * m) * d / n);
235 nv_debug(priv, "time low : 0x%08x\n", lo);
236 nv_debug(priv, "time high : 0x%08x\n", hi);
229 237
230 nv_wr32(priv, NV04_PTIMER_NUMERATOR, n); 238 nv_wr32(priv, NV04_PTIMER_NUMERATOR, n);
231 nv_wr32(priv, NV04_PTIMER_DENOMINATOR, d); 239 nv_wr32(priv, NV04_PTIMER_DENOMINATOR, d);
232 nv_wr32(priv, NV04_PTIMER_INTR_0, 0xffffffff); 240 nv_wr32(priv, NV04_PTIMER_INTR_0, 0xffffffff);
233 nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); 241 nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
242 nv_wr32(priv, NV04_PTIMER_TIME_1, hi);
243 nv_wr32(priv, NV04_PTIMER_TIME_0, lo);
244
234 return 0; 245 return 0;
235} 246}
236 247
@@ -238,6 +249,8 @@ static int
238nv04_timer_fini(struct nouveau_object *object, bool suspend) 249nv04_timer_fini(struct nouveau_object *object, bool suspend)
239{ 250{
240 struct nv04_timer_priv *priv = (void *)object; 251 struct nv04_timer_priv *priv = (void *)object;
252 if (suspend)
253 priv->suspend_time = nv04_timer_read(&priv->base);
241 nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); 254 nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
242 return nouveau_timer_fini(&priv->base, suspend); 255 return nouveau_timer_fini(&priv->base, suspend);
243} 256}