]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-uniphier/pll/pll-init-ph1-ld4.c
Merge branch 'master' of git://git.denx.de/u-boot-x86
[people/ms/u-boot.git] / arch / arm / mach-uniphier / pll / pll-init-ph1-ld4.c
1 /*
2 * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <common.h>
8 #include <linux/err.h>
9 #include <linux/io.h>
10
11 #include "../init.h"
12 #include "../sc-regs.h"
13 #include "../sg-regs.h"
14
15 #undef DPLL_SSC_RATE_1PER
16
17 static int dpll_init(unsigned int dram_freq)
18 {
19 u32 tmp;
20
21 /*
22 * Set Frequency
23 * Set 0xc(1600MHz)/0xd(1333MHz)/0xe(1066MHz)
24 * to FOUT (DPLLCTRL.bit[29:20])
25 */
26 tmp = readl(SC_DPLLCTRL);
27 tmp &= ~0x000f0000;
28 switch (dram_freq) {
29 case 1333:
30 tmp |= 0x000d0000;
31 break;
32 case 1600:
33 tmp |= 0x000c0000;
34 break;
35 default:
36 pr_err("Unsupported frequency");
37 return -EINVAL;
38 }
39
40 #if defined(DPLL_SSC_RATE_1PER)
41 tmp &= ~SC_DPLLCTRL_SSC_RATE;
42 #else
43 tmp |= SC_DPLLCTRL_SSC_RATE;
44 #endif
45 writel(tmp, SC_DPLLCTRL);
46
47 tmp = readl(SC_DPLLCTRL2);
48 tmp |= SC_DPLLCTRL2_NRSTDS;
49 writel(tmp, SC_DPLLCTRL2);
50
51 return 0;
52 }
53
54 static void upll_init(void)
55 {
56 u32 tmp, clk_mode_upll, clk_mode_axosel;
57
58 tmp = readl(SG_PINMON0);
59 clk_mode_upll = tmp & SG_PINMON0_CLK_MODE_UPLLSRC_MASK;
60 clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
61
62 /* set 0 to SNRT(UPLLCTRL.bit28) and K_LD(UPLLCTRL.bit[27]) */
63 tmp = readl(SC_UPLLCTRL);
64 tmp &= ~0x18000000;
65 writel(tmp, SC_UPLLCTRL);
66
67 if (clk_mode_upll == SG_PINMON0_CLK_MODE_UPLLSRC_DEFAULT) {
68 if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_U ||
69 clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_A) {
70 /* AXO: 25MHz */
71 tmp &= ~0x07ffffff;
72 tmp |= 0x0228f5c0;
73 } else {
74 /* AXO: default 24.576MHz */
75 tmp &= ~0x07ffffff;
76 tmp |= 0x02328000;
77 }
78 }
79
80 writel(tmp, SC_UPLLCTRL);
81
82 /* set 1 to K_LD(UPLLCTRL.bit[27]) */
83 tmp |= 0x08000000;
84 writel(tmp, SC_UPLLCTRL);
85
86 /* wait 10 usec */
87 udelay(10);
88
89 /* set 1 to SNRT(UPLLCTRL.bit[28]) */
90 tmp |= 0x10000000;
91 writel(tmp, SC_UPLLCTRL);
92 }
93
94 static void vpll_init(void)
95 {
96 u32 tmp, clk_mode_axosel;
97
98 tmp = readl(SG_PINMON0);
99 clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
100
101 /* set 1 to VPLA27WP and VPLA27WP */
102 tmp = readl(SC_VPLL27ACTRL);
103 tmp |= 0x00000001;
104 writel(tmp, SC_VPLL27ACTRL);
105 tmp = readl(SC_VPLL27BCTRL);
106 tmp |= 0x00000001;
107 writel(tmp, SC_VPLL27BCTRL);
108
109 /* Set 0 to VPLA_K_LD and VPLB_K_LD */
110 tmp = readl(SC_VPLL27ACTRL3);
111 tmp &= ~0x10000000;
112 writel(tmp, SC_VPLL27ACTRL3);
113 tmp = readl(SC_VPLL27BCTRL3);
114 tmp &= ~0x10000000;
115 writel(tmp, SC_VPLL27BCTRL3);
116
117 /* Set 0 to VPLA_SNRST and VPLB_SNRST */
118 tmp = readl(SC_VPLL27ACTRL2);
119 tmp &= ~0x10000000;
120 writel(tmp, SC_VPLL27ACTRL2);
121 tmp = readl(SC_VPLL27BCTRL2);
122 tmp &= ~0x10000000;
123 writel(tmp, SC_VPLL27BCTRL2);
124
125 /* Set 0x20 to VPLA_SNRST and VPLB_SNRST */
126 tmp = readl(SC_VPLL27ACTRL2);
127 tmp &= ~0x0000007f;
128 tmp |= 0x00000020;
129 writel(tmp, SC_VPLL27ACTRL2);
130 tmp = readl(SC_VPLL27BCTRL2);
131 tmp &= ~0x0000007f;
132 tmp |= 0x00000020;
133 writel(tmp, SC_VPLL27BCTRL2);
134
135 if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_U ||
136 clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_A) {
137 /* AXO: 25MHz */
138 tmp = readl(SC_VPLL27ACTRL3);
139 tmp &= ~0x000fffff;
140 tmp |= 0x00066664;
141 writel(tmp, SC_VPLL27ACTRL3);
142 tmp = readl(SC_VPLL27BCTRL3);
143 tmp &= ~0x000fffff;
144 tmp |= 0x00066664;
145 writel(tmp, SC_VPLL27BCTRL3);
146 } else {
147 /* AXO: default 24.576MHz */
148 tmp = readl(SC_VPLL27ACTRL3);
149 tmp &= ~0x000fffff;
150 tmp |= 0x000f5800;
151 writel(tmp, SC_VPLL27ACTRL3);
152 tmp = readl(SC_VPLL27BCTRL3);
153 tmp &= ~0x000fffff;
154 tmp |= 0x000f5800;
155 writel(tmp, SC_VPLL27BCTRL3);
156 }
157
158 /* Set 1 to VPLA_K_LD and VPLB_K_LD */
159 tmp = readl(SC_VPLL27ACTRL3);
160 tmp |= 0x10000000;
161 writel(tmp, SC_VPLL27ACTRL3);
162 tmp = readl(SC_VPLL27BCTRL3);
163 tmp |= 0x10000000;
164 writel(tmp, SC_VPLL27BCTRL3);
165
166 /* wait 10 usec */
167 udelay(10);
168
169 /* Set 0 to VPLA_SNRST and VPLB_SNRST */
170 tmp = readl(SC_VPLL27ACTRL2);
171 tmp |= 0x10000000;
172 writel(tmp, SC_VPLL27ACTRL2);
173 tmp = readl(SC_VPLL27BCTRL2);
174 tmp |= 0x10000000;
175 writel(tmp, SC_VPLL27BCTRL2);
176
177 /* set 0 to VPLA27WP and VPLA27WP */
178 tmp = readl(SC_VPLL27ACTRL);
179 tmp &= ~0x00000001;
180 writel(tmp, SC_VPLL27ACTRL);
181 tmp = readl(SC_VPLL27BCTRL);
182 tmp |= ~0x00000001;
183 writel(tmp, SC_VPLL27BCTRL);
184 }
185
186 int ph1_ld4_pll_init(const struct uniphier_board_data *bd)
187 {
188 int ret;
189
190 ret = dpll_init(bd->dram_freq);
191 if (ret)
192 return ret;
193 upll_init();
194 vpll_init();
195
196 /*
197 * Wait 500 usec until dpll get stable
198 * We wait 10 usec in upll_init() and vpll_init()
199 * so 20 usec can be saved here.
200 */
201 udelay(480);
202
203 return 0;
204 }