]> Pileus Git - ~andy/linux/blob - arch/mips/netlogic/xlp/nlm_hal.c
Merge branch 'slab/next' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg...
[~andy/linux] / arch / mips / netlogic / xlp / nlm_hal.c
1 /*
2  * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
3  * reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the NetLogic
9  * license below:
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in
19  *    the documentation and/or other materials provided with the
20  *    distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include <linux/types.h>
36 #include <linux/kernel.h>
37 #include <linux/mm.h>
38 #include <linux/delay.h>
39
40 #include <asm/mipsregs.h>
41 #include <asm/time.h>
42
43 #include <asm/netlogic/common.h>
44 #include <asm/netlogic/haldefs.h>
45 #include <asm/netlogic/xlp-hal/iomap.h>
46 #include <asm/netlogic/xlp-hal/xlp.h>
47 #include <asm/netlogic/xlp-hal/bridge.h>
48 #include <asm/netlogic/xlp-hal/pic.h>
49 #include <asm/netlogic/xlp-hal/sys.h>
50
51 /* Main initialization */
52 void nlm_node_init(int node)
53 {
54         struct nlm_soc_info *nodep;
55
56         nodep = nlm_get_node(node);
57         nodep->sysbase = nlm_get_sys_regbase(node);
58         nodep->picbase = nlm_get_pic_regbase(node);
59         nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
60         spin_lock_init(&nodep->piclock);
61 }
62
63 int nlm_irq_to_irt(int irq)
64 {
65         uint64_t pcibase;
66         int devoff, irt;
67
68         devoff = 0;
69         switch (irq) {
70         case PIC_UART_0_IRQ:
71                 devoff = XLP_IO_UART0_OFFSET(0);
72                 break;
73         case PIC_UART_1_IRQ:
74                 devoff = XLP_IO_UART1_OFFSET(0);
75                 break;
76         case PIC_MMC_IRQ:
77                 devoff = XLP_IO_SD_OFFSET(0);
78                 break;
79         case PIC_I2C_0_IRQ:     /* I2C will be fixed up */
80         case PIC_I2C_1_IRQ:
81         case PIC_I2C_2_IRQ:
82         case PIC_I2C_3_IRQ:
83                 if (cpu_is_xlpii())
84                         devoff = XLP2XX_IO_I2C_OFFSET(0);
85                 else
86                         devoff = XLP_IO_I2C0_OFFSET(0);
87                 break;
88         default:
89                 if (cpu_is_xlpii()) {
90                         switch (irq) {
91                                 /* XLP2XX has three XHCI USB controller */
92                         case PIC_2XX_XHCI_0_IRQ:
93                                 devoff = XLP2XX_IO_USB_XHCI0_OFFSET(0);
94                                 break;
95                         case PIC_2XX_XHCI_1_IRQ:
96                                 devoff = XLP2XX_IO_USB_XHCI1_OFFSET(0);
97                                 break;
98                         case PIC_2XX_XHCI_2_IRQ:
99                                 devoff = XLP2XX_IO_USB_XHCI2_OFFSET(0);
100                                 break;
101                         }
102                 } else {
103                         switch (irq) {
104                         case PIC_EHCI_0_IRQ:
105                                 devoff = XLP_IO_USB_EHCI0_OFFSET(0);
106                                 break;
107                         case PIC_EHCI_1_IRQ:
108                                 devoff = XLP_IO_USB_EHCI1_OFFSET(0);
109                                 break;
110                         case PIC_OHCI_0_IRQ:
111                                 devoff = XLP_IO_USB_OHCI0_OFFSET(0);
112                                 break;
113                         case PIC_OHCI_1_IRQ:
114                                 devoff = XLP_IO_USB_OHCI1_OFFSET(0);
115                                 break;
116                         case PIC_OHCI_2_IRQ:
117                                 devoff = XLP_IO_USB_OHCI2_OFFSET(0);
118                                 break;
119                         case PIC_OHCI_3_IRQ:
120                                 devoff = XLP_IO_USB_OHCI3_OFFSET(0);
121                                 break;
122                         }
123                 }
124         }
125
126         if (devoff != 0) {
127                 pcibase = nlm_pcicfg_base(devoff);
128                 irt = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG) & 0xffff;
129                 /* HW weirdness, I2C IRT entry has to be fixed up */
130                 switch (irq) {
131                 case PIC_I2C_1_IRQ:
132                         irt = irt + 1; break;
133                 case PIC_I2C_2_IRQ:
134                         irt = irt + 2; break;
135                 case PIC_I2C_3_IRQ:
136                         irt = irt + 3; break;
137                 }
138         } else if (irq >= PIC_PCIE_LINK_0_IRQ && irq <= PIC_PCIE_LINK_3_IRQ) {
139                 /* HW bug, PCI IRT entries are bad on early silicon, fix */
140                 irt = PIC_IRT_PCIE_LINK_INDEX(irq - PIC_PCIE_LINK_0_IRQ);
141         } else {
142                 irt = -1;
143         }
144         return irt;
145 }
146
147 unsigned int nlm_get_core_frequency(int node, int core)
148 {
149         unsigned int pll_divf, pll_divr, dfs_div, ext_div;
150         unsigned int rstval, dfsval, denom;
151         uint64_t num, sysbase;
152
153         sysbase = nlm_get_node(node)->sysbase;
154         rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
155         if (cpu_is_xlpii()) {
156                 num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26));
157                 denom = 3;
158         } else {
159                 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
160                 pll_divf = ((rstval >> 10) & 0x7f) + 1;
161                 pll_divr = ((rstval >> 8)  & 0x3) + 1;
162                 ext_div  = ((rstval >> 30) & 0x3) + 1;
163                 dfs_div  = ((dfsval >> (core * 4)) & 0xf) + 1;
164
165                 num = 800000000ULL * pll_divf;
166                 denom = 3 * pll_divr * ext_div * dfs_div;
167         }
168         do_div(num, denom);
169         return (unsigned int)num;
170 }
171
172 /* Calculate Frequency to the PIC from PLL.
173  * freq_out = ( ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13 ) /
174  * ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
175  */
176 static unsigned int nlm_2xx_get_pic_frequency(int node)
177 {
178         u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div;
179         u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
180         u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select;
181
182         sysbase = nlm_get_node(node)->sysbase;
183
184         /* Find ref_clk_base */
185         ref_clk_select =
186                 (nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
187         switch (ref_clk_select) {
188         case 0:
189                 ref_clk = 200000000ULL;
190                 ref_div = 3;
191                 break;
192         case 1:
193                 ref_clk = 100000000ULL;
194                 ref_div = 1;
195                 break;
196         case 2:
197                 ref_clk = 125000000ULL;
198                 ref_div = 1;
199                 break;
200         case 3:
201                 ref_clk = 400000000ULL;
202                 ref_div = 3;
203                 break;
204         }
205
206         /* Find the clock source PLL device for PIC */
207         reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3;
208         switch (reg_select) {
209         case 0:
210                 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0);
211                 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2);
212                 break;
213         case 1:
214                 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0));
215                 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0));
216                 break;
217         case 2:
218                 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1));
219                 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1));
220                 break;
221         case 3:
222                 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2));
223                 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2));
224                 break;
225         }
226
227         vco_post_div = (ctrl_val0 >> 5) & 0x7;
228         pll_post_div = (ctrl_val0 >> 24) & 0x7;
229         mdiv = ctrl_val2 & 0xff;
230         fdiv = (ctrl_val2 >> 8) & 0xfff;
231
232         /* Find PLL post divider value */
233         switch (pll_post_div) {
234         case 1:
235                 pll_post_div = 2;
236                 break;
237         case 3:
238                 pll_post_div = 4;
239                 break;
240         case 7:
241                 pll_post_div = 8;
242                 break;
243         case 6:
244                 pll_post_div = 16;
245                 break;
246         case 0:
247         default:
248                 pll_post_div = 1;
249                 break;
250         }
251
252         fdiv = fdiv/(1 << 13);
253         pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv;
254         pll_out_freq_den = (1 << vco_post_div) * pll_post_div * 3;
255
256         if (pll_out_freq_den > 0)
257                 do_div(pll_out_freq_num, pll_out_freq_den);
258
259         /* PIC post divider, which happens after PLL */
260         pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3;
261         do_div(pll_out_freq_num, 1 << pic_div);
262
263         return pll_out_freq_num;
264 }
265
266 unsigned int nlm_get_pic_frequency(int node)
267 {
268         if (cpu_is_xlpii())
269                 return nlm_2xx_get_pic_frequency(node);
270         else
271                 return 133333333;
272 }
273
274 unsigned int nlm_get_cpu_frequency(void)
275 {
276         return nlm_get_core_frequency(0, 0);
277 }
278
279 /*
280  * Fills upto 8 pairs of entries containing the DRAM map of a node
281  * if n < 0, get dram map for all nodes
282  */
283 int xlp_get_dram_map(int n, uint64_t *dram_map)
284 {
285         uint64_t bridgebase, base, lim;
286         uint32_t val;
287         int i, node, rv;
288
289         /* Look only at mapping on Node 0, we don't handle crazy configs */
290         bridgebase = nlm_get_bridge_regbase(0);
291         rv = 0;
292         for (i = 0; i < 8; i++) {
293                 val = nlm_read_bridge_reg(bridgebase,
294                                         BRIDGE_DRAM_NODE_TRANSLN(i));
295                 node = (val >> 1) & 0x3;
296                 if (n >= 0 && n != node)
297                         continue;
298                 val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_BAR(i));
299                 val = (val >>  12) & 0xfffff;
300                 base = (uint64_t) val << 20;
301                 val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_LIMIT(i));
302                 val = (val >>  12) & 0xfffff;
303                 if (val == 0)   /* BAR not used */
304                         continue;
305                 lim = ((uint64_t)val + 1) << 20;
306                 dram_map[rv] = base;
307                 dram_map[rv + 1] = lim;
308                 rv += 2;
309         }
310         return rv;
311 }