Exemple #1
0
void dsp_wdt_dpc(unsigned long data)
{
	struct deh_mgr *deh_mgr;
	dev_get_deh_mgr(dev_get_first(), &deh_mgr);
	if (deh_mgr)
		bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
}
void io_dpc(unsigned long ref_data)
{
	struct io_mgr *pio_mgr = (struct io_mgr *)ref_data;
	struct chnl_mgr *chnl_mgr_obj;
	struct msg_mgr *msg_mgr_obj;
	struct deh_mgr *hdeh_mgr;
	u32 requested;
	u32 serviced;

	if (!pio_mgr)
		goto func_end;
	chnl_mgr_obj = pio_mgr->chnl_mgr;
	dev_get_msg_mgr(pio_mgr->dev_obj, &msg_mgr_obj);
	dev_get_deh_mgr(pio_mgr->dev_obj, &hdeh_mgr);
	if (!chnl_mgr_obj)
		goto func_end;

	requested = pio_mgr->dpc_req;
	serviced = pio_mgr->dpc_sched;

	if (serviced == requested)
		goto func_end;

	
	do {
		
		if ((pio_mgr->intr_val > DEH_BASE) &&
		    (pio_mgr->intr_val < DEH_LIMIT)) {
			
			if (hdeh_mgr) {
#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
				print_dsp_debug_trace(pio_mgr);
#endif
				bridge_deh_notify(hdeh_mgr, DSP_SYSERROR,
						  pio_mgr->intr_val);
			}
		}
		
		input_chnl(pio_mgr, NULL, IO_SERVICE);
		output_chnl(pio_mgr, NULL, IO_SERVICE);

#ifdef CHNL_MESSAGES
		if (msg_mgr_obj) {
			
			input_msg(pio_mgr, msg_mgr_obj);
			output_msg(pio_mgr, msg_mgr_obj);
		}

#endif
#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
		if (pio_mgr->intr_val & MBX_DBG_SYSPRINTF) {
			
			print_dsp_debug_trace(pio_mgr);
		}
#endif
		serviced++;
	} while (serviced != requested);
	pio_mgr->dpc_sched = requested;
func_end:
	return;
}
Exemple #3
0
/*
 *  ======== sleep_dsp ========
 *  	Put DSP in low power consuming state.
 */
int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
		     void *pargs)
{
	int status = 0;
#ifdef CONFIG_PM
#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
	struct deh_mgr *hdeh_mgr;
#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
	u16 timeout = PWRSTST_TIMEOUT / 10;
	u32 pwr_state, target_pwr_state;
	struct omap_dsp_platform_data *pdata =
		omap_dspbridge_dev->dev.platform_data;

	/* Check if sleep code is valid */
	if ((dw_cmd != PWR_DEEPSLEEP) && (dw_cmd != PWR_EMERGENCYDEEPSLEEP))
		return -EINVAL;

	switch (dev_context->brd_state) {
	case BRD_RUNNING:
		omap_mbox_save_ctx(dev_context->mbox);
		if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
			sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
			dev_dbg(bridge, "PM: %s - sent hibernate cmd to DSP\n",
				__func__);
			target_pwr_state = PWRDM_POWER_OFF;
		} else {
			sm_interrupt_dsp(dev_context, MBX_PM_DSPRETENTION);
			target_pwr_state = PWRDM_POWER_RET;
		}
		break;
	case BRD_RETENTION:
		omap_mbox_save_ctx(dev_context->mbox);
		if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
			sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
			target_pwr_state = PWRDM_POWER_OFF;
		} else
			return 0;
		break;
	case BRD_HIBERNATION:
	case BRD_DSP_HIBERNATION:
		/* Already in Hibernation, so just return */
		dev_dbg(bridge, "PM: %s - DSP already in hibernation\n",
			__func__);
		return 0;
	case BRD_STOPPED:
		dev_dbg(bridge, "PM: %s - Board in STOP state\n", __func__);
		return 0;
	default:
		dev_dbg(bridge, "PM: %s - Bridge in Illegal state\n", __func__);
		return -EPERM;
	}

	/* Get the PRCM DSP power domain status */
	pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
						OMAP_POWERSTATEST_MASK;

	/* Wait for DSP to move into target power state */
	while ((pwr_state != target_pwr_state) && --timeout) {
		if (msleep_interruptible(10)) {
			pr_err("Waiting for DSP to Suspend interrupted\n");
			return -EPERM;
		}
		pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
					OMAP2_PM_PWSTST) & OMAP_POWERSTATEST_MASK;
	}

	if (!timeout) {
		pr_err("%s: Timed out waiting for DSP off mode, state %x\n",
		       __func__, pwr_state);
#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
		dev_get_deh_mgr(dev_context->dev_obj, &hdeh_mgr);
		bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0);
#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
		return -ETIMEDOUT;
	} else {
		/* Update the Bridger Driver state */
		if (dsp_test_sleepstate == PWRDM_POWER_OFF)
			dev_context->brd_state = BRD_HIBERNATION;
		else
			dev_context->brd_state = BRD_RETENTION;

		/* Disable wdt on hibernation. */
		dsp_wdt_enable(false);

		/* Turn off DSP Peripheral clocks */
		status = dsp_clock_disable_all(dev_context->dsp_per_clks);
		if (status)
			return status;
#ifdef CONFIG_TIDSPBRIDGE_DVFS
		else if (target_pwr_state == PWRDM_POWER_OFF) {
			/*
			 * Set the OPP to low level before moving to OFF mode
			 */
			if (pdata->dsp_set_min_opp)
				(*pdata->dsp_set_min_opp) (VDD1_OPP1);
		}
#endif /* CONFIG_TIDSPBRIDGE_DVFS */
	}
#endif /* CONFIG_PM */
	return status;
}