Exemple #1
0
static void _destroy_pm_flags(struct rproc *rproc)
{
	struct omap_rproc_priv *rpp = rproc->priv;

	if (rpp->mbox) {
		omap_mbox_put(rpp->mbox, NULL);
		rpp->mbox = NULL;
	}
	if (rpp->idle) {
		iounmap(rpp->idle);
		rpp->idle = NULL;
	}
	if (rpp->suspend) {
		iounmap(rpp->suspend);
		rpp->suspend = NULL;
	}
}
Exemple #2
0
int omap_rproc_deactivate(struct omap_device *od)
{
	int i, ret = 0;
	struct rproc *rproc = platform_get_drvdata(&od->pdev);
	struct device *dev = rproc->dev;
	struct omap_rproc_pdata *pdata = dev->platform_data;
	struct omap_rproc_timers_info *timers = pdata->timers;
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
	struct omap_rproc_priv *rpp = rproc->priv;
#endif
	if (pdata->clkdm)
		clkdm_wakeup(pdata->clkdm);

	for (i = 0; i < od->hwmods_cnt; i++) {
		ret = omap_hwmod_shutdown(od->hwmods[i]);
		if (ret)
			goto err;
	}

	for (i = 0; i < pdata->timers_cnt; i++)
		omap_dm_timer_stop(timers[i].odt);

#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
	if (rpp->iommu) {
		iommu_put(rpp->iommu);
		rpp->iommu = NULL;
	}

	if (rpp->mbox) {
		omap_mbox_put(rpp->mbox, NULL);
		rpp->mbox = NULL;
	}
#endif
err:
	if (pdata->clkdm)
		clkdm_allow_idle(pdata->clkdm);

	return ret;
}
Exemple #3
0
static int _init_pm_flags(struct rproc *rproc)
{
	struct omap_rproc_pdata *pdata = rproc->dev->platform_data;
	struct omap_rproc_priv *rpp = rproc->priv;
	struct omap_mbox *mbox;

	if (!rpp->mbox) {
		mbox = omap_mbox_get(pdata->sus_mbox_name, NULL);
		if (IS_ERR(mbox))
			return PTR_ERR(mbox);
		rpp->mbox = mbox;
	}
	if (!pdata->idle_addr)
		goto err_idle;

	rpp->idle = ioremap(pdata->idle_addr, sizeof(u32));
	if (!rpp->idle)
		goto err_idle;

	if (!pdata->suspend_addr)
		goto err_suspend;

	rpp->suspend = ioremap(pdata->suspend_addr, sizeof(u32));
	if (!rpp->suspend)
		goto err_suspend;

	rpp->idle_mask = pdata->idle_mask;
	rpp->suspend_mask = pdata->suspend_mask;

	return 0;
err_suspend:
	iounmap(rpp->idle);
	rpp->idle = NULL;
err_idle:
	omap_mbox_put(rpp->mbox, NULL);
	rpp->mbox = NULL;
	return -EIO;
}
Exemple #4
0
/* Initiliaze WKUP_M3, load the binary blob and let it run */
static int wkup_m3_init(void)
{
	struct clk *m3_clk;
	struct omap_hwmod *wkup_m3_oh;
	const struct firmware *firmware;
	int ret = 0;

	wkup_m3_oh = omap_hwmod_lookup("wkup_m3");

	if (!wkup_m3_oh) {
		pr_err("%s: could not find omap_hwmod\n", __func__);
		ret = -ENODEV;
		goto exit;
	}

	ipc_regs = ioremap(A8_M3_IPC_REGS, 0x4*8);
	if (!ipc_regs) {
		pr_err("Could not ioremap the IPC area\b");
		ret = -ENOMEM;
		goto exit;
	}

	m3_eoi = ioremap(M3_TXEV_EOI, 0x4);
	if (!m3_eoi) {
		pr_err("Could not ioremap the EOI register\n");
		ret = -ENOMEM;
		goto err1;
	}

	/* Reserve the MBOX for sending messages to M3 */
	m3_mbox = omap_mbox_get("wkup_m3", &wkup_m3_mbox_notifier);
	if (IS_ERR(m3_mbox)) {
		pr_err("Could not reserve mailbox for A8->M3 IPC\n");
		ret = -ENODEV;
		goto err2;
	}

	/* Enable access to the M3 code and data area from A8 */
	m3_clk = clk_get(NULL, "wkup_m3_fck");
	if (IS_ERR(m3_clk)) {
		pr_err("%s failed to enable WKUP_M3 clock\n", __func__);
		goto err3;
	}

	if (clk_enable(m3_clk)) {
		pr_err("%s WKUP_M3: clock enable Failed\n", __func__);
		goto err4;
	}

	m3_code = ioremap(M3_UMEM, SZ_16K);
	if (!m3_code) {
		pr_err("%s Could not ioremap M3 code space\n", __func__);
		ret = -ENOMEM;
		goto err5;
	}

	pr_info("Trying to load am335x-pm-firmware.bin (60 secs timeout)\n");

	ret = request_firmware(&firmware, "am335x-pm-firmware.bin", mpu_dev);
	if (ret < 0) {
		dev_err(mpu_dev, "request_firmware failed\n");
		goto err6;
	} else {
		memcpy(m3_code, firmware->data, firmware->size);
		pr_info("Copied the M3 firmware to UMEM\n");
	}

	ret = request_irq(AM33XX_IRQ_M3_M3SP_TXEV, wkup_m3_txev_handler,
			  IRQF_DISABLED, "wkup_m3_txev", NULL);
	if (ret) {
		pr_err("%s request_irq failed for 0x%x\n", __func__,
			AM33XX_IRQ_M3_M3SP_TXEV);
		goto err6;
	}

	m3_state = M3_STATE_RESET;

	ret = omap_hwmod_deassert_hardreset(wkup_m3_oh, "wkup_m3");
	if (ret) {
		pr_err("Could not deassert the reset for WKUP_M3\n");
		goto err6;
	} else {
		return 0;
	}

err6:
	release_firmware(firmware);
	iounmap(m3_code);
err5:
	clk_disable(m3_clk);
err4:
	clk_put(m3_clk);
err3:
	omap_mbox_put(m3_mbox, &wkup_m3_mbox_notifier);
err2:
	iounmap(m3_eoi);
err1:
	iounmap(ipc_regs);
exit:
	return ret;
}
/*
 *  ======== bridge_brd_stop ========
 *  purpose:
 *      Puts DSP in self loop.
 *
 *  Preconditions :
 *  a) None
 */
