[PATCH v3 2/4] mips: octeon: Initial minimal support for the Marvell Octeon SoC
Daniel Schwierzeck
daniel.schwierzeck at gmail.com
Tue Jun 30 00:34:34 CEST 2020
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
--
- Daniel
More information about the U-Boot
mailing list