--- /dev/null
+From bdfc967bf5fcd762473a01d39edb81f1165ba290 Mon Sep 17 00:00:00 2001
+From: Anilkumar Kolli <quic_akolli@quicinc.com>
+Date: Wed, 26 Jul 2023 19:40:31 +0530
+Subject: [PATCH 4/5] wifi: ath11k: Add coldboot calibration support for
+ QCN9074
+
+QCN9074 supports 6 GHz, which has increased number of channels
+compared to 5 GHz/2 GHz. So, to support coldboot calibration in
+QCN9074 ATH11K_COLD_BOOT_FW_RESET_DELAY extended to 60 seconds. To
+avoid code redundancy, fwreset_from_cold_boot moved to QMI and made
+common for both ahb and pci. Coldboot calibration is enabled only in
+FTM mode for QCN9074. QCN9074 requires firmware restart after coldboot,
+hence enable cbcal_restart_fw in hw_params.
+
+This support can be enabled/disabled using hw params for different
+hardware. Currently it is not enabled for QCA6390.
+
+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Anilkumar Kolli <quic_akolli@quicinc.com>
+Signed-off-by: Seevalamuthu Mariappan <quic_seevalam@quicinc.com>
+Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230726141032.3061-3-quic_rajkbhag@quicinc.com
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 28 ++------------------------
+ drivers/net/wireless/ath/ath11k/core.c | 4 ++--
+ drivers/net/wireless/ath/ath11k/pci.c | 2 ++
+ drivers/net/wireless/ath/ath11k/qmi.c | 28 ++++++++++++++++++++++++++
+ drivers/net/wireless/ath/ath11k/qmi.h | 3 ++-
+ 5 files changed, 36 insertions(+), 29 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -14,6 +14,7 @@
+ #include "ahb.h"
+ #include "debug.h"
+ #include "hif.h"
++#include "qmi.h"
+ #include <linux/remoteproc.h>
+ #include "pcic.h"
+ #include <linux/soc/qcom/smem.h>
+@@ -418,31 +419,6 @@ static void ath11k_ahb_power_down(struct
+ rproc_shutdown(ab_ahb->tgt_rproc);
+ }
+
+-static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab)
+-{
+- int timeout;
+-
+- if (!ath11k_core_coldboot_cal_support(ab) || ab->qmi.cal_done ||
+- ab->hw_params.cbcal_restart_fw == 0)
+- return 0;
+-
+- ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n");
+- timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
+- (ab->qmi.cal_done == 1),
+- ATH11K_COLD_BOOT_FW_RESET_DELAY);
+- if (timeout <= 0) {
+- ath11k_cold_boot_cal = 0;
+- ath11k_warn(ab, "Coldboot Calibration failed timed out\n");
+- }
+-
+- /* reset the firmware */
+- ath11k_ahb_power_down(ab);
+- ath11k_ahb_power_up(ab);
+-
+- ath11k_dbg(ab, ATH11K_DBG_AHB, "exited from cold boot mode\n");
+- return 0;
+-}
+-
+ static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
+ {
+ struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
+@@ -1225,7 +1201,7 @@ static int ath11k_ahb_probe(struct platf
+ goto err_ce_free;
+ }
+
+- ath11k_ahb_fwreset_from_cold_boot(ab);
++ ath11k_qmi_fwreset_from_cold_boot(ab);
+
+ return 0;
+
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -336,8 +336,8 @@ static const struct ath11k_hw_params ath
+ .idle_ps = false,
+ .supports_sta_ps = false,
+ .coldboot_cal_mm = false,
+- .coldboot_cal_ftm = false,
+- .cbcal_restart_fw = false,
++ .coldboot_cal_ftm = true,
++ .cbcal_restart_fw = true,
+ .fw_mem_mode = 2,
+ .num_vdevs = 8,
+ .num_peers = 128,
+--- a/drivers/net/wireless/ath/ath11k/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -15,6 +15,7 @@
+ #include "mhi.h"
+ #include "debug.h"
+ #include "pcic.h"
++#include "qmi.h"
+
+ #define ATH11K_PCI_BAR_NUM 0
+ #define ATH11K_PCI_DMA_MASK 32
+@@ -897,6 +898,7 @@ unsupported_wcn6855_soc:
+ ath11k_err(ab, "failed to init core: %d\n", ret);
+ goto err_irq_affinity_cleanup;
+ }
++ ath11k_qmi_fwreset_from_cold_boot(ab);
+ return 0;
+
+ err_irq_affinity_cleanup:
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -9,6 +9,7 @@
+ #include "qmi.h"
+ #include "core.h"
+ #include "debug.h"
++#include "hif.h"
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/ioport.h>
+@@ -2839,6 +2840,33 @@ int ath11k_qmi_firmware_start(struct ath
+ return 0;
+ }
+
++int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab)
++{
++ int timeout;
++
++ if (!ath11k_core_coldboot_cal_support(ab) || ab->qmi.cal_done ||
++ ab->hw_params.cbcal_restart_fw == 0)
++ return 0;
++
++ ath11k_dbg(ab, ATH11K_DBG_QMI, "wait for cold boot done\n");
++
++ timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
++ (ab->qmi.cal_done == 1),
++ ATH11K_COLD_BOOT_FW_RESET_DELAY);
++
++ if (timeout <= 0) {
++ ath11k_warn(ab, "Coldboot Calibration timed out\n");
++ return -ETIMEDOUT;
++ }
++
++ /* reset the firmware */
++ ath11k_hif_power_down(ab);
++ ath11k_hif_power_up(ab);
++ ath11k_dbg(ab, ATH11K_DBG_QMI, "exit wait for cold boot done\n");
++ return 0;
++}
++EXPORT_SYMBOL(ath11k_qmi_fwreset_from_cold_boot);
++
+ static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)
+ {
+ int timeout;
+--- a/drivers/net/wireless/ath/ath11k/qmi.h
++++ b/drivers/net/wireless/ath/ath11k/qmi.h
+@@ -37,7 +37,7 @@
+
+ #define QMI_WLANFW_MAX_DATA_SIZE_V01 6144
+ #define ATH11K_FIRMWARE_MODE_OFF 4
+-#define ATH11K_COLD_BOOT_FW_RESET_DELAY (40 * HZ)
++#define ATH11K_COLD_BOOT_FW_RESET_DELAY (60 * HZ)
+
+ #define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000
+
+@@ -519,5 +519,6 @@ void ath11k_qmi_msg_recv_work(struct wor
+ void ath11k_qmi_deinit_service(struct ath11k_base *ab);
+ int ath11k_qmi_init_service(struct ath11k_base *ab);
+ void ath11k_qmi_free_resource(struct ath11k_base *ab);
++int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab);
+
+ #endif