add support to declare contiguous region of memory to be handled
when requested by dma_alloc_coherent when it's asked for coherent
memory for this device. 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_capture.c |   62 +++++++++++++++++++++++++++-
 drivers/media/video/davinci/vpif_capture.h |    1 +
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/davinci/vpif_capture.c 
b/drivers/media/video/davinci/vpif_capture.c
index ad933e0..5609e00 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -54,18 +54,24 @@ static u32 ch0_numbuffers = 3;
 static u32 ch1_numbuffers = 3;
 static u32 ch0_bufsize = 1920 * 1080 * 2;
 static u32 ch1_bufsize = 720 * 576 * 2;
+static u32 cont_bufoffset;
+static u32 cont_bufsize;
 
 module_param(debug, int, 0644);
 module_param(ch0_numbuffers, uint, S_IRUGO);
 module_param(ch1_numbuffers, uint, S_IRUGO);
 module_param(ch0_bufsize, uint, S_IRUGO);
 module_param(ch1_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, "Channel0 buffer count (default:3)");
 MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
 MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 
2)");
 MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
+MODULE_PARM_DESC(cont_bufoffset, "Capture buffer offset (default 0)");
+MODULE_PARM_DESC(cont_bufsize, "Capture buffer size (default 0)");
 
 static struct vpif_config_params config_params = {
        .min_numbuffers = 3,
@@ -217,6 +223,23 @@ static int vpif_buffer_setup(struct videobuf_queue *q, 
unsigned int *count,
        /* Calculate the size of the buffer */
        *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;
        return 0;
@@ -892,7 +915,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
                }
        }
 
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type)
+       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev)
                return -EINVAL;
 
        index = VPIF_VIDEO_INDEX;
@@ -904,7 +927,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,
                                            common->fmt.fmt.pix.field,
@@ -2166,6 +2189,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 {
        struct vpif_subdev_info *subdevdata;
        struct vpif_capture_config *config;
+       unsigned long phys_end_kernel;
        int i, j, k, m, q, err;
        struct i2c_adapter *i2c_adap;
        struct channel_obj *ch;
@@ -2173,6 +2197,7 @@ static __init int vpif_probe(struct platform_device *pdev)
        struct video_device *vfd;
        struct resource *res;
        int subdev_count;
+       size_t size;
 
        vpif_dev = &pdev->dev;
 
@@ -2227,6 +2252,39 @@ static __init int vpif_probe(struct platform_device 
*pdev)
                ch->video_dev = vfd;
        }
 
+       /*
+        * Initialising the memory from the bootargs 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);
+               size = cont_bufsize;
+               phys_end_kernel += cont_bufoffset;
+               err = dma_declare_coherent_memory(&pdev->dev, phys_end_kernel,
+                               phys_end_kernel, size,
+                               DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+               if (!err) {
+                       dev_err(&pdev->dev, "Unable to declare MMAP memory.\n");
+                       err = -ENOMEM;
+                       goto vpif_dev_alloc_err;
+               }
+
+               /* The resources are divided into two equal memory and when we
+                * have HD output we can add them together
+                */
+               for (j = 0; j < VPIF_CAPTURE_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_CAPTURE_MAX_DEVICES; j++) {
                ch = vpif_obj.dev[j];
                ch->channel_id = j;
diff --git a/drivers/media/video/davinci/vpif_capture.h 
b/drivers/media/video/davinci/vpif_capture.h
index a693d4e..8095910 100644
--- a/drivers/media/video/davinci/vpif_capture.h
+++ b/drivers/media/video/davinci/vpif_capture.h
@@ -151,6 +151,7 @@ struct vpif_config_params {
        u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
        u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
        u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
+       u32 video_limit[VPIF_CAPTURE_NUM_CHANNELS];
        u8 max_device_type;
 };
 /* Struct which keeps track of the line numbers for the sliced vbi service */
-- 
1.7.4.1

_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to