예제 #1
0
/*
 *  ======== bridge_brd_monitor ========
 *  purpose:
 *      This bridge_brd_monitor puts DSP into a Loadable state.
 *      i.e Application can load and start the device.
 *
 *  Preconditions:
 *      Device in 'OFF' state.
 */
static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt)
{
	struct bridge_dev_context *dev_context = dev_ctxt;
	u32 temp;
	struct omap_dsp_platform_data *pdata =
		omap_dspbridge_dev->dev.platform_data;

	temp = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
					OMAP_POWERSTATEST_MASK;
	if (!(temp & 0x02)) {
		/* IVA2 is not in ON state */
		/* Read and set PM_PWSTCTRL_IVA2  to ON */
		(*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK,
			PWRDM_POWER_ON, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL);
		/* Set the SW supervised state transition */
		(*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP,
					OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);

		/* Wait until the state has moved to ON */
		while ((*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
						OMAP_INTRANSITION_MASK)
			;
		/* Disable Automatic transition */
		(*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO,
					OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
	}

	dsp_clk_enable(DSP_CLK_IVA2);

	/* set the device state to IDLE */
	dev_context->dw_brd_state = BRD_IDLE;

	return 0;
}
예제 #2
0
/*
 *  ======== bridge_dev_create ========
 *      Creates a driver object. Puts DSP in self loop.
 */
static int bridge_dev_create(struct bridge_dev_context
					**dev_cntxt,
					struct dev_object *hdev_obj,
					struct cfg_hostres *config_param)
{
	int status = 0;
	struct bridge_dev_context *dev_context = NULL;
	s32 entry_ndx;
	struct cfg_hostres *resources = config_param;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	/* Allocate and initialize a data structure to contain the bridge driver
	 *  state, which becomes the context for later calls into this driver */
	dev_context = kzalloc(sizeof(struct bridge_dev_context), GFP_KERNEL);
	if (!dev_context) {
		status = -ENOMEM;
		goto func_end;
	}

	dev_context->dw_dsp_start_add = (u32) OMAP_GEM_BASE;
	dev_context->dw_self_loop = (u32) NULL;
	dev_context->dsp_per_clks = 0;
	dev_context->dw_internal_size = OMAP_DSP_SIZE;
	/*  Clear dev context MMU table entries.
	 *  These get set on bridge_io_on_loaded() call after program loaded. */
	for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; entry_ndx++) {
		dev_context->atlb_entry[entry_ndx].ul_gpp_pa =
		    dev_context->atlb_entry[entry_ndx].ul_dsp_va = 0;
	}
	dev_context->dw_dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *)
								 (config_param->
								  dw_mem_base
								  [3]),
								 config_param->
								 dw_mem_length
								 [3]);
	if (!dev_context->dw_dsp_base_addr)
		status = -EPERM;

	if (!status) {
		dev_context->tc_word_swap_on = drv_datap->tc_wordswapon;
		dev_context->hdev_obj = hdev_obj;
		/* Store current board state. */
		dev_context->dw_brd_state = BRD_UNKNOWN;
		dev_context->resources = resources;
		dsp_clk_enable(DSP_CLK_IVA2);
		bridge_brd_stop(dev_context);
		/* Return ptr to our device state to the DSP API for storage */
		*dev_cntxt = dev_context;
	} else {
		kfree(dev_context);
	}
func_end:
	return status;
}
예제 #3
0
/**
 * dsp_clock_enable_all - Enable clocks used by the DSP
 * @dev_context		Driver's device context strucure
 *
 * This function enables all the peripheral clocks that were requested by DSP.
 */
u32 dsp_clock_enable_all(u32 dsp_per_clocks)
{
	u32 clk_id;
	u32 status = -EPERM;

	for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) {
		if (is_dsp_clk_active(dsp_per_clocks, clk_id))
			status = dsp_clk_enable(clk_id);
	}

	return status;
}
예제 #4
0
static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
{
	struct cfg_hostres *resources;
	struct hw_mmu_map_attrs_t map_attrs = {
		.endianism = HW_LITTLE_ENDIAN,
		.element_size = HW_ELEM_SIZE16BIT,
		.mixed_size = HW_MMU_CPUES,
	};
	void *dummy_va_addr;

	resources = dev_context->resources;
	dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC);

	/*
	 * Before acking the MMU fault, let's make sure MMU can only
	 * access entry #0. Then add a new entry so that the DSP OS
	 * can continue in order to dump the stack.
	 */
	hw_mmu_twl_disable(resources->dmmu_base);
	hw_mmu_tlb_flush_all(resources->dmmu_base);

	hw_mmu_tlb_add(resources->dmmu_base,
			virt_to_phys(dummy_va_addr), fault_addr,
			HW_PAGE_SIZE4KB, 1,
			&map_attrs, HW_SET, HW_SET);

	dsp_clk_enable(DSP_CLK_GPT8);

	dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);

	/* Clear MMU interrupt */
	hw_mmu_event_ack(resources->dmmu_base,
			HW_MMU_TRANSLATION_FAULT);
	dump_dsp_stack(dev_context);
	dsp_clk_disable(DSP_CLK_GPT8);

	hw_mmu_disable(resources->dmmu_base);
	free_page((unsigned long)dummy_va_addr);
}