3131/* mailbox */
3232#define QM_MB_PING_ALL_VFS 0xffff
3333#define QM_MB_STATUS_MASK GENMASK(12, 9)
34+ #define QM_MB_BUSY_MASK BIT(13)
3435
3536/* sqc shift */
3637#define QM_SQ_HOP_NUM_SHIFT 0
@@ -582,16 +583,30 @@ static void qm_mb_pre_init(struct qm_mailbox *mailbox, u8 cmd,
582583 mailbox -> rsvd = 0 ;
583584}
584585
585- /* return 0 mailbox ready, -ETIMEDOUT hardware timeout */
586- int hisi_qm_wait_mb_ready (struct hisi_qm * qm )
586+ /*
587+ * The mailbox is 128 bits and requires a single read/write operation.
588+ * Since there is no general 128-bit IO memory access API in the current
589+ * ARM64 architecture, this needs to be implemented in the driver.
590+ */
591+ static struct qm_mailbox qm_mb_read (struct hisi_qm * qm )
587592{
588- u32 val ;
593+ struct qm_mailbox mailbox = {0 };
594+
595+ #if IS_ENABLED (CONFIG_ARM64 )
596+ const void __iomem * fun_base = qm -> io_base + QM_MB_CMD_SEND_BASE ;
597+ unsigned long tmp0 , tmp1 ;
589598
590- return readl_relaxed_poll_timeout (qm -> io_base + QM_MB_CMD_SEND_BASE ,
591- val , !((val >> QM_MB_BUSY_SHIFT ) &
592- 0x1 ), POLL_PERIOD , POLL_TIMEOUT );
599+ asm volatile ("ldp %0, %1, %3\n"
600+ "stp %0, %1, %2\n"
601+ : "=&r" (tmp0 ),
602+ "=&r" (tmp1 ),
603+ "+Q" (mailbox )
604+ : "Q" (* ((char __iomem * )fun_base ))
605+ : "memory" );
606+ #endif
607+
608+ return mailbox ;
593609}
594- EXPORT_SYMBOL_GPL (hisi_qm_wait_mb_ready );
595610
596611/* 128 bit should be written to hardware at one time to trigger a mailbox */
597612static void qm_mb_write (struct hisi_qm * qm , const void * src )
@@ -614,35 +629,61 @@ static void qm_mb_write(struct hisi_qm *qm, const void *src)
614629#endif
615630}
616631
617- static int qm_mb_nolock (struct hisi_qm * qm , struct qm_mailbox * mailbox )
632+ int hisi_qm_wait_mb_ready (struct hisi_qm * qm )
618633{
634+ struct qm_mailbox mailbox = {0 };
619635 int ret ;
620- u32 val ;
621636
622- if (unlikely (hisi_qm_wait_mb_ready (qm ))) {
637+ ret = read_poll_timeout (qm_mb_read , mailbox ,
638+ !(le16_to_cpu (mailbox .w0 ) & QM_MB_BUSY_MASK ),
639+ POLL_PERIOD , POLL_TIMEOUT ,
640+ true, qm );
641+ if (ret )
623642 dev_err (& qm -> pdev -> dev , "QM mailbox is busy to start!\n" );
624- ret = - EBUSY ;
625- goto mb_busy ;
626- }
627643
628- qm_mb_write (qm , mailbox );
644+ return ret ;
645+ }
646+ EXPORT_SYMBOL_GPL (hisi_qm_wait_mb_ready );
647+
648+ static int qm_wait_mb_finish (struct hisi_qm * qm , struct qm_mailbox * mailbox )
649+ {
650+ struct device * dev = & qm -> pdev -> dev ;
651+ int ret ;
629652
630- if (unlikely (hisi_qm_wait_mb_ready (qm ))) {
631- dev_err (& qm -> pdev -> dev , "QM mailbox operation timeout!\n" );
632- ret = - ETIMEDOUT ;
633- goto mb_busy ;
653+ ret = read_poll_timeout (qm_mb_read , * mailbox ,
654+ !(le16_to_cpu (mailbox -> w0 ) & QM_MB_BUSY_MASK ),
655+ POLL_PERIOD , POLL_TIMEOUT ,
656+ true, qm );
657+ if (ret ) {
658+ dev_err (dev , "QM mailbox operation timeout!\n" );
659+ return ret ;
634660 }
635661
636- val = readl (qm -> io_base + QM_MB_CMD_SEND_BASE );
637- if (val & QM_MB_STATUS_MASK ) {
638- dev_err (& qm -> pdev -> dev , "QM mailbox operation failed!\n" );
639- ret = - EIO ;
640- goto mb_busy ;
662+ if (le16_to_cpu (mailbox -> w0 ) & QM_MB_STATUS_MASK ) {
663+ dev_err (dev , "QM mailbox operation failed!\n" );
664+ return - EIO ;
641665 }
642666
643667 return 0 ;
668+ }
669+
670+ static int qm_mb_nolock (struct hisi_qm * qm , struct qm_mailbox * mailbox )
671+ {
672+ int ret ;
673+
674+ ret = hisi_qm_wait_mb_ready (qm );
675+ if (ret )
676+ goto mb_err_cnt_increase ;
677+
678+ qm_mb_write (qm , mailbox );
679+
680+ ret = qm_wait_mb_finish (qm , mailbox );
681+ if (ret )
682+ goto mb_err_cnt_increase ;
683+
684+ return 0 ;
644685
645- mb_busy :
686+ mb_err_cnt_increase :
646687 atomic64_inc (& qm -> debug .dfx .mb_err_cnt );
647688 return ret ;
648689}
@@ -663,6 +704,25 @@ int hisi_qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue,
663704}
664705EXPORT_SYMBOL_GPL (hisi_qm_mb );
665706
707+ int hisi_qm_mb_read (struct hisi_qm * qm , u64 * base , u8 cmd , u16 queue )
708+ {
709+ struct qm_mailbox mailbox ;
710+ int ret ;
711+
712+ qm_mb_pre_init (& mailbox , cmd , 0 , queue , 1 );
713+ mutex_lock (& qm -> mailbox_lock );
714+ ret = qm_mb_nolock (qm , & mailbox );
715+ mutex_unlock (& qm -> mailbox_lock );
716+ if (ret )
717+ return ret ;
718+
719+ * base = le32_to_cpu (mailbox .base_l ) |
720+ ((u64 )le32_to_cpu (mailbox .base_h ) << 32 );
721+
722+ return 0 ;
723+ }
724+ EXPORT_SYMBOL_GPL (hisi_qm_mb_read );
725+
666726/* op 0: set xqc information to hardware, 1: get xqc information from hardware. */
667727int qm_set_and_get_xqc (struct hisi_qm * qm , u8 cmd , void * xqc , u32 qp_id , bool op )
668728{
@@ -1379,12 +1439,10 @@ static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number)
13791439 u64 sqc_vft ;
13801440 int ret ;
13811441
1382- ret = hisi_qm_mb (qm , QM_MB_CMD_SQC_VFT_V2 , 0 , 0 , 1 );
1442+ ret = hisi_qm_mb_read (qm , & sqc_vft , QM_MB_CMD_SQC_VFT_V2 , 0 );
13831443 if (ret )
13841444 return ret ;
13851445
1386- sqc_vft = readl (qm -> io_base + QM_MB_CMD_DATA_ADDR_L ) |
1387- ((u64 )readl (qm -> io_base + QM_MB_CMD_DATA_ADDR_H ) << 32 );
13881446 * base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2 );
13891447 * number = (QM_SQC_VFT_NUM_MASK_V2 &
13901448 (sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2 )) + 1 ;
@@ -1524,25 +1582,6 @@ static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
15241582 return ACC_ERR_RECOVERED ;
15251583}
15261584
1527- static int qm_get_mb_cmd (struct hisi_qm * qm , u64 * msg , u16 fun_num )
1528- {
1529- struct qm_mailbox mailbox ;
1530- int ret ;
1531-
1532- qm_mb_pre_init (& mailbox , QM_MB_CMD_DST , 0 , fun_num , 0 );
1533- mutex_lock (& qm -> mailbox_lock );
1534- ret = qm_mb_nolock (qm , & mailbox );
1535- if (ret )
1536- goto err_unlock ;
1537-
1538- * msg = readl (qm -> io_base + QM_MB_CMD_DATA_ADDR_L ) |
1539- ((u64 )readl (qm -> io_base + QM_MB_CMD_DATA_ADDR_H ) << 32 );
1540-
1541- err_unlock :
1542- mutex_unlock (& qm -> mailbox_lock );
1543- return ret ;
1544- }
1545-
15461585static void qm_clear_cmd_interrupt (struct hisi_qm * qm , u64 vf_mask )
15471586{
15481587 u32 val ;
@@ -1871,7 +1910,7 @@ static int qm_get_ifc_v3(struct hisi_qm *qm, enum qm_ifc_cmd *cmd, u32 *data, u3
18711910 u64 msg ;
18721911 int ret ;
18731912
1874- ret = qm_get_mb_cmd (qm , & msg , fun_num );
1913+ ret = hisi_qm_mb_read (qm , & msg , QM_MB_CMD_DST , fun_num );
18751914 if (ret )
18761915 return ret ;
18771916
0 commit comments