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