staging: drm/imx: make waiting for idle channel optional
Currently we wait for a channel until it's idle before actually disabling it. This is not needed for all channels though, so make waiting for idle a separate function and call it where necessary. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0b186416c9
commit
fb822a395f
3 changed files with 19 additions and 12 deletions
|
@ -97,6 +97,7 @@ void ipu_idmac_put(struct ipuv3_channel *);
|
||||||
|
|
||||||
int ipu_idmac_enable_channel(struct ipuv3_channel *channel);
|
int ipu_idmac_enable_channel(struct ipuv3_channel *channel);
|
||||||
int ipu_idmac_disable_channel(struct ipuv3_channel *channel);
|
int ipu_idmac_disable_channel(struct ipuv3_channel *channel);
|
||||||
|
int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms);
|
||||||
|
|
||||||
void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
|
void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
|
||||||
bool doublebuffer);
|
bool doublebuffer);
|
||||||
|
|
|
@ -698,23 +698,28 @@ int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
|
EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
|
||||||
|
|
||||||
|
int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms)
|
||||||
|
{
|
||||||
|
struct ipu_soc *ipu = channel->ipu;
|
||||||
|
unsigned long timeout;
|
||||||
|
|
||||||
|
timeout = jiffies + msecs_to_jiffies(ms);
|
||||||
|
while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
|
||||||
|
idma_mask(channel->num)) {
|
||||||
|
if (time_after(jiffies, timeout))
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy);
|
||||||
|
|
||||||
int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
|
int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
|
||||||
{
|
{
|
||||||
struct ipu_soc *ipu = channel->ipu;
|
struct ipu_soc *ipu = channel->ipu;
|
||||||
u32 val;
|
u32 val;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long timeout;
|
|
||||||
|
|
||||||
timeout = jiffies + msecs_to_jiffies(50);
|
|
||||||
while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
|
|
||||||
idma_mask(channel->num)) {
|
|
||||||
if (time_after(jiffies, timeout)) {
|
|
||||||
dev_warn(ipu->dev, "disabling busy idmac channel %d\n",
|
|
||||||
channel->num);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cpu_relax();
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ipu->lock, flags);
|
spin_lock_irqsave(&ipu->lock, flags);
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,7 @@ static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
|
||||||
if (ipu_crtc->dp)
|
if (ipu_crtc->dp)
|
||||||
ipu_dp_disable_channel(ipu_crtc->dp);
|
ipu_dp_disable_channel(ipu_crtc->dp);
|
||||||
ipu_dc_disable_channel(ipu_crtc->dc);
|
ipu_dc_disable_channel(ipu_crtc->dc);
|
||||||
|
ipu_idmac_wait_busy(ipu_crtc->ipu_ch, 50);
|
||||||
ipu_idmac_disable_channel(ipu_crtc->ipu_ch);
|
ipu_idmac_disable_channel(ipu_crtc->ipu_ch);
|
||||||
ipu_dmfc_disable_channel(ipu_crtc->dmfc);
|
ipu_dmfc_disable_channel(ipu_crtc->dmfc);
|
||||||
ipu_di_disable(ipu_crtc->di);
|
ipu_di_disable(ipu_crtc->di);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue