Am Freitag, den 19.06.2020, 15:44 +0200 schrieb Stefan Roese: > From: Aaron Williams <awilli...@marvell.com> > > This patch adds very basic support for the Octeon III SoCs. Only > CFI parallel NOR flash and UART is supported for now. > > Please note that the basic Octeon port does not include the DDR3/4 > initialization yet. This will be added in some follow-up patches > later. To still use U-Boot on with this port, the L2 cache (4MiB on > Octeon III CN73xx) is used as RAM. This way, U-Boot can boot to the > prompt on such boards. > > Signed-off-by: Aaron Williams <awilli...@marvell.com> > Signed-off-by: Stefan Roese <s...@denx.de> > > --- > > Changes in v3: > - Don't "relocate" to L2 cache for now > - Remove inclusion of "common.h" > > Changes in v2: > - Remove custom start.S and use common start.S. Minimal custom lowlevel > init code is currently added in the custom lowlevel_init.S. This needs > to be extended with necessary code, like errata handling etc. But for > a very first basic port, this seems to be all thats needed to boot on > the EBB7304 to the prompt. > - Removed select CREATE_ARCH_SYMLINK > - Removed Octeon II support, as its currently no added in this patchset > - Added cache.c to add the platform specific cache functions as no-ops > for Octeon as the platform is cache coherent > - Removed CONFIG_MIPS_CACHE_COHERENT > - Added CONFIG_CPU_CAVIUM_OCTEON to Kconfig and selected it for Octeon > to enable better sync with the Linux files in the future > - Add get_tbclk() -> no need to define CONFIG_SYS_MIPS_TIMER_FREQ any more > > MAINTAINERS | 6 ++ > arch/mips/Kconfig | 41 +++++++++++++ > arch/mips/Makefile | 3 + > arch/mips/mach-octeon/Kconfig | 46 +++++++++++++++ > arch/mips/mach-octeon/Makefile | 10 ++++ > arch/mips/mach-octeon/cache.c | 20 +++++++ > arch/mips/mach-octeon/clock.c | 27 +++++++++ > arch/mips/mach-octeon/cpu.c | 57 +++++++++++++++++++ > arch/mips/mach-octeon/dram.c | 28 +++++++++ > arch/mips/mach-octeon/include/ioremap.h | 30 ++++++++++ > arch/mips/mach-octeon/include/mach/cavm-reg.h | 42 ++++++++++++++ > arch/mips/mach-octeon/include/mach/clock.h | 22 +++++++ > arch/mips/mach-octeon/lowlevel_init.S | 19 +++++++ > scripts/config_whitelist.txt | 1 - > 14 files changed, 351 insertions(+), 1 deletion(-) > create mode 100644 arch/mips/mach-octeon/Kconfig > create mode 100644 arch/mips/mach-octeon/Makefile > create mode 100644 arch/mips/mach-octeon/cache.c > create mode 100644 arch/mips/mach-octeon/clock.c > create mode 100644 arch/mips/mach-octeon/cpu.c > create mode 100644 arch/mips/mach-octeon/dram.c > create mode 100644 arch/mips/mach-octeon/include/ioremap.h > create mode 100644 arch/mips/mach-octeon/include/mach/cavm-reg.h > create mode 100644 arch/mips/mach-octeon/include/mach/clock.h > create mode 100644 arch/mips/mach-octeon/lowlevel_init.S > > diff --git a/MAINTAINERS b/MAINTAINERS > index 1fd975c72f..0aa0357967 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -763,6 +763,12 @@ M: Ezequiel Garcia <ezequ...@collabora.com> > S: Maintained > F: arch/mips/mach-jz47xx/ > > +MIPS Octeon > +M: Aaron Williams <awilli...@marvell.com> > +S: Maintained > +F: arch/mips/mach-octeon/ > +F: arch/mips/include/asm/arch-octeon/ > + > MMC > M: Peng Fan <peng....@nxp.com> > S: Maintained > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig > index bccd06cb0c..dd56da6dae 100644 > --- a/arch/mips/Kconfig > +++ b/arch/mips/Kconfig > @@ -106,6 +106,23 @@ config ARCH_JZ47XX > select OF_CONTROL > select DM > > +config ARCH_OCTEON > + bool "Support Marvell Octeon CN7xxx platforms" > + select CPU_CAVIUM_OCTEON > + select DISPLAY_CPUINFO > + select DMA_ADDR_T_64BIT > + select DM > + select DM_SERIAL > + select MIPS_L2_CACHE > + select MIPS_TUNE_OCTEON3 > + select ROM_EXCEPTION_VECTORS > + select SUPPORTS_BIG_ENDIAN > + select SUPPORTS_CPU_MIPS64_OCTEON > + select PHYS_64BIT > + select OF_CONTROL > + select OF_LIVE > + imply CMD_DM > + > config MACH_PIC32 > bool "Support Microchip PIC32" > select DM > @@ -160,6 +177,7 @@ source "arch/mips/mach-bmips/Kconfig" > source "arch/mips/mach-jz47xx/Kconfig" > source "arch/mips/mach-pic32/Kconfig" > source "arch/mips/mach-mtmips/Kconfig" > +source "arch/mips/mach-octeon/Kconfig" > > if MIPS > > @@ -233,6 +251,14 @@ config CPU_MIPS64_R6 > Choose this option to build a kernel for release 6 or later of the > MIPS64 architecture. > > +config CPU_MIPS64_OCTEON > + bool "Marvell Octeon series of CPUs" > + depends on SUPPORTS_CPU_MIPS64_OCTEON > + select 64BIT > + help > + Choose this option for Marvell Octeon CPUs. These CPUs are between > + MIPS64 R5 and R6 with other extensions. > + > endchoice > > menu "General setup" > @@ -408,6 +434,12 @@ config SUPPORTS_CPU_MIPS64_R2 > config SUPPORTS_CPU_MIPS64_R6 > bool > > +config SUPPORTS_CPU_MIPS64_OCTEON > + bool > + > +config CPU_CAVIUM_OCTEON > + bool > + > config CPU_MIPS32 > bool > default y if CPU_MIPS32_R1 || CPU_MIPS32_R2 || CPU_MIPS32_R6 > @@ -415,6 +447,7 @@ config CPU_MIPS32 > config CPU_MIPS64 > bool > default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 || CPU_MIPS64_R6 > + default y if CPU_MIPS64_OCTEON > > config MIPS_TUNE_4KC > bool > @@ -431,6 +464,9 @@ config MIPS_TUNE_34KC > config MIPS_TUNE_74KC > bool > > +config MIPS_TUNE_OCTEON3 > + bool > + > config 32BIT > bool > > @@ -463,6 +499,11 @@ config MIPS_SRAM_INIT > before it can be used. If enabled, a function mips_sram_init() will > be called just before setup_stack_gd. > > +config DMA_ADDR_T_64BIT > + bool > + help > + Select this to enable 64-bit DMA addressing > + > config SYS_DCACHE_SIZE > int > default 0 > diff --git a/arch/mips/Makefile b/arch/mips/Makefile > index af3f227436..6502aebd29 100644 > --- a/arch/mips/Makefile > +++ b/arch/mips/Makefile > @@ -17,6 +17,7 @@ machine-$(CONFIG_ARCH_JZ47XX) += jz47xx > machine-$(CONFIG_MACH_PIC32) += pic32 > machine-$(CONFIG_ARCH_MTMIPS) += mtmips > machine-$(CONFIG_ARCH_MSCC) += mscc > +machine-${CONFIG_ARCH_OCTEON} += octeon > > machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y)) > libs-y += $(machdirs) > @@ -30,6 +31,7 @@ arch-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 > -Wa,-mips32r6 > arch-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,-mips64 > arch-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,-mips64r2 > arch-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,-mips64r6 > +arch-${CONFIG_CPU_MIPS64_OCTEON} += -march=octeon2 > > # Allow extra optimization for specific CPUs/SoCs > tune-$(CONFIG_MIPS_TUNE_4KC) += -mtune=4kc > @@ -37,6 +39,7 @@ tune-$(CONFIG_MIPS_TUNE_14KC) += -mtune=14kc > tune-$(CONFIG_MIPS_TUNE_24KC) += -mtune=24kc > tune-$(CONFIG_MIPS_TUNE_34KC) += -mtune=34kc > tune-$(CONFIG_MIPS_TUNE_74KC) += -mtune=74kc > +tune-${CONFIG_MIPS_TUNE_OCTEON3} += -mtune=octeon2 > > # Include default header files > cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic > diff --git a/arch/mips/mach-octeon/Kconfig b/arch/mips/mach-octeon/Kconfig > new file mode 100644 > index 0000000000..3c8ca8dd36 > --- /dev/null > +++ b/arch/mips/mach-octeon/Kconfig > @@ -0,0 +1,46 @@ > +menu "Octeon platforms" > + depends on ARCH_OCTEON > + > +config SYS_SOC > + string > + default "octeon" > + > +config OCTEON_CN7XXX > + bool "Octeon CN7XXX SoC" > + > +config OCTEON_CN70XX > + bool "Octeon CN70XX SoC" > + select OCTEON_CN7XXX > + > +config OCTEON_CN73XX > + bool "Octeon CN73XX SoC" > + select OCTEON_CN7XXX > + > +config OCTEON_CN78XX > + bool "Octeon CN78XX SoC" > + select OCTEON_CN7XXX > + > +choice > + prompt "Octeon MIPS family select" > + > +config SOC_OCTEON3 > + bool "Octeon III family" > + help > + This selects the Octeon III SoC family CN70xx, CN73XX, CN78xx > + and CNF75XX. > + > +endchoice > + > +config SYS_DCACHE_SIZE > + default 32768 > + > +config SYS_DCACHE_LINE_SIZE > + default 128 > + > +config SYS_ICACHE_SIZE > + default 79872 > + > +config SYS_ICACHE_LINE_SIZE > + default 128 > + > +endmenu > diff --git a/arch/mips/mach-octeon/Makefile b/arch/mips/mach-octeon/Makefile > new file mode 100644 > index 0000000000..2e37ca572c > --- /dev/null > +++ b/arch/mips/mach-octeon/Makefile > @@ -0,0 +1,10 @@ > +# (C) Copyright 2019 Marvell, Inc. > +# > +# SPDX-License-Identifier: GPL-2.0+ > +# > + > +obj-y += lowlevel_init.o > +obj-y += cache.o > +obj-y += clock.o > +obj-y += cpu.o > +obj-y += dram.o > diff --git a/arch/mips/mach-octeon/cache.c b/arch/mips/mach-octeon/cache.c > new file mode 100644 > index 0000000000..bea846d757 > --- /dev/null > +++ b/arch/mips/mach-octeon/cache.c > @@ -0,0 +1,20 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2020 Marvell International Ltd. > + */ > + > +#include <cpu_func.h> > + > +/* > + * The Octeon platform is cache coherent and cache flushes and invalidates > + * are not needed. Define some platform specific empty flush_foo() > + * functions here to overwrite the _weak common function as a no-op. > + * This effectively disables all cache operations. > + */ > +void flush_dcache_range(ulong start_addr, ulong stop) > +{ > +} > + > +void flush_cache(ulong start_addr, ulong size) > +{ > +} > diff --git a/arch/mips/mach-octeon/clock.c b/arch/mips/mach-octeon/clock.c > new file mode 100644 > index 0000000000..fc3776dc8f > --- /dev/null > +++ b/arch/mips/mach-octeon/clock.c > @@ -0,0 +1,27 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018, 2019 Marvell International Ltd. > + */ > + > +#include <asm/global_data.h> > +#include <mach/clock.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +ulong notrace get_tbclk(void) > +{ > + return gd->cpu_clk; > +} > + > +int octeon_get_timer_freq(void) > +{ > + return gd->cpu_clk; > +} > + > +/** > + * Returns the I/O clock speed in Hz > + */ > +u64 octeon_get_io_clock(void) > +{ > + return gd->bus_clk; > +}
do you plan to add a clock driver later? Than you could use the generic clock API in driver and wouldn't need to add custom functions ;) > diff --git a/arch/mips/mach-octeon/cpu.c b/arch/mips/mach-octeon/cpu.c > new file mode 100644 > index 0000000000..7ef17a7d66 > --- /dev/null > +++ b/arch/mips/mach-octeon/cpu.c > @@ -0,0 +1,57 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2020 Marvell International Ltd. > + */ > + > +#include <asm/global_data.h> > +#include <linux/bitops.h> > +#include <linux/compat.h> > +#include <linux/io.h> > +#include <mach/clock.h> > +#include <mach/cavm-reg.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +static int get_clocks(void) > +{ > + const u64 ref_clock = PLL_REF_CLK; > + union cavm_rst_boot rst_boot; > + > + rst_boot.u = ioread64(CAVM_RST_BOOT); > + gd->cpu_clk = ref_clock * rst_boot.s.c_mul; > + gd->bus_clk = ref_clock * rst_boot.s.pnr_mul; > + > + debug("%s: cpu: %lu, bus: %lu\n", __func__, gd->cpu_clk, gd->bus_clk); > + > + return 0; > +} > + > +/* Early mach init code run from flash */ > +int mach_cpu_init(void) > +{ > + /* Remap boot-bus 0x1fc0.0000 -> 0x1f40.0000 */ > + /* ToDo: Move this to an early running bus (bootbus) DM driver */ > + clrsetbits_be64(CAVM_MIO_BOOT_REG_CFG0, 0xffff, 0x1f40); > + > + /* Get clocks and store them in GD */ > + get_clocks(); > + > + return 0; > +} > + > +/** > + * Returns number of cores > + * > + * @return number of CPU cores for the specified node > + */ > +static int cavm_octeon_num_cores(void) > +{ > + return fls64(ioread64(CAVM_CIU_FUSE) & 0xffffffffffff); > +} > + > +int print_cpuinfo(void) > +{ > + printf("SoC: Octeon CN73xx (%d cores)\n", cavm_octeon_num_cores()); > + > + return 0; > +} > diff --git a/arch/mips/mach-octeon/dram.c b/arch/mips/mach-octeon/dram.c > new file mode 100644 > index 0000000000..ff7a59f2ab > --- /dev/null > +++ b/arch/mips/mach-octeon/dram.c > @@ -0,0 +1,28 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) Stefan Roese <s...@denx.de> > + */ > + > +#include <dm.h> > +#include <ram.h> > +#include <asm/global_data.h> > +#include <linux/compat.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +int dram_init(void) > +{ > + /* > + * No DDR init yet -> run in L2 cache > + */ > + gd->ram_size = (4 << 20); > + gd->bd->bi_dram[0].size = gd->ram_size; > + gd->bd->bi_dram[1].size = 0; > + > + return 0; > +} > + > +ulong board_get_usable_ram_top(ulong total_size) > +{ > + return gd->ram_top; > +} > diff --git a/arch/mips/mach-octeon/include/ioremap.h > b/arch/mips/mach-octeon/include/ioremap.h > new file mode 100644 > index 0000000000..59b75008a2 > --- /dev/null > +++ b/arch/mips/mach-octeon/include/ioremap.h > @@ -0,0 +1,30 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __ASM_MACH_OCTEON_IOREMAP_H > +#define __ASM_MACH_OCTEON_IOREMAP_H > + > +#include <linux/types.h> > + > +/* > + * Allow physical addresses to be fixed up to help peripherals located > + * outside the low 32-bit range -- generic pass-through version. > + */ > +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, > + phys_addr_t size) > +{ > + return phys_addr; > +} > + > +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long > size, > + unsigned long flags) > +{ > + return (void __iomem *)(XKPHYS | offset); > +} > + > +static inline int plat_iounmap(const volatile void __iomem *addr) > +{ > + return 0; > +} > + > +#define _page_cachable_default _CACHE_CACHABLE_NONCOHERENT > + > +#endif /* __ASM_MACH_OCTEON_IOREMAP_H */ > diff --git a/arch/mips/mach-octeon/include/mach/cavm-reg.h > b/arch/mips/mach-octeon/include/mach/cavm-reg.h > new file mode 100644 > index 0000000000..b961e54956 > --- /dev/null > +++ b/arch/mips/mach-octeon/include/mach/cavm-reg.h > @@ -0,0 +1,42 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2020 Marvell International Ltd. > + */ > + > +#ifndef __CAVM_REG_H__ > + > +/* Register offsets */ > +#define CAVM_CIU_FUSE ((u64 *)0x80010100000001a0) > +#define CAVM_MIO_BOOT_REG_CFG0 ((u64 *)0x8001180000000000) > +#define CAVM_RST_BOOT ((u64 *)0x8001180006001600) are those mapped or mappable addresses? The preferred way would be to just define the physical address and do a ioremap when needed. For example: void __iomem *rst_boot = ioremap(CAVM_RST_BOOT, 0); If not mappable, just define the addresses without the (u64 *) cast and do that in the code when needed like that: void __iomem *rst_boot = (void __iomem *)CAVM_RST_BOOT; > + > +/* Register structs */ > + > +/** > + * Register (RSL) rst_boot > + * > + * RST Boot Register > + */ > +union cavm_rst_boot { > + u64 u; > + struct cavm_rst_boot_s { > + u64 chipkill : 1; > + u64 jtcsrdis : 1; > + u64 ejtagdis : 1; > + u64 romen : 1; > + u64 ckill_ppdis : 1; > + u64 jt_tstmode : 1; > + u64 vrm_err : 1; > + u64 reserved_37_56 : 20; > + u64 c_mul : 7; > + u64 pnr_mul : 6; > + u64 reserved_21_23 : 3; > + u64 lboot_oci : 3; > + u64 lboot_ext : 6; > + u64 lboot : 10; > + u64 rboot : 1; > + u64 rboot_pin : 1; > + } s; > +}; I'm not sure but bitfields are maybe frowned upon. I guess the usual and preferred way would be to just define the really needed bits and masks with BIT() and GENMASK(). > + > +#endif /* __CAVM_REG_H__ */ > diff --git a/arch/mips/mach-octeon/include/mach/clock.h > b/arch/mips/mach-octeon/include/mach/clock.h > new file mode 100644 > index 0000000000..a3c1d8b2cd > --- /dev/null > +++ b/arch/mips/mach-octeon/include/mach/clock.h > @@ -0,0 +1,22 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2018, 2019 Marvell International Ltd. > + */ > + > +#ifndef __CLOCK_H__ > + > +/** System PLL reference clock */ > +#define PLL_REF_CLK 50000000 /* 50 MHz */ > +#define NS_PER_REF_CLK_TICK (1000000000 / PLL_REF_CLK) > + > +/** > + * Returns the I/O clock speed in Hz > + */ > +u64 octeon_get_io_clock(void); > + > +/** > + * Returns the core clock speed in Hz > + */ > +u64 octeon_get_core_clock(void); > + > +#endif /* __CLOCK_H__ */ > diff --git a/arch/mips/mach-octeon/lowlevel_init.S > b/arch/mips/mach-octeon/lowlevel_init.S > new file mode 100644 > index 0000000000..d9aab38cde > --- /dev/null > +++ b/arch/mips/mach-octeon/lowlevel_init.S > @@ -0,0 +1,19 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2020 Stefan Roese <s...@denx.de> > + */ > + > +#include <config.h> > +#include <asm-offsets.h> > +#include <asm/cacheops.h> > +#include <asm/regdef.h> > +#include <asm/mipsregs.h> > +#include <asm/addrspace.h> > +#include <asm/asm.h> > + > + .set noreorder > + > +LEAF(lowlevel_init) > + jr ra > + nop > + END(lowlevel_init) > diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt > index f6bf6f2474..f0e13389d0 100644 > --- a/scripts/config_whitelist.txt > +++ b/scripts/config_whitelist.txt > @@ -230,7 +230,6 @@ CONFIG_CPLD_BR_PRELIM > CONFIG_CPLD_OR_PRELIM > CONFIG_CPM2 > CONFIG_CPU_ARMV8 > -CONFIG_CPU_CAVIUM_OCTEON > CONFIG_CPU_FREQ_HZ > CONFIG_CPU_HAS_LLSC > CONFIG_CPU_HAS_PREFETCH -- - Daniel