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/clk.h> 12 13 #include <asm/time.h> 14 #include <asm/irq.h> 15 #include <asm/div64.h> 16 17 #include <lantiq_soc.h> 18 19 #include "../clk.h" 20 21 static unsigned int ram_clocks[] = { 22 CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; 23 #define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3] 24 25 /* legacy xway clock */ 26 #define CGU_SYS 0x10 27 28 /* vr9 clock */ 29 #define CGU_SYS_VR9 0x0c 30 #define CGU_IF_CLK_VR9 0x24 31 ltq_danube_fpi_hz(void)32unsigned long ltq_danube_fpi_hz(void) 33 { 34 unsigned long ddr_clock = DDR_HZ; 35 36 if (ltq_cgu_r32(CGU_SYS) & 0x40) 37 return ddr_clock >> 1; 38 return ddr_clock; 39 } 40 ltq_danube_cpu_hz(void)41unsigned long ltq_danube_cpu_hz(void) 42 { 43 switch (ltq_cgu_r32(CGU_SYS) & 0xc) { 44 case 0: 45 return CLOCK_333M; 46 case 4: 47 return DDR_HZ; 48 case 8: 49 return DDR_HZ << 1; 50 default: 51 return DDR_HZ >> 1; 52 } 53 } 54 ltq_danube_pp32_hz(void)55unsigned long ltq_danube_pp32_hz(void) 56 { 57 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3; 58 unsigned long clk; 59 60 switch (clksys) { 61 case 1: 62 clk = CLOCK_240M; 63 break; 64 case 2: 65 clk = CLOCK_222M; 66 break; 67 case 3: 68 clk = CLOCK_133M; 69 break; 70 default: 71 clk = CLOCK_266M; 72 break; 73 } 74 75 return clk; 76 } 77 ltq_ar9_sys_hz(void)78unsigned long ltq_ar9_sys_hz(void) 79 { 80 if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) 81 return CLOCK_393M; 82 return CLOCK_333M; 83 } 84 ltq_ar9_fpi_hz(void)85unsigned long ltq_ar9_fpi_hz(void) 86 { 87 unsigned long sys = ltq_ar9_sys_hz(); 88 89 if (ltq_cgu_r32(CGU_SYS) & BIT(0)) 90 return sys; 91 return sys >> 1; 92 } 93 ltq_ar9_cpu_hz(void)94unsigned long ltq_ar9_cpu_hz(void) 95 { 96 if (ltq_cgu_r32(CGU_SYS) & BIT(2)) 97 return ltq_ar9_fpi_hz(); 98 else 99 return ltq_ar9_sys_hz(); 100 } 101 ltq_vr9_cpu_hz(void)102unsigned long ltq_vr9_cpu_hz(void) 103 { 104 unsigned int cpu_sel; 105 unsigned long clk; 106 107 cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf; 108 109 switch (cpu_sel) { 110 case 0: 111 clk = CLOCK_600M; 112 break; 113 case 1: 114 clk = CLOCK_500M; 115 break; 116 case 2: 117 clk = CLOCK_393M; 118 break; 119 case 3: 120 clk = CLOCK_333M; 121 break; 122 case 5: 123 case 6: 124 clk = CLOCK_196_608M; 125 break; 126 case 7: 127 clk = CLOCK_167M; 128 break; 129 case 4: 130 case 8: 131 case 9: 132 clk = CLOCK_125M; 133 break; 134 default: 135 clk = 0; 136 break; 137 } 138 139 return clk; 140 } 141 ltq_vr9_fpi_hz(void)142unsigned long ltq_vr9_fpi_hz(void) 143 { 144 unsigned int ocp_sel, cpu_clk; 145 unsigned long clk; 146 147 cpu_clk = ltq_vr9_cpu_hz(); 148 ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3; 149 150 switch (ocp_sel) { 151 case 0: 152 /* OCP ratio 1 */ 153 clk = cpu_clk; 154 break; 155 case 2: 156 /* OCP ratio 2 */ 157 clk = cpu_clk / 2; 158 break; 159 case 3: 160 /* OCP ratio 2.5 */ 161 clk = (cpu_clk * 2) / 5; 162 break; 163 case 4: 164 /* OCP ratio 3 */ 165 clk = cpu_clk / 3; 166 break; 167 default: 168 clk = 0; 169 break; 170 } 171 172 return clk; 173 } 174 ltq_vr9_pp32_hz(void)175unsigned long ltq_vr9_pp32_hz(void) 176 { 177 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3; 178 unsigned long clk; 179 180 switch (clksys) { 181 case 1: 182 clk = CLOCK_450M; 183 break; 184 case 2: 185 clk = CLOCK_300M; 186 break; 187 default: 188 clk = CLOCK_500M; 189 break; 190 } 191 192 return clk; 193 } 194