1*d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2287e3f3fSJohn Crispin /* 3287e3f3fSJohn Crispin * 497b92108SJohn Crispin * Copyright (C) 2010 John Crispin <john@phrozen.org> 5b5a03d0cSHauke Mehrtens * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG 6287e3f3fSJohn Crispin */ 7287e3f3fSJohn Crispin 8287e3f3fSJohn Crispin #include <linux/io.h> 9287e3f3fSJohn Crispin #include <linux/export.h> 10287e3f3fSJohn Crispin #include <linux/clk.h> 11287e3f3fSJohn Crispin 12287e3f3fSJohn Crispin #include <asm/time.h> 13287e3f3fSJohn Crispin #include <asm/irq.h> 14287e3f3fSJohn Crispin #include <asm/div64.h> 15287e3f3fSJohn Crispin 16287e3f3fSJohn Crispin #include <lantiq_soc.h> 17287e3f3fSJohn Crispin 18287e3f3fSJohn Crispin #include "../clk.h" 19287e3f3fSJohn Crispin 20287e3f3fSJohn Crispin static unsigned int ram_clocks[] = { 21287e3f3fSJohn Crispin CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; 22287e3f3fSJohn Crispin #define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3] 23287e3f3fSJohn Crispin 24287e3f3fSJohn Crispin /* legacy xway clock */ 25287e3f3fSJohn Crispin #define CGU_SYS 0x10 26287e3f3fSJohn Crispin 27b5a03d0cSHauke Mehrtens /* vr9, ar10/grx390 clock */ 28b5a03d0cSHauke Mehrtens #define CGU_SYS_XRX 0x0c 2961e371d8SHauke Mehrtens #define CGU_IF_CLK_AR10 0x24 30287e3f3fSJohn Crispin ltq_danube_fpi_hz(void)31287e3f3fSJohn Crispinunsigned long ltq_danube_fpi_hz(void) 32287e3f3fSJohn Crispin { 33287e3f3fSJohn Crispin unsigned long ddr_clock = DDR_HZ; 34287e3f3fSJohn Crispin 35287e3f3fSJohn Crispin if (ltq_cgu_r32(CGU_SYS) & 0x40) 36287e3f3fSJohn Crispin return ddr_clock >> 1; 37287e3f3fSJohn Crispin return ddr_clock; 38287e3f3fSJohn Crispin } 39287e3f3fSJohn Crispin ltq_danube_cpu_hz(void)40287e3f3fSJohn Crispinunsigned long ltq_danube_cpu_hz(void) 41287e3f3fSJohn Crispin { 42287e3f3fSJohn Crispin switch (ltq_cgu_r32(CGU_SYS) & 0xc) { 43287e3f3fSJohn Crispin case 0: 44287e3f3fSJohn Crispin return CLOCK_333M; 45287e3f3fSJohn Crispin case 4: 46287e3f3fSJohn Crispin return DDR_HZ; 47287e3f3fSJohn Crispin case 8: 48287e3f3fSJohn Crispin return DDR_HZ << 1; 49287e3f3fSJohn Crispin default: 50287e3f3fSJohn Crispin return DDR_HZ >> 1; 51287e3f3fSJohn Crispin } 52287e3f3fSJohn Crispin } 53287e3f3fSJohn Crispin ltq_danube_pp32_hz(void)54740c606eSJohn Crispinunsigned long ltq_danube_pp32_hz(void) 55740c606eSJohn Crispin { 56740c606eSJohn Crispin unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3; 57740c606eSJohn Crispin unsigned long clk; 58740c606eSJohn Crispin 59740c606eSJohn Crispin switch (clksys) { 60740c606eSJohn Crispin case 1: 61740c606eSJohn Crispin clk = CLOCK_240M; 62740c606eSJohn Crispin break; 63740c606eSJohn Crispin case 2: 64740c606eSJohn Crispin clk = CLOCK_222M; 65740c606eSJohn Crispin break; 66740c606eSJohn Crispin case 3: 67740c606eSJohn Crispin clk = CLOCK_133M; 68740c606eSJohn Crispin break; 69740c606eSJohn Crispin default: 70740c606eSJohn Crispin clk = CLOCK_266M; 71740c606eSJohn Crispin break; 72740c606eSJohn Crispin } 73740c606eSJohn Crispin 74740c606eSJohn Crispin return clk; 75740c606eSJohn Crispin } 76740c606eSJohn Crispin ltq_ar9_sys_hz(void)77287e3f3fSJohn Crispinunsigned long ltq_ar9_sys_hz(void) 78287e3f3fSJohn Crispin { 79287e3f3fSJohn Crispin if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) 80287e3f3fSJohn Crispin return CLOCK_393M; 81287e3f3fSJohn Crispin return CLOCK_333M; 82287e3f3fSJohn Crispin } 83287e3f3fSJohn Crispin ltq_ar9_fpi_hz(void)84287e3f3fSJohn Crispinunsigned long ltq_ar9_fpi_hz(void) 85287e3f3fSJohn Crispin { 86287e3f3fSJohn Crispin unsigned long sys = ltq_ar9_sys_hz(); 87287e3f3fSJohn Crispin 88287e3f3fSJohn Crispin if (ltq_cgu_r32(CGU_SYS) & BIT(0)) 891601078dSJohn Crispin return sys / 3; 901601078dSJohn Crispin else 911601078dSJohn Crispin return sys / 2; 92287e3f3fSJohn Crispin } 93287e3f3fSJohn Crispin ltq_ar9_cpu_hz(void)94287e3f3fSJohn Crispinunsigned long ltq_ar9_cpu_hz(void) 95287e3f3fSJohn Crispin { 96287e3f3fSJohn Crispin if (ltq_cgu_r32(CGU_SYS) & BIT(2)) 97287e3f3fSJohn Crispin return ltq_ar9_fpi_hz(); 98287e3f3fSJohn Crispin else 99287e3f3fSJohn Crispin return ltq_ar9_sys_hz(); 100287e3f3fSJohn Crispin } 101287e3f3fSJohn Crispin ltq_vr9_cpu_hz(void)102287e3f3fSJohn Crispinunsigned long ltq_vr9_cpu_hz(void) 103287e3f3fSJohn Crispin { 104287e3f3fSJohn Crispin unsigned int cpu_sel; 105287e3f3fSJohn Crispin unsigned long clk; 106287e3f3fSJohn Crispin 107b5a03d0cSHauke Mehrtens cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf; 108287e3f3fSJohn Crispin 109287e3f3fSJohn Crispin switch (cpu_sel) { 110287e3f3fSJohn Crispin case 0: 111287e3f3fSJohn Crispin clk = CLOCK_600M; 112287e3f3fSJohn Crispin break; 113287e3f3fSJohn Crispin case 1: 114287e3f3fSJohn Crispin clk = CLOCK_500M; 115287e3f3fSJohn Crispin break; 116287e3f3fSJohn Crispin case 2: 117287e3f3fSJohn Crispin clk = CLOCK_393M; 118287e3f3fSJohn Crispin break; 119287e3f3fSJohn Crispin case 3: 120287e3f3fSJohn Crispin clk = CLOCK_333M; 121287e3f3fSJohn Crispin break; 122287e3f3fSJohn Crispin case 5: 123287e3f3fSJohn Crispin case 6: 124287e3f3fSJohn Crispin clk = CLOCK_196_608M; 125287e3f3fSJohn Crispin break; 126287e3f3fSJohn Crispin case 7: 127287e3f3fSJohn Crispin clk = CLOCK_167M; 128287e3f3fSJohn Crispin break; 129287e3f3fSJohn Crispin case 4: 130287e3f3fSJohn Crispin case 8: 131287e3f3fSJohn Crispin case 9: 132287e3f3fSJohn Crispin clk = CLOCK_125M; 133287e3f3fSJohn Crispin break; 134287e3f3fSJohn Crispin default: 135287e3f3fSJohn Crispin clk = 0; 136287e3f3fSJohn Crispin break; 137287e3f3fSJohn Crispin } 138287e3f3fSJohn Crispin 139287e3f3fSJohn Crispin return clk; 140287e3f3fSJohn Crispin } 141287e3f3fSJohn Crispin ltq_vr9_fpi_hz(void)142287e3f3fSJohn Crispinunsigned long ltq_vr9_fpi_hz(void) 143287e3f3fSJohn Crispin { 144287e3f3fSJohn Crispin unsigned int ocp_sel, cpu_clk; 145287e3f3fSJohn Crispin unsigned long clk; 146287e3f3fSJohn Crispin 147287e3f3fSJohn Crispin cpu_clk = ltq_vr9_cpu_hz(); 148b5a03d0cSHauke Mehrtens ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3; 149287e3f3fSJohn Crispin 150287e3f3fSJohn Crispin switch (ocp_sel) { 151287e3f3fSJohn Crispin case 0: 152287e3f3fSJohn Crispin /* OCP ratio 1 */ 153287e3f3fSJohn Crispin clk = cpu_clk; 154287e3f3fSJohn Crispin break; 155287e3f3fSJohn Crispin case 2: 156287e3f3fSJohn Crispin /* OCP ratio 2 */ 157287e3f3fSJohn Crispin clk = cpu_clk / 2; 158287e3f3fSJohn Crispin break; 159287e3f3fSJohn Crispin case 3: 160287e3f3fSJohn Crispin /* OCP ratio 2.5 */ 161287e3f3fSJohn Crispin clk = (cpu_clk * 2) / 5; 162287e3f3fSJohn Crispin break; 163287e3f3fSJohn Crispin case 4: 164287e3f3fSJohn Crispin /* OCP ratio 3 */ 165287e3f3fSJohn Crispin clk = cpu_clk / 3; 166287e3f3fSJohn Crispin break; 167287e3f3fSJohn Crispin default: 168287e3f3fSJohn Crispin clk = 0; 169287e3f3fSJohn Crispin break; 170287e3f3fSJohn Crispin } 171287e3f3fSJohn Crispin 172287e3f3fSJohn Crispin return clk; 173287e3f3fSJohn Crispin } 174740c606eSJohn Crispin ltq_vr9_pp32_hz(void)175740c606eSJohn Crispinunsigned long ltq_vr9_pp32_hz(void) 176740c606eSJohn Crispin { 17718a3af60SHauke Mehrtens unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; 178740c606eSJohn Crispin unsigned long clk; 179740c606eSJohn Crispin 180740c606eSJohn Crispin switch (clksys) { 18118a3af60SHauke Mehrtens case 0: 18218a3af60SHauke Mehrtens clk = CLOCK_500M; 18318a3af60SHauke Mehrtens break; 184740c606eSJohn Crispin case 1: 18518a3af60SHauke Mehrtens clk = CLOCK_432M; 186740c606eSJohn Crispin break; 187740c606eSJohn Crispin case 2: 18818a3af60SHauke Mehrtens clk = CLOCK_288M; 189740c606eSJohn Crispin break; 190740c606eSJohn Crispin default: 191740c606eSJohn Crispin clk = CLOCK_500M; 192740c606eSJohn Crispin break; 193740c606eSJohn Crispin } 194740c606eSJohn Crispin 195740c606eSJohn Crispin return clk; 196740c606eSJohn Crispin } 19761e371d8SHauke Mehrtens ltq_ar10_cpu_hz(void)19861e371d8SHauke Mehrtensunsigned long ltq_ar10_cpu_hz(void) 19961e371d8SHauke Mehrtens { 20061e371d8SHauke Mehrtens unsigned int clksys; 20161e371d8SHauke Mehrtens int cpu_fs = (ltq_cgu_r32(CGU_SYS_XRX) >> 8) & 0x1; 20261e371d8SHauke Mehrtens int freq_div = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7; 20361e371d8SHauke Mehrtens 20461e371d8SHauke Mehrtens switch (cpu_fs) { 20561e371d8SHauke Mehrtens case 0: 20661e371d8SHauke Mehrtens clksys = CLOCK_500M; 20761e371d8SHauke Mehrtens break; 20861e371d8SHauke Mehrtens case 1: 20961e371d8SHauke Mehrtens clksys = CLOCK_600M; 21061e371d8SHauke Mehrtens break; 21161e371d8SHauke Mehrtens default: 21261e371d8SHauke Mehrtens clksys = CLOCK_500M; 21361e371d8SHauke Mehrtens break; 21461e371d8SHauke Mehrtens } 21561e371d8SHauke Mehrtens 21661e371d8SHauke Mehrtens switch (freq_div) { 21761e371d8SHauke Mehrtens case 0: 21861e371d8SHauke Mehrtens return clksys; 21961e371d8SHauke Mehrtens case 1: 22061e371d8SHauke Mehrtens return clksys >> 1; 22161e371d8SHauke Mehrtens case 2: 22261e371d8SHauke Mehrtens return clksys >> 2; 22361e371d8SHauke Mehrtens default: 22461e371d8SHauke Mehrtens return clksys; 22561e371d8SHauke Mehrtens } 22661e371d8SHauke Mehrtens } 22761e371d8SHauke Mehrtens ltq_ar10_fpi_hz(void)22861e371d8SHauke Mehrtensunsigned long ltq_ar10_fpi_hz(void) 22961e371d8SHauke Mehrtens { 23061e371d8SHauke Mehrtens int freq_fpi = (ltq_cgu_r32(CGU_IF_CLK_AR10) >> 25) & 0xf; 23161e371d8SHauke Mehrtens 23261e371d8SHauke Mehrtens switch (freq_fpi) { 23361e371d8SHauke Mehrtens case 1: 23461e371d8SHauke Mehrtens return CLOCK_300M; 23561e371d8SHauke Mehrtens case 5: 23661e371d8SHauke Mehrtens return CLOCK_250M; 23761e371d8SHauke Mehrtens case 2: 23861e371d8SHauke Mehrtens return CLOCK_150M; 23961e371d8SHauke Mehrtens case 6: 24061e371d8SHauke Mehrtens return CLOCK_125M; 24161e371d8SHauke Mehrtens 24261e371d8SHauke Mehrtens default: 24361e371d8SHauke Mehrtens return CLOCK_125M; 24461e371d8SHauke Mehrtens } 24561e371d8SHauke Mehrtens } 24661e371d8SHauke Mehrtens ltq_ar10_pp32_hz(void)24761e371d8SHauke Mehrtensunsigned long ltq_ar10_pp32_hz(void) 24861e371d8SHauke Mehrtens { 24961e371d8SHauke Mehrtens unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; 25061e371d8SHauke Mehrtens unsigned long clk; 25161e371d8SHauke Mehrtens 25261e371d8SHauke Mehrtens switch (clksys) { 25361e371d8SHauke Mehrtens case 1: 25461e371d8SHauke Mehrtens clk = CLOCK_250M; 25561e371d8SHauke Mehrtens break; 25661e371d8SHauke Mehrtens case 4: 25761e371d8SHauke Mehrtens clk = CLOCK_400M; 25861e371d8SHauke Mehrtens break; 25961e371d8SHauke Mehrtens default: 26061e371d8SHauke Mehrtens clk = CLOCK_250M; 26161e371d8SHauke Mehrtens break; 26261e371d8SHauke Mehrtens } 26361e371d8SHauke Mehrtens 26461e371d8SHauke Mehrtens return clk; 26561e371d8SHauke Mehrtens } 26661e371d8SHauke Mehrtens ltq_grx390_cpu_hz(void)26761e371d8SHauke Mehrtensunsigned long ltq_grx390_cpu_hz(void) 26861e371d8SHauke Mehrtens { 26961e371d8SHauke Mehrtens unsigned int clksys; 27061e371d8SHauke Mehrtens int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); 27161e371d8SHauke Mehrtens int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7); 27261e371d8SHauke Mehrtens 27361e371d8SHauke Mehrtens switch (cpu_fs) { 27461e371d8SHauke Mehrtens case 0: 27561e371d8SHauke Mehrtens clksys = CLOCK_600M; 27661e371d8SHauke Mehrtens break; 27761e371d8SHauke Mehrtens case 1: 27861e371d8SHauke Mehrtens clksys = CLOCK_666M; 27961e371d8SHauke Mehrtens break; 28061e371d8SHauke Mehrtens case 2: 28161e371d8SHauke Mehrtens clksys = CLOCK_720M; 28261e371d8SHauke Mehrtens break; 28361e371d8SHauke Mehrtens default: 28461e371d8SHauke Mehrtens clksys = CLOCK_600M; 28561e371d8SHauke Mehrtens break; 28661e371d8SHauke Mehrtens } 28761e371d8SHauke Mehrtens 28861e371d8SHauke Mehrtens switch (freq_div) { 28961e371d8SHauke Mehrtens case 0: 29061e371d8SHauke Mehrtens return clksys; 29161e371d8SHauke Mehrtens case 1: 29261e371d8SHauke Mehrtens return clksys >> 1; 29361e371d8SHauke Mehrtens case 2: 29461e371d8SHauke Mehrtens return clksys >> 2; 29561e371d8SHauke Mehrtens default: 29661e371d8SHauke Mehrtens return clksys; 29761e371d8SHauke Mehrtens } 29861e371d8SHauke Mehrtens } 29961e371d8SHauke Mehrtens ltq_grx390_fpi_hz(void)30061e371d8SHauke Mehrtensunsigned long ltq_grx390_fpi_hz(void) 30161e371d8SHauke Mehrtens { 30261e371d8SHauke Mehrtens /* fpi clock is derived from ddr_clk */ 30361e371d8SHauke Mehrtens unsigned int clksys; 30461e371d8SHauke Mehrtens int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); 30561e371d8SHauke Mehrtens int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX)) & 0x7); 30661e371d8SHauke Mehrtens switch (cpu_fs) { 30761e371d8SHauke Mehrtens case 0: 30861e371d8SHauke Mehrtens clksys = CLOCK_600M; 30961e371d8SHauke Mehrtens break; 31061e371d8SHauke Mehrtens case 1: 31161e371d8SHauke Mehrtens clksys = CLOCK_666M; 31261e371d8SHauke Mehrtens break; 31361e371d8SHauke Mehrtens case 2: 31461e371d8SHauke Mehrtens clksys = CLOCK_720M; 31561e371d8SHauke Mehrtens break; 31661e371d8SHauke Mehrtens default: 31761e371d8SHauke Mehrtens clksys = CLOCK_600M; 31861e371d8SHauke Mehrtens break; 31961e371d8SHauke Mehrtens } 32061e371d8SHauke Mehrtens 32161e371d8SHauke Mehrtens switch (freq_div) { 32261e371d8SHauke Mehrtens case 1: 32361e371d8SHauke Mehrtens return clksys >> 1; 32461e371d8SHauke Mehrtens case 2: 32561e371d8SHauke Mehrtens return clksys >> 2; 32661e371d8SHauke Mehrtens default: 32761e371d8SHauke Mehrtens return clksys >> 1; 32861e371d8SHauke Mehrtens } 32961e371d8SHauke Mehrtens } 33061e371d8SHauke Mehrtens ltq_grx390_pp32_hz(void)33161e371d8SHauke Mehrtensunsigned long ltq_grx390_pp32_hz(void) 33261e371d8SHauke Mehrtens { 33361e371d8SHauke Mehrtens unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; 33461e371d8SHauke Mehrtens unsigned long clk; 33561e371d8SHauke Mehrtens 33661e371d8SHauke Mehrtens switch (clksys) { 33761e371d8SHauke Mehrtens case 1: 33861e371d8SHauke Mehrtens clk = CLOCK_250M; 33961e371d8SHauke Mehrtens break; 34061e371d8SHauke Mehrtens case 2: 34161e371d8SHauke Mehrtens clk = CLOCK_432M; 34261e371d8SHauke Mehrtens break; 34361e371d8SHauke Mehrtens case 4: 34461e371d8SHauke Mehrtens clk = CLOCK_400M; 34561e371d8SHauke Mehrtens break; 34661e371d8SHauke Mehrtens default: 34761e371d8SHauke Mehrtens clk = CLOCK_250M; 34861e371d8SHauke Mehrtens break; 34961e371d8SHauke Mehrtens } 35061e371d8SHauke Mehrtens return clk; 35161e371d8SHauke Mehrtens } 352