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