Skip to content

Commit 0012af6

Browse files
Zhang Yunlongrkhuangtao
authored andcommitted
camera: rockchip: cif: use dmabuf in oneframe mode
Change-Id: Ic0acd28f569ce8f4b74ec2c60fe74fd998891464 Signed-off-by: Zhang Yunlong <dalon.zhang@rock-chips.com>
1 parent 52e4502 commit 0012af6

1 file changed

Lines changed: 152 additions & 7 deletions

File tree

drivers/media/video/rk30_camera_oneframe.c

Lines changed: 152 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,10 @@ static inline unsigned int read_grf_reg(unsigned int addr)
253253
1. support rk3368.
254254
*v0.3.0:
255255
* 1. supprot rk3228h
256+
*v0.4.0:
257+
* 1.cif uses dmabuf,in this case,vb->boff is buffer fd.
256258
*/
257-
#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0)
259+
#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 4, 0)
258260
static int version = RK_CAM_VERSION_CODE;
259261
module_param(version, int, S_IRUGO);
260262

@@ -290,6 +292,18 @@ struct rk_camera_buffer
290292
u32 code;
291293
int inwork;
292294
};
295+
296+
#define RK_CAMERA_MODE_DMA_SG
297+
#ifdef RK_CAMERA_MODE_DMA_SG
298+
#define DMABUF_MAX_FRAME 32
299+
struct rk_camera_dma_buf_s {
300+
struct dma_buf *dma_buf;
301+
struct dma_buf_attachment *attach;
302+
struct sg_table *sgt;
303+
dma_addr_t dma_addr;
304+
int fd;
305+
};
306+
#endif
293307
enum rk_camera_reg_state
294308
{
295309
Reg_Invalidate,
@@ -442,8 +456,11 @@ struct rk_camera_dev
442456
wait_queue_head_t cif_stop_done;
443457
volatile bool cif_stopped;
444458
struct timeval first_tv;
445-
446459
int chip_id;
460+
#ifdef RK_CAMERA_MODE_DMA_SG
461+
struct rk_camera_dma_buf_s dma_buffer[DMABUF_MAX_FRAME];
462+
int dma_buf_cnt;
463+
#endif
447464
};
448465

449466
static const struct v4l2_queryctrl rk_camera_controls[] =
@@ -540,6 +557,118 @@ static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
540557
return;
541558
}
542559

560+
#ifdef RK_CAMERA_MODE_DMA_SG
561+
static int rk_camera_dma_attach_device(struct rk_camera_dev *pcdev)
562+
{
563+
struct device *dev = pcdev->dev;
564+
int ret;
565+
//to do something iommu future
566+
ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
567+
if (ret)
568+
return ret;
569+
570+
return 0;
571+
}
572+
573+
static void rk_camera_dma_detach_device(struct rk_camera_dev *pcdev)
574+
{
575+
//to do something iommu future
576+
}
577+
578+
static int rk_camera_dmabuf_cb(struct rk_camera_dev *pcdev,
579+
struct videobuf_buffer *vb,
580+
bool on)
581+
{
582+
struct dma_buf *dma_buffer;
583+
struct dma_buf_attachment *attach;
584+
struct sg_table *sgt;
585+
dma_addr_t dma_addr;
586+
int index = 0;
587+
int ret = 0;
588+
589+
if (on) {
590+
index = vb->i;
591+
if (index >= DMABUF_MAX_FRAME) {
592+
RKCAMERA_TR("index (%d) is wrong, max support is %d.\n", index, DMABUF_MAX_FRAME);
593+
return -EINVAL;
594+
}
595+
if (pcdev->dma_buf_cnt == 0) {
596+
ret = rk_camera_dma_attach_device(pcdev);
597+
if (ret) {
598+
RKCAMERA_TR("rk_camera_dma_attach_device fail\n");
599+
return ret;
600+
}
601+
}
602+
603+
dma_buffer = dma_buf_get(vb->boff);
604+
if (IS_ERR(dma_buffer)) {
605+
RKCAMERA_TR("dma_buf_get fail\n");
606+
return PTR_ERR(dma_buffer);
607+
}
608+
attach = dma_buf_attach(dma_buffer, pcdev->dev);
609+
if (IS_ERR(attach)) {
610+
RKCAMERA_TR("dma_buf_attach fail\n");
611+
dma_buf_put(dma_buffer);
612+
return PTR_ERR(attach);
613+
}
614+
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
615+
if (IS_ERR(sgt)) {
616+
RKCAMERA_TR("dma_buf_map_attachment fail\n");
617+
dma_buf_detach(dma_buffer, attach);
618+
dma_buf_put(dma_buffer);
619+
return PTR_ERR(sgt);
620+
}
621+
dma_addr = sg_dma_address(sgt->sgl);
622+
623+
pcdev->dma_buffer[index].dma_addr = dma_addr;
624+
pcdev->dma_buffer[index].attach = attach;
625+
pcdev->dma_buffer[index].dma_buf = dma_buffer;
626+
pcdev->dma_buffer[index].sgt = sgt;
627+
pcdev->dma_buffer[index].fd = vb->boff;
628+
pcdev->dma_buf_cnt++;
629+
630+
RKCAMERA_DG1
631+
("dma buf map: dma_addr 0x%lx, attach %p, dma_buf %p,sgt %p,fd 0x%x,buf_cnt %d, index %d\n",
632+
(unsigned long)dma_addr,
633+
attach,
634+
dma_buffer,
635+
sgt,
636+
(int)vb->boff,
637+
pcdev->dma_buf_cnt,
638+
index);
639+
} else {
640+
index = vb->i;
641+
if (index >= DMABUF_MAX_FRAME) {
642+
RKCAMERA_TR("index (%d) is wrong, max support is %d.\n", index, DMABUF_MAX_FRAME);
643+
return -EINVAL;
644+
}
645+
if (pcdev->dma_buf_cnt == 0) {
646+
RKCAMERA_DG1("dma_buf_cnt is %d.\n", pcdev->dma_buf_cnt);
647+
return ret;
648+
}
649+
attach = pcdev->dma_buffer[index].attach;
650+
dma_buffer = pcdev->dma_buffer[index].dma_buf;
651+
sgt = pcdev->dma_buffer[index].sgt;
652+
RKCAMERA_DG1
653+
("dma buf unmap: attach %p,dma_buf %p,sgt %p,fd 0x%x,buf_cnt %d,index %d\n",
654+
attach,
655+
dma_buffer,
656+
sgt,
657+
(int)vb->boff,
658+
pcdev->dma_buf_cnt,
659+
index);
660+
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
661+
dma_buf_detach(dma_buffer, attach);
662+
dma_buf_put(dma_buffer);
663+
if (pcdev->dma_buf_cnt == 1)
664+
rk_camera_dma_detach_device(pcdev);
665+
pcdev->dma_buf_cnt--;
666+
pcdev->dma_buffer[index].fd = -1;
667+
}
668+
669+
return ret;
670+
}
671+
#endif
543672

