Add defines for the memory reset bits and export the memory reset function to IPU modules.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/gpu/ipu-v3/ipu-common.c | 17 +++++++++++++---- drivers/gpu/ipu-v3/ipu-prv.h | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 5e7af61..1ad33df 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -706,14 +706,14 @@ void ipu_idmac_enable_watermark(struct ipuv3_channel *channel, bool enable) } EXPORT_SYMBOL_GPL(ipu_idmac_enable_watermark);
-static int ipu_memory_reset(struct ipu_soc *ipu) +int ipu_memory_reset(struct ipu_soc *ipu, u32 rst_mem) { unsigned long timeout;
- ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST); + ipu_cm_write(ipu, rst_mem | IPU_RST_MEM_START, IPU_MEM_RST);
timeout = jiffies + msecs_to_jiffies(1000); - while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) { + while (ipu_cm_read(ipu, IPU_MEM_RST) & IPU_RST_MEM_START) { if (time_after(jiffies, timeout)) return -ETIME; cpu_relax(); @@ -1363,7 +1363,16 @@ static int ipu_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to reset: %d\n", ret); goto out_failed_reset; } - ret = ipu_memory_reset(ipu); + ret = ipu_memory_reset(ipu, IPU_RST_MEM_SRM | IPU_RST_MEM_ALPHA | + IPU_RST_MEM_CPMEM | IPU_RST_MEM_TPM | + IPU_RST_MEM_MPM | IPU_RST_MEM_BM | + IPU_RST_MEM_RM | IPU_RST_MEM_DSTM | + IPU_RST_MEM_DSOM | IPU_RST_MEM_LUT0 | + IPU_RST_MEM_LUT1 | IPU_RST_MEM_RAM_SMFC | + IPU_RST_MEM_VDI_FIFO2 | IPU_RST_MEM_VDI_FIFO3 | + IPU_RST_MEM_ICB | IPU_RST_MEM_VDI_FIFO1 | + IPU_RST_MEM_DC_TEMPLATE | IPU_RST_MEM_DMFC_RD | + IPU_RST_MEM_DMFC_WR); if (ret) goto out_failed_reset; #endif diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index 6803cc7..8e9ef56 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -75,6 +75,28 @@ struct ipu_soc; #define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * (n)) #define IPU_INT_STAT(n) IPU_CM_REG(0x0200 + 4 * (n))
+#define IPU_RST_MEM_SRM BIT(0) +#define IPU_RST_MEM_ALPHA BIT(1) +#define IPU_RST_MEM_CPMEM BIT(2) +#define IPU_RST_MEM_TPM BIT(3) +#define IPU_RST_MEM_MPM BIT(4) +#define IPU_RST_MEM_BM BIT(5) +#define IPU_RST_MEM_RM BIT(6) +#define IPU_RST_MEM_DSTM BIT(7) +#define IPU_RST_MEM_DSOM BIT(8) +#define IPU_RST_MEM_LUT0 BIT(9) +#define IPU_RST_MEM_LUT1 BIT(10) +#define IPU_RST_MEM_RAM_SMFC BIT(11) +#define IPU_RST_MEM_VDI_FIFO2 BIT(12) +#define IPU_RST_MEM_VDI_FIFO3 BIT(13) +#define IPU_RST_MEM_ICB BIT(14) +#define IPU_RST_MEM_VDI_FIFO1 BIT(15) +#define IPU_RST_MEM_DC_TEMPLATE BIT(20) +#define IPU_RST_MEM_DMFC_RD BIT(21) +#define IPU_RST_MEM_DMFC_WR BIT(22) + +#define IPU_RST_MEM_START BIT(31) + #define IPU_DI0_COUNTER_RELEASE (1 << 24) #define IPU_DI1_COUNTER_RELEASE (1 << 25)
@@ -401,6 +423,8 @@ static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value,
void ipu_srm_dp_sync_update(struct ipu_soc *ipu);
+int ipu_memory_reset(struct ipu_soc *ipu, u32 rst_mem); + int ipu_module_enable(struct ipu_soc *ipu, u32 mask); int ipu_module_disable(struct ipu_soc *ipu, u32 mask);
Reset the write FIFO memories after disabling the DMFC to make sure no stale data is kept around.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/gpu/ipu-v3/ipu-dmfc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/ipu-v3/ipu-dmfc.c b/drivers/gpu/ipu-v3/ipu-dmfc.c index a40f211..e1e5506 100644 --- a/drivers/gpu/ipu-v3/ipu-dmfc.c +++ b/drivers/gpu/ipu-v3/ipu-dmfc.c @@ -131,8 +131,10 @@ void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc)
priv->use_count--;
- if (!priv->use_count) + if (!priv->use_count) { ipu_module_disable(priv->ipu, IPU_CONF_DMFC_EN); + ipu_memory_reset(priv->ipu, IPU_RST_MEM_DMFC_WR); + }
if (priv->use_count < 0) priv->use_count = 0;
On Mon, Aug 29, 2016 at 6:33 PM, Philipp Zabel p.zabel@pengutronix.de wrote:
Reset the write FIFO memories after disabling the DMFC to make sure no stale data is kept around.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de
drivers/gpu/ipu-v3/ipu-dmfc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/ipu-v3/ipu-dmfc.c b/drivers/gpu/ipu-v3/ipu-dmfc.c index a40f211..e1e5506 100644 --- a/drivers/gpu/ipu-v3/ipu-dmfc.c +++ b/drivers/gpu/ipu-v3/ipu-dmfc.c @@ -131,8 +131,10 @@ void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc)
priv->use_count--;
if (!priv->use_count)
if (!priv->use_count) { ipu_module_disable(priv->ipu, IPU_CONF_DMFC_EN);
ipu_memory_reset(priv->ipu, IPU_RST_MEM_DMFC_WR);
We've got use counter for DMFC as DMFC can be used by several channels simultaneously. That means only the last user may trigger the DMFC_WR memory reset operation. I assume this is not what we want - we need every channel's dedicated DMFC write memory could be reset separately. However, it looks that the hardware hasn't got the capability to do that. I think writing 1 to DMFC_WR resets all DMFC writing channels' memory.
Regards, Liu Ying
} if (priv->use_count < 0) priv->use_count = 0;
-- 2.8.1
On Mon, Aug 29, 2016 at 6:33 PM, Philipp Zabel p.zabel@pengutronix.de wrote:
Add defines for the memory reset bits and export the memory reset function to IPU modules.
This one is probably unneeded since patch 2/2 is questionable.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de
drivers/gpu/ipu-v3/ipu-common.c | 17 +++++++++++++---- drivers/gpu/ipu-v3/ipu-prv.h | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 5e7af61..1ad33df 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -706,14 +706,14 @@ void ipu_idmac_enable_watermark(struct ipuv3_channel *channel, bool enable) } EXPORT_SYMBOL_GPL(ipu_idmac_enable_watermark);
-static int ipu_memory_reset(struct ipu_soc *ipu) +int ipu_memory_reset(struct ipu_soc *ipu, u32 rst_mem) { unsigned long timeout;
ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
ipu_cm_write(ipu, rst_mem | IPU_RST_MEM_START, IPU_MEM_RST); timeout = jiffies + msecs_to_jiffies(1000);
while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
while (ipu_cm_read(ipu, IPU_MEM_RST) & IPU_RST_MEM_START) { if (time_after(jiffies, timeout)) return -ETIME; cpu_relax();
@@ -1363,7 +1363,16 @@ static int ipu_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to reset: %d\n", ret); goto out_failed_reset; }
ret = ipu_memory_reset(ipu);
ret = ipu_memory_reset(ipu, IPU_RST_MEM_SRM | IPU_RST_MEM_ALPHA |
IPU_RST_MEM_CPMEM | IPU_RST_MEM_TPM |
IPU_RST_MEM_MPM | IPU_RST_MEM_BM |
IPU_RST_MEM_RM | IPU_RST_MEM_DSTM |
IPU_RST_MEM_DSOM | IPU_RST_MEM_LUT0 |
IPU_RST_MEM_LUT1 | IPU_RST_MEM_RAM_SMFC |
IPU_RST_MEM_VDI_FIFO2 | IPU_RST_MEM_VDI_FIFO3 |
IPU_RST_MEM_ICB | IPU_RST_MEM_VDI_FIFO1 |
IPU_RST_MEM_DC_TEMPLATE | IPU_RST_MEM_DMFC_RD |
IPU_RST_MEM_DMFC_WR);
Better to define all the bits with a single meaningful macro in ipu-prv.h, which makes the code more readable.
if (ret) goto out_failed_reset;
#endif diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index 6803cc7..8e9ef56 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -75,6 +75,28 @@ struct ipu_soc; #define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * (n)) #define IPU_INT_STAT(n) IPU_CM_REG(0x0200 + 4 * (n))
+#define IPU_RST_MEM_SRM BIT(0) +#define IPU_RST_MEM_ALPHA BIT(1) +#define IPU_RST_MEM_CPMEM BIT(2) +#define IPU_RST_MEM_TPM BIT(3) +#define IPU_RST_MEM_MPM BIT(4) +#define IPU_RST_MEM_BM BIT(5) +#define IPU_RST_MEM_RM BIT(6) +#define IPU_RST_MEM_DSTM BIT(7) +#define IPU_RST_MEM_DSOM BIT(8) +#define IPU_RST_MEM_LUT0 BIT(9) +#define IPU_RST_MEM_LUT1 BIT(10) +#define IPU_RST_MEM_RAM_SMFC BIT(11) +#define IPU_RST_MEM_VDI_FIFO2 BIT(12) +#define IPU_RST_MEM_VDI_FIFO3 BIT(13) +#define IPU_RST_MEM_ICB BIT(14) +#define IPU_RST_MEM_VDI_FIFO1 BIT(15) +#define IPU_RST_MEM_DC_TEMPLATE BIT(20) +#define IPU_RST_MEM_DMFC_RD BIT(21) +#define IPU_RST_MEM_DMFC_WR BIT(22)
+#define IPU_RST_MEM_START BIT(31)
Some bits have different meaning for i.MX51 IPUv3. Please take a look at i.MX51 RM[1] page 1268. I think i.MX6x IPUv3 and i.MX53 IPUv3 are the same wrt the bits.
[1] http://www.nxp.com/files/dsp/doc/ref_manual/MCIMX51RM.pdf?fasp=1&WT_TYPE...
#define IPU_DI0_COUNTER_RELEASE (1 << 24) #define IPU_DI1_COUNTER_RELEASE (1 << 25)
@@ -401,6 +423,8 @@ static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value,
void ipu_srm_dp_sync_update(struct ipu_soc *ipu);
+int ipu_memory_reset(struct ipu_soc *ipu, u32 rst_mem);
Nit: To keep the same order with ipu-common.c, this line should be under ipu_wait_interrupt().
Regards, Liu Ying
int ipu_module_enable(struct ipu_soc *ipu, u32 mask); int ipu_module_disable(struct ipu_soc *ipu, u32 mask);
-- 2.8.1
dri-devel@lists.freedesktop.org