Beispiel #1
0
DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext,
				u16 wMbVal)
{
	struct CFG_HOSTRES resources;
	DSP_STATUS status = DSP_SOK;
	unsigned long timeout;
	u32 temp;

	status = CFG_GetHostResources((struct CFG_DEVNODE *)
			DRV_GetFirstDevExtension(), &resources);
	if (DSP_FAILED(status))
		return DSP_EFAIL;

	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
#ifdef CONFIG_BRIDGE_DVFS
		struct dspbridge_platform_data *pdata =
			omap_dspbridge_dev->dev.platform_data;
		/*
		 * When Smartreflex is ON, DSP requires at least OPP level 3
		 * to operate reliably. So boost lower OPP levels to OPP3.
		 */
		if (pdata->dsp_set_min_opp)
			(*pdata->dsp_set_min_opp)(min_active_opp);
#endif
		/* Restart the peripheral clocks */
		DSP_PeripheralClocks_Enable(pDevContext, NULL);

		/*
		 * 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control
		 *     in CM_AUTOIDLE_PLL_IVA2 register
		 */
		*(REG_UWORD32 *)(resources.dwCmBase + 0x34) = 0x1;

		/*
		 * 7:4 IVA2_DPLL_FREQSEL - IVA2 internal frq set to
		 *     0.75 MHz - 1.0 MHz
		 * 2:0 EN_IVA2_DPLL - Enable IVA2 DPLL in lock mode
		 */
		temp = *(REG_UWORD32 *)(resources.dwCmBase + 0x4);
		temp = (temp & 0xFFFFFF08) | 0x37;
		*(REG_UWORD32 *)(resources.dwCmBase + 0x4) = temp;

		/*
		 * This delay is needed to avoid mailbox timed out
		 * issue experienced while SmartReflex is ON.
		 * TODO: Instead of 1 ms calculate proper value.
		 */
		mdelay(1);

		/* Restore mailbox settings */
		HW_MBOX_restoreSettings(resources.dwMboxBase);

		/* Access MMU SYS CONFIG register to generate a short wakeup */
		temp = *(REG_UWORD32 *)(resources.dwDmmuBase + 0x10);

		pDevContext->dwBrdState = BRD_RUNNING;
	}

	timeout = jiffies + msecs_to_jiffies(1);
	while (fifo_full((void __iomem *) resources.dwMboxBase, 0)) {
		if (time_after(jiffies, timeout)) {
			pr_err("dspbridge: timed out waiting for mailbox\n");
			return WMD_E_TIMEOUT;
		}
	}

	DBG_Trace(DBG_LEVEL3, "writing %x to Mailbox\n", wMbVal);
	HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP, wMbVal);
	return DSP_SOK;
}
int send_mbox_callback(void *arg)
{
	struct WMD_DEV_CONTEXT *dev_ctxt = (struct WMD_DEV_CONTEXT *)arg;
	u32 temp;
	unsigned long flags;
	DEFINE_SPINLOCK(irq_lock);

	if (!dev_ctxt)
		return -EFAULT;

	if (dev_ctxt->dwBrdState == BRD_DSP_HIBERNATION ||
	    dev_ctxt->dwBrdState == BRD_HIBERNATION) {
		/* Restart the peripheral clocks */
		DSP_PeripheralClocks_Enable(dev_ctxt, NULL);

#ifdef CONFIG_BRIDGE_WDT3
		dsp_wdt_enable(true);
#endif

		spin_lock_irqsave(&irq_lock, flags);
		/* Enabling Dpll in lock mode*/
		temp = (u32) *((REG_UWORD32 *)
				((u32) (dev_ctxt->cmbase) + 0x34));
		temp = (temp & 0xFFFFFFFE) | 0x1;
		*((REG_UWORD32 *) ((u32) (dev_ctxt->cmbase) + 0x34)) =
			(u32) temp;
		temp = (u32) *((REG_UWORD32 *)
				((u32) (dev_ctxt->cmbase) + 0x4));
		temp = (temp & 0xFFFFF08) | 0x37;

		*((REG_UWORD32 *) ((u32) (dev_ctxt->cmbase) + 0x4)) =
			(u32) temp;
		/* Restore mailbox settings */
		omap_mbox_restore_ctx(dev_ctxt->mbox);

		/*
		  * Short wake up source is any read access to an MMU
		  * registers. Making a MMU flush or accessing any other MMU
		  * register before getting to this point will have the IVA in
		  * ON state or Retention if the DSP has moved to that state,
		  * having the Short Wakeup again is redundant and brings
		  * issues when accessing the MMU after the DSP has started
		  * its restore sequence. We will access only if the DSP
		  * is not in RET or ON.
		  */
		HW_PWRST_IVA2RegGet(dev_ctxt->prmbase, &temp);
		if (!(temp & HW_PWR_STATE_RET) && !(temp & HW_PWR_STATE_ON))
			/*
			  * Flush the TLBs, this will generate the
			  * shortwakeup.  Also wait for the DSP to restore.
			  */
                        tlb_flush_all(dev_ctxt->dwDSPMmuBase);

		udelay(10);
                spin_unlock_irqrestore(&irq_lock, flags);
                dev_ctxt->dwBrdState = BRD_RUNNING;
        } else if (dev_ctxt->dwBrdState == BRD_RETENTION) {
                /* Restart the peripheral clocks */
                DSP_PeripheralClocks_Enable(dev_ctxt, NULL);
                dev_ctxt->dwBrdState = BRD_RUNNING;
        }

	return 0;
}
Beispiel #3
0
DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext,
				u16 wMbVal)
{
#ifndef CONFIG_DISABLE_BRIDGE_PM
#ifndef CONFIG_DISABLE_BRIDGE_DVFS
	u32 opplevel;
#endif
#endif
	struct CFG_HOSTRES resources;
	unsigned long timeout;
	u32 temp;
	DSP_STATUS status = DSP_SOK;

	/* We are waiting indefinitely here. This needs to be fixed in the
	 * second phase */
	CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(),
			&resources);

	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
