{QM_SUPPORT_DB_ISOLATION, 0x30,   0, BIT(0),  0x0, 0x0, 0x0},
        {QM_SUPPORT_FUNC_QOS,     0x3100, 0, BIT(8),  0x0, 0x0, 0x1},
        {QM_SUPPORT_STOP_QP,      0x3100, 0, BIT(9),  0x0, 0x0, 0x1},
+       {QM_SUPPORT_STOP_FUNC,     0x3100, 0, BIT(10), 0x0, 0x0, 0x1},
        {QM_SUPPORT_MB_COMMAND,   0x3100, 0, BIT(11), 0x0, 0x0, 0x1},
        {QM_SUPPORT_SVA_PREFETCH, 0x3100, 0, BIT(14), 0x0, 0x0, 0x1},
 };
        return ret;
 }
 
+static int qm_drain_qm(struct hisi_qm *qm)
+{
+       return hisi_qm_mb(qm, QM_MB_CMD_FLUSH_QM, 0, 0, 0);
+}
+
 static int qm_stop_qp(struct hisi_qp *qp)
 {
        return hisi_qm_mb(qp->qm, QM_MB_CMD_STOP_QP, 0, qp->qp_id, 0);
 
 static int qm_stop_qp_nolock(struct hisi_qp *qp)
 {
-       struct device *dev = &qp->qm->pdev->dev;
+       struct hisi_qm *qm = qp->qm;
+       struct device *dev = &qm->pdev->dev;
        int ret;
 
        /*
 
        atomic_set(&qp->qp_status.flags, QP_STOP);
 
-       ret = qm_drain_qp(qp);
-       if (ret)
-               dev_err(dev, "Failed to drain out data for stopping!\n");
+       /* V3 supports direct stop function when FLR prepare */
+       if (qm->ver < QM_HW_V3 || qm->status.stop_reason == QM_NORMAL) {
+               ret = qm_drain_qp(qp);
+               if (ret)
+                       dev_err(dev, "Failed to drain out data for stopping qp(%u)!\n", qp->qp_id);
+       }
 
-       flush_workqueue(qp->qm->wq);
+       flush_workqueue(qm->wq);
        if (unlikely(qp->is_resetting && atomic_read(&qp->qp_status.used)))
                qp_stop_fail_cb(qp);
 
 
        down_write(&qm->qps_lock);
 
-       qm->status.stop_reason = r;
        if (atomic_read(&qm->status.flags) == QM_STOP)
                goto err_unlock;
 
        /* Stop all the request sending at first. */
        atomic_set(&qm->status.flags, QM_STOP);
+       qm->status.stop_reason = r;
 
-       if (qm->status.stop_reason == QM_SOFT_RESET ||
-           qm->status.stop_reason == QM_DOWN) {
+       if (qm->status.stop_reason != QM_NORMAL) {
                hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET);
+               /*
+                * When performing soft reset, the hardware will no longer
+                * do tasks, and the tasks in the device will be flushed
+                * out directly since the master ooo is closed.
+                */
+               if (test_bit(QM_SUPPORT_STOP_FUNC, &qm->caps) &&
+                   r != QM_SOFT_RESET) {
+                       ret = qm_drain_qm(qm);
+                       if (ret) {
+                               dev_err(dev, "failed to drain qm!\n");
+                               goto err_unlock;
+                       }
+               }
+
                ret = qm_stop_started_qp(qm);
                if (ret < 0) {
                        dev_err(dev, "Failed to stop started qp!\n");
        }
 
        qm_clear_queues(qm);
+       qm->status.stop_reason = QM_NORMAL;
 
 err_unlock:
        up_write(&qm->qps_lock);