]>
Commit | Line | Data |
---|---|---|
682e09ff MY |
1 | /* |
2 | * Copyright (C) 2016 Socionext Inc. | |
3 | * Author: Masahiro Yamada <yamada.masahiro@socionext.com> | |
4 | * | |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
7f8e7539 | 8 | #include <linux/bitfield.h> |
682e09ff | 9 | #include <linux/bitops.h> |
d9a70368 | 10 | #include <linux/delay.h> |
f2ce50b2 | 11 | #include <linux/kernel.h> |
d9a70368 | 12 | #include <linux/errno.h> |
682e09ff MY |
13 | #include <linux/io.h> |
14 | #include <linux/sizes.h> | |
15 | ||
16 | #include "pll.h" | |
17 | ||
18 | /* PLL type: SSC */ | |
19 | #define SC_PLLCTRL_SSC_DK_MASK GENMASK(14, 0) | |
20 | #define SC_PLLCTRL_SSC_EN BIT(31) | |
21 | #define SC_PLLCTRL2_NRSTDS BIT(28) | |
22 | #define SC_PLLCTRL2_SSC_JK_MASK GENMASK(26, 0) | |
bc647958 | 23 | #define SC_PLLCTRL3_REGI_MASK GENMASK(19, 16) |
682e09ff MY |
24 | |
25 | /* PLL type: VPLL27 */ | |
26 | #define SC_VPLL27CTRL_WP BIT(0) | |
27 | #define SC_VPLL27CTRL3_K_LD BIT(28) | |
28 | ||
29 | /* PLL type: DSPLL */ | |
30 | #define SC_DSPLLCTRL2_K_LD BIT(28) | |
31 | ||
32 | int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq, | |
33 | unsigned int ssc_rate, unsigned int divn) | |
34 | { | |
35 | void __iomem *base; | |
36 | u32 tmp; | |
37 | ||
38 | base = ioremap(reg_base, SZ_16); | |
39 | if (!base) | |
40 | return -ENOMEM; | |
41 | ||
42 | if (freq != UNIPHIER_PLL_FREQ_DEFAULT) { | |
43 | tmp = readl(base); /* SSCPLLCTRL */ | |
44 | tmp &= ~SC_PLLCTRL_SSC_DK_MASK; | |
7f8e7539 MY |
45 | tmp |= FIELD_PREP(SC_PLLCTRL_SSC_DK_MASK, |
46 | DIV_ROUND_CLOSEST(487UL * freq * ssc_rate, | |
47 | divn * 512)); | |
682e09ff MY |
48 | writel(tmp, base); |
49 | ||
50 | tmp = readl(base + 4); | |
51 | tmp &= ~SC_PLLCTRL2_SSC_JK_MASK; | |
7f8e7539 MY |
52 | tmp |= FIELD_PREP(SC_PLLCTRL2_SSC_JK_MASK, |
53 | DIV_ROUND_CLOSEST(21431887UL * freq, | |
54 | divn * 512)); | |
c30c44e7 | 55 | writel(tmp, base + 4); |
682e09ff MY |
56 | |
57 | udelay(50); | |
58 | } | |
59 | ||
60 | tmp = readl(base + 4); /* SSCPLLCTRL2 */ | |
61 | tmp |= SC_PLLCTRL2_NRSTDS; | |
62 | writel(tmp, base + 4); | |
63 | ||
64 | iounmap(base); | |
65 | ||
66 | return 0; | |
67 | } | |
68 | ||
69 | int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base) | |
70 | { | |
71 | void __iomem *base; | |
72 | u32 tmp; | |
73 | ||
74 | base = ioremap(reg_base, SZ_16); | |
75 | if (!base) | |
76 | return -ENOMEM; | |
77 | ||
682e09ff MY |
78 | tmp = readl(base); /* SSCPLLCTRL */ |
79 | tmp |= SC_PLLCTRL_SSC_EN; | |
80 | writel(tmp, base); | |
81 | ||
82 | iounmap(base); | |
83 | ||
84 | return 0; | |
85 | } | |
86 | ||
bc647958 MY |
87 | int uniphier_ld20_sscpll_set_regi(unsigned long reg_base, unsigned regi) |
88 | { | |
89 | void __iomem *base; | |
90 | u32 tmp; | |
91 | ||
92 | base = ioremap(reg_base, SZ_16); | |
93 | if (!base) | |
94 | return -ENOMEM; | |
95 | ||
4013bbb1 | 96 | tmp = readl(base + 8); /* SSCPLLCTRL3 */ |
bc647958 | 97 | tmp &= ~SC_PLLCTRL3_REGI_MASK; |
7f8e7539 | 98 | tmp |= FIELD_PREP(SC_PLLCTRL3_REGI_MASK, regi); |
bc647958 MY |
99 | writel(tmp, base + 8); |
100 | ||
101 | iounmap(base); | |
102 | ||
103 | return 0; | |
104 | } | |
105 | ||
682e09ff MY |
106 | int uniphier_ld20_vpll27_init(unsigned long reg_base) |
107 | { | |
108 | void __iomem *base; | |
109 | u32 tmp; | |
110 | ||
111 | base = ioremap(reg_base, SZ_16); | |
112 | if (!base) | |
113 | return -ENOMEM; | |
114 | ||
115 | tmp = readl(base); /* VPLL27CTRL */ | |
116 | tmp |= SC_VPLL27CTRL_WP; /* write protect off */ | |
117 | writel(tmp, base); | |
118 | ||
119 | tmp = readl(base + 8); /* VPLL27CTRL3 */ | |
120 | tmp |= SC_VPLL27CTRL3_K_LD; | |
121 | writel(tmp, base + 8); | |
122 | ||
123 | tmp = readl(base); /* VPLL27CTRL */ | |
124 | tmp &= ~SC_VPLL27CTRL_WP; /* write protect on */ | |
125 | writel(tmp, base); | |
126 | ||
127 | iounmap(base); | |
128 | ||
129 | return 0; | |
130 | } | |
131 | ||
132 | int uniphier_ld20_dspll_init(unsigned long reg_base) | |
133 | { | |
134 | void __iomem *base; | |
135 | u32 tmp; | |
136 | ||
137 | base = ioremap(reg_base, SZ_16); | |
138 | if (!base) | |
139 | return -ENOMEM; | |
140 | ||
4013bbb1 | 141 | tmp = readl(base + 4); /* DSPLLCTRL2 */ |
682e09ff | 142 | tmp |= SC_DSPLLCTRL2_K_LD; |
4013bbb1 | 143 | writel(tmp, base + 4); |
682e09ff MY |
144 | |
145 | iounmap(base); | |
146 | ||
147 | return 0; | |
148 | } |