Skip to content

Commit bd4c8ba

Browse files
author
Bartosz Golaszewski
committed
power: sequencing: qcom-wcn: improve support for wcn6855
WCN6855 (also known as QCA6490) is similar to the already supported QCA6390 but takes in two more supplies so add a new vregs list for it. On sm8450-hdk it also requires a short assert of the xo-clk pin so add handling for it in a dedicated unit. As we now have a separate set of targets for this variant, store the pointer to the targets struct associated with a model in the device match data. Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://lore.kernel.org/r/20241018-sc8280xp-pwrseq-v6-2-8da8310d9564@linaro.org Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
1 parent f82bf3c commit bd4c8ba

1 file changed

Lines changed: 98 additions & 3 deletions

File tree

drivers/power/sequencing/pwrseq-qcom-wcn.c

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct pwrseq_qcom_wcn_pdata {
2222
size_t num_vregs;
2323
unsigned int pwup_delay_ms;
2424
unsigned int gpio_enable_delay_ms;
25+
const struct pwrseq_target_data **targets;
2526
};
2627

2728
struct pwrseq_qcom_wcn_ctx {
@@ -31,6 +32,7 @@ struct pwrseq_qcom_wcn_ctx {
3132
struct regulator_bulk_data *regs;
3233
struct gpio_desc *bt_gpio;
3334
struct gpio_desc *wlan_gpio;
35+
struct gpio_desc *xo_clk_gpio;
3436
struct clk *clk;
3537
unsigned long last_gpio_enable_jf;
3638
};
@@ -98,6 +100,33 @@ static const struct pwrseq_unit_data *pwrseq_qcom_wcn_unit_deps[] = {
98100
NULL
99101
};
100102

103+
static int pwrseq_qcom_wcn6855_clk_assert(struct pwrseq_device *pwrseq)
104+
{
105+
struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
106+
107+
if (!ctx->xo_clk_gpio)
108+
return 0;
109+
110+
msleep(1);
111+
112+
gpiod_set_value_cansleep(ctx->xo_clk_gpio, 1);
113+
usleep_range(100, 200);
114+
115+
return 0;
116+
}
117+
118+
static const struct pwrseq_unit_data pwrseq_qcom_wcn6855_xo_clk_assert = {
119+
.name = "xo-clk-assert",
120+
.enable = pwrseq_qcom_wcn6855_clk_assert,
121+
};
122+
123+
static const struct pwrseq_unit_data *pwrseq_qcom_wcn6855_unit_deps[] = {
124+
&pwrseq_qcom_wcn_vregs_unit_data,
125+
&pwrseq_qcom_wcn_clk_unit_data,
126+
&pwrseq_qcom_wcn6855_xo_clk_assert,
127+
NULL
128+
};
129+
101130
static int pwrseq_qcom_wcn_bt_enable(struct pwrseq_device *pwrseq)
102131
{
103132
struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
@@ -125,6 +154,13 @@ static const struct pwrseq_unit_data pwrseq_qcom_wcn_bt_unit_data = {
125154
.disable = pwrseq_qcom_wcn_bt_disable,
126155
};
127156

157+
static const struct pwrseq_unit_data pwrseq_qcom_wcn6855_bt_unit_data = {
158+
.name = "wlan-enable",
159+
.deps = pwrseq_qcom_wcn6855_unit_deps,
160+
.enable = pwrseq_qcom_wcn_bt_enable,
161+
.disable = pwrseq_qcom_wcn_bt_disable,
162+
};
163+
128164
static int pwrseq_qcom_wcn_wlan_enable(struct pwrseq_device *pwrseq)
129165
{
130166
struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
@@ -152,6 +188,13 @@ static const struct pwrseq_unit_data pwrseq_qcom_wcn_wlan_unit_data = {
152188
.disable = pwrseq_qcom_wcn_wlan_disable,
153189
};
154190

191+
static const struct pwrseq_unit_data pwrseq_qcom_wcn6855_wlan_unit_data = {
192+
.name = "wlan-enable",
193+
.deps = pwrseq_qcom_wcn6855_unit_deps,
194+
.enable = pwrseq_qcom_wcn_wlan_enable,
195+
.disable = pwrseq_qcom_wcn_wlan_disable,
196+
};
197+
155198
static int pwrseq_qcom_wcn_pwup_delay(struct pwrseq_device *pwrseq)
156199
{
157200
struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
@@ -162,6 +205,18 @@ static int pwrseq_qcom_wcn_pwup_delay(struct pwrseq_device *pwrseq)
162205
return 0;
163206
}
164207

208+
static int pwrseq_qcom_wcn6855_xo_clk_deassert(struct pwrseq_device *pwrseq)
209+
{
210+
struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
211+
212+
if (ctx->xo_clk_gpio) {
213+
usleep_range(2000, 5000);
214+
gpiod_set_value_cansleep(ctx->xo_clk_gpio, 0);
215+
}
216+
217+
return pwrseq_qcom_wcn_pwup_delay(pwrseq);
218+
}
219+
165220
static const struct pwrseq_target_data pwrseq_qcom_wcn_bt_target_data = {
166221
.name = "bluetooth",
167222
.unit = &pwrseq_qcom_wcn_bt_unit_data,
@@ -174,12 +229,30 @@ static const struct pwrseq_target_data pwrseq_qcom_wcn_wlan_target_data = {
174229
.post_enable = pwrseq_qcom_wcn_pwup_delay,
175230
};
176231

232+
static const struct pwrseq_target_data pwrseq_qcom_wcn6855_bt_target_data = {
233+
.name = "bluetooth",
234+
.unit = &pwrseq_qcom_wcn6855_bt_unit_data,
235+
.post_enable = pwrseq_qcom_wcn6855_xo_clk_deassert,
236+
};
237+
238+
static const struct pwrseq_target_data pwrseq_qcom_wcn6855_wlan_target_data = {
239+
.name = "wlan",
240+
.unit = &pwrseq_qcom_wcn6855_wlan_unit_data,
241+
.post_enable = pwrseq_qcom_wcn6855_xo_clk_deassert,
242+
};
243+
177244
static const struct pwrseq_target_data *pwrseq_qcom_wcn_targets[] = {
178245
&pwrseq_qcom_wcn_bt_target_data,
179246
&pwrseq_qcom_wcn_wlan_target_data,
180247
NULL
181248
};
182249

250+
static const struct pwrseq_target_data *pwrseq_qcom_wcn6855_targets[] = {
251+
&pwrseq_qcom_wcn6855_bt_target_data,
252+
&pwrseq_qcom_wcn6855_wlan_target_data,
253+
NULL
254+
};
255+
183256
static const char *const pwrseq_qca6390_vregs[] = {
184257
"vddio",
185258
"vddaon",
@@ -196,13 +269,28 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_qca6390_of_data = {
196269
.num_vregs = ARRAY_SIZE(pwrseq_qca6390_vregs),
197270
.pwup_delay_ms = 60,
198271
.gpio_enable_delay_ms = 100,
272+
.targets = pwrseq_qcom_wcn_targets,
273+
};
274+
275+
static const char *const pwrseq_wcn6855_vregs[] = {
276+
"vddio",
277+
"vddaon",
278+
"vddpmu",
279+
"vddpmumx",
280+
"vddpmucx",
281+
"vddrfa0p95",
282+
"vddrfa1p3",
283+
"vddrfa1p9",
284+
"vddpcie1p3",
285+
"vddpcie1p9",
199286
};
200287

201288
static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn6855_of_data = {
202-
.vregs = pwrseq_qca6390_vregs,
203-
.num_vregs = ARRAY_SIZE(pwrseq_qca6390_vregs),
289+
.vregs = pwrseq_wcn6855_vregs,
290+
.num_vregs = ARRAY_SIZE(pwrseq_wcn6855_vregs),
204291
.pwup_delay_ms = 50,
205292
.gpio_enable_delay_ms = 5,
293+
.targets = pwrseq_qcom_wcn6855_targets,
206294
};
207295

208296
static const char *const pwrseq_wcn7850_vregs[] = {
@@ -219,6 +307,7 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn7850_of_data = {
219307
.vregs = pwrseq_wcn7850_vregs,
220308
.num_vregs = ARRAY_SIZE(pwrseq_wcn7850_vregs),
221309
.pwup_delay_ms = 50,
310+
.targets = pwrseq_qcom_wcn_targets,
222311
};
223312

224313
static int pwrseq_qcom_wcn_match(struct pwrseq_device *pwrseq,
@@ -295,6 +384,12 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
295384
return dev_err_probe(dev, PTR_ERR(ctx->wlan_gpio),
296385
"Failed to get the WLAN enable GPIO\n");
297386

387+
ctx->xo_clk_gpio = devm_gpiod_get_optional(dev, "xo-clk",
388+
GPIOD_OUT_LOW);
389+
if (IS_ERR(ctx->xo_clk_gpio))
390+
return dev_err_probe(dev, PTR_ERR(ctx->xo_clk_gpio),
391+
"Failed to get the XO_CLK GPIO\n");
392+
298393
/*
299394
* Set direction to output but keep the current value in order to not
300395
* disable the WLAN module accidentally if it's already powered on.
@@ -313,7 +408,7 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
313408
config.owner = THIS_MODULE;
314409
config.drvdata = ctx;
315410
config.match = pwrseq_qcom_wcn_match;
316-
config.targets = pwrseq_qcom_wcn_targets;
411+
config.targets = ctx->pdata->targets;
317412

318413
ctx->pwrseq = devm_pwrseq_device_register(dev, &config);
319414
if (IS_ERR(ctx->pwrseq))

0 commit comments

Comments
 (0)