static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
{
	int status = 0;
	struct bridge_dev_context *dev_context = dev_ctxt;
	u32 dsp_pwr_state;
	int i;
	struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry;
	struct omap_dsp_platform_data *pdata =
		omap_dspbridge_dev->dev.platform_data;

	if (dev_context->dw_brd_state == BRD_STOPPED)
		return status;

	/* as per TRM, it is advised to first drive the IVA2 to 'Standby' mode,
	 * before turning off the clocks.. This is to ensure that there are no
	 * pending L3 or other transactons from IVA2 */
	dsp_pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
					OMAP_POWERSTATEST_MASK;
	if (dsp_pwr_state != PWRDM_POWER_OFF) {
		(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
					OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
		sm_interrupt_dsp(dev_context, MBX_PM_DSPIDLE);
		mdelay(10);

		/* IVA2 is not in OFF state */
		/* Set PM_PWSTCTRL_IVA2  to OFF */
		(*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK,
			PWRDM_POWER_OFF, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL);
		/* Set the SW supervised state transition for Sleep */
		(*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_SLEEP,
					OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
	}
	udelay(10);
	/* Release the Ext Base virtual Address as the next DSP Program
	 * may have a different load address */
	if (dev_context->dw_dsp_ext_base_addr)
		dev_context->dw_dsp_ext_base_addr = 0;

	dev_context->dw_brd_state = BRD_STOPPED;	/* update board state */

	dsp_wdt_enable(false);

	/* Reset DSP */
	(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,
		OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);

	/* Disable the mailbox interrupts */
	if (dev_context->mbox) {
		omap_mbox_disable_irq(dev_context->mbox, IRQ_RX);
		omap_mbox_put(dev_context->mbox);
		dev_context->mbox = NULL;
	}
	if (dev_context->dsp_mmu) {
		pr_err("Proc stop mmu if statement\n");
		for (i = 0; i < BRDIOCTL_NUMOFMMUTLB; i++) {
			if (!tlb[i].ul_gpp_pa)
				continue;
			iommu_kunmap(dev_context->dsp_mmu, tlb[i].ul_gpp_va);
		}
		i = 0;
		while (l4_peripheral_table[i].phys_addr) {
			iommu_kunmap(dev_context->dsp_mmu,
				l4_peripheral_table[i].dsp_virt_addr);
			i++;
		}
		iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg0_da);
		iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg1_da);
		dsp_mmu_exit(dev_context->dsp_mmu);
		dev_context->dsp_mmu = NULL;
	}
	/* Reset IVA IOMMU*/
	(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK,
		OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);

	dsp_clock_disable_all(dev_context->dsp_per_clks);
	dsp_clk_disable(DSP_CLK_IVA2);

	return status;
}