1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * clock_am43xx.c
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * clocks for AM43XX based boards
5*4882a593Smuzhiyun * Derived from AM33XX based boards
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <common.h>
13*4882a593Smuzhiyun #include <asm/arch/cpu.h>
14*4882a593Smuzhiyun #include <asm/arch/clock.h>
15*4882a593Smuzhiyun #include <asm/arch/hardware.h>
16*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
17*4882a593Smuzhiyun #include <asm/io.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER;
20*4882a593Smuzhiyun struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP;
21*4882a593Smuzhiyun struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun const struct dpll_regs dpll_mpu_regs = {
24*4882a593Smuzhiyun .cm_clkmode_dpll = CM_WKUP + 0x560,
25*4882a593Smuzhiyun .cm_idlest_dpll = CM_WKUP + 0x564,
26*4882a593Smuzhiyun .cm_clksel_dpll = CM_WKUP + 0x56c,
27*4882a593Smuzhiyun .cm_div_m2_dpll = CM_WKUP + 0x570,
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun const struct dpll_regs dpll_core_regs = {
31*4882a593Smuzhiyun .cm_clkmode_dpll = CM_WKUP + 0x520,
32*4882a593Smuzhiyun .cm_idlest_dpll = CM_WKUP + 0x524,
33*4882a593Smuzhiyun .cm_clksel_dpll = CM_WKUP + 0x52C,
34*4882a593Smuzhiyun .cm_div_m4_dpll = CM_WKUP + 0x538,
35*4882a593Smuzhiyun .cm_div_m5_dpll = CM_WKUP + 0x53C,
36*4882a593Smuzhiyun .cm_div_m6_dpll = CM_WKUP + 0x540,
37*4882a593Smuzhiyun };
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun const struct dpll_regs dpll_per_regs = {
40*4882a593Smuzhiyun .cm_clkmode_dpll = CM_WKUP + 0x5E0,
41*4882a593Smuzhiyun .cm_idlest_dpll = CM_WKUP + 0x5E4,
42*4882a593Smuzhiyun .cm_clksel_dpll = CM_WKUP + 0x5EC,
43*4882a593Smuzhiyun .cm_div_m2_dpll = CM_WKUP + 0x5F0,
44*4882a593Smuzhiyun };
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun const struct dpll_regs dpll_ddr_regs = {
47*4882a593Smuzhiyun .cm_clkmode_dpll = CM_WKUP + 0x5A0,
48*4882a593Smuzhiyun .cm_idlest_dpll = CM_WKUP + 0x5A4,
49*4882a593Smuzhiyun .cm_clksel_dpll = CM_WKUP + 0x5AC,
50*4882a593Smuzhiyun .cm_div_m2_dpll = CM_WKUP + 0x5B0,
51*4882a593Smuzhiyun .cm_div_m4_dpll = CM_WKUP + 0x5B8,
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun
setup_clocks_for_console(void)54*4882a593Smuzhiyun void setup_clocks_for_console(void)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun /* Do not add any spl_debug prints in this function */
59*4882a593Smuzhiyun clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
60*4882a593Smuzhiyun CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
61*4882a593Smuzhiyun CD_CLKCTRL_CLKTRCTRL_SHIFT);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun /* Enable UART0 */
64*4882a593Smuzhiyun clrsetbits_le32(&cmwkup->wkup_uart0ctrl,
65*4882a593Smuzhiyun MODULE_CLKCTRL_MODULEMODE_MASK,
66*4882a593Smuzhiyun MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
67*4882a593Smuzhiyun MODULE_CLKCTRL_MODULEMODE_SHIFT);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) ||
70*4882a593Smuzhiyun (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) {
71*4882a593Smuzhiyun clkctrl = readl(&cmwkup->wkup_uart0ctrl);
72*4882a593Smuzhiyun idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
73*4882a593Smuzhiyun MODULE_CLKCTRL_IDLEST_SHIFT;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun
enable_basic_clocks(void)77*4882a593Smuzhiyun void enable_basic_clocks(void)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun u32 *const clk_domains[] = {
80*4882a593Smuzhiyun &cmper->l3clkstctrl,
81*4882a593Smuzhiyun &cmper->l3sclkstctrl,
82*4882a593Smuzhiyun &cmper->l4lsclkstctrl,
83*4882a593Smuzhiyun &cmwkup->wkclkstctrl,
84*4882a593Smuzhiyun &cmper->emifclkstctrl,
85*4882a593Smuzhiyun 0
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun u32 *const clk_modules_explicit_en[] = {
89*4882a593Smuzhiyun &cmper->l3clkctrl,
90*4882a593Smuzhiyun &cmper->l4lsclkctrl,
91*4882a593Smuzhiyun &cmper->l4fwclkctrl,
92*4882a593Smuzhiyun &cmwkup->wkl4wkclkctrl,
93*4882a593Smuzhiyun &cmper->l3instrclkctrl,
94*4882a593Smuzhiyun &cmper->l4hsclkctrl,
95*4882a593Smuzhiyun &cmwkup->wkgpio0clkctrl,
96*4882a593Smuzhiyun &cmwkup->wkctrlclkctrl,
97*4882a593Smuzhiyun &cmper->timer2clkctrl,
98*4882a593Smuzhiyun &cmper->gpmcclkctrl,
99*4882a593Smuzhiyun &cmper->elmclkctrl,
100*4882a593Smuzhiyun &cmper->mmc0clkctrl,
101*4882a593Smuzhiyun &cmper->mmc1clkctrl,
102*4882a593Smuzhiyun &cmwkup->wkup_i2c0ctrl,
103*4882a593Smuzhiyun &cmper->gpio1clkctrl,
104*4882a593Smuzhiyun &cmper->gpio2clkctrl,
105*4882a593Smuzhiyun &cmper->gpio3clkctrl,
106*4882a593Smuzhiyun &cmper->gpio4clkctrl,
107*4882a593Smuzhiyun &cmper->gpio5clkctrl,
108*4882a593Smuzhiyun &cmper->i2c1clkctrl,
109*4882a593Smuzhiyun &cmper->cpgmac0clkctrl,
110*4882a593Smuzhiyun &cmper->emiffwclkctrl,
111*4882a593Smuzhiyun &cmper->emifclkctrl,
112*4882a593Smuzhiyun &cmper->otfaemifclkctrl,
113*4882a593Smuzhiyun &cmper->qspiclkctrl,
114*4882a593Smuzhiyun &cmper->spi0clkctrl,
115*4882a593Smuzhiyun 0
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* Select the Master osc clk as Timer2 clock source */
121*4882a593Smuzhiyun writel(0x1, &cmdpll->clktimer2clk);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* For OPP100 the mac clock should be /5. */
124*4882a593Smuzhiyun writel(0x4, &cmdpll->clkselmacclk);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun #ifdef CONFIG_TI_EDMA3
enable_edma3_clocks(void)128*4882a593Smuzhiyun void enable_edma3_clocks(void)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun u32 *const clk_domains_edma3[] = {
131*4882a593Smuzhiyun 0
132*4882a593Smuzhiyun };
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun u32 *const clk_modules_explicit_en_edma3[] = {
135*4882a593Smuzhiyun &cmper->tpccclkctrl,
136*4882a593Smuzhiyun &cmper->tptc0clkctrl,
137*4882a593Smuzhiyun 0
138*4882a593Smuzhiyun };
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun do_enable_clocks(clk_domains_edma3,
141*4882a593Smuzhiyun clk_modules_explicit_en_edma3,
142*4882a593Smuzhiyun 1);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
disable_edma3_clocks(void)145*4882a593Smuzhiyun void disable_edma3_clocks(void)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun u32 *const clk_domains_edma3[] = {
148*4882a593Smuzhiyun 0
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun u32 *const clk_modules_disable_edma3[] = {
152*4882a593Smuzhiyun &cmper->tpccclkctrl,
153*4882a593Smuzhiyun &cmper->tptc0clkctrl,
154*4882a593Smuzhiyun 0
155*4882a593Smuzhiyun };
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun do_disable_clocks(clk_domains_edma3,
158*4882a593Smuzhiyun clk_modules_disable_edma3,
159*4882a593Smuzhiyun 1);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun #endif
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
enable_usb_clocks(int index)164*4882a593Smuzhiyun void enable_usb_clocks(int index)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun u32 *usbclkctrl = 0;
167*4882a593Smuzhiyun u32 *usbphyocp2scpclkctrl = 0;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun if (index == 0) {
170*4882a593Smuzhiyun usbclkctrl = &cmper->usb0clkctrl;
171*4882a593Smuzhiyun usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl;
172*4882a593Smuzhiyun setbits_le32(&cmper->usb0clkctrl,
173*4882a593Smuzhiyun USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
174*4882a593Smuzhiyun setbits_le32(&cmwkup->usbphy0clkctrl,
175*4882a593Smuzhiyun USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
176*4882a593Smuzhiyun } else if (index == 1) {
177*4882a593Smuzhiyun usbclkctrl = &cmper->usb1clkctrl;
178*4882a593Smuzhiyun usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl;
179*4882a593Smuzhiyun setbits_le32(&cmper->usb1clkctrl,
180*4882a593Smuzhiyun USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
181*4882a593Smuzhiyun setbits_le32(&cmwkup->usbphy1clkctrl,
182*4882a593Smuzhiyun USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun u32 *const clk_domains_usb[] = {
186*4882a593Smuzhiyun 0
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun u32 *const clk_modules_explicit_en_usb[] = {
190*4882a593Smuzhiyun usbclkctrl,
191*4882a593Smuzhiyun usbphyocp2scpclkctrl,
192*4882a593Smuzhiyun 0
193*4882a593Smuzhiyun };
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun do_enable_clocks(clk_domains_usb, clk_modules_explicit_en_usb, 1);
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
disable_usb_clocks(int index)198*4882a593Smuzhiyun void disable_usb_clocks(int index)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun u32 *usbclkctrl = 0;
201*4882a593Smuzhiyun u32 *usbphyocp2scpclkctrl = 0;
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun if (index == 0) {
204*4882a593Smuzhiyun usbclkctrl = &cmper->usb0clkctrl;
205*4882a593Smuzhiyun usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl;
206*4882a593Smuzhiyun clrbits_le32(&cmper->usb0clkctrl,
207*4882a593Smuzhiyun USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
208*4882a593Smuzhiyun clrbits_le32(&cmwkup->usbphy0clkctrl,
209*4882a593Smuzhiyun USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
210*4882a593Smuzhiyun } else if (index == 1) {
211*4882a593Smuzhiyun usbclkctrl = &cmper->usb1clkctrl;
212*4882a593Smuzhiyun usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl;
213*4882a593Smuzhiyun clrbits_le32(&cmper->usb1clkctrl,
214*4882a593Smuzhiyun USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
215*4882a593Smuzhiyun clrbits_le32(&cmwkup->usbphy1clkctrl,
216*4882a593Smuzhiyun USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun u32 *const clk_domains_usb[] = {
220*4882a593Smuzhiyun 0
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun u32 *const clk_modules_disable_usb[] = {
224*4882a593Smuzhiyun usbclkctrl,
225*4882a593Smuzhiyun usbphyocp2scpclkctrl,
226*4882a593Smuzhiyun 0
227*4882a593Smuzhiyun };
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun do_disable_clocks(clk_domains_usb, clk_modules_disable_usb, 1);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun #endif
232