1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
3*4882a593Smuzhiyun * reserved.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * This software is available to you under a choice of one of two
6*4882a593Smuzhiyun * licenses. You may choose to be licensed under the terms of the GNU
7*4882a593Smuzhiyun * General Public License (GPL) Version 2, available from the file
8*4882a593Smuzhiyun * COPYING in the main directory of this source tree, or the NetLogic
9*4882a593Smuzhiyun * license below:
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without
12*4882a593Smuzhiyun * modification, are permitted provided that the following conditions
13*4882a593Smuzhiyun * are met:
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * 1. Redistributions of source code must retain the above copyright
16*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer.
17*4882a593Smuzhiyun * 2. Redistributions in binary form must reproduce the above copyright
18*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer in
19*4882a593Smuzhiyun * the documentation and/or other materials provided with the
20*4882a593Smuzhiyun * distribution.
21*4882a593Smuzhiyun *
22*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
23*4882a593Smuzhiyun * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24*4882a593Smuzhiyun * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*4882a593Smuzhiyun * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
26*4882a593Smuzhiyun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27*4882a593Smuzhiyun * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28*4882a593Smuzhiyun * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29*4882a593Smuzhiyun * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30*4882a593Smuzhiyun * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31*4882a593Smuzhiyun * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32*4882a593Smuzhiyun * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*4882a593Smuzhiyun */
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #include <linux/types.h>
36*4882a593Smuzhiyun #include <linux/kernel.h>
37*4882a593Smuzhiyun #include <linux/mm.h>
38*4882a593Smuzhiyun #include <linux/delay.h>
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #include <asm/mipsregs.h>
41*4882a593Smuzhiyun #include <asm/time.h>
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #include <asm/netlogic/common.h>
44*4882a593Smuzhiyun #include <asm/netlogic/haldefs.h>
45*4882a593Smuzhiyun #include <asm/netlogic/xlp-hal/iomap.h>
46*4882a593Smuzhiyun #include <asm/netlogic/xlp-hal/xlp.h>
47*4882a593Smuzhiyun #include <asm/netlogic/xlp-hal/bridge.h>
48*4882a593Smuzhiyun #include <asm/netlogic/xlp-hal/pic.h>
49*4882a593Smuzhiyun #include <asm/netlogic/xlp-hal/sys.h>
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /* Main initialization */
nlm_node_init(int node)52*4882a593Smuzhiyun void nlm_node_init(int node)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun struct nlm_soc_info *nodep;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun nodep = nlm_get_node(node);
57*4882a593Smuzhiyun if (node == 0)
58*4882a593Smuzhiyun nodep->coremask = 1; /* node 0, boot cpu */
59*4882a593Smuzhiyun nodep->sysbase = nlm_get_sys_regbase(node);
60*4882a593Smuzhiyun nodep->picbase = nlm_get_pic_regbase(node);
61*4882a593Smuzhiyun nodep->ebase = read_c0_ebase() & MIPS_EBASE_BASE;
62*4882a593Smuzhiyun if (cpu_is_xlp9xx())
63*4882a593Smuzhiyun nodep->socbus = xlp9xx_get_socbus(node);
64*4882a593Smuzhiyun else
65*4882a593Smuzhiyun nodep->socbus = 0;
66*4882a593Smuzhiyun spin_lock_init(&nodep->piclock);
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
xlp9xx_irq_to_irt(int irq)69*4882a593Smuzhiyun static int xlp9xx_irq_to_irt(int irq)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun switch (irq) {
72*4882a593Smuzhiyun case PIC_GPIO_IRQ:
73*4882a593Smuzhiyun return 12;
74*4882a593Smuzhiyun case PIC_I2C_0_IRQ:
75*4882a593Smuzhiyun return 125;
76*4882a593Smuzhiyun case PIC_I2C_1_IRQ:
77*4882a593Smuzhiyun return 126;
78*4882a593Smuzhiyun case PIC_I2C_2_IRQ:
79*4882a593Smuzhiyun return 127;
80*4882a593Smuzhiyun case PIC_I2C_3_IRQ:
81*4882a593Smuzhiyun return 128;
82*4882a593Smuzhiyun case PIC_9XX_XHCI_0_IRQ:
83*4882a593Smuzhiyun return 114;
84*4882a593Smuzhiyun case PIC_9XX_XHCI_1_IRQ:
85*4882a593Smuzhiyun return 115;
86*4882a593Smuzhiyun case PIC_9XX_XHCI_2_IRQ:
87*4882a593Smuzhiyun return 116;
88*4882a593Smuzhiyun case PIC_UART_0_IRQ:
89*4882a593Smuzhiyun return 133;
90*4882a593Smuzhiyun case PIC_UART_1_IRQ:
91*4882a593Smuzhiyun return 134;
92*4882a593Smuzhiyun case PIC_SATA_IRQ:
93*4882a593Smuzhiyun return 143;
94*4882a593Smuzhiyun case PIC_NAND_IRQ:
95*4882a593Smuzhiyun return 151;
96*4882a593Smuzhiyun case PIC_SPI_IRQ:
97*4882a593Smuzhiyun return 152;
98*4882a593Smuzhiyun case PIC_MMC_IRQ:
99*4882a593Smuzhiyun return 153;
100*4882a593Smuzhiyun case PIC_PCIE_LINK_LEGACY_IRQ(0):
101*4882a593Smuzhiyun case PIC_PCIE_LINK_LEGACY_IRQ(1):
102*4882a593Smuzhiyun case PIC_PCIE_LINK_LEGACY_IRQ(2):
103*4882a593Smuzhiyun case PIC_PCIE_LINK_LEGACY_IRQ(3):
104*4882a593Smuzhiyun return 191 + irq - PIC_PCIE_LINK_LEGACY_IRQ_BASE;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun return -1;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
xlp_irq_to_irt(int irq)109*4882a593Smuzhiyun static int xlp_irq_to_irt(int irq)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun uint64_t pcibase;
112*4882a593Smuzhiyun int devoff, irt;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun devoff = 0;
115*4882a593Smuzhiyun switch (irq) {
116*4882a593Smuzhiyun case PIC_UART_0_IRQ:
117*4882a593Smuzhiyun devoff = XLP_IO_UART0_OFFSET(0);
118*4882a593Smuzhiyun break;
119*4882a593Smuzhiyun case PIC_UART_1_IRQ:
120*4882a593Smuzhiyun devoff = XLP_IO_UART1_OFFSET(0);
121*4882a593Smuzhiyun break;
122*4882a593Smuzhiyun case PIC_MMC_IRQ:
123*4882a593Smuzhiyun devoff = XLP_IO_MMC_OFFSET(0);
124*4882a593Smuzhiyun break;
125*4882a593Smuzhiyun case PIC_I2C_0_IRQ: /* I2C will be fixed up */
126*4882a593Smuzhiyun case PIC_I2C_1_IRQ:
127*4882a593Smuzhiyun case PIC_I2C_2_IRQ:
128*4882a593Smuzhiyun case PIC_I2C_3_IRQ:
129*4882a593Smuzhiyun if (cpu_is_xlpii())
130*4882a593Smuzhiyun devoff = XLP2XX_IO_I2C_OFFSET(0);
131*4882a593Smuzhiyun else
132*4882a593Smuzhiyun devoff = XLP_IO_I2C0_OFFSET(0);
133*4882a593Smuzhiyun break;
134*4882a593Smuzhiyun case PIC_SATA_IRQ:
135*4882a593Smuzhiyun devoff = XLP_IO_SATA_OFFSET(0);
136*4882a593Smuzhiyun break;
137*4882a593Smuzhiyun case PIC_GPIO_IRQ:
138*4882a593Smuzhiyun devoff = XLP_IO_GPIO_OFFSET(0);
139*4882a593Smuzhiyun break;
140*4882a593Smuzhiyun case PIC_NAND_IRQ:
141*4882a593Smuzhiyun devoff = XLP_IO_NAND_OFFSET(0);
142*4882a593Smuzhiyun break;
143*4882a593Smuzhiyun case PIC_SPI_IRQ:
144*4882a593Smuzhiyun devoff = XLP_IO_SPI_OFFSET(0);
145*4882a593Smuzhiyun break;
146*4882a593Smuzhiyun default:
147*4882a593Smuzhiyun if (cpu_is_xlpii()) {
148*4882a593Smuzhiyun switch (irq) {
149*4882a593Smuzhiyun /* XLP2XX has three XHCI USB controller */
150*4882a593Smuzhiyun case PIC_2XX_XHCI_0_IRQ:
151*4882a593Smuzhiyun devoff = XLP2XX_IO_USB_XHCI0_OFFSET(0);
152*4882a593Smuzhiyun break;
153*4882a593Smuzhiyun case PIC_2XX_XHCI_1_IRQ:
154*4882a593Smuzhiyun devoff = XLP2XX_IO_USB_XHCI1_OFFSET(0);
155*4882a593Smuzhiyun break;
156*4882a593Smuzhiyun case PIC_2XX_XHCI_2_IRQ:
157*4882a593Smuzhiyun devoff = XLP2XX_IO_USB_XHCI2_OFFSET(0);
158*4882a593Smuzhiyun break;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun } else {
161*4882a593Smuzhiyun switch (irq) {
162*4882a593Smuzhiyun case PIC_EHCI_0_IRQ:
163*4882a593Smuzhiyun devoff = XLP_IO_USB_EHCI0_OFFSET(0);
164*4882a593Smuzhiyun break;
165*4882a593Smuzhiyun case PIC_EHCI_1_IRQ:
166*4882a593Smuzhiyun devoff = XLP_IO_USB_EHCI1_OFFSET(0);
167*4882a593Smuzhiyun break;
168*4882a593Smuzhiyun case PIC_OHCI_0_IRQ:
169*4882a593Smuzhiyun devoff = XLP_IO_USB_OHCI0_OFFSET(0);
170*4882a593Smuzhiyun break;
171*4882a593Smuzhiyun case PIC_OHCI_1_IRQ:
172*4882a593Smuzhiyun devoff = XLP_IO_USB_OHCI1_OFFSET(0);
173*4882a593Smuzhiyun break;
174*4882a593Smuzhiyun case PIC_OHCI_2_IRQ:
175*4882a593Smuzhiyun devoff = XLP_IO_USB_OHCI2_OFFSET(0);
176*4882a593Smuzhiyun break;
177*4882a593Smuzhiyun case PIC_OHCI_3_IRQ:
178*4882a593Smuzhiyun devoff = XLP_IO_USB_OHCI3_OFFSET(0);
179*4882a593Smuzhiyun break;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun if (devoff != 0) {
185*4882a593Smuzhiyun uint32_t val;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun pcibase = nlm_pcicfg_base(devoff);
188*4882a593Smuzhiyun val = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG);
189*4882a593Smuzhiyun if (val == 0xffffffff) {
190*4882a593Smuzhiyun irt = -1;
191*4882a593Smuzhiyun } else {
192*4882a593Smuzhiyun irt = val & 0xffff;
193*4882a593Smuzhiyun /* HW weirdness, I2C IRT entry has to be fixed up */
194*4882a593Smuzhiyun switch (irq) {
195*4882a593Smuzhiyun case PIC_I2C_1_IRQ:
196*4882a593Smuzhiyun irt = irt + 1; break;
197*4882a593Smuzhiyun case PIC_I2C_2_IRQ:
198*4882a593Smuzhiyun irt = irt + 2; break;
199*4882a593Smuzhiyun case PIC_I2C_3_IRQ:
200*4882a593Smuzhiyun irt = irt + 3; break;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun } else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) &&
204*4882a593Smuzhiyun irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) {
205*4882a593Smuzhiyun /* HW bug, PCI IRT entries are bad on early silicon, fix */
206*4882a593Smuzhiyun irt = PIC_IRT_PCIE_LINK_INDEX(irq -
207*4882a593Smuzhiyun PIC_PCIE_LINK_LEGACY_IRQ_BASE);
208*4882a593Smuzhiyun } else {
209*4882a593Smuzhiyun irt = -1;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun return irt;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
nlm_irq_to_irt(int irq)214*4882a593Smuzhiyun int nlm_irq_to_irt(int irq)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun /* return -2 for irqs without 1-1 mapping */
217*4882a593Smuzhiyun if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) && irq <= PIC_PCIE_LINK_MSI_IRQ(3))
218*4882a593Smuzhiyun return -2;
219*4882a593Smuzhiyun if (irq >= PIC_PCIE_MSIX_IRQ(0) && irq <= PIC_PCIE_MSIX_IRQ(3))
220*4882a593Smuzhiyun return -2;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun if (cpu_is_xlp9xx())
223*4882a593Smuzhiyun return xlp9xx_irq_to_irt(irq);
224*4882a593Smuzhiyun else
225*4882a593Smuzhiyun return xlp_irq_to_irt(irq);
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
nlm_xlp2_get_core_frequency(int node,int core)228*4882a593Smuzhiyun static unsigned int nlm_xlp2_get_core_frequency(int node, int core)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun unsigned int pll_post_div, ctrl_val0, ctrl_val1, denom;
231*4882a593Smuzhiyun uint64_t num, sysbase, clockbase;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun if (cpu_is_xlp9xx()) {
234*4882a593Smuzhiyun clockbase = nlm_get_clock_regbase(node);
235*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(clockbase,
236*4882a593Smuzhiyun SYS_9XX_CPU_PLL_CTRL0(core));
237*4882a593Smuzhiyun ctrl_val1 = nlm_read_sys_reg(clockbase,
238*4882a593Smuzhiyun SYS_9XX_CPU_PLL_CTRL1(core));
239*4882a593Smuzhiyun } else {
240*4882a593Smuzhiyun sysbase = nlm_get_node(node)->sysbase;
241*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(sysbase,
242*4882a593Smuzhiyun SYS_CPU_PLL_CTRL0(core));
243*4882a593Smuzhiyun ctrl_val1 = nlm_read_sys_reg(sysbase,
244*4882a593Smuzhiyun SYS_CPU_PLL_CTRL1(core));
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun /* Find PLL post divider value */
248*4882a593Smuzhiyun switch ((ctrl_val0 >> 24) & 0x7) {
249*4882a593Smuzhiyun case 1:
250*4882a593Smuzhiyun pll_post_div = 2;
251*4882a593Smuzhiyun break;
252*4882a593Smuzhiyun case 3:
253*4882a593Smuzhiyun pll_post_div = 4;
254*4882a593Smuzhiyun break;
255*4882a593Smuzhiyun case 7:
256*4882a593Smuzhiyun pll_post_div = 8;
257*4882a593Smuzhiyun break;
258*4882a593Smuzhiyun case 6:
259*4882a593Smuzhiyun pll_post_div = 16;
260*4882a593Smuzhiyun break;
261*4882a593Smuzhiyun case 0:
262*4882a593Smuzhiyun default:
263*4882a593Smuzhiyun pll_post_div = 1;
264*4882a593Smuzhiyun break;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun num = 1000000ULL * (400 * 3 + 100 * (ctrl_val1 & 0x3f));
268*4882a593Smuzhiyun denom = 3 * pll_post_div;
269*4882a593Smuzhiyun do_div(num, denom);
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun return (unsigned int)num;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
nlm_xlp_get_core_frequency(int node,int core)274*4882a593Smuzhiyun static unsigned int nlm_xlp_get_core_frequency(int node, int core)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun unsigned int pll_divf, pll_divr, dfs_div, ext_div;
277*4882a593Smuzhiyun unsigned int rstval, dfsval, denom;
278*4882a593Smuzhiyun uint64_t num, sysbase;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun sysbase = nlm_get_node(node)->sysbase;
281*4882a593Smuzhiyun rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
282*4882a593Smuzhiyun dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
283*4882a593Smuzhiyun pll_divf = ((rstval >> 10) & 0x7f) + 1;
284*4882a593Smuzhiyun pll_divr = ((rstval >> 8) & 0x3) + 1;
285*4882a593Smuzhiyun ext_div = ((rstval >> 30) & 0x3) + 1;
286*4882a593Smuzhiyun dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun num = 800000000ULL * pll_divf;
289*4882a593Smuzhiyun denom = 3 * pll_divr * ext_div * dfs_div;
290*4882a593Smuzhiyun do_div(num, denom);
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun return (unsigned int)num;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
nlm_get_core_frequency(int node,int core)295*4882a593Smuzhiyun unsigned int nlm_get_core_frequency(int node, int core)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun if (cpu_is_xlpii())
298*4882a593Smuzhiyun return nlm_xlp2_get_core_frequency(node, core);
299*4882a593Smuzhiyun else
300*4882a593Smuzhiyun return nlm_xlp_get_core_frequency(node, core);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun /*
304*4882a593Smuzhiyun * Calculate PIC frequency from PLL registers.
305*4882a593Smuzhiyun * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) /
306*4882a593Smuzhiyun * ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
307*4882a593Smuzhiyun */
nlm_xlp2_get_pic_frequency(int node)308*4882a593Smuzhiyun static unsigned int nlm_xlp2_get_pic_frequency(int node)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx;
311*4882a593Smuzhiyun u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
312*4882a593Smuzhiyun u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk;
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun sysbase = nlm_get_node(node)->sysbase;
315*4882a593Smuzhiyun clockbase = nlm_get_clock_regbase(node);
316*4882a593Smuzhiyun cpu_xlp9xx = cpu_is_xlp9xx();
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /* Find ref_clk_base */
319*4882a593Smuzhiyun if (cpu_xlp9xx)
320*4882a593Smuzhiyun ref_clk_select = (nlm_read_sys_reg(sysbase,
321*4882a593Smuzhiyun SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3;
322*4882a593Smuzhiyun else
323*4882a593Smuzhiyun ref_clk_select = (nlm_read_sys_reg(sysbase,
324*4882a593Smuzhiyun SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
325*4882a593Smuzhiyun switch (ref_clk_select) {
326*4882a593Smuzhiyun case 0:
327*4882a593Smuzhiyun ref_clk = 200000000ULL;
328*4882a593Smuzhiyun ref_div = 3;
329*4882a593Smuzhiyun break;
330*4882a593Smuzhiyun case 1:
331*4882a593Smuzhiyun ref_clk = 100000000ULL;
332*4882a593Smuzhiyun ref_div = 1;
333*4882a593Smuzhiyun break;
334*4882a593Smuzhiyun case 2:
335*4882a593Smuzhiyun ref_clk = 125000000ULL;
336*4882a593Smuzhiyun ref_div = 1;
337*4882a593Smuzhiyun break;
338*4882a593Smuzhiyun case 3:
339*4882a593Smuzhiyun ref_clk = 400000000ULL;
340*4882a593Smuzhiyun ref_div = 3;
341*4882a593Smuzhiyun break;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun /* Find the clock source PLL device for PIC */
345*4882a593Smuzhiyun if (cpu_xlp9xx) {
346*4882a593Smuzhiyun reg_select = nlm_read_sys_reg(clockbase,
347*4882a593Smuzhiyun SYS_9XX_CLK_DEV_SEL_REG) & 0x3;
348*4882a593Smuzhiyun switch (reg_select) {
349*4882a593Smuzhiyun case 0:
350*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(clockbase,
351*4882a593Smuzhiyun SYS_9XX_PLL_CTRL0);
352*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(clockbase,
353*4882a593Smuzhiyun SYS_9XX_PLL_CTRL2);
354*4882a593Smuzhiyun break;
355*4882a593Smuzhiyun case 1:
356*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(clockbase,
357*4882a593Smuzhiyun SYS_9XX_PLL_CTRL0_DEVX(0));
358*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(clockbase,
359*4882a593Smuzhiyun SYS_9XX_PLL_CTRL2_DEVX(0));
360*4882a593Smuzhiyun break;
361*4882a593Smuzhiyun case 2:
362*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(clockbase,
363*4882a593Smuzhiyun SYS_9XX_PLL_CTRL0_DEVX(1));
364*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(clockbase,
365*4882a593Smuzhiyun SYS_9XX_PLL_CTRL2_DEVX(1));
366*4882a593Smuzhiyun break;
367*4882a593Smuzhiyun case 3:
368*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(clockbase,
369*4882a593Smuzhiyun SYS_9XX_PLL_CTRL0_DEVX(2));
370*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(clockbase,
371*4882a593Smuzhiyun SYS_9XX_PLL_CTRL2_DEVX(2));
372*4882a593Smuzhiyun break;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun } else {
375*4882a593Smuzhiyun reg_select = (nlm_read_sys_reg(sysbase,
376*4882a593Smuzhiyun SYS_CLK_DEV_SEL_REG) >> 22) & 0x3;
377*4882a593Smuzhiyun switch (reg_select) {
378*4882a593Smuzhiyun case 0:
379*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(sysbase,
380*4882a593Smuzhiyun SYS_PLL_CTRL0);
381*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(sysbase,
382*4882a593Smuzhiyun SYS_PLL_CTRL2);
383*4882a593Smuzhiyun break;
384*4882a593Smuzhiyun case 1:
385*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(sysbase,
386*4882a593Smuzhiyun SYS_PLL_CTRL0_DEVX(0));
387*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(sysbase,
388*4882a593Smuzhiyun SYS_PLL_CTRL2_DEVX(0));
389*4882a593Smuzhiyun break;
390*4882a593Smuzhiyun case 2:
391*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(sysbase,
392*4882a593Smuzhiyun SYS_PLL_CTRL0_DEVX(1));
393*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(sysbase,
394*4882a593Smuzhiyun SYS_PLL_CTRL2_DEVX(1));
395*4882a593Smuzhiyun break;
396*4882a593Smuzhiyun case 3:
397*4882a593Smuzhiyun ctrl_val0 = nlm_read_sys_reg(sysbase,
398*4882a593Smuzhiyun SYS_PLL_CTRL0_DEVX(2));
399*4882a593Smuzhiyun ctrl_val2 = nlm_read_sys_reg(sysbase,
400*4882a593Smuzhiyun SYS_PLL_CTRL2_DEVX(2));
401*4882a593Smuzhiyun break;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun vco_post_div = (ctrl_val0 >> 5) & 0x7;
406*4882a593Smuzhiyun pll_post_div = (ctrl_val0 >> 24) & 0x7;
407*4882a593Smuzhiyun mdiv = ctrl_val2 & 0xff;
408*4882a593Smuzhiyun fdiv = (ctrl_val2 >> 8) & 0x1fff;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun /* Find PLL post divider value */
411*4882a593Smuzhiyun switch (pll_post_div) {
412*4882a593Smuzhiyun case 1:
413*4882a593Smuzhiyun pll_post_div = 2;
414*4882a593Smuzhiyun break;
415*4882a593Smuzhiyun case 3:
416*4882a593Smuzhiyun pll_post_div = 4;
417*4882a593Smuzhiyun break;
418*4882a593Smuzhiyun case 7:
419*4882a593Smuzhiyun pll_post_div = 8;
420*4882a593Smuzhiyun break;
421*4882a593Smuzhiyun case 6:
422*4882a593Smuzhiyun pll_post_div = 16;
423*4882a593Smuzhiyun break;
424*4882a593Smuzhiyun case 0:
425*4882a593Smuzhiyun default:
426*4882a593Smuzhiyun pll_post_div = 1;
427*4882a593Smuzhiyun break;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun fdiv = fdiv/(1 << 13);
431*4882a593Smuzhiyun pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv;
432*4882a593Smuzhiyun pll_out_freq_den = (1 << vco_post_div) * pll_post_div * ref_div;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun if (pll_out_freq_den > 0)
435*4882a593Smuzhiyun do_div(pll_out_freq_num, pll_out_freq_den);
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun /* PIC post divider, which happens after PLL */
438*4882a593Smuzhiyun if (cpu_xlp9xx)
439*4882a593Smuzhiyun pic_div = nlm_read_sys_reg(clockbase,
440*4882a593Smuzhiyun SYS_9XX_CLK_DEV_DIV_REG) & 0x3;
441*4882a593Smuzhiyun else
442*4882a593Smuzhiyun pic_div = (nlm_read_sys_reg(sysbase,
443*4882a593Smuzhiyun SYS_CLK_DEV_DIV_REG) >> 22) & 0x3;
444*4882a593Smuzhiyun do_div(pll_out_freq_num, 1 << pic_div);
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun return pll_out_freq_num;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
nlm_get_pic_frequency(int node)449*4882a593Smuzhiyun unsigned int nlm_get_pic_frequency(int node)
450*4882a593Smuzhiyun {
451*4882a593Smuzhiyun if (cpu_is_xlpii())
452*4882a593Smuzhiyun return nlm_xlp2_get_pic_frequency(node);
453*4882a593Smuzhiyun else
454*4882a593Smuzhiyun return 133333333;
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun
nlm_get_cpu_frequency(void)457*4882a593Smuzhiyun unsigned int nlm_get_cpu_frequency(void)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun return nlm_get_core_frequency(0, 0);
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun /*
463*4882a593Smuzhiyun * Fills upto 8 pairs of entries containing the DRAM map of a node
464*4882a593Smuzhiyun * if node < 0, get dram map for all nodes
465*4882a593Smuzhiyun */
nlm_get_dram_map(int node,uint64_t * dram_map,int nentries)466*4882a593Smuzhiyun int nlm_get_dram_map(int node, uint64_t *dram_map, int nentries)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun uint64_t bridgebase, base, lim;
469*4882a593Smuzhiyun uint32_t val;
470*4882a593Smuzhiyun unsigned int barreg, limreg, xlatreg;
471*4882a593Smuzhiyun int i, n, rv;
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun /* Look only at mapping on Node 0, we don't handle crazy configs */
474*4882a593Smuzhiyun bridgebase = nlm_get_bridge_regbase(0);
475*4882a593Smuzhiyun rv = 0;
476*4882a593Smuzhiyun for (i = 0; i < 8; i++) {
477*4882a593Smuzhiyun if (rv + 1 >= nentries)
478*4882a593Smuzhiyun break;
479*4882a593Smuzhiyun if (cpu_is_xlp9xx()) {
480*4882a593Smuzhiyun barreg = BRIDGE_9XX_DRAM_BAR(i);
481*4882a593Smuzhiyun limreg = BRIDGE_9XX_DRAM_LIMIT(i);
482*4882a593Smuzhiyun xlatreg = BRIDGE_9XX_DRAM_NODE_TRANSLN(i);
483*4882a593Smuzhiyun } else {
484*4882a593Smuzhiyun barreg = BRIDGE_DRAM_BAR(i);
485*4882a593Smuzhiyun limreg = BRIDGE_DRAM_LIMIT(i);
486*4882a593Smuzhiyun xlatreg = BRIDGE_DRAM_NODE_TRANSLN(i);
487*4882a593Smuzhiyun }
488*4882a593Smuzhiyun if (node >= 0) {
489*4882a593Smuzhiyun /* node specified, get node mapping of BAR */
490*4882a593Smuzhiyun val = nlm_read_bridge_reg(bridgebase, xlatreg);
491*4882a593Smuzhiyun n = (val >> 1) & 0x3;
492*4882a593Smuzhiyun if (n != node)
493*4882a593Smuzhiyun continue;
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun val = nlm_read_bridge_reg(bridgebase, barreg);
496*4882a593Smuzhiyun val = (val >> 12) & 0xfffff;
497*4882a593Smuzhiyun base = (uint64_t) val << 20;
498*4882a593Smuzhiyun val = nlm_read_bridge_reg(bridgebase, limreg);
499*4882a593Smuzhiyun val = (val >> 12) & 0xfffff;
500*4882a593Smuzhiyun if (val == 0) /* BAR not used */
501*4882a593Smuzhiyun continue;
502*4882a593Smuzhiyun lim = ((uint64_t)val + 1) << 20;
503*4882a593Smuzhiyun dram_map[rv] = base;
504*4882a593Smuzhiyun dram_map[rv + 1] = lim;
505*4882a593Smuzhiyun rv += 2;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun return rv;
508*4882a593Smuzhiyun }
509