Message ID | 20121004154748.GA19445@btlists.it (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Hi Davide, On Thu, Oct 4, 2012 at 9:18 PM, Davide Bonfanti <davide.bonfanti@bticino.it> wrote: > 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. > Thanks for the patch. The patch is on a code base which is not being maintained now. And as of now there isn’t support for dm365 in mainline as to rebase this patch. Regards, --Prabhakar > Signed-off-by: Davide Bonfanti <davide.bonfanti@bticino.it> > Signed-off-by: Angelo Aresi <angelo.aresi@bticino.it> > --- > 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 > Davinci-linux-open-source@linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
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),