|
9 | 9 | #include <linux/clk-provider.h>
|
10 | 10 | #include <linux/delay.h>
|
11 | 11 | #include <linux/io.h>
|
| 12 | +#include <linux/iopoll.h> |
12 | 13 | #include <linux/of.h>
|
| 14 | + |
13 | 15 | #include <dt-bindings/clock/jz4780-cgu.h>
|
14 | 16 | #include "cgu.h"
|
15 | 17 | #include "pm.h"
|
16 | 18 |
|
17 | 19 | /* CGU register offsets */
|
18 | 20 | #define CGU_REG_CLOCKCONTROL 0x00
|
19 |
| -#define CGU_REG_PLLCONTROL 0x0c |
| 21 | +#define CGU_REG_LCR 0x04 |
20 | 22 | #define CGU_REG_APLL 0x10
|
21 | 23 | #define CGU_REG_MPLL 0x14
|
22 | 24 | #define CGU_REG_EPLL 0x18
|
|
46 | 48 | #define CGU_REG_CLOCKSTATUS 0xd4
|
47 | 49 |
|
48 | 50 | /* bits within the OPCR register */
|
49 |
| -#define OPCR_SPENDN0 (1 << 7) |
50 |
| -#define OPCR_SPENDN1 (1 << 6) |
| 51 | +#define OPCR_SPENDN0 BIT(7) |
| 52 | +#define OPCR_SPENDN1 BIT(6) |
51 | 53 |
|
52 | 54 | /* bits within the USBPCR register */
|
53 | 55 | #define USBPCR_USB_MODE BIT(31)
|
|
88 | 90 | #define USBVBFIL_IDDIGFIL_MASK (0xffff << USBVBFIL_IDDIGFIL_SHIFT)
|
89 | 91 | #define USBVBFIL_USBVBFIL_MASK (0xffff)
|
90 | 92 |
|
| 93 | +/* bits within the LCR register */ |
| 94 | +#define LCR_PD_SCPU BIT(31) |
| 95 | +#define LCR_SCPUS BIT(27) |
| 96 | + |
| 97 | +/* bits within the CLKGR1 register */ |
| 98 | +#define CLKGR1_CORE1 BIT(15) |
| 99 | + |
91 | 100 | static struct ingenic_cgu *cgu;
|
92 | 101 |
|
93 | 102 | static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
|
@@ -205,6 +214,42 @@ static const struct clk_ops jz4780_otg_phy_ops = {
|
205 | 214 | .set_rate = jz4780_otg_phy_set_rate,
|
206 | 215 | };
|
207 | 216 |
|
| 217 | +static int jz4780_core1_enable(struct clk_hw *hw) |
| 218 | +{ |
| 219 | + struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); |
| 220 | + struct ingenic_cgu *cgu = ingenic_clk->cgu; |
| 221 | + const unsigned int timeout = 5000; |
| 222 | + unsigned long flags; |
| 223 | + int retval; |
| 224 | + u32 lcr, clkgr1; |
| 225 | + |
| 226 | + spin_lock_irqsave(&cgu->lock, flags); |
| 227 | + |
| 228 | + lcr = readl(cgu->base + CGU_REG_LCR); |
| 229 | + lcr &= ~LCR_PD_SCPU; |
| 230 | + writel(lcr, cgu->base + CGU_REG_LCR); |
| 231 | + |
| 232 | + clkgr1 = readl(cgu->base + CGU_REG_CLKGR1); |
| 233 | + clkgr1 &= ~CLKGR1_CORE1; |
| 234 | + writel(clkgr1, cgu->base + CGU_REG_CLKGR1); |
| 235 | + |
| 236 | + spin_unlock_irqrestore(&cgu->lock, flags); |
| 237 | + |
| 238 | + /* wait for the CPU to be powered up */ |
| 239 | + retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr, |
| 240 | + !(lcr & LCR_SCPUS), 10, timeout); |
| 241 | + if (retval == -ETIMEDOUT) { |
| 242 | + pr_err("%s: Wait for power up core1 timeout\n", __func__); |
| 243 | + return retval; |
| 244 | + } |
| 245 | + |
| 246 | + return 0; |
| 247 | +} |
| 248 | + |
| 249 | +static const struct clk_ops jz4780_core1_ops = { |
| 250 | + .enable = jz4780_core1_enable, |
| 251 | +}; |
| 252 | + |
208 | 253 | static const s8 pll_od_encoding[16] = {
|
209 | 254 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
|
210 | 255 | 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
|
@@ -699,9 +744,9 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
|
699 | 744 | },
|
700 | 745 |
|
701 | 746 | [JZ4780_CLK_CORE1] = {
|
702 |
| - "core1", CGU_CLK_GATE, |
| 747 | + "core1", CGU_CLK_CUSTOM, |
703 | 748 | .parents = { JZ4780_CLK_CPU, -1, -1, -1 },
|
704 |
| - .gate = { CGU_REG_CLKGR1, 15 }, |
| 749 | + .custom = { &jz4780_core1_ops }, |
705 | 750 | },
|
706 | 751 |
|
707 | 752 | };
|
|
0 commit comments