/* * ======== 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; }
/* * ======== 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; }
/** * 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; }
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); }