Commit c60e153d authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] omap3isp: ccdc: Use the DMA API for FPC

Replace the OMAP-specific IOMMU API usage by the DMA API for FPC. The
table is now allocated using dma_alloc_coherent() and the related sg
table is retrieved using dma_get_sgtable() for sync operations.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: default avatarSakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent d33186d0
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/omap-iommu.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <media/v4l2-event.h> #include <media/v4l2-event.h>
...@@ -578,7 +577,7 @@ static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc) ...@@ -578,7 +577,7 @@ static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
if (!ccdc->fpc_en) if (!ccdc->fpc_en)
return; return;
isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC, isp_reg_writel(isp, ccdc->fpc.dma, OMAP3_ISP_IOMEM_CCDC,
ISPCCDC_FPC_ADDR); ISPCCDC_FPC_ADDR);
/* The FPNUM field must be set before enabling FPC. */ /* The FPNUM field must be set before enabling FPC. */
isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT), isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT),
...@@ -718,8 +717,9 @@ static int ccdc_config(struct isp_ccdc_device *ccdc, ...@@ -718,8 +717,9 @@ static int ccdc_config(struct isp_ccdc_device *ccdc,
ccdc->shadow_update = 0; ccdc->shadow_update = 0;
if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) { if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) {
u32 table_old = 0; struct omap3isp_ccdc_fpc fpc;
u32 table_new; struct ispccdc_fpc fpc_old = { .addr = NULL, };
struct ispccdc_fpc fpc_new;
u32 size; u32 size;
if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED) if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
...@@ -728,35 +728,39 @@ static int ccdc_config(struct isp_ccdc_device *ccdc, ...@@ -728,35 +728,39 @@ static int ccdc_config(struct isp_ccdc_device *ccdc,
ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag); ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag);
if (ccdc->fpc_en) { if (ccdc->fpc_en) {
if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc, if (copy_from_user(&fpc, ccdc_struct->fpc, sizeof(fpc)))
sizeof(ccdc->fpc)))
return -EFAULT; return -EFAULT;
size = fpc.fpnum * 4;
/* /*
* table_new must be 64-bytes aligned, but it's * The table address must be 64-bytes aligned, which is
* already done by omap_iommu_vmalloc(). * guaranteed by dma_alloc_coherent().
*/ */
size = ccdc->fpc.fpnum * 4; fpc_new.fpnum = fpc.fpnum;
table_new = omap_iommu_vmalloc(isp->domain, isp->dev, fpc_new.addr = dma_alloc_coherent(isp->dev, size,
0, size, IOMMU_FLAG); &fpc_new.dma,
if (IS_ERR_VALUE(table_new)) GFP_KERNEL);
if (fpc_new.addr == NULL)
return -ENOMEM; return -ENOMEM;
if (copy_from_user(omap_da_to_va(isp->dev, table_new), if (copy_from_user(fpc_new.addr,
(__force void __user *) (__force void __user *)fpc.fpcaddr,
ccdc->fpc.fpcaddr, size)) { size)) {
omap_iommu_vfree(isp->domain, isp->dev, dma_free_coherent(isp->dev, size, fpc_new.addr,
table_new); fpc_new.dma);
return -EFAULT; return -EFAULT;
} }
table_old = ccdc->fpc.fpcaddr; fpc_old = ccdc->fpc;
ccdc->fpc.fpcaddr = table_new; ccdc->fpc = fpc_new;
} }
ccdc_configure_fpc(ccdc); ccdc_configure_fpc(ccdc);
if (table_old != 0)
omap_iommu_vfree(isp->domain, isp->dev, table_old); if (fpc_old.addr != NULL)
dma_free_coherent(isp->dev, fpc_old.fpnum * 4,
fpc_old.addr, fpc_old.dma);
} }
return ccdc_lsc_config(ccdc, ccdc_struct); return ccdc_lsc_config(ccdc, ccdc_struct);
...@@ -2574,8 +2578,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp) ...@@ -2574,8 +2578,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
cancel_work_sync(&ccdc->lsc.table_work); cancel_work_sync(&ccdc->lsc.table_work);
ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue); ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
if (ccdc->fpc.fpcaddr != 0) if (ccdc->fpc.addr != NULL)
omap_iommu_vfree(isp->domain, isp->dev, ccdc->fpc.fpcaddr); dma_free_coherent(isp->dev, ccdc->fpc.fpnum * 4, ccdc->fpc.addr,
ccdc->fpc.dma);
mutex_destroy(&ccdc->ioctl_lock); mutex_destroy(&ccdc->ioctl_lock);
} }
...@@ -46,6 +46,12 @@ enum ccdc_input_entity { ...@@ -46,6 +46,12 @@ enum ccdc_input_entity {
#define OMAP3ISP_CCDC_NEVENTS 16 #define OMAP3ISP_CCDC_NEVENTS 16
struct ispccdc_fpc {
void *addr;
dma_addr_t dma;
unsigned int fpnum;
};
enum ispccdc_lsc_state { enum ispccdc_lsc_state {
LSC_STATE_STOPPED = 0, LSC_STATE_STOPPED = 0,
LSC_STATE_STOPPING = 1, LSC_STATE_STOPPING = 1,
...@@ -140,7 +146,7 @@ struct isp_ccdc_device { ...@@ -140,7 +146,7 @@ struct isp_ccdc_device {
fpc_en:1; fpc_en:1;
struct omap3isp_ccdc_blcomp blcomp; struct omap3isp_ccdc_blcomp blcomp;
struct omap3isp_ccdc_bclamp clamp; struct omap3isp_ccdc_bclamp clamp;
struct omap3isp_ccdc_fpc fpc; struct ispccdc_fpc fpc;
struct ispccdc_lsc lsc; struct ispccdc_lsc lsc;
unsigned int update; unsigned int update;
unsigned int shadow_update; unsigned int shadow_update;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment