blob: 11c1565e271eb691c8917bfa8b9b3c55119be977 [file] [log] [blame]
Caesar Wanged6b9a52016-08-11 02:11:45 +08001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Caesar Wanged6b9a52016-08-11 02:11:45 +08005 */
6
7#include <plat_private.h>
8#include <pmu.h>
9#include <pwm.h>
10#include <soc.h>
11
12#define PWM0_IOMUX_PWM_EN (1 << 0)
13#define PWM1_IOMUX_PWM_EN (1 << 1)
14#define PWM2_IOMUX_PWM_EN (1 << 2)
15#define PWM3_IOMUX_PWM_EN (1 << 3)
16
17struct pwm_data_s {
18 uint32_t iomux_bitmask;
19 uint32_t enable_bitmask;
20};
21
22static struct pwm_data_s pwm_data;
23
24/*
25 * Disable the PWMs.
26 */
27void disable_pwms(void)
28{
29 uint32_t i, val;
30
31 pwm_data.iomux_bitmask = 0;
32
33 /* Save PWMs pinmux and change PWMs pinmux to GPIOs */
34 val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX);
35 if (((val >> GRF_GPIO4C2_IOMUX_SHIFT) &
36 GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C2_IOMUX_PWM) {
37 pwm_data.iomux_bitmask |= PWM0_IOMUX_PWM_EN;
38 val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
39 GRF_GPIO4C2_IOMUX_SHIFT);
40 mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
41 }
42
43 val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX);
44 if (((val >> GRF_GPIO4C6_IOMUX_SHIFT) &
45 GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C6_IOMUX_PWM) {
46 pwm_data.iomux_bitmask |= PWM1_IOMUX_PWM_EN;
47 val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
48 GRF_GPIO4C6_IOMUX_SHIFT);
49 mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
50 }
51
52 val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX);
53 if (((val >> PMUGRF_GPIO1C3_IOMUX_SHIFT) &
54 GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO1C3_IOMUX_PWM) {
55 pwm_data.iomux_bitmask |= PWM2_IOMUX_PWM_EN;
56 val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
57 PMUGRF_GPIO1C3_IOMUX_SHIFT);
58 mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val);
59 }
60
61 val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX);
62 if (((val >> PMUGRF_GPIO0A6_IOMUX_SHIFT) &
63 GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO0A6_IOMUX_PWM) {
64 pwm_data.iomux_bitmask |= PWM3_IOMUX_PWM_EN;
65 val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
66 PMUGRF_GPIO0A6_IOMUX_SHIFT);
67 mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val);
68 }
69
70 /* Disable the pwm channel */
71 pwm_data.enable_bitmask = 0;
72 for (i = 0; i < 4; i++) {
73 val = mmio_read_32(PWM_BASE + PWM_CTRL(i));
74 if ((val & PWM_ENABLE) != PWM_ENABLE)
75 continue;
76 pwm_data.enable_bitmask |= (1 << i);
77 mmio_write_32(PWM_BASE + PWM_CTRL(i), val & ~PWM_ENABLE);
78 }
79}
80
81/*
82 * Enable the PWMs.
83 */
84void enable_pwms(void)
85{
86 uint32_t i, val;
87
88 for (i = 0; i < 4; i++) {
89 val = mmio_read_32(PWM_BASE + PWM_CTRL(i));
90 if (!(pwm_data.enable_bitmask & (1 << i)))
91 continue;
92 mmio_write_32(PWM_BASE + PWM_CTRL(i), val | PWM_ENABLE);
93 }
94
95 /* Restore all IOMUXes */
96 if (pwm_data.iomux_bitmask & PWM3_IOMUX_PWM_EN) {
97 val = BITS_WITH_WMASK(PMUGRF_GPIO0A6_IOMUX_PWM,
98 GRF_IOMUX_2BIT_MASK,
99 PMUGRF_GPIO0A6_IOMUX_SHIFT);
100 mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val);
101 }
102
103 if (pwm_data.iomux_bitmask & PWM2_IOMUX_PWM_EN) {
104 val = BITS_WITH_WMASK(PMUGRF_GPIO1C3_IOMUX_PWM,
105 GRF_IOMUX_2BIT_MASK,
106 PMUGRF_GPIO1C3_IOMUX_SHIFT);
107 mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val);
108 }
109
110 if (pwm_data.iomux_bitmask & PWM1_IOMUX_PWM_EN) {
111 val = BITS_WITH_WMASK(GRF_GPIO4C6_IOMUX_PWM,
112 GRF_IOMUX_2BIT_MASK,
113 GRF_GPIO4C6_IOMUX_SHIFT);
114 mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
115 }
116
117 if (pwm_data.iomux_bitmask & PWM0_IOMUX_PWM_EN) {
118 val = BITS_WITH_WMASK(GRF_GPIO4C2_IOMUX_PWM,
119 GRF_IOMUX_2BIT_MASK,
120 GRF_GPIO4C2_IOMUX_SHIFT);
121 mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
122 }
123}