From f4fe362e3f0a3b3d08bd6cfeb57004c777d8ba0f Mon Sep 17 00:00:00 2001 From: Jaya Surya Mathavan Date: Tue, 23 Jun 2020 11:40:04 +0530 Subject: [PATCH] ath11k: add coldboot calibration in qcn9000 Changed ATH11K_COLD_BOOT_FW_RESET_DELAY to 60 seconds to support qcn9000 Firmware reset after coldboot-calibration moved to qmi and made common for both ahb and pci. Signed-off-by: Jaya Surya Mathavan --- drivers/net/wireless/ath/ath11k/ahb.c | 37 +++++++++++----------------------- drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/pci.c | 3 +++ drivers/net/wireless/ath/ath11k/qmi.c | 32 +++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/qmi.h | 3 ++- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index be6d79b..b7eef6c 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -11,6 +11,7 @@ #include "ahb.h" #include "debug.h" #include "hif.h" +#include "qmi.h" #include static const u8 ath11k_tx_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { @@ -557,30 +558,6 @@ static void ath11k_ahb_power_down(struct ath11k_base *ab) rproc_shutdown(ab->tgt_rproc); } -int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab) -{ - int timeout; - - if (enable_cold_boot_cal == 0 || ab->qmi.cal_done) - 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_warn(ab, "Coldboot Calibration timed out\n"); - return -ETIMEDOUT; - } - - /* reset the firmware */ - ath11k_ahb_power_down(ab); - ath11k_ahb_power_up(ab); - ath11k_dbg(ab, ATH11K_DBG_AHB, "exit wait for cold boot done\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; @@ -861,10 +838,12 @@ static const struct ath11k_hif_ops ath11k_ahb_hif_ops = { static int ath11k_ahb_probe(struct platform_device *pdev) { struct ath11k_base *ab; + struct device *dev = &pdev->dev; const struct of_device_id *of_id; struct resource *mem_res; void __iomem *mem; int ret; + u32 hw_mode_id; of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev); if (!of_id) { @@ -904,6 +883,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev) ab->mem_len = resource_size(mem_res); ab->fixed_bdf_addr= true; ab->fixed_mem_region = true; + ab->enable_cold_boot_cal = enable_cold_boot_cal; platform_set_drvdata(pdev, ab); ret = ath11k_core_pre_init(ab); @@ -934,8 +914,15 @@ static int ath11k_ahb_probe(struct platform_device *pdev) goto err_ce_free; } + /* TODO + * below 4 lines can be removed once fw changes available + */ + of_property_read_u32(dev->of_node, "wlan-hw-mode", + &hw_mode_id); + if (hw_mode_id == WMI_HOST_HW_MODE_2G_PHYB) + ab->enable_cold_boot_cal = 0; - ath11k_ahb_fwreset_from_cold_boot(ab); + ath11k_qmi_fwreset_from_cold_boot(ab); return 0; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 8ea0b58..f3da827 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -832,6 +832,7 @@ struct ath11k_base { bool fixed_bdf_addr; bool m3_fw_support; + bool enable_cold_boot_cal; bool mhi_support; bool fixed_mem_region; bool use_register_windowing; diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 806e6e8..d9a4675 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -12,6 +12,7 @@ #include "mhi.h" #include "pci.h" #include "debug.h" +#include "qmi.h" static const u8 ath11k_tx_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { ATH11K_TX_RING_MASK_0, @@ -1215,6 +1216,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ab->static_window_map = true; ab->is_poll = true; ab->poll.lmac_poll = true; + ab->enable_cold_boot_cal = enable_cold_boot_cal; } else { ab->fixed_mem_region = false; } @@ -1268,6 +1270,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ath11k_err(ab, "failed to init core: %d\n", ret); goto err_free_irq; } + ath11k_qmi_fwreset_from_cold_boot(ab); return 0; err_free_irq: diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index be4ccea..f6d178b 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -6,6 +6,7 @@ #include "qmi.h" #include "core.h" #include "debug.h" +#include "hif.h" #include #include #include @@ -2420,7 +2421,10 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab) if (of_property_read_u32(dev->of_node, "qcom,caldb-addr", &addr)) ath11k_warn(ab, "qmi fail to get caldb-addr in dt\n"); - if (ab->fixed_bdf_addr) { + if (ab->fixed_bdf_addr && ab->enable_cold_boot_cal) { + ab->qmi.target_mem[idx].paddr = (u32)addr; + ab->qmi.target_mem[idx].vaddr = (u32)addr; + } else if (ab->fixed_bdf_addr) { ab->qmi.target_mem[idx].paddr = 0UL; ab->qmi.target_mem[idx].vaddr = 0UL; } else { @@ -2982,6 +2986,30 @@ int ath11k_qmi_firmware_start(struct ath11k_base *ab, return 0; } +int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab) +{ + int timeout; + + if (ab->enable_cold_boot_cal == 0 || ab->qmi.cal_done) + 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); + int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab) { int ret; @@ -3417,7 +3445,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) queue_work(ab->workqueue, &ab->restart_work); break; } - if (enable_cold_boot_cal && ab->qmi.cal_done == 0) { + if (ab->enable_cold_boot_cal && ab->qmi.cal_done == 0) { ath11k_qmi_process_coldboot_calibration(ab); } else { clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index e95c71b..9226328 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -51,7 +51,7 @@ #define ATH11K_FIRMWARE_MODE_OFF 4 #define ATH11K_QMI_TARGET_MEM_MODE_DEFAULT 0 -#define ATH11K_COLD_BOOT_FW_RESET_DELAY (40 * HZ) +#define ATH11K_COLD_BOOT_FW_RESET_DELAY (60 * HZ) struct ath11k_base; @@ -602,6 +602,7 @@ int wlfw_send_qdss_trace_config_download_req(struct ath11k_base *ab, int ath11k_send_qdss_trace_mode_req(struct ath11k_base *ab, enum wlfw_qdss_trace_mode_enum_v01 mode); +int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab); #endif -- 2.7.4