@@ -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)
258260static int version = RK_CAM_VERSION_CODE ;
259261module_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
293307enum 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
449466static 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
661795static 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 ;
707845fail :
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