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

Commit dd1da8de authored by Martin Peres's avatar Martin Peres Committed by Ben Skeggs
Browse files

drm/nouveau/pm: make clocks_set return an error code clocks_set can fail.



Reporting an error is better than silently refusing to reclock.

V2: Use the same logic on nv40

Signed-off-by: default avatarMartin Peres <martin.peres@labri.fr>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 61091837
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -555,7 +555,7 @@ struct nouveau_pm_engine {


	int  (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
	int  (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
	void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
	void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
	void (*clocks_set)(struct drm_device *, void *);
	int (*clocks_set)(struct drm_device *, void *);


	int (*voltage_get)(struct drm_device *);
	int (*voltage_get)(struct drm_device *);
	int (*voltage_set)(struct drm_device *, int voltage);
	int (*voltage_set)(struct drm_device *, int voltage);
+2 −2
Original line number Original line Diff line number Diff line
@@ -55,7 +55,7 @@ void nv04_pm_clock_set(struct drm_device *, void *);
/* nv40_pm.c */
/* nv40_pm.c */
int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
void nv40_pm_clocks_set(struct drm_device *, void *);
int nv40_pm_clocks_set(struct drm_device *, void *);
int nv40_pm_pwm_get(struct drm_device *, struct dcb_gpio_entry *, u32*, u32*);
int nv40_pm_pwm_get(struct drm_device *, struct dcb_gpio_entry *, u32*, u32*);
int nv40_pm_pwm_set(struct drm_device *, struct dcb_gpio_entry *, u32, u32);
int nv40_pm_pwm_set(struct drm_device *, struct dcb_gpio_entry *, u32, u32);


@@ -70,7 +70,7 @@ int nv50_pm_pwm_set(struct drm_device *, struct dcb_gpio_entry *, u32, u32);
/* nva3_pm.c */
/* nva3_pm.c */
int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
void *nva3_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
void *nva3_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
void nva3_pm_clocks_set(struct drm_device *, void *);
int nva3_pm_clocks_set(struct drm_device *, void *);


/* nvc0_pm.c */
/* nvc0_pm.c */
int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
+5 −2
Original line number Original line Diff line number Diff line
@@ -222,7 +222,7 @@ nv40_pm_gr_idle(void *data)
	return true;
	return true;
}
}


void
int
nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
{
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -231,7 +231,7 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
	struct bit_entry M;
	struct bit_entry M;
	u32 crtc_mask = 0;
	u32 crtc_mask = 0;
	u8 sr1[2];
	u8 sr1[2];
	int i;
	int i, ret = -EAGAIN;


	/* determine which CRTCs are active, fetch VGA_SR1 for each */
	/* determine which CRTCs are active, fetch VGA_SR1 for each */
	for (i = 0; i < 2; i++) {
	for (i = 0; i < 2; i++) {
@@ -263,6 +263,8 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
	if (!nv_wait_cb(dev, nv40_pm_gr_idle, dev))
	if (!nv_wait_cb(dev, nv40_pm_gr_idle, dev))
		goto resume;
		goto resume;


	ret = 0;

	/* set engine clocks */
	/* set engine clocks */
	nv_mask(dev, 0x00c040, 0x00000333, 0x00000000);
	nv_mask(dev, 0x00c040, 0x00000333, 0x00000000);
	nv_wr32(dev, 0x004004, info->npll_coef);
	nv_wr32(dev, 0x004004, info->npll_coef);
@@ -345,6 +347,7 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);


	kfree(info);
	kfree(info);
	return ret;
}
}


int
int
+5 −1
Original line number Original line Diff line number Diff line
@@ -287,12 +287,13 @@ nva3_pm_grcp_idle(void *data)
	return false;
	return false;
}
}


void
int
nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
{
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nva3_pm_state *info = pre_state;
	struct nva3_pm_state *info = pre_state;
	unsigned long flags;
	unsigned long flags;
	int ret = -EAGAIN;


	/* prevent any new grctx switches from starting */
	/* prevent any new grctx switches from starting */
	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
@@ -328,6 +329,8 @@ nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
		nv_wr32(dev, 0x100210, 0x80000000);
		nv_wr32(dev, 0x100210, 0x80000000);
	}
	}


	ret = 0;

cleanup:
cleanup:
	/* unfreeze PFIFO */
	/* unfreeze PFIFO */
	nv_mask(dev, 0x002504, 0x00000001, 0x00000000);
	nv_mask(dev, 0x002504, 0x00000001, 0x00000000);
@@ -339,4 +342,5 @@ nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
		nv_mask(dev, 0x400824, 0x10000000, 0x10000000);
		nv_mask(dev, 0x400824, 0x10000000, 0x10000000);
	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
	kfree(info);
	kfree(info);
	return ret;
}
}