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