Re: [RFC v3 09/13] [media] exynos5-fimc-is: Add the hardware pipeline control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sylwester,

On Sun, Aug 4, 2013 at 8:30 PM, Sylwester Nawrocki
<sylvester.nawrocki@xxxxxxxxx> wrote:
> Hi Arun,
>
> On 08/02/2013 05:02 PM, Arun Kumar K wrote:
>>
>> This patch adds the crucial hardware pipeline control for the
>> fimc-is driver. All the subdev nodes will call this pipeline
>> interfaces to reach the hardware. Responsibilities of this module
>> involves configuring and maintaining the hardware pipeline involving
>> multiple sub-ips like ISP, DRC, Scalers, ODC, 3DNR, FD etc.
>>
>> Signed-off-by: Arun Kumar K<arun.kk@xxxxxxxxxxx>
>> Signed-off-by: Kilyeon Im<kilyeon.im@xxxxxxxxxxx>
>> ---

[snip]


>> +static int fimc_is_pipeline_isp_setparams(struct fimc_is_pipeline
>> *pipeline,
>> +               unsigned int enable)
>> +{
>> +       struct isp_param *isp_param =&pipeline->is_region->parameter.isp;
>> +       struct fimc_is *is = pipeline->is;
>> +       unsigned int indexes, lindex, hindex;
>> +       unsigned int sensor_width, sensor_height, scc_width, scc_height;
>> +       unsigned int crop_x, crop_y, isp_width, isp_height;
>> +       unsigned int sensor_ratio, output_ratio;
>> +       int ret;
>> +
>> +       /* Crop calculation */
>> +       sensor_width = pipeline->sensor_width;
>> +       sensor_height = pipeline->sensor_height;
>> +       scc_width = pipeline->scaler_width[SCALER_SCC];
>> +       scc_height = pipeline->scaler_height[SCALER_SCC];
>> +       isp_width = sensor_width;
>> +       isp_height = sensor_height;
>> +       crop_x = crop_y = 0;
>> +
>> +       sensor_ratio = sensor_width * 1000 / sensor_height;
>> +       output_ratio = scc_width * 1000 / scc_height;
>> +
>> +       if (sensor_ratio == output_ratio) {
>> +               isp_width = sensor_width;
>> +               isp_height = sensor_height;
>> +       } else if (sensor_ratio<  output_ratio) {
>> +               isp_height = (sensor_width * scc_height) / scc_width;
>> +               isp_height = ALIGN(isp_height, 2);
>> +               crop_y = ((sensor_height - isp_height)>>  1)&  0xFFFFFFFE;
>
>
> nit: Use ~1U instead of 0xFFFFFFFE.
>
>
>> +       } else {
>> +               isp_width = (sensor_height * scc_width) / scc_height;
>> +               isp_width = ALIGN(isp_width, 4);
>> +               crop_x =  ((sensor_width - isp_width)>>  1)&  0xFFFFFFFE;
>
>
> Ditto.
>
>> +       }
>> +       pipeline->isp_width = isp_width;
>> +       pipeline->isp_height = isp_height;
>> +
>> +       indexes = hindex = lindex = 0;
>> +
>> +       isp_param->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
>> +       isp_param->otf_output.width = pipeline->sensor_width;
>> +       isp_param->otf_output.height = pipeline->sensor_height;
>> +       isp_param->otf_output.format = OTF_OUTPUT_FORMAT_YUV444;
>> +       isp_param->otf_output.bitwidth = OTF_OUTPUT_BIT_WIDTH_12BIT;
>> +       isp_param->otf_output.order = OTF_INPUT_ORDER_BAYER_GR_BG;
>> +       lindex |= LOWBIT_OF(PARAM_ISP_OTF_OUTPUT);
>> +       hindex |= HIGHBIT_OF(PARAM_ISP_OTF_OUTPUT);
>> +       indexes++;
>
>
> All right, let's stop this hindex/lindex/indexes madness. I've already
> commented on that IIRC. Nevertheless, this should be replaced with proper
> bitmap operations. A similar issue has been fixed in commit
>
>
>> +       isp_param->dma1_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
>> +       lindex |= LOWBIT_OF(PARAM_ISP_DMA1_OUTPUT);
>> +       hindex |= HIGHBIT_OF(PARAM_ISP_DMA1_OUTPUT);
>> +       indexes++;
>> +
>> +       isp_param->dma2_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
>> +       lindex |= LOWBIT_OF(PARAM_ISP_DMA2_OUTPUT);
>> +       hindex |= HIGHBIT_OF(PARAM_ISP_DMA2_OUTPUT);
>> +       indexes++;
>> +
>> +       if (enable)
>> +               isp_param->control.bypass = CONTROL_BYPASS_DISABLE;
>> +       else
>> +               isp_param->control.bypass = CONTROL_BYPASS_ENABLE;
>> +       isp_param->control.cmd = CONTROL_COMMAND_START;
>> +       isp_param->control.run_mode = 1;
>> +       lindex |= LOWBIT_OF(PARAM_ISP_CONTROL);
>> +       hindex |= HIGHBIT_OF(PARAM_ISP_CONTROL);
>> +       indexes++;
>> +
>> +       isp_param->dma1_input.cmd = DMA_INPUT_COMMAND_BUF_MNGR;
>> +       isp_param->dma1_input.width = sensor_width;
>> +       isp_param->dma1_input.height = sensor_height;
>> +       isp_param->dma1_input.dma_crop_offset_x = crop_x;
>> +       isp_param->dma1_input.dma_crop_offset_y = crop_y;
>> +       isp_param->dma1_input.dma_crop_width = isp_width;
>> +       isp_param->dma1_input.dma_crop_height = isp_height;
>> +       isp_param->dma1_input.bayer_crop_offset_x = 0;
>> +       isp_param->dma1_input.bayer_crop_offset_y = 0;
>> +       isp_param->dma1_input.bayer_crop_width = 0;
>> +       isp_param->dma1_input.bayer_crop_height = 0;
>> +       isp_param->dma1_input.user_min_frametime = 0;
>> +       isp_param->dma1_input.user_max_frametime = 66666;
>> +       isp_param->dma1_input.wide_frame_gap = 1;
>> +       isp_param->dma1_input.frame_gap = 4096;
>> +       isp_param->dma1_input.line_gap = 45;
>> +       isp_param->dma1_input.order = DMA_INPUT_ORDER_GR_BG;
>> +       isp_param->dma1_input.plane = 1;
>> +       isp_param->dma1_input.buffer_number = 1;
>> +       isp_param->dma1_input.buffer_address = 0;
>> +       isp_param->dma1_input.reserved[1] = 0;
>> +       isp_param->dma1_input.reserved[2] = 0;
>> +       if (pipeline->isp.fmt->fourcc == V4L2_PIX_FMT_SGRBG8)
>> +               isp_param->dma1_input.bitwidth = DMA_INPUT_BIT_WIDTH_8BIT;
>> +       else if (pipeline->isp.fmt->fourcc == V4L2_PIX_FMT_SGRBG10)
>> +               isp_param->dma1_input.bitwidth =
>> DMA_INPUT_BIT_WIDTH_10BIT;
>> +       else
>> +               isp_param->dma1_input.bitwidth =
>> DMA_INPUT_BIT_WIDTH_12BIT;
>> +       lindex |= LOWBIT_OF(PARAM_ISP_DMA1_INPUT);
>> +       hindex |= HIGHBIT_OF(PARAM_ISP_DMA1_INPUT);
>> +       indexes++;
>> +
>> +       lindex = 0xFFFFFFFF;
>> +       hindex = 0xFFFFFFFF;
>
>
> Hmm, is this a workaround for some firmware bug ? You're setting individual
> bits of lindex, hindex only to set them all to 1 just before using those
> variables ? WTH ? :)
>

