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); + + 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; }; -- 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