[openwrt/openwrt] bmips: automatically detect CPU frequency

LEDE Commits lede-commits at lists.infradead.org
Mon Mar 8 08:46:07 GMT 2021


noltari pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/a3b863dc9fa799d5a2195131cd018898b044177f

commit a3b863dc9fa799d5a2195131cd018898b044177f
Author: Álvaro Fernández Rojas <noltari at gmail.com>
AuthorDate: Fri Mar 5 17:51:39 2021 +0100

    bmips: automatically detect CPU frequency
    
    Some BCM63xx SoCs support multiple CPU frequencies depending on HW
    configuration.
    
    Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
 ...-bmips-automatically-detect-CPU-frequency.patch | 239 +++++++++++++++++++++
 1 file changed, 239 insertions(+)

diff --git a/target/linux/bmips/patches-5.10/200-bmips-automatically-detect-CPU-frequency.patch b/target/linux/bmips/patches-5.10/200-bmips-automatically-detect-CPU-frequency.patch
new file mode 100644
index 0000000000..d68e4b97e8
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/200-bmips-automatically-detect-CPU-frequency.patch
@@ -0,0 +1,239 @@
+From 38d5e4b3bcc25db14a2d5f428acf56dff862c97e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 5 Mar 2021 15:14:32 +0100
+Subject: [PATCH] bmips: automatically detect CPU frequency
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some BCM63xx SoCs support multiple CPU frequencies depending on HW config.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ arch/mips/bmips/setup.c                   | 197 +++++++++++++++++++++-
+ arch/mips/configs/bmips_bcm63xx_defconfig |  91 ++++++++++
+ 2 files changed, 281 insertions(+), 7 deletions(-)
+ create mode 100644 arch/mips/configs/bmips_bcm63xx_defconfig
+
+--- a/arch/mips/bmips/setup.c
++++ b/arch/mips/bmips/setup.c
+@@ -31,11 +31,51 @@
+ 
+ #define RELO_NORMAL_VEC		BIT(18)
+ 
++#define REG_BCM6318_SOB		((void __iomem *)CKSEG1ADDR(0x10000900))
++#define BCM6318_FREQ_SHIFT	23
++#define BCM6318_FREQ_MASK	(0x3 << BCM6318_FREQ_SHIFT)
++
+ #define REG_BCM6328_OTP		((void __iomem *)CKSEG1ADDR(0x1000062c))
+ #define BCM6328_TP1_DISABLED	BIT(9)
++#define REG_BCM6328_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001a40))
++#define BCM6328_FCVO_SHIFT	7
++#define BCM6328_FCVO_MASK	(0x1f << BCM6328_FCVO_SHIFT)
++
++#define REG_BCM6358_DDR_PLLC	((void __iomem *)CKSEG1ADDR(0x100012b8))
++#define BCM6358_PLLC_M1_SHIFT	0
++#define BCM6358_PLLC_M1_MASK	(0xff << BCM6358_PLLC_M1_SHIFT)
++#define BCM6358_PLLC_N1_SHIFT	23
++#define BCM6358_PLLC_N1_MASK	(0x3f << BCM6358_PLLC_N1_SHIFT)
++#define BCM6358_PLLC_N2_SHIFT	29
++#define BCM6358_PLLC_N2_MASK	(0x7 << BCM6358_PLLC_N2_SHIFT)
++
++#define REG_BCM6362_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001814))
++#define BCM6362_FCVO_SHIFT	1
++#define BCM6362_FCVO_MASK	(0x1f << BCM6362_FCVO_SHIFT)
++
++#define REG_BCM6368_DDR_PLLC	((void __iomem *)CKSEG1ADDR(0x100012a0))
++#define BCM6368_PLLC_P1_SHIFT	0
++#define BCM6368_PLLC_P1_MASK	(0xf << BCM6368_PLLC_P1_SHIFT)
++#define BCM6368_PLLC_P2_SHIFT	4
++#define BCM6368_PLLC_P2_MASK	(0xf << BCM6368_PLLC_P2_SHIFT)
++#define BCM6368_PLLC_NDIV_SHIFT	16
++#define BCM6368_PLLC_NDIV_MASK	(0x1ff << BCM6368_PLLC_NDIV_SHIFT)
++#define REG_BCM6368_DDR_PLLD	((void __iomem *)CKSEG1ADDR(0x100012a4))
++#define BCM6368_PLLD_MDIV_SHIFT	0
++#define BCM6368_PLLD_MDIV_MASK	(0xff << BCM6368_PLLD_MDIV_SHIFT)
++
++#define REG_BCM63268_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001814))
++#define BCM63268_FCVO_SHIFT	21
++#define BCM63268_FCVO_MASK	(0xf << BCM63268_FCVO_SHIFT)
++
+ 
+ static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
+ 
++struct bmips_cpufreq {
++	const char		*compatible;
++	u32			(*cpu_freq)(void);
++};
++
+ struct bmips_quirk {
+ 	const char		*compatible;
+ 	void			(*quirk_fn)(void);
+@@ -138,17 +178,160 @@ const char *get_system_type(void)
+ 	return "Generic BMIPS kernel";
+ }
+ 
++static u32 bcm6318_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM6318_SOB);
++
++	switch ((val & BCM6318_FREQ_MASK) >> BCM6318_FREQ_SHIFT) {
++	case 0:
++		return 166000000;
++	case 2:
++		return 250000000;
++	case 3:
++		return 333000000;
++	case 1:
++		return 400000000;
++	default:
++		return 0;
++	}
++}
++
++static u32 bcm6328_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM6328_MISC_SB);
++
++	switch ((val & BCM6328_FCVO_MASK) >> BCM6328_FCVO_SHIFT) {
++	case 0x12:
++	case 0x14:
++	case 0x19:
++		return 160000000;
++	case 0x1c:
++		return 192000000;
++	case 0x13:
++	case 0x15:
++		return 200000000;
++	case 0x1a:
++		return 384000000;
++	case 0x16:
++		return 400000000;
++	default:
++		return 320000000;
++	}
++}
++
++static u32 bcm6358_cpufreq(void)
++{
++	u32 val, n1, n2, m1;
++
++	val = __raw_readl(REG_BCM6358_DDR_PLLC);
++	n1 = (val & BCM6358_PLLC_M1_MASK) >> BCM6358_PLLC_N1_SHIFT;
++	n2 = (val & BCM6358_PLLC_N2_MASK) >> BCM6358_PLLC_N2_SHIFT;
++	m1 = (val & BCM6358_PLLC_M1_MASK) >> BCM6358_PLLC_M1_SHIFT;
++
++	return (16 * 1000000 * n1 * n2) / m1;
++}
++
++static u32 bcm6362_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM6362_MISC_SB);
++
++	switch ((val & BCM6362_FCVO_MASK) >> BCM6362_FCVO_SHIFT) {
++	case 0x04:
++	case 0x0c:
++	case 0x14:
++	case 0x1c:
++		return 160000000;
++	case 0x15:
++	case 0x1d:
++		return 200000000;
++	case 0x03:
++	case 0x0b:
++	case 0x13:
++	case 0x1b:
++		return 240000000;
++	case 0x07:
++	case 0x17:
++		return 384000000;
++	case 0x05:
++	case 0x0e:
++	case 0x16:
++	case 0x1e:
++	case 0x1f:
++		return 400000000;
++	case 0x06:
++		return 440000000;
++	default:
++		return 320000000;
++	}
++}
++
++static u32 bcm6368_cpufreq(void)
++{
++	unsigned int val, p1, p2, ndiv, m1;
++
++	val = __raw_readl(REG_BCM6368_DDR_PLLC);
++	p1 = (val & BCM6368_PLLC_P1_MASK) >> BCM6368_PLLC_P1_SHIFT;
++	p2 = (val & BCM6368_PLLC_P2_MASK) >> BCM6368_PLLC_P2_SHIFT;
++	ndiv = (val & BCM6368_PLLC_NDIV_MASK) >>
++	       BCM6368_PLLC_NDIV_SHIFT;
++
++	val = __raw_readl(REG_BCM6368_DDR_PLLD);
++	m1 = (val & BCM6368_PLLD_MDIV_MASK) >> BCM6368_PLLD_MDIV_SHIFT;
++
++	return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
++}
++
++static u32 bcm63268_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM63268_MISC_SB);
++
++	switch ((val & BCM63268_FCVO_MASK) >> BCM63268_FCVO_SHIFT) {
++	case 0x3:
++	case 0xe:
++		return 320000000;
++	case 0xa:
++		return 333000000;
++	case 0x2:
++	case 0xb:
++	case 0xf:
++		return 400000000;
++	default:
++		return 0;
++	}
++}
++
++static const struct bmips_cpufreq bmips_cpufreq_list[] = {
++	{ "brcm,bcm6318", &bcm6318_cpufreq },
++	{ "brcm,bcm6328", &bcm6328_cpufreq },
++	{ "brcm,bcm6358", &bcm6358_cpufreq },
++	{ "brcm,bcm6362", &bcm6362_cpufreq },
++	{ "brcm,bcm6368", &bcm6368_cpufreq },
++	{ "brcm,bcm63268", &bcm63268_cpufreq },
++	{ /* sentinel */ }
++};
++
+ void __init plat_time_init(void)
+ {
++	const struct bmips_cpufreq *cf;
+ 	struct device_node *np;
+-	u32 freq;
++	u32 freq = 0;
+ 
+-	np = of_find_node_by_name(NULL, "cpus");
+-	if (!np)
+-		panic("missing 'cpus' DT node");
+-	if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
+-		panic("missing 'mips-hpt-frequency' property");
+-	of_node_put(np);
++	for (cf = bmips_cpufreq_list; cf->cpu_freq; cf++) {
++		if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
++					     cf->compatible)) {
++			freq = cf->cpu_freq() / 2;
++			printk("%s detected @ %u MHz\n", cf->compatible, freq / 500000);
++		}
++	}
++
++	if (!freq) {
++		np = of_find_node_by_name(NULL, "cpus");
++		if (!np)
++			panic("missing 'cpus' DT node");
++		if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
++			panic("missing 'mips-hpt-frequency' property");
++		of_node_put(np);
++	}
+ 
+ 	mips_hpt_frequency = freq;
+ }



More information about the lede-commits mailing list