diff mbox

[v1] DaVinci: dm365: added sdram dma clock divide ratio management

Message ID 20121004154748.GA19445@btlists.it (mailing list archive)
State Not Applicable
Headers show

Commit Message

davide.bonfanti@bticino.it Oct. 4, 2012, 3:48 p.m. UTC
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 <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(-)

Comments

Lad, Prabhakar Oct. 26, 2012, 10:41 a.m. UTC | #1
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 mbox

Patch

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),