ath10k: Add support for NON BMI platform

WCN3990 does not uses BMI for fw download.
Refactor startup sequence to support non BMI
platform.

CRs-Fixed: 1114413
Change-Id: I1e1f5c3808decf319474629ab257ae908895f3a8
Signed-off-by: Govind Singh <govinds@codeaurora.org>
This commit is contained in:
Govind Singh 2017-01-09 17:11:20 +05:30 committed by Gerrit - the friendly Code Review server
parent 110e102fe3
commit 15f7852689
2 changed files with 115 additions and 93 deletions

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
* Copyright (c) 2011-2013, 2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -1797,44 +1797,46 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
lockdep_assert_held(&ar->conf_mutex);
clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
if (!ar->qmi.is_qmi) {
ar->running_fw = fw;
ar->running_fw = fw;
ath10k_bmi_start(ar);
ath10k_bmi_start(ar);
if (ath10k_init_configure_target(ar)) {
status = -EINVAL;
goto err;
}
status = ath10k_download_cal_data(ar);
if (status)
goto err;
/* Some of of qca988x solutions are having global reset issue
* during target initialization. Bypassing PLL setting before
* downloading firmware and letting the SoC run on REF_CLK is
* fixing the problem. Corresponding firmware change is also needed
* to set the clock source once the target is initialized.
*/
if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
ar->running_fw->fw_file.fw_features)) {
status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
if (status) {
ath10k_err(ar, "could not write to skip_clock_init: %d\n",
status);
if (ath10k_init_configure_target(ar)) {
status = -EINVAL;
goto err;
}
status = ath10k_download_cal_data(ar);
if (status)
goto err;
/* Some of of qca988x solutions are having global reset issue
* during target initialization. Bypassing PLL setting before
* downloading firmware and letting the SoC run on REF_CLK is
* fixing the problem. Corresponding firmware change is also
* needed to set the clock source once the target is
* initialized.
*/
if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
ar->running_fw->fw_file.fw_features)) {
status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
if (status) {
ath10k_err(ar, "skip_clock_init failed: %d\n",
status);
goto err;
}
}
status = ath10k_download_fw(ar);
if (status)
goto err;
status = ath10k_init_uart(ar);
if (status)
goto err;
}
status = ath10k_download_fw(ar);
if (status)
goto err;
status = ath10k_init_uart(ar);
if (status)
goto err;
ar->htc.htc_ops.target_send_suspend_complete =
ath10k_send_suspend_complete;
@ -1844,9 +1846,11 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
goto err;
}
status = ath10k_bmi_done(ar);
if (status)
goto err;
if (!ar->qmi.is_qmi) {
status = ath10k_bmi_done(ar);
if (status)
goto err;
}
status = ath10k_wmi_attach(ar);
if (status) {
@ -2076,59 +2080,63 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
return ret;
}
memset(&target_info, 0, sizeof(target_info));
ret = ath10k_bmi_get_target_info(ar, &target_info);
if (ret) {
ath10k_err(ar, "could not get target info (%d)\n", ret);
goto err_power_down;
if (!ar->qmi.is_qmi) {
memset(&target_info, 0, sizeof(target_info));
ret = ath10k_bmi_get_target_info(ar, &target_info);
if (ret) {
ath10k_err(ar, "could not get target info (%d)\n", ret);
goto err_power_down;
}
ar->target_version = target_info.version;
ar->hw->wiphy->hw_version = target_info.version;
ret = ath10k_init_hw_params(ar);
if (ret) {
ath10k_err(ar, "could not get hw params (%d)\n", ret);
goto err_power_down;
}
ret = ath10k_core_fetch_firmware_files(ar);
if (ret) {
ath10k_err(ar, "could not fetch firmware files (%d)\n",
ret);
goto err_power_down;
}
BUILD_BUG_ON(sizeof(ar->hw->wiphy->fw_version) !=
sizeof(ar->normal_mode_fw.fw_file.fw_version));
memcpy(ar->hw->wiphy->fw_version,
ar->normal_mode_fw.fw_file.fw_version,
sizeof(ar->hw->wiphy->fw_version));
ath10k_debug_print_hwfw_info(ar);
ret = ath10k_core_pre_cal_download(ar);
if (ret) {
/* pre calibration data download is not necessary
* for all the chipsets. Ignore failures and continue.
*/
ath10k_dbg(ar, ATH10K_DBG_BOOT,
"could not load pre cal data: %d\n", ret);
}
ret = ath10k_core_get_board_id_from_otp(ar);
if (ret && ret != -EOPNOTSUPP) {
ath10k_err(ar, "failed to get board id from otp: %d\n",
ret);
goto err_free_firmware_files;
}
ret = ath10k_core_fetch_board_file(ar);
if (ret) {
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
goto err_free_firmware_files;
}
ath10k_debug_print_board_info(ar);
}
ar->target_version = target_info.version;
ar->hw->wiphy->hw_version = target_info.version;
ret = ath10k_init_hw_params(ar);
if (ret) {
ath10k_err(ar, "could not get hw params (%d)\n", ret);
goto err_power_down;
}
ret = ath10k_core_fetch_firmware_files(ar);
if (ret) {
ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
goto err_power_down;
}
BUILD_BUG_ON(sizeof(ar->hw->wiphy->fw_version) !=
sizeof(ar->normal_mode_fw.fw_file.fw_version));
memcpy(ar->hw->wiphy->fw_version, ar->normal_mode_fw.fw_file.fw_version,
sizeof(ar->hw->wiphy->fw_version));
ath10k_debug_print_hwfw_info(ar);
ret = ath10k_core_pre_cal_download(ar);
if (ret) {
/* pre calibration data download is not necessary
* for all the chipsets. Ignore failures and continue.
*/
ath10k_dbg(ar, ATH10K_DBG_BOOT,
"could not load pre cal data: %d\n", ret);
}
ret = ath10k_core_get_board_id_from_otp(ar);
if (ret && ret != -EOPNOTSUPP) {
ath10k_err(ar, "failed to get board id from otp: %d\n",
ret);
goto err_free_firmware_files;
}
ret = ath10k_core_fetch_board_file(ar);
if (ret) {
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
goto err_free_firmware_files;
}
ath10k_debug_print_board_info(ar);
ret = ath10k_core_init_firmware_features(ar);
if (ret) {
ath10k_err(ar, "fatal problem with firmware features: %d\n",
@ -2136,11 +2144,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_free_firmware_files;
}
ret = ath10k_swap_code_seg_init(ar, &ar->normal_mode_fw.fw_file);
if (ret) {
ath10k_err(ar, "failed to initialize code swap segment: %d\n",
ret);
goto err_free_firmware_files;
if (!ar->qmi.is_qmi) {
ret = ath10k_swap_code_seg_init(ar,
&ar->normal_mode_fw.fw_file);
if (ret) {
ath10k_err(ar, "failed to init code swap segment: %d\n",
ret);
goto err_free_firmware_files;
}
}
mutex_lock(&ar->conf_mutex);
@ -2309,6 +2320,11 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
ar->regs = &qca4019_regs;
ar->hw_values = &qca4019_values;
break;
case ATH10K_HW_WCN3990:
ar->regs = &wcn3990_regs;
ar->hw_values = &wcn3990_values;
ar->qmi.is_qmi = true;
break;
default:
ath10k_err(ar, "unsupported core hardware revision %d\n",
hw_rev);

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
* Copyright (c) 2011-2013, 2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -138,6 +138,11 @@ struct ath10k_bmi {
bool done_sent;
};
struct ath10k_qmi {
bool fw_ready;
bool is_qmi;
};
struct ath10k_mem_chunk {
void *vaddr;
dma_addr_t paddr;
@ -736,6 +741,7 @@ struct ath10k {
const struct ath10k_hw_regs *regs;
const struct ath10k_hw_values *hw_values;
struct ath10k_bmi bmi;
struct ath10k_qmi qmi;
struct ath10k_wmi wmi;
struct ath10k_htc htc;
struct ath10k_htt htt;