summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Monkman <jay.monkman@freescale.com>2013-06-14 11:47:50 -0500
committerJay Monkman <jay.monkman@freescale.com>2013-06-14 11:47:50 -0500
commitf4857b5482c67dcc9757d50cf57cb32728af788b (patch)
tree9b2d7c7c382ee1cdc3160d662a94b7b3deaa67f7
parentdf551ae02c600f8bc9244441700f7da7ac62ac88 (diff)
ENGR00267024 mx6q: Stop DMA memory fragmentation
Applied patch from customer to prevent DMA memory fragmentation. Customer reported system crashes due to running out of DMA-able memory while playing videos. Reported in CT42391649. Signed-off-by: Jay Monkman <jay.monkman@freescale.com>
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabrelite.c30
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c28
-rw-r--r--drivers/media/video/mxc/output/mxc_vout.c10
-rw-r--r--drivers/media/video/videobuf-dma-contig.c3
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c2
5 files changed, 66 insertions, 7 deletions
diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
index e1075fec4b68..92c51198c890 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
@@ -919,6 +919,16 @@ static struct fsl_mxc_capture_platform_data capture_data[] = {
};
+struct imx_vout_mem {
+ resource_size_t res_mbase;
+ resource_size_t res_msize;
+};
+
+static struct imx_vout_mem vout_mem __initdata = {
+ .res_msize = SZ_128M,
+};
+
+
static void sabrelite_suspend_enter(void)
{
/* suspend preparation */
@@ -1156,6 +1166,7 @@ static void __init mx6_sabrelite_board_init(void)
struct clk *clko2;
struct clk *new_parent;
int rate;
+ struct platform_device *voutdev;
mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_pads,
ARRAY_SIZE(mx6q_sabrelite_pads));
@@ -1184,7 +1195,17 @@ static void __init mx6_sabrelite_board_init(void)
imx6q_add_vdoa();
imx6q_add_lcdif(&lcdif_data);
imx6q_add_ldb(&ldb_data);
- imx6q_add_v4l2_output(0);
+ voutdev = imx6q_add_v4l2_output(0);
+ if (vout_mem.res_msize && voutdev) {
+ dma_declare_coherent_memory(&voutdev->dev,
+ vout_mem.res_mbase,
+ vout_mem.res_mbase,
+ vout_mem.res_msize,
+ (DMA_MEMORY_MAP |
+ DMA_MEMORY_EXCLUSIVE));
+ }
+
+
imx6q_add_v4l2_capture(0, &capture_data[0]);
imx6q_add_v4l2_capture(1, &capture_data[1]);
imx6q_add_mipi_csi2(&mipi_csi2_pdata);
@@ -1314,6 +1335,13 @@ static void __init mx6q_sabrelite_reserve(void)
imx6q_gpu_pdata.reserved_mem_base = phys;
}
#endif
+ if (vout_mem.res_msize) {
+ phys = memblock_alloc_base(vout_mem.res_msize,
+ SZ_4K, SZ_1G);
+ memblock_remove(phys, vout_mem.res_msize);
+ vout_mem.res_mbase = phys;
+ }
+
}
/*
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c
index 227008796bd8..3f90df0281d9 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabresd.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c
@@ -1425,6 +1425,15 @@ static struct fsl_mxc_capture_platform_data capture_data[] = {
};
+struct imx_vout_mem {
+ resource_size_t res_mbase;
+ resource_size_t res_msize;
+};
+
+static struct imx_vout_mem vout_mem __initdata = {
+ .res_msize = SZ_128M,
+};
+
static void sabresd_suspend_enter(void)
{
/* suspend preparation */
@@ -1704,6 +1713,7 @@ static void __init mx6_sabresd_board_init(void)
struct clk *clko, *clko2;
struct clk *new_parent;
int rate;
+ struct platform_device *voutdev;
if (cpu_is_mx6q())
mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_pads,
@@ -1752,7 +1762,16 @@ static void __init mx6_sabresd_board_init(void)
imx6q_add_mipi_dsi(&mipi_dsi_pdata);
imx6q_add_lcdif(&lcdif_data);
imx6q_add_ldb(&ldb_data);
- imx6q_add_v4l2_output(0);
+ voutdev = imx6q_add_v4l2_output(0);
+ if (vout_mem.res_msize && voutdev) {
+ dma_declare_coherent_memory(&voutdev->dev,
+ vout_mem.res_mbase,
+ vout_mem.res_mbase,
+ vout_mem.res_msize,
+ (DMA_MEMORY_MAP |
+ DMA_MEMORY_EXCLUSIVE));
+ }
+
imx6q_add_v4l2_capture(0, &capture_data[0]);
imx6q_add_v4l2_capture(1, &capture_data[1]);
imx6q_add_mipi_csi2(&mipi_csi2_pdata);
@@ -1979,6 +1998,13 @@ static void __init mx6q_sabresd_reserve(void)
imx6q_gpu_pdata.reserved_mem_base = phys;
}
#endif
+
+ if (vout_mem.res_msize) {
+ phys = memblock_alloc_base(vout_mem.res_msize,
+ SZ_4K, SZ_1G);
+ memblock_remove(phys, vout_mem.res_msize);
+ vout_mem.res_mbase = phys;
+ }
}
/*
diff --git a/drivers/media/video/mxc/output/mxc_vout.c b/drivers/media/video/mxc/output/mxc_vout.c
index 4ea663005812..e0840bf7a1c2 100644
--- a/drivers/media/video/mxc/output/mxc_vout.c
+++ b/drivers/media/video/mxc/output/mxc_vout.c
@@ -2077,9 +2077,13 @@ static int mxc_vout_probe(struct platform_device *pdev)
return -ENOMEM;
dev->dev = &pdev->dev;
- dev->dev->dma_mask = kmalloc(sizeof(*dev->dev->dma_mask), GFP_KERNEL);
- *dev->dev->dma_mask = DMA_BIT_MASK(32);
- dev->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+ if (!dev->dev->dma_mask) {
+ dev->dev->dma_mask = kmalloc(sizeof(*dev->dev->dma_mask),
+ GFP_KERNEL);
+ if (dev->dev->dma_mask)
+ *dev->dev->dma_mask = DMA_BIT_MASK(32);
+ dev->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+ }
ret = v4l2_device_register(dev->dev, &dev->v4l2_dev);
if (ret) {
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index af7ff78c9259..2a5623c5a213 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -284,7 +284,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
mem->size = PAGE_ALIGN(buf->bsize);
mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
- &mem->dma_handle, GFP_DMA);
+ &mem->dma_handle,
+ GFP_DMA | GFP_KERNEL | __GFP_NOFAIL);
if (!mem->vaddr) {
dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
mem->size);
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 708e8e97112a..07f6d9d1d6d8 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -126,7 +126,7 @@ static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem)
mem->cpu_addr = (unsigned long)
dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size),
(dma_addr_t *) (&mem->phy_addr),
- GFP_DMA | GFP_KERNEL);
+ GFP_DMA | GFP_KERNEL | __GFP_NOFAIL);
pr_debug("[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr);
if ((void *)(mem->cpu_addr) == NULL) {
printk(KERN_ERR "Physical memory allocation error!\n");