|
10 | 10 | * http://www.gnu.org/copyleft/gpl.html
|
11 | 11 | */
|
12 | 12 |
|
13 |
| -#include <linux/clk.h> |
14 |
| -#include <linux/delay.h> |
15 | 13 | #include <linux/io.h>
|
16 | 14 | #include <linux/irq.h>
|
17 | 15 | #include <linux/irqchip.h>
|
18 | 16 | #include <linux/of.h>
|
19 | 17 | #include <linux/of_address.h>
|
20 | 18 | #include <linux/of_irq.h>
|
21 |
| -#include <linux/platform_device.h> |
22 |
| -#include <linux/pm_domain.h> |
23 |
| -#include <linux/regulator/consumer.h> |
24 | 19 | #include <linux/irqchip/arm-gic.h>
|
25 | 20 | #include "common.h"
|
26 | 21 | #include "hardware.h"
|
27 | 22 |
|
28 |
| -#define GPC_CNTR 0x000 |
29 | 23 | #define GPC_IMR1 0x008
|
30 |
| -#define GPC_PGC_GPU_PDN 0x260 |
31 |
| -#define GPC_PGC_GPU_PUPSCR 0x264 |
32 |
| -#define GPC_PGC_GPU_PDNSCR 0x268 |
33 | 24 | #define GPC_PGC_CPU_PDN 0x2a0
|
34 | 25 | #define GPC_PGC_CPU_PUPSCR 0x2a4
|
35 | 26 | #define GPC_PGC_CPU_PDNSCR 0x2a8
|
|
39 | 30 | #define IMR_NUM 4
|
40 | 31 | #define GPC_MAX_IRQS (IMR_NUM * 32)
|
41 | 32 |
|
42 |
| -#define GPU_VPU_PUP_REQ BIT(1) |
43 |
| -#define GPU_VPU_PDN_REQ BIT(0) |
44 |
| - |
45 |
| -#define GPC_CLK_MAX 6 |
46 |
| - |
47 |
| -struct pu_domain { |
48 |
| - struct generic_pm_domain base; |
49 |
| - struct regulator *reg; |
50 |
| - struct clk *clk[GPC_CLK_MAX]; |
51 |
| - int num_clks; |
52 |
| -}; |
53 |
| - |
54 | 33 | static void __iomem *gpc_base;
|
55 | 34 | static u32 gpc_wake_irqs[IMR_NUM];
|
56 | 35 | static u32 gpc_saved_imrs[IMR_NUM];
|
@@ -296,199 +275,3 @@ void __init imx_gpc_check_dt(void)
|
296 | 275 | gpc_base = of_iomap(np, 0);
|
297 | 276 | }
|
298 | 277 | }
|
299 |
| - |
300 |
| -static void _imx6q_pm_pu_power_off(struct generic_pm_domain *genpd) |
301 |
| -{ |
302 |
| - int iso, iso2sw; |
303 |
| - u32 val; |
304 |
| - |
305 |
| - /* Read ISO and ISO2SW power down delays */ |
306 |
| - val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR); |
307 |
| - iso = val & 0x3f; |
308 |
| - iso2sw = (val >> 8) & 0x3f; |
309 |
| - |
310 |
| - /* Gate off PU domain when GPU/VPU when powered down */ |
311 |
| - writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN); |
312 |
| - |
313 |
| - /* Request GPC to power down GPU/VPU */ |
314 |
| - val = readl_relaxed(gpc_base + GPC_CNTR); |
315 |
| - val |= GPU_VPU_PDN_REQ; |
316 |
| - writel_relaxed(val, gpc_base + GPC_CNTR); |
317 |
| - |
318 |
| - /* Wait ISO + ISO2SW IPG clock cycles */ |
319 |
| - ndelay((iso + iso2sw) * 1000 / 66); |
320 |
| -} |
321 |
| - |
322 |
| -static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd) |
323 |
| -{ |
324 |
| - struct pu_domain *pu = container_of(genpd, struct pu_domain, base); |
325 |
| - |
326 |
| - _imx6q_pm_pu_power_off(genpd); |
327 |
| - |
328 |
| - if (pu->reg) |
329 |
| - regulator_disable(pu->reg); |
330 |
| - |
331 |
| - return 0; |
332 |
| -} |
333 |
| - |
334 |
| -static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd) |
335 |
| -{ |
336 |
| - struct pu_domain *pu = container_of(genpd, struct pu_domain, base); |
337 |
| - int i, ret, sw, sw2iso; |
338 |
| - u32 val; |
339 |
| - |
340 |
| - if (pu->reg) |
341 |
| - ret = regulator_enable(pu->reg); |
342 |
| - if (pu->reg && ret) { |
343 |
| - pr_err("%s: failed to enable regulator: %d\n", __func__, ret); |
344 |
| - return ret; |
345 |
| - } |
346 |
| - |
347 |
| - /* Enable reset clocks for all devices in the PU domain */ |
348 |
| - for (i = 0; i < pu->num_clks; i++) |
349 |
| - clk_prepare_enable(pu->clk[i]); |
350 |
| - |
351 |
| - /* Gate off PU domain when GPU/VPU when powered down */ |
352 |
| - writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN); |
353 |
| - |
354 |
| - /* Read ISO and ISO2SW power down delays */ |
355 |
| - val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR); |
356 |
| - sw = val & 0x3f; |
357 |
| - sw2iso = (val >> 8) & 0x3f; |
358 |
| - |
359 |
| - /* Request GPC to power up GPU/VPU */ |
360 |
| - val = readl_relaxed(gpc_base + GPC_CNTR); |
361 |
| - val |= GPU_VPU_PUP_REQ; |
362 |
| - writel_relaxed(val, gpc_base + GPC_CNTR); |
363 |
| - |
364 |
| - /* Wait ISO + ISO2SW IPG clock cycles */ |
365 |
| - ndelay((sw + sw2iso) * 1000 / 66); |
366 |
| - |
367 |
| - /* Disable reset clocks for all devices in the PU domain */ |
368 |
| - for (i = 0; i < pu->num_clks; i++) |
369 |
| - clk_disable_unprepare(pu->clk[i]); |
370 |
| - |
371 |
| - return 0; |
372 |
| -} |
373 |
| - |
374 |
| -static struct generic_pm_domain imx6q_arm_domain = { |
375 |
| - .name = "ARM", |
376 |
| -}; |
377 |
| - |
378 |
| -static struct pu_domain imx6q_pu_domain = { |
379 |
| - .base = { |
380 |
| - .name = "PU", |
381 |
| - .power_off = imx6q_pm_pu_power_off, |
382 |
| - .power_on = imx6q_pm_pu_power_on, |
383 |
| - }, |
384 |
| -}; |
385 |
| - |
386 |
| -static struct generic_pm_domain imx6sl_display_domain = { |
387 |
| - .name = "DISPLAY", |
388 |
| -}; |
389 |
| - |
390 |
| -static struct generic_pm_domain *imx_gpc_domains[] = { |
391 |
| - &imx6q_arm_domain, |
392 |
| - &imx6q_pu_domain.base, |
393 |
| - &imx6sl_display_domain, |
394 |
| -}; |
395 |
| - |
396 |
| -static struct genpd_onecell_data imx_gpc_onecell_data = { |
397 |
| - .domains = imx_gpc_domains, |
398 |
| - .num_domains = ARRAY_SIZE(imx_gpc_domains), |
399 |
| -}; |
400 |
| - |
401 |
| -static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg) |
402 |
| -{ |
403 |
| - struct clk *clk; |
404 |
| - int i, ret; |
405 |
| - |
406 |
| - imx6q_pu_domain.reg = pu_reg; |
407 |
| - |
408 |
| - for (i = 0; ; i++) { |
409 |
| - clk = of_clk_get(dev->of_node, i); |
410 |
| - if (IS_ERR(clk)) |
411 |
| - break; |
412 |
| - if (i >= GPC_CLK_MAX) { |
413 |
| - dev_err(dev, "more than %d clocks\n", GPC_CLK_MAX); |
414 |
| - goto clk_err; |
415 |
| - } |
416 |
| - imx6q_pu_domain.clk[i] = clk; |
417 |
| - } |
418 |
| - imx6q_pu_domain.num_clks = i; |
419 |
| - |
420 |
| - /* Enable power always in case bootloader disabled it. */ |
421 |
| - imx6q_pm_pu_power_on(&imx6q_pu_domain.base); |
422 |
| - |
423 |
| - if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) |
424 |
| - return 0; |
425 |
| - |
426 |
| - imx6q_pu_domain.base.states = devm_kzalloc(dev, |
427 |
| - sizeof(*imx6q_pu_domain.base.states), |
428 |
| - GFP_KERNEL); |
429 |
| - if (!imx6q_pu_domain.base.states) |
430 |
| - return -ENOMEM; |
431 |
| - |
432 |
| - imx6q_pu_domain.base.states[0].power_off_latency_ns = 25000; |
433 |
| - imx6q_pu_domain.base.states[0].power_on_latency_ns = 2000000; |
434 |
| - imx6q_pu_domain.base.state_count = 1; |
435 |
| - |
436 |
| - for (i = 0; i < ARRAY_SIZE(imx_gpc_domains); i++) |
437 |
| - pm_genpd_init(imx_gpc_domains[i], NULL, false); |
438 |
| - |
439 |
| - ret = of_genpd_add_provider_onecell(dev->of_node, |
440 |
| - &imx_gpc_onecell_data); |
441 |
| - if (ret) |
442 |
| - goto power_off; |
443 |
| - |
444 |
| - return 0; |
445 |
| - |
446 |
| -power_off: |
447 |
| - imx6q_pm_pu_power_off(&imx6q_pu_domain.base); |
448 |
| -clk_err: |
449 |
| - while (i--) |
450 |
| - clk_put(imx6q_pu_domain.clk[i]); |
451 |
| - imx6q_pu_domain.reg = NULL; |
452 |
| - return -EINVAL; |
453 |
| -} |
454 |
| - |
455 |
| -static int imx_gpc_probe(struct platform_device *pdev) |
456 |
| -{ |
457 |
| - struct regulator *pu_reg; |
458 |
| - int ret; |
459 |
| - |
460 |
| - /* bail out if DT too old and doesn't provide the necessary info */ |
461 |
| - if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells")) |
462 |
| - return 0; |
463 |
| - |
464 |
| - pu_reg = devm_regulator_get_optional(&pdev->dev, "pu"); |
465 |
| - if (PTR_ERR(pu_reg) == -ENODEV) |
466 |
| - pu_reg = NULL; |
467 |
| - if (IS_ERR(pu_reg)) { |
468 |
| - ret = PTR_ERR(pu_reg); |
469 |
| - dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret); |
470 |
| - return ret; |
471 |
| - } |
472 |
| - |
473 |
| - return imx_gpc_genpd_init(&pdev->dev, pu_reg); |
474 |
| -} |
475 |
| - |
476 |
| -static const struct of_device_id imx_gpc_dt_ids[] = { |
477 |
| - { .compatible = "fsl,imx6q-gpc" }, |
478 |
| - { .compatible = "fsl,imx6sl-gpc" }, |
479 |
| - { } |
480 |
| -}; |
481 |
| - |
482 |
| -static struct platform_driver imx_gpc_driver = { |
483 |
| - .driver = { |
484 |
| - .name = "imx-gpc", |
485 |
| - .of_match_table = imx_gpc_dt_ids, |
486 |
| - }, |
487 |
| - .probe = imx_gpc_probe, |
488 |
| -}; |
489 |
| - |
490 |
| -static int __init imx_pgc_init(void) |
491 |
| -{ |
492 |
| - return platform_driver_register(&imx_gpc_driver); |
493 |
| -} |
494 |
| -subsys_initcall(imx_pgc_init); |
0 commit comments