@@ -77,6 +77,25 @@ enum geni_i2c_err_code {
7777#define XFER_TIMEOUT HZ
7878#define RST_TIMEOUT HZ
7979
80+ #define QCOM_I2C_MIN_NUM_OF_MSGS_MULTI_DESC 2
81+
82+ /**
83+ * struct geni_i2c_gpi_multi_desc_xfer - Structure for multi transfer support
84+ *
85+ * @msg_idx_cnt: Current message index being processed in the transfer
86+ * @unmap_msg_cnt: Number of messages that have been unmapped
87+ * @irq_cnt: Number of transfer completion interrupts received
88+ * @dma_buf: Array of virtual addresses for DMA-safe buffers
89+ * @dma_addr: Array of DMA addresses corresponding to the buffers
90+ */
91+ struct geni_i2c_gpi_multi_desc_xfer {
92+ u32 msg_idx_cnt ;
93+ u32 unmap_msg_cnt ;
94+ u32 irq_cnt ;
95+ void * * dma_buf ;
96+ dma_addr_t * dma_addr ;
97+ };
98+
8099struct geni_i2c_dev {
81100 struct geni_se se ;
82101 u32 tx_wm ;
@@ -99,6 +118,9 @@ struct geni_i2c_dev {
99118 struct dma_chan * rx_c ;
100119 bool gpi_mode ;
101120 bool abort_done ;
121+ bool is_tx_multi_desc_xfer ;
122+ u32 num_msgs ;
123+ struct geni_i2c_gpi_multi_desc_xfer i2c_multi_desc_config ;
102124};
103125
104126struct geni_i2c_desc {
@@ -499,6 +521,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
499521static void i2c_gpi_cb_result (void * cb , const struct dmaengine_result * result )
500522{
501523 struct geni_i2c_dev * gi2c = cb ;
524+ struct geni_i2c_gpi_multi_desc_xfer * tx_multi_xfer ;
502525
503526 if (result -> result != DMA_TRANS_NOERROR ) {
504527 dev_err (gi2c -> se .dev , "DMA txn failed:%d\n" , result -> result );
@@ -507,6 +530,11 @@ static void i2c_gpi_cb_result(void *cb, const struct dmaengine_result *result)
507530 dev_dbg (gi2c -> se .dev , "DMA xfer has pending: %d\n" , result -> residue );
508531 }
509532
533+ if (gi2c -> is_tx_multi_desc_xfer ) {
534+ tx_multi_xfer = & gi2c -> i2c_multi_desc_config ;
535+ tx_multi_xfer -> irq_cnt ++ ;
536+ }
537+
510538 complete (& gi2c -> done );
511539}
512540
@@ -525,7 +553,72 @@ static void geni_i2c_gpi_unmap(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
525553 }
526554}
527555
528- static int geni_i2c_gpi (struct geni_i2c_dev * gi2c , struct i2c_msg * msg ,
556+ /**
557+ * geni_i2c_gpi_multi_desc_unmap() - Unmaps DMA buffers post multi message TX transfers
558+ * @gi2c: I2C dev handle
559+ * @msgs: Array of I2C messages
560+ * @peripheral: Pointer to gpi_i2c_config
561+ */
562+ static void geni_i2c_gpi_multi_desc_unmap (struct geni_i2c_dev * gi2c , struct i2c_msg msgs [],
563+ struct gpi_i2c_config * peripheral )
564+ {
565+ u32 msg_xfer_cnt , wr_idx = 0 ;
566+ struct geni_i2c_gpi_multi_desc_xfer * tx_multi_xfer = & gi2c -> i2c_multi_desc_config ;
567+
568+ msg_xfer_cnt = gi2c -> err ? tx_multi_xfer -> msg_idx_cnt : tx_multi_xfer -> irq_cnt ;
569+
570+ /* Unmap the processed DMA buffers based on the received interrupt count */
571+ for (; tx_multi_xfer -> unmap_msg_cnt < msg_xfer_cnt ; tx_multi_xfer -> unmap_msg_cnt ++ ) {
572+ wr_idx = tx_multi_xfer -> unmap_msg_cnt ;
573+ geni_i2c_gpi_unmap (gi2c , & msgs [wr_idx ],
574+ tx_multi_xfer -> dma_buf [wr_idx ],
575+ tx_multi_xfer -> dma_addr [wr_idx ],
576+ NULL , 0 );
577+
578+ if (tx_multi_xfer -> unmap_msg_cnt == gi2c -> num_msgs - 1 ) {
579+ kfree (tx_multi_xfer -> dma_buf );
580+ kfree (tx_multi_xfer -> dma_addr );
581+ break ;
582+ }
583+ }
584+ }
585+
586+ /**
587+ * geni_i2c_gpi_multi_xfer_timeout_handler() - Handles multi message transfer timeout
588+ * @dev: Pointer to the corresponding dev node
589+ * @multi_xfer: Pointer to the geni_i2c_gpi_multi_desc_xfer
590+ * @transfer_timeout_msecs: Timeout value in milliseconds
591+ * @transfer_comp: Completion object of the transfer
592+ *
593+ * This function waits for the completion of each processed transfer messages
594+ * based on the interrupts generated upon transfer completion.
595+ *
596+ * Return: On success returns 0, -ETIMEDOUT on timeout.
597+ */
598+ static int geni_i2c_gpi_multi_xfer_timeout_handler (struct device * dev ,
599+ struct geni_i2c_gpi_multi_desc_xfer * multi_xfer ,
600+ u32 transfer_timeout_msecs ,
601+ struct completion * transfer_comp )
602+ {
603+ int i ;
604+ u32 time_left ;
605+
606+ for (i = 0 ; i < multi_xfer -> msg_idx_cnt - 1 ; i ++ ) {
607+ reinit_completion (transfer_comp );
608+
609+ if (multi_xfer -> msg_idx_cnt != multi_xfer -> irq_cnt ) {
610+ time_left = wait_for_completion_timeout (transfer_comp ,
611+ transfer_timeout_msecs );
612+ if (!time_left ) {
613+ dev_err (dev , "%s: Transfer timeout\n" , __func__ );
614+ return - ETIMEDOUT ;
615+ }
616+ }
617+ }
618+ return 0 ;
619+ }
620+
621+ static int geni_i2c_gpi (struct geni_i2c_dev * gi2c , struct i2c_msg msgs [],
529622 struct dma_slave_config * config , dma_addr_t * dma_addr_p ,
530623 void * * buf , unsigned int op , struct dma_chan * dma_chan )
531624{
@@ -537,26 +630,45 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
537630 enum dma_transfer_direction dma_dirn ;
538631 struct dma_async_tx_descriptor * desc ;
539632 int ret ;
633+ struct geni_i2c_gpi_multi_desc_xfer * gi2c_gpi_xfer ;
634+ dma_cookie_t cookie ;
635+ u32 msg_idx ;
540636
541637 peripheral = config -> peripheral_config ;
638+ gi2c_gpi_xfer = & gi2c -> i2c_multi_desc_config ;
639+ msg_idx = gi2c_gpi_xfer -> msg_idx_cnt ;
542640
543- dma_buf = i2c_get_dma_safe_msg_buf (msg , 1 );
544- if (!dma_buf )
545- return - ENOMEM ;
641+ dma_buf = i2c_get_dma_safe_msg_buf (& msgs [msg_idx ], 1 );
642+ if (!dma_buf ) {
643+ ret = - ENOMEM ;
644+ goto out ;
645+ }
546646
547647 if (op == I2C_WRITE )
548648 map_dirn = DMA_TO_DEVICE ;
549649 else
550650 map_dirn = DMA_FROM_DEVICE ;
551651
552- addr = dma_map_single (gi2c -> se .dev -> parent , dma_buf , msg -> len , map_dirn );
652+ addr = dma_map_single (gi2c -> se .dev -> parent , dma_buf ,
653+ msgs [msg_idx ].len , map_dirn );
553654 if (dma_mapping_error (gi2c -> se .dev -> parent , addr )) {
554- i2c_put_dma_safe_msg_buf (dma_buf , msg , false);
555- return - ENOMEM ;
655+ i2c_put_dma_safe_msg_buf (dma_buf , & msgs [msg_idx ], false);
656+ ret = - ENOMEM ;
657+ goto out ;
658+ }
659+
660+ if (gi2c -> is_tx_multi_desc_xfer ) {
661+ flags = DMA_CTRL_ACK ;
662+
663+ /* BEI bit to be cleared for last TRE */
664+ if (msg_idx == gi2c -> num_msgs - 1 )
665+ flags |= DMA_PREP_INTERRUPT ;
666+ } else {
667+ flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK ;
556668 }
557669
558670 /* set the length as message for rx txn */
559- peripheral -> rx_len = msg -> len ;
671+ peripheral -> rx_len = msgs [ msg_idx ]. len ;
560672 peripheral -> op = op ;
561673
562674 ret = dmaengine_slave_config (dma_chan , config );
@@ -567,14 +679,21 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
567679
568680 peripheral -> set_config = 0 ;
569681 peripheral -> multi_msg = true;
570- flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK ;
571682
572683 if (op == I2C_WRITE )
573684 dma_dirn = DMA_MEM_TO_DEV ;
574685 else
575686 dma_dirn = DMA_DEV_TO_MEM ;
576687
577- desc = dmaengine_prep_slave_single (dma_chan , addr , msg -> len , dma_dirn , flags );
688+ desc = dmaengine_prep_slave_single (dma_chan , addr , msgs [msg_idx ].len ,
689+ dma_dirn , flags );
690+ if (!desc && !(flags & DMA_PREP_INTERRUPT )) {
691+ /* Retry with interrupt if not enough TREs */
692+ flags |= DMA_PREP_INTERRUPT ;
693+ desc = dmaengine_prep_slave_single (dma_chan , addr , msgs [msg_idx ].len ,
694+ dma_dirn , flags );
695+ }
696+
578697 if (!desc ) {
579698 dev_err (gi2c -> se .dev , "prep_slave_sg failed\n" );
580699 ret = - EIO ;
@@ -584,15 +703,48 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
584703 desc -> callback_result = i2c_gpi_cb_result ;
585704 desc -> callback_param = gi2c ;
586705
587- dmaengine_submit (desc );
588- * buf = dma_buf ;
589- * dma_addr_p = addr ;
706+ if (!((msgs [msg_idx ].flags & I2C_M_RD ) && op == I2C_WRITE ))
707+ gi2c_gpi_xfer -> msg_idx_cnt ++ ;
590708
709+ cookie = dmaengine_submit (desc );
710+ if (dma_submit_error (cookie )) {
711+ dev_err (gi2c -> se .dev ,
712+ "%s: dmaengine_submit failed (%d)\n" , __func__ , cookie );
713+ ret = - EINVAL ;
714+ goto err_config ;
715+ }
716+
717+ if (gi2c -> is_tx_multi_desc_xfer ) {
718+ gi2c_gpi_xfer -> dma_buf [msg_idx ] = dma_buf ;
719+ gi2c_gpi_xfer -> dma_addr [msg_idx ] = addr ;
720+
721+ dma_async_issue_pending (gi2c -> tx_c );
722+
723+ if ((msg_idx == (gi2c -> num_msgs - 1 )) || flags & DMA_PREP_INTERRUPT ) {
724+ ret = geni_i2c_gpi_multi_xfer_timeout_handler (gi2c -> se .dev , gi2c_gpi_xfer ,
725+ XFER_TIMEOUT , & gi2c -> done );
726+ if (ret ) {
727+ dev_err (gi2c -> se .dev ,
728+ "I2C multi write msg transfer timeout: %d\n" ,
729+ ret );
730+ gi2c -> err = ret ;
731+ return ret ;
732+ }
733+ }
734+ } else {
735+ /* Non multi descriptor message transfer */
736+ * buf = dma_buf ;
737+ * dma_addr_p = addr ;
738+ }
591739 return 0 ;
592740
593741err_config :
594- dma_unmap_single (gi2c -> se .dev -> parent , addr , msg -> len , map_dirn );
595- i2c_put_dma_safe_msg_buf (dma_buf , msg , false);
742+ dma_unmap_single (gi2c -> se .dev -> parent , addr ,
743+ msgs [msg_idx ].len , map_dirn );
744+ i2c_put_dma_safe_msg_buf (dma_buf , & msgs [msg_idx ], false);
745+
746+ out :
747+ gi2c -> err = ret ;
596748 return ret ;
597749}
598750
@@ -604,6 +756,7 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
604756 unsigned long time_left ;
605757 dma_addr_t tx_addr , rx_addr ;
606758 void * tx_buf = NULL , * rx_buf = NULL ;
759+ struct geni_i2c_gpi_multi_desc_xfer * tx_multi_xfer ;
607760 const struct geni_i2c_clk_fld * itr = gi2c -> clk_fld ;
608761
609762 config .peripheral_config = & peripheral ;
@@ -617,6 +770,41 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
617770 peripheral .set_config = 1 ;
618771 peripheral .multi_msg = false;
619772
773+ gi2c -> num_msgs = num ;
774+ gi2c -> is_tx_multi_desc_xfer = false;
775+
776+ tx_multi_xfer = & gi2c -> i2c_multi_desc_config ;
777+ memset (tx_multi_xfer , 0 , sizeof (struct geni_i2c_gpi_multi_desc_xfer ));
778+
779+ /*
780+ * If number of write messages are two and higher then
781+ * configure hardware for multi descriptor transfers with BEI.
782+ */
783+ if (num >= QCOM_I2C_MIN_NUM_OF_MSGS_MULTI_DESC ) {
784+ gi2c -> is_tx_multi_desc_xfer = true;
785+ for (i = 0 ; i < num ; i ++ ) {
786+ if (msgs [i ].flags & I2C_M_RD ) {
787+ /*
788+ * Multi descriptor transfer with BEI
789+ * support is enabled for write transfers.
790+ * TODO: Add BEI optimization support for
791+ * read transfers later.
792+ */
793+ gi2c -> is_tx_multi_desc_xfer = false;
794+ break ;
795+ }
796+ }
797+ }
798+
799+ if (gi2c -> is_tx_multi_desc_xfer ) {
800+ tx_multi_xfer -> dma_buf = kcalloc (num , sizeof (void * ), GFP_KERNEL );
801+ tx_multi_xfer -> dma_addr = kcalloc (num , sizeof (dma_addr_t ), GFP_KERNEL );
802+ if (!tx_multi_xfer -> dma_buf || !tx_multi_xfer -> dma_addr ) {
803+ ret = - ENOMEM ;
804+ goto err ;
805+ }
806+ }
807+
620808 for (i = 0 ; i < num ; i ++ ) {
621809 gi2c -> cur = & msgs [i ];
622810 gi2c -> err = 0 ;
@@ -627,33 +815,41 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
627815 peripheral .stretch = 1 ;
628816
629817 peripheral .addr = msgs [i ].addr ;
818+ if (i > 0 && (!(msgs [i ].flags & I2C_M_RD )))
819+ peripheral .multi_msg = false;
630820
631- ret = geni_i2c_gpi (gi2c , & msgs [ i ] , & config ,
821+ ret = geni_i2c_gpi (gi2c , msgs , & config ,
632822 & tx_addr , & tx_buf , I2C_WRITE , gi2c -> tx_c );
633823 if (ret )
634824 goto err ;
635825
636826 if (msgs [i ].flags & I2C_M_RD ) {
637- ret = geni_i2c_gpi (gi2c , & msgs [ i ] , & config ,
827+ ret = geni_i2c_gpi (gi2c , msgs , & config ,
638828 & rx_addr , & rx_buf , I2C_READ , gi2c -> rx_c );
639829 if (ret )
640830 goto err ;
641831
642832 dma_async_issue_pending (gi2c -> rx_c );
643833 }
644834
645- dma_async_issue_pending (gi2c -> tx_c );
646-
647- time_left = wait_for_completion_timeout (& gi2c -> done , XFER_TIMEOUT );
648- if (!time_left )
649- gi2c -> err = - ETIMEDOUT ;
835+ if (!gi2c -> is_tx_multi_desc_xfer ) {
836+ dma_async_issue_pending (gi2c -> tx_c );
837+ time_left = wait_for_completion_timeout (& gi2c -> done , XFER_TIMEOUT );
838+ if (!time_left ) {
839+ dev_err (gi2c -> se .dev , "%s:I2C timeout\n" , __func__ );
840+ gi2c -> err = - ETIMEDOUT ;
841+ }
842+ }
650843
651844 if (gi2c -> err ) {
652845 ret = gi2c -> err ;
653846 goto err ;
654847 }
655848
656- geni_i2c_gpi_unmap (gi2c , & msgs [i ], tx_buf , tx_addr , rx_buf , rx_addr );
849+ if (!gi2c -> is_tx_multi_desc_xfer )
850+ geni_i2c_gpi_unmap (gi2c , & msgs [i ], tx_buf , tx_addr , rx_buf , rx_addr );
851+ else if (tx_multi_xfer -> unmap_msg_cnt != tx_multi_xfer -> irq_cnt )
852+ geni_i2c_gpi_multi_desc_unmap (gi2c , msgs , & peripheral );
657853 }
658854
659855 return num ;
@@ -662,7 +858,11 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
662858 dev_err (gi2c -> se .dev , "GPI transfer failed: %d\n" , ret );
663859 dmaengine_terminate_sync (gi2c -> rx_c );
664860 dmaengine_terminate_sync (gi2c -> tx_c );
665- geni_i2c_gpi_unmap (gi2c , & msgs [i ], tx_buf , tx_addr , rx_buf , rx_addr );
861+ if (gi2c -> is_tx_multi_desc_xfer )
862+ geni_i2c_gpi_multi_desc_unmap (gi2c , msgs , & peripheral );
863+ else
864+ geni_i2c_gpi_unmap (gi2c , & msgs [i ], tx_buf , tx_addr , rx_buf , rx_addr );
865+
666866 return ret ;
667867}
668868
0 commit comments