Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/23752
Change subject: soc/cavium: Implement common clock system ......................................................................
soc/cavium: Implement common clock system
Get rid of cn81xx custom clock code. Fix UART divisor.
Change-Id: Ifc4fdbaeec78e2fbc956b4821730f2c16f779b91 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/soc/cavium/cn81xx/Makefile.inc D src/soc/cavium/cn81xx/clock.c D src/soc/cavium/cn81xx/include/soc/clock.h M src/soc/cavium/cn81xx/include/soc/soc.h M src/soc/cavium/cn81xx/timer.c M src/soc/cavium/cn81xx/uart.c M src/soc/cavium/common/Makefile.inc A src/soc/cavium/common/clock.c M src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h A src/soc/cavium/common/include/soc/clock.h M src/soc/cavium/common/twsi.c M src/soc/cavium/common/wdt.c 12 files changed, 128 insertions(+), 197 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/52/23752/1
diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc index fbba930..8fe8f44 100644 --- a/src/soc/cavium/cn81xx/Makefile.inc +++ b/src/soc/cavium/cn81xx/Makefile.inc @@ -26,7 +26,6 @@ #bootblock-y += ../common/gpio.c #bootblock-y += ../common/pwm.c bootblock-y += bootblock.c -bootblock-y += clock.c #bootblock-y += gpio.c bootblock-y += twsi.c bootblock-y += l2c.c @@ -79,7 +78,6 @@ #verstage-y += ../common/i2c.c #verstage-y += spi.c #verstage-$(CONFIG_DRIVERS_UART) += uart.c -#verstage-y += clock.c #verstage-y += timer.c verstage-y += ../common/wdt.c
@@ -88,7 +86,6 @@ romstage-y += ../common/cbmem.c romstage-y += spi.c romstage-$(CONFIG_DRIVERS_UART) += uart.c -romstage-y += clock.c romstage-y += mmu_operations.c #romstage-y += ../common/pwm.c romstage-y += timer.c @@ -103,7 +100,6 @@ ramstage-y += spi.c ramstage-y += twsi.c ramstage-$(CONFIG_DRIVERS_UART) += uart.c -##ramstage-y += clock.c #ramstage-y += ../common/gpio.c #ramstage-y += gpio.c #ramstage-y += ../common/i2c.c diff --git a/src/soc/cavium/cn81xx/clock.c b/src/soc/cavium/cn81xx/clock.c deleted file mode 100644 index 0af466c..0000000 --- a/src/soc/cavium/cn81xx/clock.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2017-present Facebook, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arch/io.h> -#include <libbdk-hal/bdk-clock.h> -#include <soc/addressmap.h> -#include <soc/clock.h> -#include <soc/soc.h> -#include <soc/timer.h> - -uint64_t clock_get_rate(bdk_clock_t source) -{ - struct cn81xx_rst *rst = (struct cn81xx_rst *)RST_PF_BAR0; - const uint64_t REF_CLOCK = BDK_REF_CLOCK; - - u64 mul = read64(&rst->boot); - - switch (source) { - case BDK_CLOCK_TIME: - return BDK_GTI_RATE; /* Programed as part of setup */ - case BDK_CLOCK_MAIN_REF: - return REF_CLOCK; - case BDK_CLOCK_RCLK: - mul = (mul >> RST_BOOT_C_MUL_SHIFT) & RST_BOOT_C_MUL_MASK; - return REF_CLOCK * mul; - case BDK_CLOCK_SCLK: - mul = (mul >> RST_BOOT_PNR_MUL_SHIFT) & RST_BOOT_PNR_MUL_MASK; - return REF_CLOCK * mul; - } - - return 0; -} diff --git a/src/soc/cavium/cn81xx/include/soc/clock.h b/src/soc/cavium/cn81xx/include/soc/clock.h deleted file mode 100644 index ad535e0..0000000 --- a/src/soc/cavium/cn81xx/include/soc/clock.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (c) 2003-2017 Cavium Inc. (support@cavium.com). All rights - * reserved. - * Copyright 2017-present Facebook, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __SOC_CAVIUM_CN81XX_CLOCK_H__ -#define __SOC_CAVIUM_CN81XX_CLOCK_H__ - -#include <commonlib/helpers.h> -#include <libbdk-arch/bdk-numa.h> -#include <libbdk-hal/bdk-clock.h> -#include <soc/addressmap.h> -#include <types.h> - -#if 0 -enum cn81xx_clock_source { - BDK_CLOCK_TIME, /* Clock for telling time with fast access. Uses GTI in core */ - BDK_CLOCK_MAIN_REF, /* Main reference clock */ - BDK_CLOCK_RCLK, /* Clock used by cores, coherent bus and L2 cache. */ - BDK_CLOCK_SCLK, /* Clock used by IO blocks. */ -}; -#endif - -#define BDK_REF_CLOCK 50000000ULL - -#if 0 -uint64_t clock_get_rate(enum cn81xx_clock_source); -static inline uint64_t bdk_clock_get_rate(bdk_node_t node, enum cn81xx_clock_source clock) -{ - return clock_get_rate((enum cn81xx_clock_source)clock); -} -#endif -/* FIXME(dhendrix): ...and later moved into bdk-clock.h... */ -#if 0 -uint64_t clock_get_rate(bdk_clock_t clock); -static inline uint64_t clock_get_rate_slow(bdk_clock_t clock) -{ - clock_get_rate(clock); -} -#endif - -#endif /* __SOC_CAVIUM_CN81XX_CLOCK_H__ */ diff --git a/src/soc/cavium/cn81xx/include/soc/soc.h b/src/soc/cavium/cn81xx/include/soc/soc.h index d1f200b..a751e64 100644 --- a/src/soc/cavium/cn81xx/include/soc/soc.h +++ b/src/soc/cavium/cn81xx/include/soc/soc.h @@ -19,72 +19,6 @@ #include <inttypes.h> #include <types.h>
-/* RST registers */ -struct cn81xx_rst { - u64 boot; - u64 delay; - u64 cfg; - u64 ocx; - u8 rsvd1[0x8]; - u64 intr; - u64 intr_w1s; - u64 ckill; - u64 ctl0; - u64 ctl1; - u64 ctl2; - u8 rsvd2[0x28]; - u64 soft_rst; - u64 out_ctl; - u64 thermal_alert; - u8 rsvd3[0x8]; - u64 int_ena_w1s; - u64 int_ena_w1c; - u8 rsvd4[0x10]; - u64 soft_prst0; - u64 soft_prst1; - u64 soft_prst2; - u8 rsvd5[0x28]; - u64 pp_power; - u64 power_dbg; - u64 pp_power_stat; - u8 rsvd6[0x20]; - u64 pp_available; - u64 pp_reset; - u64 pp_pending; - u8 rsvd7[0x8]; - u64 ref_cntr; - u8 rsvd8[0x50]; - u64 debug; - u8 rsvd9[0x8]; - u64 cold_data0; - u64 cold_data1; - u64 cold_data2; - u64 cold_data3; - u64 cold_data4; - u64 cold_data5; -}; -check_member(cn81xx_rst, cold_data5, 0x17e8 - 0x1600); - -#define RST_BOOT_RBOOT_PIN (1 << 0) -#define RST_BOOT_RBOOT (1 << 1) -#define RST_BOOT_LBOOT_SHIFT 2 -#define RST_BOOT_LBOOT_MASK 0x3ff -#define RST_BOOT_LBOOT_EXT23_SHIFT 12 -#define RST_BOOT_LBOOT_EXT23_MASK 0x3f -#define RST_BOOT_LBOOT_JTG (1 << 24) -#define RST_BOOT_LBOOT_CKILL (1 << 25) -#define RST_BOOT_PNR_MUL_SHIFT 33 -#define RST_BOOT_PNR_MUL_MASK 0x3f -#define RST_BOOT_C_MUL_SHIFT 40 -#define RST_BOOT_C_MUL_MASK 0x7f -#define RST_BOOT_DIS_SCAN (1 << 55) -#define RST_BOOT_DIS_HUK (1 << 56) -#define RST_BOOT_JT_TSTMODE (1 << 58) -#define RST_BOOT_CKILL_PPDIS (1 << 59) -#define RST_BOOT_TRUSTED_MODE (1 << 60) -#define RST_BOOT_JTCSRDIS (1 << 62) -#define RST_BOOT_CHIPKILL (1 << 63) - /* MIO BOOT Registers */ struct cn81xx_mio_boot { u8 rsvd0[0xb0]; diff --git a/src/soc/cavium/cn81xx/timer.c b/src/soc/cavium/cn81xx/timer.c index 3d59a40..a60d5cb 100644 --- a/src/soc/cavium/cn81xx/timer.c +++ b/src/soc/cavium/cn81xx/timer.c @@ -39,7 +39,7 @@ return;
/* Configure GTI to tick at BDK_GTI_RATE */ - u64 sclk = clock_get_rate(BDK_CLOCK_SCLK); + u64 sclk = thunderx_get_io_clock(); #if 0 /* * FIXME(dhendrix): Had difficulty using reference code's way of @@ -58,7 +58,7 @@ read32(>i->cc_cntcr); /* FIXME: is this needed? */
/* Enable the core timer */ - BDK_MSR(CNTFRQ_EL0, BDK_GTI_RATE); /* Needed for Asim (FIXME: not needed for HW?) */ + BDK_MSR(CNTFRQ_EL0, 100000000ull); /* Needed for Asim (FIXME: not needed for HW?) */ #if 0 bdk_ap_cntps_ctl_el1_t cntps_ctl_el1; cntps_ctl_el1.u = 0; diff --git a/src/soc/cavium/cn81xx/uart.c b/src/soc/cavium/cn81xx/uart.c index b4759aa..aacca82 100644 --- a/src/soc/cavium/cn81xx/uart.c +++ b/src/soc/cavium/cn81xx/uart.c @@ -15,11 +15,22 @@ #include <stdint.h> #include <soc/clock.h> #include <soc/uart.h> +#include <assert.h> + +#define UART_SCLK_DIV 3 + +static size_t uart_sclk_divisor(size_t reg) +{ + static const u8 div[] = {1, 2, 4, 6, 8, 16, 24, 32}; + + assert(reg < ARRAY_SIZE(div)); + + return div[reg]; +}
unsigned int uart_platform_refclk(void) { - /* FIXME: this probably isn't right */ - return BDK_REF_CLOCK; + return thunderx_get_io_clock() / uart_sclk_divisor(UART_SCLK_DIV); }
uintptr_t uart_platform_base(int idx) @@ -45,7 +56,7 @@ c. Deassert the HCLK clock divider reset: UCTL_CTL[H_CLKDIV_RST] = 0. */ clrsetbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLKDIV_MASK << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT, - 3 << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT); + UART_SCLK_DIV << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT); clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLK_BYP_SEL); setbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLK_EN); clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLKDIV_RST); @@ -78,7 +89,8 @@ This means BRDI = 1 and BRDF = 0.085. Therefore, fractional part, BRDF = integer((0.085x64)+0.5) = 5 Generated baud rate divider = 1+5/64 = 1.078 */ - u64 divisor = clock_get_rate(BDK_CLOCK_SCLK) / (baudrate * 16 * 6 / 64); + u64 divisor = thunderx_get_io_clock() / + (baudrate * 16 * uart_sclk_divisor(UART_SCLK_DIV) / 64); write32(&uart->pl011.ibrd, divisor >> 6); write32(&uart->pl011.fbrd, divisor & UART_FBRD_BAUD_DIVFRAC_MASK);
diff --git a/src/soc/cavium/common/Makefile.inc b/src/soc/cavium/common/Makefile.inc index 6777dfc..48cc7bd 100644 --- a/src/soc/cavium/common/Makefile.inc +++ b/src/soc/cavium/common/Makefile.inc @@ -17,13 +17,17 @@
bootblock-$(CONFIG_BOOTBLOCK_CUSTOM) += bootblock.c bootblock-y += twsi.c +bootblock-y += clock.c
romstage-y += twsi.c +romstage-y += clock.c +
ramstage-y += twsi.c +ramstage-y += clock.c
CPPFLAGS_common += -Isrc/soc/cavium/common/include
diff --git a/src/soc/cavium/common/clock.c b/src/soc/cavium/common/clock.c new file mode 100644 index 0000000..1a5664d --- /dev/null +++ b/src/soc/cavium/common/clock.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2016, Cavium, Inc. support@cavium.com + * Aaron Williams, aaron.williams@cavium.com + * Copyright 2018-present Facebook, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <soc/clock.h> +#include <arch/io.h> + +#define RST_BOOT ((void *const)0x87e006001600ll) +#define PLL_REF_CLK 50000000 /* 50 MHz */ + +union cavm_rst_boot { + u64 u; + struct { + u64 rboot_pin:1; + u64 rboot:1; + u64 lboot:10; + u64 lboot_ext23:6; + u64 lboot_ext45:6; + u64 reserved_24_29:6; + u64 lboot_oci:3; + u64 pnr_mul:6; + u64 reserved_39_39:1; + u64 c_mul:7; + u64 reserved_47_54:8; + u64 dis_scan:1; + u64 dis_huk:1; + u64 vrm_err:1; + u64 jt_tstmode:1; + u64 ckill_ppdis:1; + u64 trusted_mode:1; + u64 ejtagdis:1; + u64 jtcsrdis:1; + u64 chipkill:1; + } s; +}; + +/** + * Returns the reference clock speed in Hz + */ +u64 thunderx_get_ref_clock(void) +{ + return PLL_REF_CLK; +} + + +/** + * Returns the I/O clock speed in Hz + */ +u64 thunderx_get_io_clock(void) +{ + union cavm_rst_boot rst_boot; + + rst_boot.u = read64(RST_BOOT); + + return rst_boot.s.pnr_mul * PLL_REF_CLK; +} + +/** + * Returns the core clock speed in Hz + */ +u64 thunderx_get_core_clock(void) +{ + union cavm_rst_boot rst_boot; + + rst_boot.u = read64(RST_BOOT); + + return rst_boot.s.c_mul * PLL_REF_CLK; +} diff --git a/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h b/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h index ce02223..9a22fde 100644 --- a/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h +++ b/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h @@ -42,6 +42,9 @@ /* FIXME(dhendrix): added */ #include <libbdk-arch/bdk-asm.h> #include <libbdk-arch/bdk-numa.h> +/* FIXME(prudolph): added */ + +#include <soc/clock.h>
/** * @file @@ -66,10 +69,21 @@ BDK_CLOCK_SCLK, /**< Clock used by IO blocks. */ } bdk_clock_t;
-uint64_t clock_get_rate(bdk_clock_t clock); static inline uint64_t clock_get_rate_slow(bdk_clock_t clock) { - clock_get_rate(clock); + const uint64_t REF_CLOCK = 50000000; + + switch (clock) { + case BDK_CLOCK_TIME: + return BDK_GTI_RATE; /* Programed as part of setup */ + case BDK_CLOCK_MAIN_REF: + return REF_CLOCK; + case BDK_CLOCK_RCLK: + return thunderx_get_core_clock(); + case BDK_CLOCK_SCLK: + return thunderx_get_io_clock(); + } + return 0; }
/** diff --git a/src/soc/cavium/common/include/soc/clock.h b/src/soc/cavium/common/include/soc/clock.h new file mode 100644 index 0000000..78025dc --- /dev/null +++ b/src/soc/cavium/common/include/soc/clock.h @@ -0,0 +1,15 @@ +/* + * Copyright 2018-present Facebook, Inc. + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef SRC_SOC_CAVIUM_CN81XX_INCLUDE_CLOCK_H_ +#define SRC_SOC_CAVIUM_CN81XX_INCLUDE_CLOCK_H_ + +#include <types.h> + +u64 thunderx_get_ref_clock(void); +u64 thunderx_get_io_clock(void); +u64 thunderx_get_core_clock(void); + +#endif /* SRC_SOC_CAVIUM_CN81XX_INCLUDE_CLOCK_H_ */ diff --git a/src/soc/cavium/common/twsi.c b/src/soc/cavium/common/twsi.c index e2ea838..d9fd3fb 100644 --- a/src/soc/cavium/common/twsi.c +++ b/src/soc/cavium/common/twsi.c @@ -6,16 +6,13 @@
#include <console/console.h> #include <soc/twsi.h> +#include <soc/clock.h> #include <device/i2c.h> #include <device/i2c_simple.h> #include <assert.h> #include <delay.h> #include <arch/io.h>
- -#define RST_BOOT ((void *const)0x87e006001600ll) -#define PLL_REF_CLK 50000000 /* 50 MHz */ - #define TWSI_THP 24
#define TWSI_SW_TWSI 0x1000 @@ -23,32 +20,6 @@ #define TWSI_INT 0x1010 #define TWSI_SW_TWSI_EXT 0x1018
-union rst_boot { - u64 u; - struct { - u64 rboot_pin:1; - u64 rboot:1; - u64 lboot:10; - u64 lboot_ext23:6; - u64 lboot_ext45:6; - u64 reserved_24_29:6; - u64 lboot_oci:3; - u64 pnr_mul:6; - u64 reserved_39_39:1; - u64 c_mul:7; - u64 reserved_47_54:8; - u64 dis_scan:1; - u64 dis_huk:1; - u64 vrm_err:1; - u64 jt_tstmode:1; - u64 ckill_ppdis:1; - u64 trusted_mode:1; - u64 ejtagdis:1; - u64 jtcsrdis:1; - u64 chipkill:1; - } s; -}; - union twsx_sw_twsi { u64 u; struct { @@ -636,16 +607,14 @@
static int twsi_set_speed(void *baseaddr, const unsigned int speed) { - int io_clock_hz; + u64 io_clock_hz; int n_div; int m_div; union twsx_sw_twsi sw_twsi; - union rst_boot rst_boot;
printk(BIOS_DEBUG, "%s(%p, %u)\n", __func__, baseaddr, speed); - rst_boot.u = read64(RST_BOOT);
- io_clock_hz = rst_boot.s.pnr_mul * PLL_REF_CLK; + io_clock_hz = thunderx_get_io_clock();
/* Set the TWSI clock to a conservative TWSI_BUS_FREQ. Compute the * clocks M divider based on the SCLK. diff --git a/src/soc/cavium/common/wdt.c b/src/soc/cavium/common/wdt.c index 514a304..9b0f28f 100644 --- a/src/soc/cavium/common/wdt.c +++ b/src/soc/cavium/common/wdt.c @@ -29,7 +29,7 @@ */ void watchdog_set(unsigned int timeout_ms) { - uint64_t sclk = clock_get_rate(BDK_CLOCK_SCLK); + uint64_t sclk = thunderx_get_io_clock(); uint64_t timeout_sclk = sclk * timeout_ms / 1000; /* Per comment above, we want the watchdog to expire at 3x the rate specified */ timeout_sclk /= 3;