gpu: ipu-v3: Fix IRT usage

There can be multiple IC tasks using the IRT, so the IRT needs
a separate use counter. Create a private ipu_irt_enable() to
enable the IRT module when any IC task requires rotation, and
ipu_irt_disable() when a task no longer needs the IRT.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
Steve Longerbeam 2016-07-19 18:11:08 -07:00 committed by Philipp Zabel
parent ea6bead7eb
commit 58e366eb86
1 changed files with 31 additions and 9 deletions

View File

@ -160,6 +160,7 @@ struct ipu_ic_priv {
spinlock_t lock;
struct ipu_soc *ipu;
int use_count;
int irt_use_count;
struct ipu_ic task[IC_NUM_TASKS];
};
@ -379,8 +380,6 @@ void ipu_ic_task_disable(struct ipu_ic *ic)
ipu_ic_write(ic, ic_conf, IC_CONF);
ic->rotation = ic->graphics = false;
spin_unlock_irqrestore(&priv->lock, flags);
}
EXPORT_SYMBOL_GPL(ipu_ic_task_disable);
@ -629,22 +628,41 @@ int ipu_ic_task_idma_init(struct ipu_ic *ic, struct ipuv3_channel *channel,
}
EXPORT_SYMBOL_GPL(ipu_ic_task_idma_init);
static void ipu_irt_enable(struct ipu_ic *ic)
{
struct ipu_ic_priv *priv = ic->priv;
if (!priv->irt_use_count)
ipu_module_enable(priv->ipu, IPU_CONF_ROT_EN);
priv->irt_use_count++;
}
static void ipu_irt_disable(struct ipu_ic *ic)
{
struct ipu_ic_priv *priv = ic->priv;
if (priv->irt_use_count) {
if (!--priv->irt_use_count)
ipu_module_disable(priv->ipu, IPU_CONF_ROT_EN);
}
}
int ipu_ic_enable(struct ipu_ic *ic)
{
struct ipu_ic_priv *priv = ic->priv;
unsigned long flags;
u32 module = IPU_CONF_IC_EN;
spin_lock_irqsave(&priv->lock, flags);
if (ic->rotation)
module |= IPU_CONF_ROT_EN;
if (!priv->use_count)
ipu_module_enable(priv->ipu, module);
ipu_module_enable(priv->ipu, IPU_CONF_IC_EN);
priv->use_count++;
if (ic->rotation)
ipu_irt_enable(ic);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
@ -655,18 +673,22 @@ int ipu_ic_disable(struct ipu_ic *ic)
{
struct ipu_ic_priv *priv = ic->priv;
unsigned long flags;
u32 module = IPU_CONF_IC_EN | IPU_CONF_ROT_EN;
spin_lock_irqsave(&priv->lock, flags);
priv->use_count--;
if (!priv->use_count)
ipu_module_disable(priv->ipu, module);
ipu_module_disable(priv->ipu, IPU_CONF_IC_EN);
if (priv->use_count < 0)
priv->use_count = 0;
if (ic->rotation)
ipu_irt_disable(ic);
ic->rotation = ic->graphics = false;
spin_unlock_irqrestore(&priv->lock, flags);
return 0;