.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | | - * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 and |
---|
6 | | - * only version 2 as published by the Free Software Foundation. |
---|
7 | | - * |
---|
8 | | - * This program is distributed in the hope that it will be useful, |
---|
9 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
10 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
11 | | - * GNU General Public License for more details. |
---|
| 3 | + * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved. |
---|
12 | 4 | */ |
---|
13 | 5 | |
---|
14 | 6 | #include <linux/bitops.h> |
---|
15 | 7 | #include <linux/delay.h> |
---|
16 | 8 | #include <linux/err.h> |
---|
| 9 | +#include <linux/export.h> |
---|
17 | 10 | #include <linux/jiffies.h> |
---|
18 | 11 | #include <linux/kernel.h> |
---|
19 | 12 | #include <linux/ktime.h> |
---|
20 | 13 | #include <linux/pm_domain.h> |
---|
21 | 14 | #include <linux/regmap.h> |
---|
| 15 | +#include <linux/regulator/consumer.h> |
---|
22 | 16 | #include <linux/reset-controller.h> |
---|
23 | 17 | #include <linux/slab.h> |
---|
24 | 18 | #include "gdsc.h" |
---|
.. | .. |
---|
36 | 30 | /* CFG_GDSCR */ |
---|
37 | 31 | #define GDSC_POWER_UP_COMPLETE BIT(16) |
---|
38 | 32 | #define GDSC_POWER_DOWN_COMPLETE BIT(15) |
---|
| 33 | +#define GDSC_RETAIN_FF_ENABLE BIT(11) |
---|
39 | 34 | #define CFG_GDSCR_OFFSET 0x4 |
---|
40 | 35 | |
---|
41 | 36 | /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ |
---|
42 | | -#define EN_REST_WAIT_VAL (0x2 << 20) |
---|
43 | | -#define EN_FEW_WAIT_VAL (0x8 << 16) |
---|
44 | | -#define CLK_DIS_WAIT_VAL (0x2 << 12) |
---|
| 37 | +#define EN_REST_WAIT_VAL 0x2 |
---|
| 38 | +#define EN_FEW_WAIT_VAL 0x8 |
---|
| 39 | +#define CLK_DIS_WAIT_VAL 0x2 |
---|
| 40 | + |
---|
| 41 | +/* Transition delay shifts */ |
---|
| 42 | +#define EN_REST_WAIT_SHIFT 20 |
---|
| 43 | +#define EN_FEW_WAIT_SHIFT 16 |
---|
| 44 | +#define CLK_DIS_WAIT_SHIFT 12 |
---|
45 | 45 | |
---|
46 | 46 | #define RETAIN_MEM BIT(14) |
---|
47 | 47 | #define RETAIN_PERIPH BIT(13) |
---|
.. | .. |
---|
120 | 120 | int ret; |
---|
121 | 121 | u32 val = (status == GDSC_ON) ? 0 : SW_COLLAPSE_MASK; |
---|
122 | 122 | |
---|
| 123 | + if (status == GDSC_ON && sc->rsupply) { |
---|
| 124 | + ret = regulator_enable(sc->rsupply); |
---|
| 125 | + if (ret < 0) |
---|
| 126 | + return ret; |
---|
| 127 | + } |
---|
| 128 | + |
---|
123 | 129 | ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val); |
---|
124 | 130 | if (ret) |
---|
125 | 131 | return ret; |
---|
.. | .. |
---|
149 | 155 | udelay(1); |
---|
150 | 156 | } |
---|
151 | 157 | |
---|
152 | | - return gdsc_poll_status(sc, status); |
---|
| 158 | + ret = gdsc_poll_status(sc, status); |
---|
| 159 | + WARN(ret, "%s status stuck at 'o%s'", sc->pd.name, status ? "ff" : "n"); |
---|
| 160 | + |
---|
| 161 | + if (!ret && status == GDSC_OFF && sc->rsupply) { |
---|
| 162 | + ret = regulator_disable(sc->rsupply); |
---|
| 163 | + if (ret < 0) |
---|
| 164 | + return ret; |
---|
| 165 | + } |
---|
| 166 | + |
---|
| 167 | + return ret; |
---|
153 | 168 | } |
---|
154 | 169 | |
---|
155 | 170 | static inline int gdsc_deassert_reset(struct gdsc *sc) |
---|
.. | .. |
---|
173 | 188 | static inline void gdsc_force_mem_on(struct gdsc *sc) |
---|
174 | 189 | { |
---|
175 | 190 | int i; |
---|
176 | | - u32 mask = RETAIN_MEM | RETAIN_PERIPH; |
---|
| 191 | + u32 mask = RETAIN_MEM; |
---|
| 192 | + |
---|
| 193 | + if (!(sc->flags & NO_RET_PERIPH)) |
---|
| 194 | + mask |= RETAIN_PERIPH; |
---|
177 | 195 | |
---|
178 | 196 | for (i = 0; i < sc->cxc_count; i++) |
---|
179 | 197 | regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask); |
---|
.. | .. |
---|
182 | 200 | static inline void gdsc_clear_mem_on(struct gdsc *sc) |
---|
183 | 201 | { |
---|
184 | 202 | int i; |
---|
185 | | - u32 mask = RETAIN_MEM | RETAIN_PERIPH; |
---|
| 203 | + u32 mask = RETAIN_MEM; |
---|
| 204 | + |
---|
| 205 | + if (!(sc->flags & NO_RET_PERIPH)) |
---|
| 206 | + mask |= RETAIN_PERIPH; |
---|
186 | 207 | |
---|
187 | 208 | for (i = 0; i < sc->cxc_count; i++) |
---|
188 | 209 | regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0); |
---|
.. | .. |
---|
208 | 229 | regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, |
---|
209 | 230 | GMEM_RESET_MASK, 0); |
---|
210 | 231 | } |
---|
| 232 | + |
---|
| 233 | +static void gdsc_retain_ff_on(struct gdsc *sc) |
---|
| 234 | +{ |
---|
| 235 | + u32 mask = GDSC_RETAIN_FF_ENABLE; |
---|
| 236 | + |
---|
| 237 | + regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); |
---|
| 238 | +} |
---|
| 239 | + |
---|
211 | 240 | static int gdsc_enable(struct generic_pm_domain *domain) |
---|
212 | 241 | { |
---|
213 | 242 | struct gdsc *sc = domain_to_gdsc(domain); |
---|
.. | .. |
---|
259 | 288 | */ |
---|
260 | 289 | udelay(1); |
---|
261 | 290 | } |
---|
| 291 | + |
---|
| 292 | + if (sc->flags & RETAIN_FF_ENABLE) |
---|
| 293 | + gdsc_retain_ff_on(sc); |
---|
262 | 294 | |
---|
263 | 295 | return 0; |
---|
264 | 296 | } |
---|
.. | .. |
---|
314 | 346 | */ |
---|
315 | 347 | mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK | |
---|
316 | 348 | EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK; |
---|
317 | | - val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL; |
---|
| 349 | + |
---|
| 350 | + if (!sc->en_rest_wait_val) |
---|
| 351 | + sc->en_rest_wait_val = EN_REST_WAIT_VAL; |
---|
| 352 | + if (!sc->en_few_wait_val) |
---|
| 353 | + sc->en_few_wait_val = EN_FEW_WAIT_VAL; |
---|
| 354 | + if (!sc->clk_dis_wait_val) |
---|
| 355 | + sc->clk_dis_wait_val = CLK_DIS_WAIT_VAL; |
---|
| 356 | + |
---|
| 357 | + val = sc->en_rest_wait_val << EN_REST_WAIT_SHIFT | |
---|
| 358 | + sc->en_few_wait_val << EN_FEW_WAIT_SHIFT | |
---|
| 359 | + sc->clk_dis_wait_val << CLK_DIS_WAIT_SHIFT; |
---|
| 360 | + |
---|
318 | 361 | ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val); |
---|
319 | 362 | if (ret) |
---|
320 | 363 | return ret; |
---|
.. | .. |
---|
330 | 373 | if (on < 0) |
---|
331 | 374 | return on; |
---|
332 | 375 | |
---|
333 | | - /* |
---|
334 | | - * Votable GDSCs can be ON due to Vote from other masters. |
---|
335 | | - * If a Votable GDSC is ON, make sure we have a Vote. |
---|
336 | | - */ |
---|
337 | | - if ((sc->flags & VOTABLE) && on) |
---|
338 | | - gdsc_enable(&sc->pd); |
---|
| 376 | + if (on) { |
---|
| 377 | + /* The regulator must be on, sync the kernel state */ |
---|
| 378 | + if (sc->rsupply) { |
---|
| 379 | + ret = regulator_enable(sc->rsupply); |
---|
| 380 | + if (ret < 0) |
---|
| 381 | + return ret; |
---|
| 382 | + } |
---|
339 | 383 | |
---|
340 | | - /* If ALWAYS_ON GDSCs are not ON, turn them ON */ |
---|
341 | | - if (sc->flags & ALWAYS_ON) { |
---|
342 | | - if (!on) |
---|
343 | | - gdsc_enable(&sc->pd); |
---|
| 384 | + /* |
---|
| 385 | + * Votable GDSCs can be ON due to Vote from other masters. |
---|
| 386 | + * If a Votable GDSC is ON, make sure we have a Vote. |
---|
| 387 | + */ |
---|
| 388 | + if (sc->flags & VOTABLE) { |
---|
| 389 | + ret = regmap_update_bits(sc->regmap, sc->gdscr, |
---|
| 390 | + SW_COLLAPSE_MASK, val); |
---|
| 391 | + if (ret) |
---|
| 392 | + return ret; |
---|
| 393 | + } |
---|
| 394 | + |
---|
| 395 | + /* Turn on HW trigger mode if supported */ |
---|
| 396 | + if (sc->flags & HW_CTRL) { |
---|
| 397 | + ret = gdsc_hwctrl(sc, true); |
---|
| 398 | + if (ret < 0) |
---|
| 399 | + return ret; |
---|
| 400 | + } |
---|
| 401 | + |
---|
| 402 | + /* |
---|
| 403 | + * Make sure the retain bit is set if the GDSC is already on, |
---|
| 404 | + * otherwise we end up turning off the GDSC and destroying all |
---|
| 405 | + * the register contents that we thought we were saving. |
---|
| 406 | + */ |
---|
| 407 | + if (sc->flags & RETAIN_FF_ENABLE) |
---|
| 408 | + gdsc_retain_ff_on(sc); |
---|
| 409 | + } else if (sc->flags & ALWAYS_ON) { |
---|
| 410 | + /* If ALWAYS_ON GDSCs are not ON, turn them ON */ |
---|
| 411 | + gdsc_enable(&sc->pd); |
---|
344 | 412 | on = true; |
---|
345 | | - sc->pd.flags |= GENPD_FLAG_ALWAYS_ON; |
---|
346 | 413 | } |
---|
347 | 414 | |
---|
348 | 415 | if (on || (sc->pwrsts & PWRSTS_RET)) |
---|
.. | .. |
---|
350 | 417 | else |
---|
351 | 418 | gdsc_clear_mem_on(sc); |
---|
352 | 419 | |
---|
353 | | - sc->pd.power_off = gdsc_disable; |
---|
354 | | - sc->pd.power_on = gdsc_enable; |
---|
| 420 | + if (sc->flags & ALWAYS_ON) |
---|
| 421 | + sc->pd.flags |= GENPD_FLAG_ALWAYS_ON; |
---|
| 422 | + if (!sc->pd.power_off) |
---|
| 423 | + sc->pd.power_off = gdsc_disable; |
---|
| 424 | + if (!sc->pd.power_on) |
---|
| 425 | + sc->pd.power_on = gdsc_enable; |
---|
355 | 426 | pm_genpd_init(&sc->pd, NULL, !on); |
---|
356 | 427 | |
---|
357 | 428 | return 0; |
---|
.. | .. |
---|
374 | 445 | GFP_KERNEL); |
---|
375 | 446 | if (!data->domains) |
---|
376 | 447 | return -ENOMEM; |
---|
| 448 | + |
---|
| 449 | + for (i = 0; i < num; i++) { |
---|
| 450 | + if (!scs[i] || !scs[i]->supply) |
---|
| 451 | + continue; |
---|
| 452 | + |
---|
| 453 | + scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply); |
---|
| 454 | + if (IS_ERR(scs[i]->rsupply)) |
---|
| 455 | + return PTR_ERR(scs[i]->rsupply); |
---|
| 456 | + } |
---|
377 | 457 | |
---|
378 | 458 | data->num_domains = num; |
---|
379 | 459 | for (i = 0; i < num; i++) { |
---|
.. | .. |
---|
414 | 494 | } |
---|
415 | 495 | of_genpd_del_provider(dev->of_node); |
---|
416 | 496 | } |
---|
| 497 | + |
---|
| 498 | +/* |
---|
| 499 | + * On SDM845+ the GPU GX domain is *almost* entirely controlled by the GMU |
---|
| 500 | + * running in the CX domain so the CPU doesn't need to know anything about the |
---|
| 501 | + * GX domain EXCEPT.... |
---|
| 502 | + * |
---|
| 503 | + * Hardware constraints dictate that the GX be powered down before the CX. If |
---|
| 504 | + * the GMU crashes it could leave the GX on. In order to successfully bring back |
---|
| 505 | + * the device the CPU needs to disable the GX headswitch. There being no sane |
---|
| 506 | + * way to reach in and touch that register from deep inside the GPU driver we |
---|
| 507 | + * need to set up the infrastructure to be able to ensure that the GPU can |
---|
| 508 | + * ensure that the GX is off during this super special case. We do this by |
---|
| 509 | + * defining a GX gdsc with a dummy enable function and a "default" disable |
---|
| 510 | + * function. |
---|
| 511 | + * |
---|
| 512 | + * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU |
---|
| 513 | + * driver. During power up, nothing will happen from the CPU (and the GMU will |
---|
| 514 | + * power up normally but during power down this will ensure that the GX domain |
---|
| 515 | + * is *really* off - this gives us a semi standard way of doing what we need. |
---|
| 516 | + */ |
---|
| 517 | +int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain) |
---|
| 518 | +{ |
---|
| 519 | + /* Do nothing but give genpd the impression that we were successful */ |
---|
| 520 | + return 0; |
---|
| 521 | +} |
---|
| 522 | +EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable); |
---|