Hi Manjunath,

Thanks for the patch.

On Tuesday 17 April 2012 14:23:03 Manjunath Hadli wrote:
> add support to declare contiguous region of memory to be handled
> when requested by dma_alloc_coherent call. The user can specify
> the size of the buffers with an offset from the kernel image
> using cont_bufsize and cont_bufoffset module parameters respectively.
> 
> Signed-off-by: Manjunath Hadli <manjunath.ha...@ti.com>
> ---
>  drivers/media/video/davinci/vpif_display.c |   65 ++++++++++++++++++++++++-
>  drivers/media/video/davinci/vpif_display.h |    1 +
>  2 files changed, 64 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/video/davinci/vpif_display.c
> b/drivers/media/video/davinci/vpif_display.c index 355ad5c..27bc03d 100644
> --- a/drivers/media/video/davinci/vpif_display.c
> +++ b/drivers/media/video/davinci/vpif_display.c
> @@ -57,18 +57,24 @@ static u32 ch2_numbuffers = 3;
>  static u32 ch3_numbuffers = 3;
>  static u32 ch2_bufsize = 1920 * 1080 * 2;
>  static u32 ch3_bufsize = 720 * 576 * 2;
> +static u32 cont_bufoffset;
> +static u32 cont_bufsize;
> 
>  module_param(debug, int, 0644);
>  module_param(ch2_numbuffers, uint, S_IRUGO);
>  module_param(ch3_numbuffers, uint, S_IRUGO);
>  module_param(ch2_bufsize, uint, S_IRUGO);
>  module_param(ch3_bufsize, uint, S_IRUGO);
> +module_param(cont_bufoffset, uint, S_IRUGO);
> +module_param(cont_bufsize, uint, S_IRUGO);
> 
>  MODULE_PARM_DESC(debug, "Debug level 0-1");
>  MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)");
>  MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)");
>  MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x
> 2)"); MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x
> 576 x 2)"); +MODULE_PARM_DESC(cont_bufoffset, "Display offset(default 0)");
> +MODULE_PARM_DESC(cont_bufsize, "Display buffer size(default 0)");
> 
>  static struct vpif_config_params config_params = {
>       .min_numbuffers         = 3,
> @@ -187,6 +193,24 @@ static int vpif_buffer_setup(struct videobuf_queue *q,
> unsigned int *count, return 0;
> 
>       *size = config_params.channel_bufsize[ch->channel_id];
> +
> +     /*
> +      * Checking if the buffer size exceeds the available buffer
> +      * ycmux_mode = 0 means 1 channel mode HD and
> +      * ycmux_mode = 1 means 2 channels mode SD
> +      */
> +     if (ch->vpifparams.std_info.ycmux_mode == 0) {
> +             if (config_params.video_limit[ch->channel_id])
> +                     while (*size * *count > (config_params.video_limit[0]
> +                                     + config_params.video_limit[1]))
> +                             (*count)--;
> +     } else {
> +             if (config_params.video_limit[ch->channel_id])
> +                     while (*size * *count >
> +                             config_params.video_limit[ch->channel_id])
> +                             (*count)--;
> +     }
> +
>       if (*count < config_params.min_numbuffers)
>               *count = config_params.min_numbuffers;
> 
> @@ -830,7 +854,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
> 
>       common = &ch->common[index];
> 
> -     if (common->fmt.type != reqbuf->type)
> +     if (common->fmt.type != reqbuf->type || !vpif_dev)
>               return -EINVAL;
> 
>       if (0 != common->io_usrs)
> @@ -847,7 +871,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
> 
>       /* Initialize videobuf queue as per the buffer type */
>       videobuf_queue_dma_contig_init(&common->buffer_queue,
> -                                         &video_qops, NULL,
> +                                         &video_qops, vpif_dev,
>                                           &common->irqlock,
>                                           reqbuf->type, field,
>                                           sizeof(struct videobuf_buffer), fh,
> @@ -1686,12 +1710,14 @@ static __init int vpif_probe(struct platform_device
> *pdev) struct vpif_subdev_info *subdevdata;
>       struct vpif_display_config *config;
>       int i, j = 0, k, q, m, err = 0;
> +     unsigned long phys_end_kernel;
>       struct i2c_adapter *i2c_adap;
>       struct common_obj *common;
>       struct channel_obj *ch;
>       struct video_device *vfd;
>       struct resource *res;
>       int subdev_count;
> +     size_t size;
> 
>       vpif_dev = &pdev->dev;
> 
> @@ -1749,6 +1775,41 @@ static __init int vpif_probe(struct platform_device
> *pdev) ch->video_dev = vfd;
>       }
> 
> +     /* Initialising the memory from the input arguments file for
> +      * contiguous memory buffers and avoid defragmentation
> +      */
> +     if (cont_bufsize) {
> +             /* attempt to determine the end of Linux kernel memory */
> +             phys_end_kernel = virt_to_phys((void *)PAGE_OFFSET) +
> +                     (num_physpages << PAGE_SHIFT);
> +             phys_end_kernel += cont_bufoffset;
> +             size = cont_bufsize;
> +
> +             err = dma_declare_coherent_memory(&pdev->dev, phys_end_kernel,
> +                             phys_end_kernel, size,
> +                             DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);

This is a pretty dangerous hack. You should compute the memory address and 
size in board code, and pass it to the driver through a device resource (don't 
forget to call request_mem_region on the resource). I think the 
dma_declare_coherent_memory() call should be moved to board code as well.

> +             if (!err) {
> +                     dev_err(&pdev->dev, "Unable to declare MMAP memory.\n");
> +                     err = -ENOMEM;
> +                     goto probe_out;
> +             }
> +
> +             /* The resources are divided into two equal memory and when
> +              * we have HD output we can add them together
> +              */
> +             for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
> +                     ch = vpif_obj.dev[j];
> +                     ch->channel_id = j;
> +
> +                     /* only enabled if second resource exists */
> +                     config_params.video_limit[ch->channel_id] = 0;
> +                     if (cont_bufsize)
> +                             config_params.video_limit[ch->channel_id] =
> +                                                                     size/2;
> +             }
> +     }
> +
>       for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
>               ch = vpif_obj.dev[j];
>               /* Initialize field of the channel objects */
> diff --git a/drivers/media/video/davinci/vpif_display.h
> b/drivers/media/video/davinci/vpif_display.h index dd4887c..8a311f1 100644
> --- a/drivers/media/video/davinci/vpif_display.h
> +++ b/drivers/media/video/davinci/vpif_display.h
> @@ -158,6 +158,7 @@ struct vpif_config_params {
>       u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
>       u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
>       u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
> +     u32 video_limit[VPIF_DISPLAY_NUM_CHANNELS];
>       u8 min_numbuffers;
>  };

-- 
Regards,

Laurent Pinchart

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

Reply via email to