enum ia_css_err ia_css_spctrl_start(sp_ID_t sp_id) { unsigned int HIVE_ADDR_sp_start_isp_entry; #if defined(HAS_SEC_SP) unsigned int HIVE_ADDR_sp1_start_entry; #endif /* HAS_SEC_SP */ if ((sp_id >= N_SP_ID) || ((sp_id < N_SP_ID) && (!spctrl_loaded[sp_id]))) return IA_CSS_ERR_INVALID_ARGUMENTS; if (sp_id == SP0_ID) HIVE_ADDR_sp_start_isp_entry = spctrl_cofig_info[sp_id].sp_entry; #if defined(HAS_SEC_SP) else HIVE_ADDR_sp1_start_entry = spctrl_cofig_info[sp_id].sp_entry; #endif /* HAS_SEC_SP */ #if !defined(C_RUN) && !defined(HRT_UNSCHED) sp_dmem_store(sp_id, spctrl_cofig_info[sp_id].spctrl_config_dmem_addr, &spctrl_cofig_info[sp_id].dmem_config, sizeof(spctrl_cofig_info[sp_id].dmem_config)); #endif if (sp_id == SP0_ID) hrt_cell_start_function(SP, sp_start_isp); #if defined(HAS_SEC_SP) else /* Secondary SP is named as sp1 in the firmware however in SDK secondary SP is named as SP2 */ hrt_cell_start_function(SP2, sp1_start); #endif /* HAS_SEC_SP */ return IA_CSS_SUCCESS; }
enum ia_css_err ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe, unsigned int or_mask, unsigned int and_mask) { const struct ia_css_fw_info *fw = &sh_css_sp_fw; unsigned int HIVE_ADDR_host_sp_com = fw->info.sp.host_sp_com; unsigned int offset; struct sh_css_event_irq_mask event_irq_mask; (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */ sh_css_dtrace(SH_DBG_TRACE, "ia_css_pipe_set_irq_mask(" "or_mask=%x, and_mask=%x)\n", or_mask, and_mask); assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES); /*assert(or_mask <= UINT16_MAX);*/ /*assert(and_mask <= UINT16_MAX);*/ event_irq_mask.or_mask = (uint16_t)or_mask; event_irq_mask.and_mask = (uint16_t)and_mask; offset = offsetof(struct host_sp_communication, host2sp_event_irq_mask[ia_css_pipe_get_pipe_num(pipe)]); assert(offset % HRT_BUS_BYTES == 0); sp_dmem_store(SP0_ID, (unsigned int)sp_address_of(host_sp_com) + offset, &event_irq_mask, sizeof(event_irq_mask)); return IA_CSS_SUCCESS; }
static void store_sp_per_frame_data(const struct ia_css_fw_info *fw) { unsigned int HIVE_ADDR_sp_per_frame_data = 0; assert(fw != NULL); switch (fw->type) { case ia_css_sp_firmware: HIVE_ADDR_sp_per_frame_data = fw->info.sp.per_frame_data; break; #if defined(IS_ISP_2500_SYSTEM) case ia_css_sp1_firmware: (void)fw; break; #endif case ia_css_acc_firmware: HIVE_ADDR_sp_per_frame_data = fw->info.acc.per_frame_data; break; case ia_css_isp_firmware: return; } sp_dmem_store(SP0_ID, (unsigned int)sp_address_of(sp_per_frame_data), &per_frame_data, sizeof(per_frame_data)); }
static void upload_var(void *sp_address, void *val, size_t size) { if (!sp_address) return; sp_dmem_store(SP0_ID, HOST_ADDRESS(sp_address), val, size); }
static void sh_css_acc_init(struct sh_css_acc_fw *firmware) { struct sh_css_acc_sp *sp = &firmware->header.sp; unsigned sp_address = (unsigned)HOST_ADDRESS( sp->fw.info.sp.ddr_parameter_address); unsigned sp_size = (unsigned)HOST_ADDRESS( sp->fw.info.sp.ddr_parameter_size); unsigned value = firmware->header.parameters.ddr_address; unsigned size = firmware->header.parameters.ddr_size; /* MW: "sp_address" is an offset address, 0 is a legal value*/ if (sp_address != 0) { sp_dmem_store(SP0_ID, sp_address, &value, sizeof(value)); sp_dmem_store(SP0_ID, sp_size, &size, sizeof(size)); } }
enum ia_css_err ia_css_spctrl_start(sp_ID_t sp_id) { unsigned int HIVE_ADDR_sp_start_isp_entry; if ((sp_id >= N_SP_ID) || ((sp_id < N_SP_ID) && (!spctrl_loaded[sp_id]))) return IA_CSS_ERR_INVALID_ARGUMENTS; HIVE_ADDR_sp_start_isp_entry = spctrl_cofig_info[sp_id].sp_entry; #if !defined(C_RUN) && !defined(HRT_UNSCHED) sp_dmem_store(sp_id, spctrl_cofig_info[sp_id].spctrl_config_dmem_addr, &spctrl_cofig_info[sp_id].dmem_config, sizeof(spctrl_cofig_info[sp_id].dmem_config)); #endif hrt_cell_start_function(SP, sp_start_isp); return IA_CSS_SUCCESS; }
/* Initialize the entire contents of the DMEM at once -- does not need to * do this from the host */ void sh_css_sp_store_init_dmem(const struct sh_css_fw_info *fw) { struct sh_css_sp_init_dmem_cfg init_dmem_cfg; mmgr_store(init_dmem_ddr, fw->blob.data, fw->blob.data_size); /* Configure the data structure to initialize dmem */ init_dmem_cfg.done = false; init_dmem_cfg.ddr_data_addr = init_dmem_ddr; init_dmem_cfg.dmem_data_addr = (hrt_vaddress)fw->blob.data_target; init_dmem_cfg.data_size = fw->blob.data_size; init_dmem_cfg.dmem_bss_addr = (hrt_vaddress)fw->blob.bss_target; init_dmem_cfg.bss_size = fw->blob.bss_size; sp_dmem_store(SP0_ID, (unsigned)fw->info.sp.init_dmem_data, &init_dmem_cfg, sizeof(init_dmem_cfg)); }
static void store_sp_per_frame_data(const struct sh_css_fw_info *fw) { unsigned int HIVE_ADDR_sp_per_frame_data = 0; switch (fw->type) { case sh_css_sp_firmware: HIVE_ADDR_sp_per_frame_data = fw->info.sp.per_frame_data; break; case sh_css_acc_firmware: HIVE_ADDR_sp_per_frame_data = fw->info.acc.per_frame_data; break; case sh_css_isp_firmware: return; } sp_dmem_store(SP0_ID, (unsigned int)sp_address_of(sp_per_frame_data), &per_frame_data, sizeof(per_frame_data)); }
static const unsigned char * sh_css_acc_upload_isp_code(const struct sh_css_acc_fw *firmware) { struct sh_css_acc_fw_hdr *header = (struct sh_css_acc_fw_hdr *)&firmware->header; const unsigned char *binary = firmware->header.isp_code; if (!binary) { const unsigned char *blob = SH_CSS_ACC_ISP_CODE(firmware); unsigned size = SH_CSS_ACC_ISP_SIZE(firmware); binary = (const unsigned char *)HOST_ADDRESS( sh_css_load_blob(blob, size)); header->isp_code = binary; } if (!binary) return NULL; sp_dmem_store(SP0_ID, HOST_ADDRESS(header->sp.isp_code), &binary, sizeof(binary)); return binary; }
/* Initialize dmem_cfg in SP dmem and start SP program*/ enum ia_css_err ia_css_spctrl_start(sp_ID_t sp_id) { if ((sp_id >= N_SP_ID) || ((sp_id < N_SP_ID) && (!spctrl_loaded[sp_id]))) return IA_CSS_ERR_INVALID_ARGUMENTS; /* Set descr in the SP to initialize the SP DMEM */ /* * The FW stores user-space pointers to the FW, the ISP pointer * is only available here * */ assert(sizeof(unsigned int) <= sizeof(hrt_data)); sp_dmem_store(sp_id, spctrl_cofig_info[sp_id].spctrl_config_dmem_addr, &spctrl_cofig_info[sp_id].dmem_config, sizeof(spctrl_cofig_info[sp_id].dmem_config)); /* set the start address */ sp_ctrl_store(sp_id, SP_START_ADDR_REG, (hrt_data)spctrl_cofig_info[sp_id].sp_entry); sp_ctrl_setbit(sp_id, SP_SC_REG, SP_RUN_BIT); sp_ctrl_setbit(sp_id, SP_SC_REG, SP_START_BIT); return IA_CSS_SUCCESS; }
void sh_css_event_init_irq_mask(void) { int i; const struct ia_css_fw_info *fw = &sh_css_sp_fw; unsigned int HIVE_ADDR_host_sp_com = fw->info.sp.host_sp_com; unsigned int offset; struct sh_css_event_irq_mask event_irq_mask_init; event_irq_mask_init.or_mask = IA_CSS_EVENT_TYPE_ALL; event_irq_mask_init.and_mask = IA_CSS_EVENT_TYPE_NONE; (void)HIVE_ADDR_host_sp_com; /* Suppress warnings in CRUN */ assert(sizeof(event_irq_mask_init) % HRT_BUS_BYTES == 0); for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) { offset = offsetof(struct host_sp_communication, host2sp_event_irq_mask[i]); assert(offset % HRT_BUS_BYTES == 0); sp_dmem_store(SP0_ID, (unsigned int)sp_address_of(host_sp_com) + offset, &event_irq_mask_init, sizeof(event_irq_mask_init)); } }