Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12fb9525 authored by Ben Skeggs's avatar Ben Skeggs Committed by Francisco Jerez
Browse files

drm/nouveau: introduce a util function to wait on reg != val



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent ceac3099
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -795,7 +795,9 @@ extern int nouveau_ioctl_getparam(struct drm_device *, void *data,
				   struct drm_file *);
				   struct drm_file *);
extern int  nouveau_ioctl_setparam(struct drm_device *, void *data,
extern int  nouveau_ioctl_setparam(struct drm_device *, void *data,
				   struct drm_file *);
				   struct drm_file *);
extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout,
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);
			    uint32_t reg, uint32_t mask, uint32_t val);
extern bool nouveau_wait_for_idle(struct drm_device *);
extern bool nouveau_wait_for_idle(struct drm_device *);
extern int  nouveau_card_init(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) \
#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 */
/* PRAMIN access */
static inline u32 nv_ri32(struct drm_device *dev, unsigned offset)
static inline u32 nv_ri32(struct drm_device *dev, unsigned offset)
+2 −2
Original line number Original line Diff line number Diff line
@@ -999,8 +999,8 @@ nv_load_state_ext(struct drm_device *dev, int head,
		if (dev_priv->card_type == NV_10) {
		if (dev_priv->card_type == NV_10) {
			/* Not waiting for vertical retrace before modifying
			/* Not waiting for vertical retrace before modifying
			   CRE_53/CRE_54 causes lockups. */
			   CRE_53/CRE_54 causes lockups. */
			nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
			nouveau_wait_eq(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, 0x0);
		}
		}


		wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
		wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
+20 −2
Original line number Original line Diff line number Diff line
@@ -1126,7 +1126,8 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
}
}


/* Wait until (value(reg) & mask) == val, up until timeout has hit */
/* Wait until (value(reg) & mask) == val, up until timeout has hit */
bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
bool
nouveau_wait_eq(struct drm_device *dev, uint64_t timeout,
		uint32_t reg, uint32_t mask, uint32_t val)
		uint32_t reg, uint32_t mask, uint32_t val)
{
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -1141,6 +1142,23 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
	return false;
	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 */
/* Waits for PGRAPH to go completely idle */
bool nouveau_wait_for_idle(struct drm_device *dev)
bool nouveau_wait_for_idle(struct drm_device *dev)
{
{
+6 −6
Original line number Original line Diff line number Diff line
@@ -74,13 +74,13 @@ static int sample_load_twice(struct drm_device *dev, bool sense[2])
		 * use a 10ms timeout (guards against crtc being inactive, in
		 * use a 10ms timeout (guards against crtc being inactive, in
		 * which case blank state would never change)
		 * which case blank state would never change)
		 */
		 */
		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
		if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
				     0x00000001, 0x00000000))
				     0x00000001, 0x00000000))
			return -EBUSY;
			return -EBUSY;
		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
		if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
				     0x00000001, 0x00000001))
				     0x00000001, 0x00000001))
			return -EBUSY;
			return -EBUSY;
		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
		if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
				     0x00000001, 0x00000000))
				     0x00000001, 0x00000000))
			return -EBUSY;
			return -EBUSY;