]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
drm/nouveau: introduce a util function to wait on reg != val
authorBen Skeggs <bskeggs@redhat.com>
Fri, 19 Nov 2010 04:32:56 +0000 (14:32 +1000)
committerFrancisco Jerez <currojerez@riseup.net>
Wed, 8 Dec 2010 02:00:36 +0000 (03:00 +0100)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_hw.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv04_dac.c

index bbf19861b6c80e5529a911f2856d2c42b8c93741..e82dff4008c91658dee02b4e4f5c581db6068861 100644 (file)
@@ -795,8 +795,10 @@ extern int  nouveau_ioctl_getparam(struct drm_device *, void *data,
                                   struct drm_file *);
 extern int  nouveau_ioctl_setparam(struct drm_device *, void *data,
                                   struct drm_file *);
-extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout,
-                              uint32_t reg, uint32_t mask, uint32_t val);
+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_for_idle(struct drm_device *);
 extern int  nouveau_card_init(struct drm_device *);
 
@@ -1434,7 +1436,9 @@ static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val)
 }
 
 #define nv_wait(dev, reg, mask, val) \
-       nouveau_wait_until(dev, 2000000000ULL, (reg), (mask), (val))
+       nouveau_wait_eq(dev, 2000000000ULL, (reg), (mask), (val))
+#define nv_wait_ne(dev, reg, mask, val) \
+       nouveau_wait_ne(dev, 2000000000ULL, (reg), (mask), (val))
 
 /* PRAMIN access */
 static inline u32 nv_ri32(struct drm_device *dev, unsigned offset)
index 6ba640e7a7e936df9a7babcc480bbe30d0967260..053edf9d2f67db4c6ed86536ea08f89d8c5b8b51 100644 (file)
@@ -999,8 +999,8 @@ nv_load_state_ext(struct drm_device *dev, int head,
                if (dev_priv->card_type == NV_10) {
                        /* Not waiting for vertical retrace before modifying
                           CRE_53/CRE_54 causes lockups. */
-                       nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
-                       nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
+                       nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
+                       nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
                }
 
                wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
index e779e93204538129ca10656909ef3f165fd501ad..e0811f93243d8f5f42d8ae0638c72edb67f8046b 100644 (file)
@@ -1126,8 +1126,9 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
 }
 
 /* Wait until (value(reg) & mask) == val, up until timeout has hit */
-bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
-                       uint32_t reg, uint32_t mask, uint32_t val)
+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;
@@ -1141,6 +1142,23 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t 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;
+}
+
 /* Waits for PGRAPH to go completely idle */
 bool nouveau_wait_for_idle(struct drm_device *dev)
 {
index ba6423f2ffccb2e5e7f2a8c9ea431c4aa087cec2..e000455e06d0154000b97d6883614afa8ff5aa98 100644 (file)
@@ -74,14 +74,14 @@ static int sample_load_twice(struct drm_device *dev, bool sense[2])
                 * use a 10ms timeout (guards against crtc being inactive, in
                 * which case blank state would never change)
                 */
-               if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
-                                       0x00000001, 0x00000000))
+               if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+                                    0x00000001, 0x00000000))
                        return -EBUSY;
-               if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
-                                       0x00000001, 0x00000001))
+               if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+                                    0x00000001, 0x00000001))
                        return -EBUSY;
-               if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
-                                       0x00000001, 0x00000000))
+               if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+                                    0x00000001, 0x00000000))
                        return -EBUSY;
 
                udelay(100);