Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3dd9f66 authored by Manikandan Mohan's avatar Manikandan Mohan
Browse files

cnss2: Add support XO Clock selection leakage prevention



QCA6490 needs XO clock selection assert for 2ms to latch the clock
configuration before WLAN enable gpio assert. Update cnss platform
driver code to support this gpio toggling.

Change-Id: I31c48365e6b5cfbbeae849f1a9a9ee1dc44050cd
Signed-off-by: default avatarManikandan Mohan <manikand@codeaurora.org>
parent e53264fa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
+49 −1
Original line number Diff line number Diff line
@@ -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,