diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 9e4a813489c0..b558700d1d96 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -783,32 +784,40 @@ static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data) return -1; } +static void mxc_jpeg_free(struct mxc_jpeg_dev *jpeg, size_t size, void *addr, dma_addr_t handle) +{ + if (jpeg->sram_pool) + gen_pool_free(jpeg->sram_pool, (unsigned long)addr, size); + else + dma_free_coherent(jpeg->dev, size, addr, handle); +} + static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) { /* free descriptor for decoding/encoding phase */ - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data.desc, - jpeg->slot_data.desc_handle); + mxc_jpeg_free(jpeg, sizeof(struct mxc_jpeg_desc), + jpeg->slot_data.desc, + jpeg->slot_data.desc_handle); jpeg->slot_data.desc = NULL; jpeg->slot_data.desc_handle = 0; /* free descriptor for encoder configuration phase / decoder DHT */ - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data.cfg_desc, - jpeg->slot_data.cfg_desc_handle); + mxc_jpeg_free(jpeg, sizeof(struct mxc_jpeg_desc), + jpeg->slot_data.cfg_desc, + jpeg->slot_data.cfg_desc_handle); jpeg->slot_data.cfg_desc_handle = 0; jpeg->slot_data.cfg_desc = NULL; /* free configuration stream */ - dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, - jpeg->slot_data.cfg_stream_vaddr, - jpeg->slot_data.cfg_stream_handle); + mxc_jpeg_free(jpeg, MXC_JPEG_MAX_CFG_STREAM, + jpeg->slot_data.cfg_stream_vaddr, + jpeg->slot_data.cfg_stream_handle); jpeg->slot_data.cfg_stream_vaddr = NULL; jpeg->slot_data.cfg_stream_handle = 0; - dma_free_coherent(jpeg->dev, jpeg->slot_data.cfg_dec_size, - jpeg->slot_data.cfg_dec_vaddr, - jpeg->slot_data.cfg_dec_daddr); + mxc_jpeg_free(jpeg, jpeg->slot_data.cfg_dec_size, + jpeg->slot_data.cfg_dec_vaddr, + jpeg->slot_data.cfg_dec_daddr); jpeg->slot_data.cfg_dec_size = 0; jpeg->slot_data.cfg_dec_vaddr = NULL; jpeg->slot_data.cfg_dec_daddr = 0; @@ -816,6 +825,15 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) jpeg->slot_data.used = false; } +static struct mxc_jpeg_desc *mxc_jpeg_alloc(struct mxc_jpeg_dev *jpeg, size_t size, + dma_addr_t *handle) +{ + if (jpeg->sram_pool) + return gen_pool_dma_zalloc(jpeg->sram_pool, size, handle); + else + return dma_alloc_coherent(jpeg->dev, size, handle, GFP_ATOMIC); +} + static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) { struct mxc_jpeg_desc *desc; @@ -826,37 +844,29 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) goto skip_alloc; /* already allocated, reuse it */ /* allocate descriptor for decoding/encoding phase */ - desc = dma_alloc_coherent(jpeg->dev, - sizeof(struct mxc_jpeg_desc), - &jpeg->slot_data.desc_handle, - GFP_ATOMIC); + desc = mxc_jpeg_alloc(jpeg, sizeof(struct mxc_jpeg_desc), + &jpeg->slot_data.desc_handle); if (!desc) goto err; jpeg->slot_data.desc = desc; /* allocate descriptor for configuration phase (encoder only) */ - cfg_desc = dma_alloc_coherent(jpeg->dev, - sizeof(struct mxc_jpeg_desc), - &jpeg->slot_data.cfg_desc_handle, - GFP_ATOMIC); + cfg_desc = mxc_jpeg_alloc(jpeg, sizeof(struct mxc_jpeg_desc), + &jpeg->slot_data.cfg_desc_handle); if (!cfg_desc) goto err; jpeg->slot_data.cfg_desc = cfg_desc; /* allocate configuration stream */ - cfg_stm = dma_alloc_coherent(jpeg->dev, - MXC_JPEG_MAX_CFG_STREAM, - &jpeg->slot_data.cfg_stream_handle, - GFP_ATOMIC); + cfg_stm = mxc_jpeg_alloc(jpeg, MXC_JPEG_MAX_CFG_STREAM, + &jpeg->slot_data.cfg_stream_handle); if (!cfg_stm) goto err; jpeg->slot_data.cfg_stream_vaddr = cfg_stm; jpeg->slot_data.cfg_dec_size = MXC_JPEG_PATTERN_WIDTH * MXC_JPEG_PATTERN_HEIGHT * 2; - jpeg->slot_data.cfg_dec_vaddr = dma_alloc_coherent(jpeg->dev, - jpeg->slot_data.cfg_dec_size, - &jpeg->slot_data.cfg_dec_daddr, - GFP_ATOMIC); + jpeg->slot_data.cfg_dec_vaddr = mxc_jpeg_alloc(jpeg, jpeg->slot_data.cfg_dec_size, + &jpeg->slot_data.cfg_dec_daddr); if (!jpeg->slot_data.cfg_dec_vaddr) goto err; @@ -2884,6 +2894,10 @@ static int mxc_jpeg_probe(struct platform_device *pdev) jpeg->dev = dev; jpeg->mode = mode; + /* SRAM pool is optional */ + jpeg->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0); + dev_info(dev, "Using DMA descriptor pool in %cRAM\n", jpeg->sram_pool ? 'S' : 'D'); + /* Get clocks */ ret = devm_clk_bulk_get_all(&pdev->dev, &jpeg->clks); if (ret < 0) { diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h index 44e46face6d1..9c5b4f053ded 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h @@ -141,6 +141,7 @@ struct mxc_jpeg_dev { int num_domains; struct device **pd_dev; struct device_link **pd_link; + struct gen_pool *sram_pool; }; /**