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