xref: /linux/arch/mips/lantiq/xway/clk.c (revision 4413e16d9d21673bb5048a2e542f1aaa00015c2e)
1 /*
2  *  This program is free software; you can redistribute it and/or modify it
3  *  under the terms of the GNU General Public License version 2 as published
4  *  by the Free Software Foundation.
5  *
6  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7  */
8 
9 #include <linux/io.h>
10 #include <linux/export.h>
11 #include <linux/init.h>
12 #include <linux/clk.h>
13 
14 #include <asm/time.h>
15 #include <asm/irq.h>
16 #include <asm/div64.h>
17 
18 #include <lantiq_soc.h>
19 
20 #include "../clk.h"
21 
22 static unsigned int ram_clocks[] = {
23 	CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
24 #define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3]
25 
26 /* legacy xway clock */
27 #define CGU_SYS			0x10
28 
29 /* vr9 clock */
30 #define CGU_SYS_VR9		0x0c
31 #define CGU_IF_CLK_VR9		0x24
32 
33 unsigned long ltq_danube_fpi_hz(void)
34 {
35 	unsigned long ddr_clock = DDR_HZ;
36 
37 	if (ltq_cgu_r32(CGU_SYS) & 0x40)
38 		return ddr_clock >> 1;
39 	return ddr_clock;
40 }
41 
42 unsigned long ltq_danube_cpu_hz(void)
43 {
44 	switch (ltq_cgu_r32(CGU_SYS) & 0xc) {
45 	case 0:
46 		return CLOCK_333M;
47 	case 4:
48 		return DDR_HZ;
49 	case 8:
50 		return DDR_HZ << 1;
51 	default:
52 		return DDR_HZ >> 1;
53 	}
54 }
55 
56 unsigned long ltq_ar9_sys_hz(void)
57 {
58 	if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2)
59 		return CLOCK_393M;
60 	return CLOCK_333M;
61 }
62 
63 unsigned long ltq_ar9_fpi_hz(void)
64 {
65 	unsigned long sys = ltq_ar9_sys_hz();
66 
67 	if (ltq_cgu_r32(CGU_SYS) & BIT(0))
68 		return sys;
69 	return sys >> 1;
70 }
71 
72 unsigned long ltq_ar9_cpu_hz(void)
73 {
74 	if (ltq_cgu_r32(CGU_SYS) & BIT(2))
75 		return ltq_ar9_fpi_hz();
76 	else
77 		return ltq_ar9_sys_hz();
78 }
79 
80 unsigned long ltq_vr9_cpu_hz(void)
81 {
82 	unsigned int cpu_sel;
83 	unsigned long clk;
84 
85 	cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf;
86 
87 	switch (cpu_sel) {
88 	case 0:
89 		clk = CLOCK_600M;
90 		break;
91 	case 1:
92 		clk = CLOCK_500M;
93 		break;
94 	case 2:
95 		clk = CLOCK_393M;
96 		break;
97 	case 3:
98 		clk = CLOCK_333M;
99 		break;
100 	case 5:
101 	case 6:
102 		clk = CLOCK_196_608M;
103 		break;
104 	case 7:
105 		clk = CLOCK_167M;
106 		break;
107 	case 4:
108 	case 8:
109 	case 9:
110 		clk = CLOCK_125M;
111 		break;
112 	default:
113 		clk = 0;
114 		break;
115 	}
116 
117 	return clk;
118 }
119 
120 unsigned long ltq_vr9_fpi_hz(void)
121 {
122 	unsigned int ocp_sel, cpu_clk;
123 	unsigned long clk;
124 
125 	cpu_clk = ltq_vr9_cpu_hz();
126 	ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3;
127 
128 	switch (ocp_sel) {
129 	case 0:
130 		/* OCP ratio 1 */
131 		clk = cpu_clk;
132 		break;
133 	case 2:
134 		/* OCP ratio 2 */
135 		clk = cpu_clk / 2;
136 		break;
137 	case 3:
138 		/* OCP ratio 2.5 */
139 		clk = (cpu_clk * 2) / 5;
140 		break;
141 	case 4:
142 		/* OCP ratio 3 */
143 		clk = cpu_clk / 3;
144 		break;
145 	default:
146 		clk = 0;
147 		break;
148 	}
149 
150 	return clk;
151 }
152