diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c | 15 |
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 | ||
| 41 | static u64 | 42 | static 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 | |||
| 238 | nv04_timer_fini(struct nouveau_object *object, bool suspend) | 249 | nv04_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 | } |
