This patch applies to: v2.6.32.17-6450-g6725c92 commit 74f19831af149656f705b3b8a8c32bdf8c1c74fb
The CLKDIV register is then used to select a divide ratio of the SDRAM(DMA) clock for the pixel clock frequency which is used to clock the data into the PCLK. The CLKDIV register is then used to select a divide ratio of the SDRAM(DMA) clock for the pixel clock frequency which is used to clock the data into the PCLK. The value of this register depends on the resize ratios of the IPIPE resizers and the available SDRAM system bandwidth. Once defined input and output resolutions to the Resizer, the clock must be at least MAX(input_resolution, output_resolution) * framerate. This is a rough approximation, the resizer needs some additional lines and pixels at the frames edges so a slightly higher clock than above is needed. A 12.5% of increment is implemented. If resizer clock is too high, then what will happen is that resizer will try to read pixels at every clock cycle. If there is someone else running in the system (VPSS capture or ARM or codec) then if the resizer will fail to read the pixel at any given moment due to other master using the DDR at that time, IT WILL ABORT the operation causing an incomplete frame in memory. Signed-off-by: Davide Bonfanti <[email protected]> Signed-off-by: Angelo Aresi <[email protected]> --- drivers/char/dm365_ipipe.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/drivers/char/dm365_ipipe.c b/drivers/char/dm365_ipipe.c index a945122..6161875 100644 --- a/drivers/char/dm365_ipipe.c +++ b/drivers/char/dm365_ipipe.c @@ -33,6 +33,8 @@ #include <linux/videodev2.h> #include <media/davinci/dm365_ipipe.h> #include <media/davinci/imp_hw_if.h> +#include <media/davinci/vpfe_capture.h> +#include <linux/clk.h> #include <mach/irqs.h> @@ -599,6 +601,43 @@ static void calculate_resize_ratios(struct ipipe_params *param, int index) (param->rsz_rsc_param[index].o_vsz + 1); } +/* calculate_sdram_dma_divide_ratio() + * calculate the divide ratio of the SDRAM(DMA). This is called after setting + * the input/output size since the speed depends on video size and framrate + */ +static void calculate_sdram_dma_divide_ratio(struct ipipe_params *param, + struct v4l2_fract fps) +{ + struct clk *vpss_clk; + unsigned long vpss_rate, pixels = 0; + + vpss_clk = clk_get(NULL, "vpss_master"); + vpss_rate = clk_get_rate(vpss_clk); + clk_put(vpss_clk); + + pixels = (param->ipipe_hsz + 1) * (param->ipipe_vsz + 1); + if (param->rsz_en[RSZ_A]) { + if (pixels < (param->rsz_rsc_param[RSZ_A].o_hsz + 1) * + (param->rsz_rsc_param[RSZ_A].o_vsz + 1)) + pixels = (param->rsz_rsc_param[RSZ_A].o_hsz + 1) * + (param->rsz_rsc_param[RSZ_A].o_vsz + 1); + } + if (param->rsz_en[RSZ_B]) { + if (pixels < (param->rsz_rsc_param[RSZ_B].o_hsz + 1) * + (param->rsz_rsc_param[RSZ_B].o_vsz + 1)) + pixels = (param->rsz_rsc_param[RSZ_B].o_hsz + 1) * + (param->rsz_rsc_param[RSZ_B].o_vsz + 1); + } + param->ipipeif_param.var.if_5_1.clk_div.m = 1; /*numerator*/ + /* apply a 12.5% of margin for front/back porch */ + pixels += pixels >> 3; + + param->ipipeif_param.var.if_5_1.clk_div.n = vpss_rate / + (pixels * fps.denominator / fps.numerator); + param->ipipeif_param.clock_select = SDRAM_CLK; + +} + static int ipipe_do_hw_setup(struct device *dev, void *config) { struct ipipe_params *param = (struct ipipe_params *)config; @@ -615,6 +654,9 @@ static int ipipe_do_hw_setup(struct device *dev, void *config) calculate_resize_ratios(param, RSZ_A); if (param->rsz_en[RSZ_B]) calculate_resize_ratios(param, RSZ_B); + calculate_sdram_dma_divide_ratio(param, + ((struct vpfe_device *) + dev_get_drvdata(dev))->std_info.fps); ret = ipipe_hw_setup(param); } mutex_unlock(&oper_state.lock); @@ -3132,6 +3174,9 @@ static int configure_resizer_in_ss_mode(struct device *dev, (param->rsz_rsc_param[RSZ_B].o_vsz + 1); } } + calculate_sdram_dma_divide_ratio(param, + ((struct vpfe_device *) + dev_get_drvdata(dev))->std_info.fps); } mutex_unlock(&oper_state.lock); return 0; @@ -3597,6 +3642,9 @@ static int configure_previewer_in_ss_mode(struct device *dev, calculate_resize_ratios(param, RSZ_B); calculate_sdram_offsets(param, RSZ_B); } + calculate_sdram_dma_divide_ratio(param, + ((struct vpfe_device *) + dev_get_drvdata(dev))->std_info.fps); } else { struct rsz_output_spec *output_specs = kmalloc(sizeof(struct rsz_output_spec), -- 1.6.3.3 _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