#ifndef CONFIG_DISABLE_BRIDGE_PM
#ifndef CONFIG_DISABLE_BRIDGE_DVFS
#ifndef CONFIG_OMAP3_PM
		opplevel = omap_pm_dsp_get_opp();
		/* If OPP is at minimum level, increase it before waking up
		* the DSP */
		if (opplevel == 1) {
			omap_pm_dsp_set_min_opp(opplevel+1);
			DBG_Trace(DBG_LEVEL7, "CHNLSM_InterruptDSP:Setting "
			"the vdd1 constraint level to %d before "
			"waking DSP \n", (opplevel + 1));
		}

#else
		opplevel = constraint_get_level(dsp_constraint_handle);
		/* If OPP is at minimum level, increase it before waking up
		 * the DSP */
		if (opplevel == 1) {
			if (constraint_set(dsp_constraint_handle,
			   (opplevel+1)) != 0) {
				DBG_Trace(DBG_LEVEL7, "CHNLSM_InterruptDSP: "
					 "Constraint set failed\n");
				return DSP_EFAIL;
			}
			DBG_Trace(DBG_LEVEL7, "CHNLSM_InterruptDSP:Setting "
				 "the vdd1 constraint level to %d before "
				 "waking DSP \n", (opplevel + 1));
		}

#endif
#endif
#endif
		/* Restart the IVA clock that was disabled while
		 * the DSP initiated Hibernation. */
		if ((pDevContext->dwBrdState == BRD_DSP_HIBERNATION)
		   || (pDevContext->dwBrdState == BRD_HIBERNATION)) {
			status = CLK_Enable(SERVICESCLK_iva2_ck);
			if (DSP_FAILED(status))
				return status;
		}

		/* Read MMU register to invoke short wakeup of DSP */
		temp = (u32) *((REG_UWORD32 *) ((u32)
		       (resources.dwDmmuBase) + 0x10));

		/* Restore mailbox settings */
		HW_MBOX_restoreSettings(resources.dwMboxBase);
		DBG_Trace(DBG_LEVEL6, "MailBoxSettings: SYSCONFIG = 0x%x\n",
			  mboxsetting.sysconfig);
		DBG_Trace(DBG_LEVEL6, "MailBoxSettings: IRQENABLE0 = 0x%x\n",
			  mboxsetting.irqEnable0);
		DBG_Trace(DBG_LEVEL6, "MailBoxSettings: IRQENABLE1 = 0x%x\n",
			 mboxsetting.irqEnable1);
		/* Restart the peripheral clocks that were disabled only
		 * in DSP initiated Hibernation case.*/
		if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION)
			DSP_PeripheralClocks_Enable(pDevContext, NULL);

		pDevContext->dwBrdState = BRD_RUNNING;
	}
	timeout = jiffies + msecs_to_jiffies(35);
	while (HW_MBOX_IsFull(resources.dwMboxBase, MBOX_ARM2DSP)) {
		if (time_after(jiffies, timeout)) {
			printk(KERN_ERR "dspbridge: "
				"timed out waiting for mailbox\n");
			return WMD_E_TIMEOUT;
		}
	}
	DBG_Trace(DBG_LEVEL3, "writing %x to Mailbox\n",
		  wMbVal);

	HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP,
			 wMbVal);
	return DSP_SOK;
}
Beispiel #4
0
DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext,
				u16 wMbVal)
{
#ifdef CONFIG_BRIDGE_DVFS
	struct dspbridge_platform_data *pdata =
		omap_dspbridge_dev->dev.platform_data;
	u32 opplevel = 0;
#endif
	struct CFG_HOSTRES resources;
	DSP_STATUS status = DSP_SOK;
	unsigned long timeout;
	u32 temp;

	status = CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(),
				      &resources);
	if (DSP_FAILED(status))
		return DSP_EFAIL;
#ifdef CONFIG_BRIDGE_DVFS
	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
		if (pdata->dsp_get_opp)
			opplevel = (*pdata->dsp_get_opp)();
		if (opplevel == 1) {
			if (pdata->dsp_set_min_opp)
				(*pdata->dsp_set_min_opp)(opplevel+1);
		}
	}
#endif

	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
		/* Restart the IVA clock that was disabled while
		 * the DSP initiated Hibernation. */
			status = CLK_Enable(SERVICESCLK_iva2_ck);
			if (DSP_FAILED(status))
				return status;

		/* Restore mailbox settings */
		/* Restart the peripheral clocks that were disabled only
		 * in DSP initiated Hibernation case.*/
		if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION) {
			DSP_PeripheralClocks_Enable(pDevContext, NULL);
			/* Enabling Dpll in lock mode*/
			temp = (u32) *((REG_UWORD32 *)
				       ((u32) (resources.dwCmBase) + 0x34));
			temp = (temp & 0xFFFFFFFE) | 0x1;
			*((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x34)) =
				(u32) temp;
			temp = (u32) *((REG_UWORD32 *)
				       ((u32) (resources.dwCmBase) + 0x4));
			temp = (temp & 0xFFFFFC8) | 0x37;

			*((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x4)) =
				(u32) temp;
		}
		HW_MBOX_restoreSettings(resources.dwMboxBase);

		/*  Access MMU SYS CONFIG register to generate a short wakeup */
		temp = (u32) *((REG_UWORD32 *) ((u32)
						(resources.dwDmmuBase) + 0x10));

		pDevContext->dwBrdState = BRD_RUNNING;
	}
	timeout = jiffies + msecs_to_jiffies(1);
	while (fifo_full((void __iomem *) resources.dwMboxBase, 0)) {
		if (time_after(jiffies, timeout)) {
			printk(KERN_ERR "dspbridge: timed out waiting for mailbox\n");
			return WMD_E_TIMEOUT;
		}
	}
	DBG_Trace(DBG_LEVEL3, "writing %x to Mailbox\n",
		  wMbVal);

	HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP,
			 wMbVal);
	return DSP_SOK;
}