forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
351 lines
5.2 KiB
351 lines
5.2 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* |
|
* |
|
* Copyright (C) 2010 John Crispin <[email protected]> |
|
* Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG |
|
*/ |
|
|
|
#include <linux/io.h> |
|
#include <linux/export.h> |
|
#include <linux/clk.h> |
|
|
|
#include <asm/time.h> |
|
#include <asm/irq.h> |
|
#include <asm/div64.h> |
|
|
|
#include <lantiq_soc.h> |
|
|
|
#include "../clk.h" |
|
|
|
static unsigned int ram_clocks[] = { |
|
CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; |
|
#define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3] |
|
|
|
/* legacy xway clock */ |
|
#define CGU_SYS 0x10 |
|
|
|
/* vr9, ar10/grx390 clock */ |
|
#define CGU_SYS_XRX 0x0c |
|
#define CGU_IF_CLK_AR10 0x24 |
|
|
|
unsigned long ltq_danube_fpi_hz(void) |
|
{ |
|
unsigned long ddr_clock = DDR_HZ; |
|
|
|
if (ltq_cgu_r32(CGU_SYS) & 0x40) |
|
return ddr_clock >> 1; |
|
return ddr_clock; |
|
} |
|
|
|
unsigned long ltq_danube_cpu_hz(void) |
|
{ |
|
switch (ltq_cgu_r32(CGU_SYS) & 0xc) { |
|
case 0: |
|
return CLOCK_333M; |
|
case 4: |
|
return DDR_HZ; |
|
case 8: |
|
return DDR_HZ << 1; |
|
default: |
|
return DDR_HZ >> 1; |
|
} |
|
} |
|
|
|
unsigned long ltq_danube_pp32_hz(void) |
|
{ |
|
unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3; |
|
unsigned long clk; |
|
|
|
switch (clksys) { |
|
case 1: |
|
clk = CLOCK_240M; |
|
break; |
|
case 2: |
|
clk = CLOCK_222M; |
|
break; |
|
case 3: |
|
clk = CLOCK_133M; |
|
break; |
|
default: |
|
clk = CLOCK_266M; |
|
break; |
|
} |
|
|
|
return clk; |
|
} |
|
|
|
unsigned long ltq_ar9_sys_hz(void) |
|
{ |
|
if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) |
|
return CLOCK_393M; |
|
return CLOCK_333M; |
|
} |
|
|
|
unsigned long ltq_ar9_fpi_hz(void) |
|
{ |
|
unsigned long sys = ltq_ar9_sys_hz(); |
|
|
|
if (ltq_cgu_r32(CGU_SYS) & BIT(0)) |
|
return sys / 3; |
|
else |
|
return sys / 2; |
|
} |
|
|
|
unsigned long ltq_ar9_cpu_hz(void) |
|
{ |
|
if (ltq_cgu_r32(CGU_SYS) & BIT(2)) |
|
return ltq_ar9_fpi_hz(); |
|
else |
|
return ltq_ar9_sys_hz(); |
|
} |
|
|
|
unsigned long ltq_vr9_cpu_hz(void) |
|
{ |
|
unsigned int cpu_sel; |
|
unsigned long clk; |
|
|
|
cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf; |
|
|
|
switch (cpu_sel) { |
|
case 0: |
|
clk = CLOCK_600M; |
|
break; |
|
case 1: |
|
clk = CLOCK_500M; |
|
break; |
|
case 2: |
|
clk = CLOCK_393M; |
|
break; |
|
case 3: |
|
clk = CLOCK_333M; |
|
break; |
|
case 5: |
|
case 6: |
|
clk = CLOCK_196_608M; |
|
break; |
|
case 7: |
|
clk = CLOCK_167M; |
|
break; |
|
case 4: |
|
case 8: |
|
case 9: |
|
clk = CLOCK_125M; |
|
break; |
|
default: |
|
clk = 0; |
|
break; |
|
} |
|
|
|
return clk; |
|
} |
|
|
|
unsigned long ltq_vr9_fpi_hz(void) |
|
{ |
|
unsigned int ocp_sel, cpu_clk; |
|
unsigned long clk; |
|
|
|
cpu_clk = ltq_vr9_cpu_hz(); |
|
ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3; |
|
|
|
switch (ocp_sel) { |
|
case 0: |
|
/* OCP ratio 1 */ |
|
clk = cpu_clk; |
|
break; |
|
case 2: |
|
/* OCP ratio 2 */ |
|
clk = cpu_clk / 2; |
|
break; |
|
case 3: |
|
/* OCP ratio 2.5 */ |
|
clk = (cpu_clk * 2) / 5; |
|
break; |
|
case 4: |
|
/* OCP ratio 3 */ |
|
clk = cpu_clk / 3; |
|
break; |
|
default: |
|
clk = 0; |
|
break; |
|
} |
|
|
|
return clk; |
|
} |
|
|
|
unsigned long ltq_vr9_pp32_hz(void) |
|
{ |
|
unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; |
|
unsigned long clk; |
|
|
|
switch (clksys) { |
|
case 0: |
|
clk = CLOCK_500M; |
|
break; |
|
case 1: |
|
clk = CLOCK_432M; |
|
break; |
|
case 2: |
|
clk = CLOCK_288M; |
|
break; |
|
default: |
|
clk = CLOCK_500M; |
|
break; |
|
} |
|
|
|
return clk; |
|
} |
|
|
|
unsigned long ltq_ar10_cpu_hz(void) |
|
{ |
|
unsigned int clksys; |
|
int cpu_fs = (ltq_cgu_r32(CGU_SYS_XRX) >> 8) & 0x1; |
|
int freq_div = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7; |
|
|
|
switch (cpu_fs) { |
|
case 0: |
|
clksys = CLOCK_500M; |
|
break; |
|
case 1: |
|
clksys = CLOCK_600M; |
|
break; |
|
default: |
|
clksys = CLOCK_500M; |
|
break; |
|
} |
|
|
|
switch (freq_div) { |
|
case 0: |
|
return clksys; |
|
case 1: |
|
return clksys >> 1; |
|
case 2: |
|
return clksys >> 2; |
|
default: |
|
return clksys; |
|
} |
|
} |
|
|
|
unsigned long ltq_ar10_fpi_hz(void) |
|
{ |
|
int freq_fpi = (ltq_cgu_r32(CGU_IF_CLK_AR10) >> 25) & 0xf; |
|
|
|
switch (freq_fpi) { |
|
case 1: |
|
return CLOCK_300M; |
|
case 5: |
|
return CLOCK_250M; |
|
case 2: |
|
return CLOCK_150M; |
|
case 6: |
|
return CLOCK_125M; |
|
|
|
default: |
|
return CLOCK_125M; |
|
} |
|
} |
|
|
|
unsigned long ltq_ar10_pp32_hz(void) |
|
{ |
|
unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; |
|
unsigned long clk; |
|
|
|
switch (clksys) { |
|
case 1: |
|
clk = CLOCK_250M; |
|
break; |
|
case 4: |
|
clk = CLOCK_400M; |
|
break; |
|
default: |
|
clk = CLOCK_250M; |
|
break; |
|
} |
|
|
|
return clk; |
|
} |
|
|
|
unsigned long ltq_grx390_cpu_hz(void) |
|
{ |
|
unsigned int clksys; |
|
int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); |
|
int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7); |
|
|
|
switch (cpu_fs) { |
|
case 0: |
|
clksys = CLOCK_600M; |
|
break; |
|
case 1: |
|
clksys = CLOCK_666M; |
|
break; |
|
case 2: |
|
clksys = CLOCK_720M; |
|
break; |
|
default: |
|
clksys = CLOCK_600M; |
|
break; |
|
} |
|
|
|
switch (freq_div) { |
|
case 0: |
|
return clksys; |
|
case 1: |
|
return clksys >> 1; |
|
case 2: |
|
return clksys >> 2; |
|
default: |
|
return clksys; |
|
} |
|
} |
|
|
|
unsigned long ltq_grx390_fpi_hz(void) |
|
{ |
|
/* fpi clock is derived from ddr_clk */ |
|
unsigned int clksys; |
|
int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); |
|
int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX)) & 0x7); |
|
switch (cpu_fs) { |
|
case 0: |
|
clksys = CLOCK_600M; |
|
break; |
|
case 1: |
|
clksys = CLOCK_666M; |
|
break; |
|
case 2: |
|
clksys = CLOCK_720M; |
|
break; |
|
default: |
|
clksys = CLOCK_600M; |
|
break; |
|
} |
|
|
|
switch (freq_div) { |
|
case 1: |
|
return clksys >> 1; |
|
case 2: |
|
return clksys >> 2; |
|
default: |
|
return clksys >> 1; |
|
} |
|
} |
|
|
|
unsigned long ltq_grx390_pp32_hz(void) |
|
{ |
|
unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; |
|
unsigned long clk; |
|
|
|
switch (clksys) { |
|
case 1: |
|
clk = CLOCK_250M; |
|
break; |
|
case 2: |
|
clk = CLOCK_432M; |
|
break; |
|
case 4: |
|
clk = CLOCK_400M; |
|
break; |
|
default: |
|
clk = CLOCK_250M; |
|
break; |
|
} |
|
return clk; |
|
}
|
|
|