1 /*
2  * Copyright (C) 2013-2014 Panasonic Corporation
3  * Copyright (C) 2015-2016 Socionext Inc.
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <linux/delay.h>
9 #include <linux/io.h>
10 
11 #include "../init.h"
12 #include "../sc-regs.h"
13 #include "../sg-regs.h"
14 #include "pll.h"
15 
16 static void vpll_init(void)
17 {
18 	u32 tmp, clk_mode_axosel;
19 
20 	/* Set VPLL27A &  VPLL27B */
21 	tmp = readl(SG_PINMON0);
22 	clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
23 
24 	/* 25MHz or 6.25MHz is default for Pro4R, no need to set VPLLA/B */
25 	if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ ||
26 	    clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_6250KHZ)
27 		return;
28 
29 	/* Disable write protect of VPLL27ACTRL[2-7]*, VPLL27BCTRL[2-8] */
30 	tmp = readl(SC_VPLL27ACTRL);
31 	tmp |= 0x00000001;
32 	writel(tmp, SC_VPLL27ACTRL);
33 	tmp = readl(SC_VPLL27BCTRL);
34 	tmp |= 0x00000001;
35 	writel(tmp, SC_VPLL27BCTRL);
36 
37 	/* Unset VPLA_K_LD and VPLB_K_LD bit */
38 	tmp = readl(SC_VPLL27ACTRL3);
39 	tmp &= ~0x10000000;
40 	writel(tmp, SC_VPLL27ACTRL3);
41 	tmp = readl(SC_VPLL27BCTRL3);
42 	tmp &= ~0x10000000;
43 	writel(tmp, SC_VPLL27BCTRL3);
44 
45 	/* Set VPLA_M and VPLB_M to 0x20 */
46 	tmp = readl(SC_VPLL27ACTRL2);
47 	tmp &= ~0x0000007f;
48 	tmp |= 0x00000020;
49 	writel(tmp, SC_VPLL27ACTRL2);
50 	tmp = readl(SC_VPLL27BCTRL2);
51 	tmp &= ~0x0000007f;
52 	tmp |= 0x00000020;
53 	writel(tmp, SC_VPLL27BCTRL2);
54 
55 	if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ ||
56 	    clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_6250KHZ) {
57 		/* Set VPLA_K and VPLB_K for AXO: 25MHz */
58 		tmp = readl(SC_VPLL27ACTRL3);
59 		tmp &= ~0x000fffff;
60 		tmp |= 0x00066666;
61 		writel(tmp, SC_VPLL27ACTRL3);
62 		tmp = readl(SC_VPLL27BCTRL3);
63 		tmp &= ~0x000fffff;
64 		tmp |= 0x00066666;
65 		writel(tmp, SC_VPLL27BCTRL3);
66 	} else {
67 		/* Set VPLA_K and VPLB_K for AXO: 24.576 MHz */
68 		tmp = readl(SC_VPLL27ACTRL3);
69 		tmp &= ~0x000fffff;
70 		tmp |= 0x000f5800;
71 		writel(tmp, SC_VPLL27ACTRL3);
72 		tmp = readl(SC_VPLL27BCTRL3);
73 		tmp &= ~0x000fffff;
74 		tmp |= 0x000f5800;
75 		writel(tmp, SC_VPLL27BCTRL3);
76 	}
77 
78 	/* wait 1 usec */
79 	udelay(1);
80 
81 	/* Set VPLA_K_LD and VPLB_K_LD to load K parameters */
82 	tmp = readl(SC_VPLL27ACTRL3);
83 	tmp |= 0x10000000;
84 	writel(tmp, SC_VPLL27ACTRL3);
85 	tmp = readl(SC_VPLL27BCTRL3);
86 	tmp |= 0x10000000;
87 	writel(tmp, SC_VPLL27BCTRL3);
88 
89 	/* Unset VPLA_SNRST and VPLB_SNRST bit */
90 	tmp = readl(SC_VPLL27ACTRL2);
91 	tmp |= 0x10000000;
92 	writel(tmp, SC_VPLL27ACTRL2);
93 	tmp = readl(SC_VPLL27BCTRL2);
94 	tmp |= 0x10000000;
95 	writel(tmp, SC_VPLL27BCTRL2);
96 
97 	/* Enable write protect of VPLL27ACTRL[2-7]*, VPLL27BCTRL[2-8] */
98 	tmp = readl(SC_VPLL27ACTRL);
99 	tmp &= ~0x00000001;
100 	writel(tmp, SC_VPLL27ACTRL);
101 	tmp = readl(SC_VPLL27BCTRL);
102 	tmp &= ~0x00000001;
103 	writel(tmp, SC_VPLL27BCTRL);
104 }
105 
106 void uniphier_pro4_pll_init(void)
107 {
108 	vpll_init();
109 	uniphier_ld4_dpll_ssc_en();
110 }
111