Message ID | 20200619134452.1174341-3-sr@denx.de |
---|---|
State | Superseded |
Headers | show |
Series | mips: Add initial Octeon MIPS64 base support | expand |
Am Freitag, den 19.06.2020, 15:44 +0200 schrieb Stefan Roese: > From: Aaron Williams <awilliams at 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 <awilliams at marvell.com> > Signed-off-by: Stefan Roese <sr at 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 <ezequiel at collabora.com> > S: Maintained > F: arch/mips/mach-jz47xx/ > > +MIPS Octeon > +M: Aaron Williams <awilliams at marvell.com> > +S: Maintained > +F: arch/mips/mach-octeon/ > +F: arch/mips/include/asm/arch-octeon/ > + > MMC > M: Peng Fan <peng.fan at 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 <sr at 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 <sr at 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
On 30.06.20 00:34, Daniel Schwierzeck wrote: > Am Freitag, den 19.06.2020, 15:44 +0200 schrieb Stefan Roese: >> From: Aaron Williams <awilliams at 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 <awilliams at marvell.com> >> Signed-off-by: Stefan Roese <sr at 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 <ezequiel at collabora.com> >> S: Maintained >> F: arch/mips/mach-jz47xx/ >> >> +MIPS Octeon >> +M: Aaron Williams <awilliams at marvell.com> >> +S: Maintained >> +F: arch/mips/mach-octeon/ >> +F: arch/mips/include/asm/arch-octeon/ >> + >> MMC >> M: Peng Fan <peng.fan at 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 ;) I know thats a bit cumbersome. I'll remove the custom functions in the next version. >> 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 <sr at 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); Will update in next version. > 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'm not too happy with them as well. But that's whats used in the original Octeon code. I assume that its auto generated. > I guess the usual > and preferred way would be to just define the really needed bits and > masks with BIT() and GENMASK(). I agree. Using bitfields also has the great disadvantage, that it can't be used with different endianesses. And this hits us when using drivers for MIPS Octeon and ARM Octeon TX/TX2 (like I2C etc). I'll move to BIT() etc in the next version here. >> + >> +#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 <sr at 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 Viele Gr??e, Stefan
diff --git a/MAINTAINERS b/MAINTAINERS index 1fd975c72f..0aa0357967 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -763,6 +763,12 @@ M: Ezequiel Garcia <ezequiel at collabora.com> S: Maintained F: arch/mips/mach-jz47xx/ +MIPS Octeon +M: Aaron Williams <awilliams at marvell.com> +S: Maintained +F: arch/mips/mach-octeon/ +F: arch/mips/include/asm/arch-octeon/ + MMC M: Peng Fan <peng.fan at 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; +} 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 <sr at 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) + +/* 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; +}; + +#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 <sr at 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