Commit 5aabff05 authored by Toshi Kikuchi's avatar Toshi Kikuchi Committed by Kalle Valo

ath10k: read calibration data from Device Tree

This patch adds support for reading calibration data from Device Tree.
It looks for the calibration data in Device Tree if it can't find it
in a file. If there's no node in Device Tree, ath10k will try to find the
calibration data from OTP.

The node for the calibration data should be defined like this:

pci {
        pcie@0 {
                reg = <0 0 0 0 0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
                device_type = "pci";

                ath10k@0,0 {
                        reg = <0 0 0 0 0>;
                        device_type = "pci";
                        qcom,ath10k-calibration-data = [ 01 02 03 ... ];
                };
        };
};
Signed-off-by: default avatarToshi Kikuchi <toshik@chromium.org>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 488dad95
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/of.h>
#include "core.h" #include "core.h"
#include "mac.h" #include "mac.h"
...@@ -249,6 +250,63 @@ static int ath10k_download_cal_file(struct ath10k *ar) ...@@ -249,6 +250,63 @@ static int ath10k_download_cal_file(struct ath10k *ar)
return 0; return 0;
} }
static int ath10k_download_cal_dt(struct ath10k *ar)
{
struct device_node *node;
int data_len;
void *data;
int ret;
node = ar->dev->of_node;
if (!node)
/* Device Tree is optional, don't print any warnings if
* there's no node for ath10k.
*/
return -ENOENT;
if (!of_get_property(node, "qcom,ath10k-calibration-data",
&data_len)) {
/* The calibration data node is optional */
return -ENOENT;
}
if (data_len != QCA988X_CAL_DATA_LEN) {
ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
data_len);
ret = -EMSGSIZE;
goto out;
}
data = kmalloc(data_len, GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto out;
}
ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data",
data, data_len);
if (ret) {
ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
ret);
goto out_free;
}
ret = ath10k_download_board_data(ar, data, data_len);
if (ret) {
ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
ret);
goto out_free;
}
ret = 0;
out_free:
kfree(data);
out:
return ret;
}
static int ath10k_download_and_run_otp(struct ath10k *ar) static int ath10k_download_and_run_otp(struct ath10k *ar)
{ {
u32 result, address = ar->hw_params.patch_load_addr; u32 result, address = ar->hw_params.patch_load_addr;
...@@ -662,7 +720,17 @@ static int ath10k_download_cal_data(struct ath10k *ar) ...@@ -662,7 +720,17 @@ static int ath10k_download_cal_data(struct ath10k *ar)
} }
ath10k_dbg(ar, ATH10K_DBG_BOOT, ath10k_dbg(ar, ATH10K_DBG_BOOT,
"boot did not find a calibration file, try OTP next: %d\n", "boot did not find a calibration file, try DT next: %d\n",
ret);
ret = ath10k_download_cal_dt(ar);
if (ret == 0) {
ar->cal_mode = ATH10K_CAL_MODE_DT;
goto done;
}
ath10k_dbg(ar, ATH10K_DBG_BOOT,
"boot did not find DT entry, try OTP next: %d\n",
ret); ret);
ret = ath10k_download_and_run_otp(ar); ret = ath10k_download_and_run_otp(ar);
......
...@@ -401,6 +401,7 @@ enum ath10k_dev_flags { ...@@ -401,6 +401,7 @@ enum ath10k_dev_flags {
enum ath10k_cal_mode { enum ath10k_cal_mode {
ATH10K_CAL_MODE_FILE, ATH10K_CAL_MODE_FILE,
ATH10K_CAL_MODE_OTP, ATH10K_CAL_MODE_OTP,
ATH10K_CAL_MODE_DT,
}; };
static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
...@@ -410,6 +411,8 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) ...@@ -410,6 +411,8 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
return "file"; return "file";
case ATH10K_CAL_MODE_OTP: case ATH10K_CAL_MODE_OTP:
return "otp"; return "otp";
case ATH10K_CAL_MODE_DT:
return "dt";
} }
return "unknown"; return "unknown";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment