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_danube_pp32_hz(void) 57 { 58 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3; 59 unsigned long clk; 60 61 switch (clksys) { 62 case 1: 63 clk = CLOCK_240M; 64 break; 65 case 2: 66 clk = CLOCK_222M; 67 break; 68 case 3: 69 clk = CLOCK_133M; 70 break; 71 default: 72 clk = CLOCK_266M; 73 break; 74 } 75 76 return clk; 77 } 78 79 unsigned long ltq_ar9_sys_hz(void) 80 { 81 if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) 82 return CLOCK_393M; 83 return CLOCK_333M; 84 } 85 86 unsigned long ltq_ar9_fpi_hz(void) 87 { 88 unsigned long sys = ltq_ar9_sys_hz(); 89 90 if (ltq_cgu_r32(CGU_SYS) & BIT(0)) 91 return sys; 92 return sys >> 1; 93 } 94 95 unsigned long ltq_ar9_cpu_hz(void) 96 { 97 if (ltq_cgu_r32(CGU_SYS) & BIT(2)) 98 return ltq_ar9_fpi_hz(); 99 else 100 return ltq_ar9_sys_hz(); 101 } 102 103 unsigned long ltq_vr9_cpu_hz(void) 104 { 105 unsigned int cpu_sel; 106 unsigned long clk; 107 108 cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf; 109 110 switch (cpu_sel) { 111 case 0: 112 clk = CLOCK_600M; 113 break; 114 case 1: 115 clk = CLOCK_500M; 116 break; 117 case 2: 118 clk = CLOCK_393M; 119 break; 120 case 3: 121 clk = CLOCK_333M; 122 break; 123 case 5: 124 case 6: 125 clk = CLOCK_196_608M; 126 break; 127 case 7: 128 clk = CLOCK_167M; 129 break; 130 case 4: 131 case 8: 132 case 9: 133 clk = CLOCK_125M; 134 break; 135 default: 136 clk = 0; 137 break; 138 } 139 140 return clk; 141 } 142 143 unsigned long ltq_vr9_fpi_hz(void) 144 { 145 unsigned int ocp_sel, cpu_clk; 146 unsigned long clk; 147 148 cpu_clk = ltq_vr9_cpu_hz(); 149 ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3; 150 151 switch (ocp_sel) { 152 case 0: 153 /* OCP ratio 1 */ 154 clk = cpu_clk; 155 break; 156 case 2: 157 /* OCP ratio 2 */ 158 clk = cpu_clk / 2; 159 break; 160 case 3: 161 /* OCP ratio 2.5 */ 162 clk = (cpu_clk * 2) / 5; 163 break; 164 case 4: 165 /* OCP ratio 3 */ 166 clk = cpu_clk / 3; 167 break; 168 default: 169 clk = 0; 170 break; 171 } 172 173 return clk; 174 } 175 176 unsigned long ltq_vr9_pp32_hz(void) 177 { 178 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3; 179 unsigned long clk; 180 181 switch (clksys) { 182 case 1: 183 clk = CLOCK_450M; 184 break; 185 case 2: 186 clk = CLOCK_300M; 187 break; 188 default: 189 clk = CLOCK_500M; 190 break; 191 } 192 193 return clk; 194 } 195