/** ihist_stats_config: * @entry: Pointer to entry struct of ihist stats * @pix_settings: Pointer to the pipeline settings * @in_param_size: Size of pix_settings * * Configure the entry and reg_cmd for ihist_stats using values passed in pix * settings * * * Return 0 on Success, negative on ERROR **/ static int ihist_stats_config(isp_stats_entry_t *entry, isp_hw_pix_setting_params_t *pix_settings, uint32_t in_param_size) { ISP_StatsIhist_CfgType *pcmd = entry->reg_cmd; uint32_t window_w_t, window_h_t, total_pixels; isp_pix_camif_cfg_t *camif_cfg = &pix_settings->camif_cfg; int32_t shift_bits; if (!entry->enable) { ISP_DBG(ISP_MOD_STATS, "%s: ihist not enabled", __func__); return 0; } entry->session_id = pix_settings->outputs->stream_param.session_id; entry->is_ispif_split = pix_settings->camif_cfg.ispif_out_info.is_split; if (pix_settings->camif_cfg.ispif_out_info.is_split) { if (!(pix_settings->outputs[0].isp_out_info.stripe_id == 0)) entry->buf_offset = ISP_STATS_IHIST_BUF_SIZE; } else { entry->buf_offset = 0; } entry->ion_fd = pix_settings->ion_fd; entry->hfr_mode = pix_settings->camif_cfg.hfr_mode; entry->comp_flag = 1; if (pix_settings->outputs[0].stream_param.width > 0) { window_w_t = camif_cfg->sensor_out_info.request_crop.last_pixel - camif_cfg->sensor_out_info.request_crop.first_pixel + 1; window_h_t = camif_cfg->sensor_out_info.request_crop.last_line - camif_cfg->sensor_out_info.request_crop.first_line + 1; } else { CDBG_ERROR("%s: error, width = 0\n", __func__); return -1; } pcmd->channelSelect = 0; pcmd->rgnHNum = FLOOR16(window_w_t/2)-1; pcmd->rgnVNum = FLOOR16(window_h_t/2)-1; pcmd->rgnHOffset = 0; pcmd->rgnVOffset = 0; /* calculate shift bits */ total_pixels = (float)((pcmd->rgnHNum + 1) * (pcmd->rgnVNum + 1)) / 2.0; shift_bits = CEIL_LOG2(total_pixels); shift_bits -= 16; shift_bits = MAX(0, shift_bits); shift_bits = MIN(4, shift_bits); ISP_DBG(ISP_MOD_STATS, "%s: tot %d shift %d", __func__, total_pixels, shift_bits); pcmd->shiftBits = shift_bits; pcmd->siteSelect = 0; entry->is_ispif_split = pix_settings->camif_cfg.ispif_out_info.is_split; if (entry->is_ispif_split) { uint32_t end_point_stats_bound; uint32_t overlap = pix_settings->camif_cfg.ispif_out_info.overlap; isp_out_info_t *isp_out = &pix_settings->outputs[0].isp_out_info; /* Its possible that end point of stats boundary is falling completely within the left strip so the calculation for the no_regions_left will depend on the end of the stats boundary. */ end_point_stats_bound = pcmd->rgnHOffset + 2 * (pcmd->rgnHNum + 1); if (end_point_stats_bound > isp_out->right_stripe_offset + overlap) end_point_stats_bound = isp_out->right_stripe_offset + overlap; entry->buf_offset = isp_out->stripe_id * ISP_STATS_IHIST_BUF_SIZE; entry->num_left_rgns = (end_point_stats_bound > pcmd->rgnHOffset) ? (end_point_stats_bound - pcmd->rgnHOffset) / 2 : 0; entry->num_right_rgns = (pcmd->rgnHNum + 1) - entry->num_left_rgns; if (isp_out->stripe_id == ISP_STRIPE_LEFT) { /* Make sure if number of region is zero for each side, we don't actually program 0 region */ pcmd->rgnHNum = (entry->num_left_rgns > 0) ? entry->num_left_rgns - 1 : 1; pcmd->rgnHOffset = (entry->num_left_rgns > 0) ? pcmd->rgnHOffset : 2; // Default offset for IHIST stats } else { /* ISP_STRIPE_RIGHT */ pcmd->rgnHNum = (entry->num_right_rgns > 0) ? entry->num_right_rgns - 1 : 1; pcmd->rgnHOffset = pcmd->rgnHOffset + (entry->num_left_rgns * 2) - isp_out->right_stripe_offset; pcmd->rgnHOffset = (entry->num_right_rgns > 0) ? pcmd->rgnHOffset : 2; // Default offset for IHIST stats } } ISP_DBG(ISP_MOD_STATS, "IHIST statsconfig shiftBits %d\n", pcmd->shiftBits); ISP_DBG(ISP_MOD_STATS, "IHIST statsconfig channelSelect %d\n", pcmd->channelSelect); ISP_DBG(ISP_MOD_STATS, "IHIST statsconfig siteSelect %d\n", pcmd->siteSelect); ISP_DBG(ISP_MOD_STATS, "IHIST statsconfig rgnHNum %d\n", pcmd->rgnHNum); ISP_DBG(ISP_MOD_STATS, "IHIST statsconfig rgnVNum %d\n", pcmd->rgnVNum); entry->hw_update_pending = 1; return 0; }
/* Load essential runtime code onto the SPUs */ void * loadRuntimeOnSpus(SpuThreadData * spu_data) { int i, no_spus; no_spus = spu_data->no_spu_threads; char * jtocPtr = (char * ) (spu_data->boot_record->jtocStart + spu_data->boot_record->jtocMiddleOffset); int jtocNumOff = spu_data->boot_record->jtocNumericOffset; int jtocRefOff = spu_data->boot_record->jtocReferenceOffset; spu_data->boot_record->jtocLastCachedNumericOffset = (uint32_t)jtocNumOff; spu_data->boot_record->jtocLastCachedReferenceOffset = (uint32_t)jtocRefOff; spu_data->boot_record->jtocDirty = 0; char * jtocStart = FLOOR16(jtocPtr + jtocNumOff); char * jtocEnd = CEIL16(jtocPtr + jtocRefOff); int jtocLength = (int)(jtocEnd - jtocStart); // copy data across to each spu for (i=0; i<no_spus; i++) { int error = 0; error |= spe_mfcio_get(spu_data->spus[i].ctx, RUNTIME_CODE_START, (void *) spu_data->boot_record->oolRuntimeCodeInstructions, spu_data->boot_record->oolRuntimeCodeLength, PROXY_TAG_GROUP, 0, 0); if ((RUNTIME_CODE_START + spu_data->boot_record->oolRuntimeCodeLength) >= CODE_ENTRYPOINT) { fprintf(stderr, "Error, Cell SPU ool runtime code too long\n"); exit(1); } // copy across the runtime entry method error |= spe_mfcio_get(spu_data->spus[i].ctx, CODE_ENTRYPOINT, (void *) spu_data->boot_record->runtimeEntryMethod, spu_data->boot_record->runtimeEntryLength, PROXY_TAG_GROUP, 0, 0); if ((CODE_ENTRYPOINT + spu_data->boot_record->runtimeEntryLength) >= CODE_ENTRYPOINT_END) { fprintf(stderr, "Error, Cell SPU code entrypoint is too long\n"); exit(1); } // copy the JTOC across error |= spe_mfcio_get(spu_data->spus[i].ctx, FLOOR16(JTOC_PTR + jtocNumOff), jtocStart, jtocLength, PROXY_TAG_GROUP, 0, 0); spu_data->spus[i].jtocStart = jtocPtr + jtocNumOff; spu_data->spus[i].jtocEnd = jtocPtr + jtocRefOff; loadTocTables(spu_data, i); if (error) { perror("Failed loading runtime on Cell SPUs"); exit(1); } } // wait for each SPU dma to complete for (i=0; i<no_spus; i++) { unsigned int status, write_complete; if (spe_mfcio_tag_status_read(spu_data->spus[i].ctx, PROXY_TAG_GROUP_BM, SPE_TAG_ALL, &status)) { perror("Failed while waiting for DMA copy of runtime to Cell SPUs"); exit(1); } write_complete = RUNTIME_COPY_COMPLETE; // tell spu to jump to java runtime if (spe_in_mbox_write(spu_data->spus[i].ctx, &write_complete, 1, SPE_MBOX_ANY_NONBLOCKING) < 0) { perror("Failed writing phys_id to SPU mailbox while SPU was booting"); exit(1); } spu_data->spus[i].jtocDirty = 0; spu_data->spus[i].in_use = 0; } }