MFC_WRITEL(0, MFC_REG_RISC2HOST_INT); \
} while (0)
+static inline int mfc_wait_pending(struct mfc_dev *dev)
+{
+ unsigned int status;
+ unsigned long timeout;
+
+ /* Check F/W wait status */
+ timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
+ do {
+ if (time_after(jiffies, timeout)) {
+ mfc_err_dev("Timeout while waiting MFC F/W done\n");
+ return -EIO;
+ }
+ status = MFC_READL(MFC_REG_FIRMWARE_STATUS_INFO);
+ } while ((status & 0x1) == 0);
+
+ /* Check H/W pending status */
+ timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
+ do {
+ if (time_after(jiffies, timeout)) {
+ mfc_err_dev("Timeout while pendng clear\n");
+ mfc_err_dev("MFC access pending R: %#x, BUS: %#x\n",
+ MFC_READL(MFC_REG_MFC_RPEND),
+ MFC_READL(MFC_REG_MFC_BUS_STATUS));
+ return -EIO;
+ }
+ status = MFC_READL(MFC_REG_MFC_RPEND);
+ } while (status != 0);
+
+ MFC_TRACE_DEV("** pending wait done\n");
+
+ return 0;
+}
+
static inline int mfc_stop_bus(struct mfc_dev *dev)
{
unsigned int status;
* -> IP Protection enable -> clock on
*/
dev->pm.clock_on_steps |= 0x1 << 1;
- if (dev->pm.base_type != MFCBUF_INVALID)
+ if (dev->pm.base_type != MFCBUF_INVALID) {
+ dev->pm.clock_on_steps |= 0x1 << 2;
+ ret = mfc_wait_pending(dev);
+ if (ret != 0) {
+ mfc_err_dev("pending wait failed (%d)\n", ret);
+ call_dop(dev, dump_and_stop_debug_mode, dev);
+ return ret;
+ }
+ dev->pm.clock_on_steps |= 0x1 << 3;
mfc_set_risc_base_addr(dev, dev->pm.base_type);
+ }
- dev->pm.clock_on_steps |= 0x1 << 2;
+ dev->pm.clock_on_steps |= 0x1 << 4;
#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
if (dev->curr_ctx_is_drm) {
unsigned long flags;
mfc_debug(3, "Begin: enable protection\n");
ret = exynos_smc(SMC_PROTECTION_SET, 0,
dev->id, SMC_PROTECTION_ENABLE);
- dev->pm.clock_on_steps |= 0x1 << 3;
+ dev->pm.clock_on_steps |= 0x1 << 5;
if (ret != DRMDRV_OK) {
mfc_err_dev("Protection Enable failed! ret(%u)\n", ret);
call_dop(dev, dump_and_stop_debug_mode, dev);
}
#endif
- dev->pm.clock_on_steps |= 0x1 << 4;
+ dev->pm.clock_on_steps |= 0x1 << 6;
ret = clk_enable(dev->pm.clock);
if (ret < 0) {
mfc_err_dev("clk_enable failed (%d)\n", ret);
return ret;
}
- dev->pm.clock_on_steps |= 0x1 << 5;
+ dev->pm.clock_on_steps |= 0x1 << 7;
atomic_inc_return(&dev->clk_ref);
- dev->pm.clock_on_steps |= 0x1 << 6;
+ dev->pm.clock_on_steps |= 0x1 << 8;
state = atomic_read(&dev->clk_ref);
mfc_debug(2, "+ %d\n", state);
- MFC_TRACE_DEV("** clock_on end: ref state(%d)\n", state);
+ MFC_TRACE_DEV("** clock_on end: ref(%d) step(%#x)\n", state, dev->pm.clock_on_steps);
MFC_TRACE_LOG_DEV("c+%d", state);
return 0;
dev->pm.clock_off_steps |= 0x1 << 7;
state = atomic_read(&dev->clk_ref);
mfc_debug(2, "- %d\n", state);
- MFC_TRACE_DEV("** clock_off end: ref state(%d)\n", state);
+ MFC_TRACE_DEV("** clock_off end: ref(%d) step(%#x)\n", state, dev->pm.clock_off_steps);
MFC_TRACE_LOG_DEV("c-%d", state);
}