544673
/*
545674
* Videobuf operations
@@ -628,6 +757,11 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
628757
}
629758
#endif
630759
}
760+
#ifdef RK_CAMERA_MODE_DMA_SG
761+
pcdev->dma_buf_cnt = 0;
762+
for (i = 0; i < DMABUF_MAX_FRAME; i++)
763+
pcdev->dma_buffer[i].fd = -1;
764+
#endif
631765
pcdev->video_vq = vq;
632766
RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
633767

@@ -661,14 +795,16 @@ static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer
661795
static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
662796
{
663797
struct soc_camera_device *icd = vq->priv_data;
798+
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
799+
struct rk_camera_dev *pcdev = ici->priv;
664800
struct rk_camera_buffer *buf;
665801
int ret;
666802
int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
667803
icd->current_fmt->host_fmt);
668804

669805
debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
670806

671-
if ((bytes_per_line < 0) || (vb->boff == 0))
807+
if ((bytes_per_line < 0) || (vb->boff == 0) || (vb->boff == -1))
672808
return -EINVAL;
673809

674810
buf = container_of(vb, struct rk_camera_buffer, vb);
@@ -700,9 +836,11 @@ static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer
700836
if (ret) {
701837
goto fail;
702838
}
839+
#ifdef RK_CAMERA_MODE_DMA_SG
840+
rk_camera_dmabuf_cb(pcdev, vb, true);
841+
#endif
703842
vb->state = VIDEOBUF_PREPARED;
704843
}
705-
706844
return 0;
707845
fail:
708846
rk_videobuf_free(vq, buf);
@@ -728,8 +866,13 @@ static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_came
728866
BUG();
729867
}
730868
} else {
869+
#ifdef RK_CAMERA_MODE_DMA_SG
870+
y_addr = (unsigned long)pcdev->dma_buffer[vb->i].dma_addr;
871+
uv_addr = y_addr + vb->width * vb->height;
872+
#else
731873
y_addr = vb->boff;
732874
uv_addr = y_addr + vb->width * vb->height;
875+
#endif
733876
}
734877
#if defined(CONFIG_ARCH_RK3188)
735878
rk_camera_cif_reset(pcdev,false);
@@ -1373,10 +1516,12 @@ static void rk_videobuf_release(struct videobuf_queue *vq,
13731516
}
13741517
#endif
13751518

1376-
flush_workqueue(pcdev->camera_wq);
1377-
1519+
flush_workqueue(pcdev->camera_wq);
1520+
#ifdef RK_CAMERA_MODE_DMA_SG
1521+
rk_camera_dmabuf_cb(pcdev, vb, false);
1522+
#endif
13781523
rk_videobuf_free(vq, buf);
1379-
1524+
13801525
#if CAMERA_VIDEOBUF_ARM_ACCESS
13811526
if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
13821527
vb_info = pcdev->vbinfo + vb->i;

0 commit comments

Comments
 (0)