예제 #1
0
/** 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;
}
예제 #2
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;
	}
}