Merge "cnss2: Add support XO Clock selection leakage prevention"

This commit is contained in:
qctecmdr 2021-01-21 04:59:13 -08:00 • committed by Gerrit - the friendly Code Review server
commit 31b7bc4b6d
2 changed files with 50 additions and 1 deletions

View file

@ -90,6 +90,7 @@ struct cnss_pinctrl_info {
struct pinctrl_state *wlan_en_active;
struct pinctrl_state *wlan_en_sleep;
int bt_en_gpio;
int xo_clk_gpio; /*qca6490 only */
};
#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)

View file

@ -43,6 +43,7 @@ static struct cnss_clk_cfg cnss_clk_list[] = {
#define BOOTSTRAP_ACTIVE "bootstrap_active"
#define WLAN_EN_GPIO "wlan-en-gpio"
#define BT_EN_GPIO "qcom,bt-en-gpio"
#define XO_CLK_GPIO "qcom,xo-clk-gpio"
#define WLAN_EN_ACTIVE "wlan_en_active"
#define WLAN_EN_SLEEP "wlan_en_sleep"
@ -711,11 +712,57 @@ int cnss_get_pinctrl(struct cnss_plat_data *plat_priv)
pinctrl_info->bt_en_gpio = -EINVAL;
}
/* Added for QCA6490 to minimize XO CLK selection leakage prevention */
if (of_find_property(dev->of_node, XO_CLK_GPIO, NULL)) {
pinctrl_info->xo_clk_gpio = of_get_named_gpio(dev->of_node,
XO_CLK_GPIO, 0);
cnss_pr_dbg("QCA6490 XO_CLK GPIO: %d\n",
pinctrl_info->xo_clk_gpio);
} else {
pinctrl_info->xo_clk_gpio = -EINVAL;
}
return 0;
out:
return ret;
}
#define CNSS_XO_CLK_RETRY_COUNT_MAX 5
static void cnss_set_xo_clk_gpio_state(struct cnss_plat_data *plat_priv,
bool enable)
{
int xo_clk_gpio = plat_priv->pinctrl_info.xo_clk_gpio, retry = 0, ret;
if (xo_clk_gpio < 0 || plat_priv->device_id != QCA6490_DEVICE_ID)
return;
retry_gpio_req:
ret = gpio_request(xo_clk_gpio, "XO_CLK_GPIO");
if (ret) {
if (retry++ < CNSS_XO_CLK_RETRY_COUNT_MAX) {
/* wait for ~(10 - 20) ms */
usleep_range(10000, 20000);
goto retry_gpio_req;
}
}
if (ret) {
cnss_pr_err("QCA6490 XO CLK Gpio request failed\n");
return;
}
if (enable) {
gpio_direction_output(xo_clk_gpio, 1);
/*XO CLK must be asserted for some time before WLAN_EN */
usleep_range(100, 200);
} else {
/* Assert XO CLK ~(2-5)ms before off for valid latch in HW */
usleep_range(2000, 5000);
gpio_direction_output(xo_clk_gpio, 0);
}
gpio_free(xo_clk_gpio);
}
static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
bool state)
{
@ -742,7 +789,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
}
udelay(BOOTSTRAP_DELAY);
}
cnss_set_xo_clk_gpio_state(plat_priv, true);
if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_active)) {
ret = pinctrl_select_state
(pinctrl_info->pinctrl,
@ -754,6 +801,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
}
udelay(WLAN_ENABLE_DELAY);
}
cnss_set_xo_clk_gpio_state(plat_priv, false);
} else {
if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_sleep)) {
ret = pinctrl_select_state(pinctrl_info->pinctrl,