We set this 0xffffff so that all the init params which are copied
earlier during pipeline_open
are set to the firmware. FW set_param cannot be done after copying of
init params since
FW expects isp params to be set correctly before accepting any other params.
So this is a workaround to force all init values to go along with the
ISP params.

>
> Anyway, instead of doing this:
>
>         lindex |= LOWBIT_OF(A);
>         hindex |= HIGHBIT_OF(A);
>         indexes++;
>
>         lindex |= LOWBIT_OF(B);
>         hindex |= HIGHBIT_OF(B);
>         indexes++;
>
>         ...
>
>         fimc_is_itf_set_param(..., indexes, lindex, hindex);
>
>
> You could do:
>
>         u32 index[2];
>
>         __set_bit(A, index);
>
>         __set_bit(B, index);
>
>         ...
>
>         indexes = hweight32(index[0]);
>         indexes += hweight32(index[1]);
>
>         fimc_is_itf_set_param(..., indexes, index[0], index[1]);
>
> I.e. the bit operations work well with arbitrary length bitmaps.
>

Ok I will use this method.

> BTW, the firmware interface seems pretty odd with it's requirement to
> pass bitmask and number of bits set in this bitmaks separately. Does
> it ever allow 'indexes' to be different than number of bits set in
> lindex, hindex ? What happens in such case ?

Yes. It is working even when indexes is set as 0 !
I will remove that indexes field and use only bitmask.

Regards
Arun
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux