1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2013-2014 Panasonic Corporation
4  * Copyright (C) 2015-2016 Socionext Inc.
5  */
6 
7 #include <linux/delay.h>
8 #include <linux/io.h>
9 
10 #include "../init.h"
11 #include "../sc-regs.h"
12 #include "../sg-regs.h"
13 #include "pll.h"
14 
upll_init(void)15 static void upll_init(void)
16 {
17 	u32 tmp, clk_mode_upll, clk_mode_axosel;
18 
19 	tmp = readl(sg_base + SG_PINMON0);
20 	clk_mode_upll   = tmp & SG_PINMON0_CLK_MODE_UPLLSRC_MASK;
21 	clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
22 
23 	/* set 0 to SNRT(UPLLCTRL.bit28) and K_LD(UPLLCTRL.bit[27]) */
24 	tmp = readl(sc_base + SC_UPLLCTRL);
25 	tmp &= ~0x18000000;
26 	writel(tmp, sc_base + SC_UPLLCTRL);
27 
28 	if (clk_mode_upll == SG_PINMON0_CLK_MODE_UPLLSRC_DEFAULT) {
29 		if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_U ||
30 		    clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_A) {
31 			/* AXO: 25MHz */
32 			tmp &= ~0x07ffffff;
33 			tmp |= 0x0228f5c0;
34 		} else {
35 			/* AXO: default 24.576MHz */
36 			tmp &= ~0x07ffffff;
37 			tmp |= 0x02328000;
38 		}
39 	}
40 
41 	writel(tmp, sc_base + SC_UPLLCTRL);
42 
43 	/* set 1 to K_LD(UPLLCTRL.bit[27]) */
44 	tmp |= 0x08000000;
45 	writel(tmp, sc_base + SC_UPLLCTRL);
46 
47 	/* wait 10 usec */
48 	udelay(10);
49 
50 	/* set 1 to SNRT(UPLLCTRL.bit[28]) */
51 	tmp |= 0x10000000;
52 	writel(tmp, sc_base + SC_UPLLCTRL);
53 }
54 
vpll_init(void)55 static void vpll_init(void)
56 {
57 	u32 tmp, clk_mode_axosel;
58 
59 	tmp = readl(sg_base + SG_PINMON0);
60 	clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
61 
62 	/* set 1 to VPLA27WP and VPLA27WP */
63 	tmp = readl(sc_base + SC_VPLL27ACTRL);
64 	tmp |= 0x00000001;
65 	writel(tmp, sc_base + SC_VPLL27ACTRL);
66 	tmp = readl(sc_base + SC_VPLL27BCTRL);
67 	tmp |= 0x00000001;
68 	writel(tmp, sc_base + SC_VPLL27BCTRL);
69 
70 	/* Set 0 to VPLA_K_LD and VPLB_K_LD */
71 	tmp = readl(sc_base + SC_VPLL27ACTRL3);
72 	tmp &= ~0x10000000;
73 	writel(tmp, sc_base + SC_VPLL27ACTRL3);
74 	tmp = readl(sc_base + SC_VPLL27BCTRL3);
75 	tmp &= ~0x10000000;
76 	writel(tmp, sc_base + SC_VPLL27BCTRL3);
77 
78 	/* Set 0 to VPLA_SNRST and VPLB_SNRST */
79 	tmp = readl(sc_base + SC_VPLL27ACTRL2);
80 	tmp &= ~0x10000000;
81 	writel(tmp, sc_base + SC_VPLL27ACTRL2);
82 	tmp = readl(sc_base + SC_VPLL27BCTRL2);
83 	tmp &= ~0x10000000;
84 	writel(tmp, sc_base + SC_VPLL27BCTRL2);
85 
86 	/* Set 0x20 to VPLA_SNRST and VPLB_SNRST */
87 	tmp = readl(sc_base + SC_VPLL27ACTRL2);
88 	tmp &= ~0x0000007f;
89 	tmp |= 0x00000020;
90 	writel(tmp, sc_base + SC_VPLL27ACTRL2);
91 	tmp = readl(sc_base + SC_VPLL27BCTRL2);
92 	tmp &= ~0x0000007f;
93 	tmp |= 0x00000020;
94 	writel(tmp, sc_base + SC_VPLL27BCTRL2);
95 
96 	if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_U ||
97 	    clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_A) {
98 		/* AXO: 25MHz */
99 		tmp = readl(sc_base + SC_VPLL27ACTRL3);
100 		tmp &= ~0x000fffff;
101 		tmp |= 0x00066664;
102 		writel(tmp, sc_base + SC_VPLL27ACTRL3);
103 		tmp = readl(sc_base + SC_VPLL27BCTRL3);
104 		tmp &= ~0x000fffff;
105 		tmp |= 0x00066664;
106 		writel(tmp, sc_base + SC_VPLL27BCTRL3);
107 	} else {
108 		/* AXO: default 24.576MHz */
109 		tmp = readl(sc_base + SC_VPLL27ACTRL3);
110 		tmp &= ~0x000fffff;
111 		tmp |= 0x000f5800;
112 		writel(tmp, sc_base + SC_VPLL27ACTRL3);
113 		tmp = readl(sc_base + SC_VPLL27BCTRL3);
114 		tmp &= ~0x000fffff;
115 		tmp |= 0x000f5800;
116 		writel(tmp, sc_base + SC_VPLL27BCTRL3);
117 	}
118 
119 	/* Set 1 to VPLA_K_LD and VPLB_K_LD */
120 	tmp = readl(sc_base + SC_VPLL27ACTRL3);
121 	tmp |= 0x10000000;
122 	writel(tmp, sc_base + SC_VPLL27ACTRL3);
123 	tmp = readl(sc_base + SC_VPLL27BCTRL3);
124 	tmp |= 0x10000000;
125 	writel(tmp, sc_base + SC_VPLL27BCTRL3);
126 
127 	/* wait 10 usec */
128 	udelay(10);
129 
130 	/* Set 0 to VPLA_SNRST and VPLB_SNRST */
131 	tmp = readl(sc_base + SC_VPLL27ACTRL2);
132 	tmp |= 0x10000000;
133 	writel(tmp, sc_base + SC_VPLL27ACTRL2);
134 	tmp = readl(sc_base + SC_VPLL27BCTRL2);
135 	tmp |= 0x10000000;
136 	writel(tmp, sc_base + SC_VPLL27BCTRL2);
137 
138 	/* set 0 to VPLA27WP and VPLA27WP */
139 	tmp = readl(sc_base + SC_VPLL27ACTRL);
140 	tmp &= ~0x00000001;
141 	writel(tmp, sc_base + SC_VPLL27ACTRL);
142 	tmp = readl(sc_base + SC_VPLL27BCTRL);
143 	tmp |= ~0x00000001;
144 	writel(tmp, sc_base + SC_VPLL27BCTRL);
145 }
146 
uniphier_ld4_pll_init(void)147 void uniphier_ld4_pll_init(void)
148 {
149 	upll_init();
150 	vpll_init();
151 	uniphier_ld4_dpll_ssc_en();
152 }
153