On Fri, Mar 02, 2018 at 11:48:10PM +0100, Alexandre Belloni wrote:
> Introduce support for the MIPS based Microsemi Ocelot SoCs.
> 
> Signed-off-by: Alexandre Belloni <alexandre.bell...@bootlin.com>
> ---
>  arch/mips/Makefile                            |  4 ++
>  arch/mips/configs/generic/board-ocelot.config | 40 +++++++++++++
>  arch/mips/generic/Kconfig                     | 17 ++++++
>  arch/mips/generic/Makefile                    |  1 +
>  arch/mips/generic/board-ocelot.c              | 83 
> +++++++++++++++++++++++++++
>  5 files changed, 145 insertions(+)
>  create mode 100644 arch/mips/configs/generic/board-ocelot.config
>  create mode 100644 arch/mips/generic/board-ocelot.c

very nice :-)

> diff --git a/arch/mips/configs/generic/board-ocelot.config 
> b/arch/mips/configs/generic/board-ocelot.config
> new file mode 100644
> index 000000000000..7f9e1eaccc34
> --- /dev/null
> +++ b/arch/mips/configs/generic/board-ocelot.config
> @@ -0,0 +1,40 @@
> +# require CONFIG_32BIT=y

If this has a 24KEc, does it make sense to use:
# require CONFIG_CPU_MIPS32_R2=y
like ni169445 and xilfpga do. There doesn't seem to be any point
enabling support in 32r6 generic kernels for example.

Similarly if the platform is little endian only, you could also add:
# require CONFIG_CPU_LITTLE_ENDIAN=y

> +
> +CONFIG_LEGACY_BOARD_OCELOT=y
> +
> +CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y

Hmm, can this break any other generic platforms that already make the
DTB command line override the arcs_cmdline? Paul?

I.e. In arch_mem_init() the condition of copying arcs_cmdline to
boot_command_line would switch from !boot_command_line[0] to
arcs_cmdline[0]. I suppose arcs_cmdline[] may not have been written in
those cases. If its safe then it should probably be a standard thing
selected by MIPS_GENERIC instead of a board specific thing.

> +CONFIG_MAGIC_SYSRQ=y

Perhaps its worth adding this to the base generic_defconfig if its
useful to have.

> +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1

That is already the default, though I wonder if we should set it to 0
for safety, which still retains the functionality, but just may require
writing to /proc/sys/kernel/sysrq or passing sysrq_always_enabled as a
kernel parameter to use sysrq from keyboard / uart.

> diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig
> index 2ff3b17bfab1..04b8d2262f9d 100644
> --- a/arch/mips/generic/Kconfig
> +++ b/arch/mips/generic/Kconfig
> @@ -27,6 +27,23 @@ config LEGACY_BOARD_SEAD3
>         Enable this to include support for booting on MIPS SEAD-3 FPGA-based
>         development boards, which boot using a legacy boot protocol.
>  
> +comment "MSCC Ocelot doesn't work with SEAD3 enabled"
> +       depends on LEGACY_BOARD_SEAD3

broken indentation. Tab please.

> +
> +config LEGACY_BOARD_OCELOT
> +     bool "Support MSCC Ocelot boards"
> +     depends on LEGACY_BOARD_SEAD3=n
> +     select LEGACY_BOARDS
> +     select MSCC_OCELOT
> +
> +config MSCC_OCELOT
> +     bool
> +     select DMA_NONCOHERENT

MIPS_GENERIC already selects DMA_PERFDEV_COHERENT, which should already
treat devices as non-coherent unless they have the dma-coherent DT
property.

> +     select GPIOLIB
> +     select MSCC_OCELOT_IRQ
> +     select SYS_HAS_EARLY_PRINTK
> +     select USE_GENERIC_EARLY_PRINTK_8250
> +
>  comment "FIT/UHI Boards"
>  
>  config FIT_IMAGE_FDT_BOSTON
> diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
> index 5c31e0c4697d..d03a36f869a4 100644
> --- a/arch/mips/generic/Makefile
> +++ b/arch/mips/generic/Makefile
> @@ -14,5 +14,6 @@ obj-y += proc.o
>  
>  obj-$(CONFIG_YAMON_DT_SHIM)          += yamon-dt.o
>  obj-$(CONFIG_LEGACY_BOARD_SEAD3)     += board-sead3.o
> +obj-$(CONFIG_LEGACY_BOARD_OCELOT)    += board-ocelot.o
>  obj-$(CONFIG_KEXEC)                  += kexec.o
>  obj-$(CONFIG_VIRT_BOARD_RANCHU)              += board-ranchu.o
> diff --git a/arch/mips/generic/board-ocelot.c 
> b/arch/mips/generic/board-ocelot.c
> new file mode 100644
> index 000000000000..752c6edbe1d5
> --- /dev/null
> +++ b/arch/mips/generic/board-ocelot.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Microsemi MIPS SoC support
> + *
> + * Copyright (c) 2017 Microsemi Corporation
> + */
> +#include <asm/machine.h>
> +#include <asm/prom.h>
> +
> +#define DEVCPU_GCB_CHIP_REGS_CHIP_ID 0x71070000
> +#define CHIP_ID_PART_ID                      GENMASK(27, 12)
> +
> +#define OCELOT_PART_ID                       (0x7514 << 12)
> +
> +#define UART_UART                    0x70100000
> +
> +static __init bool ocelot_detect(void)
> +{
> +     u32 rev;
> +
> +     rev = __raw_readl((void *)DEVCPU_GCB_CHIP_REGS_CHIP_ID);

Isn't that an address in the user segment, i.e. TLB mapped virtual
memory? Does the bootloader set up a wired mapping for it or something?

The address looks similar to UART_UART which is given to ioremap so must
be a physical address. Perhaps the mapping you're using is 1:1
virtual:physical address?

If its using a TLB mapping, then:
1) That isn't safe this early to run on other platforms, as it'll give a
   TLB refill exception. It should be quite possible to detect such a
   mapping to make it safer though.
2) If yamon initialises the TLB to a known state, then that may well be
   a hacky but workable way to distinguish yamon (sead3) from redboot
   (mscc) in future.

> +
> +     if ((rev & CHIP_ID_PART_ID) != OCELOT_PART_ID)
> +             return 0;
> +
> +     /* Copy command line from bootloader early for Initrd detection */
> +     if (fw_arg0 < 10 && (fw_arg1 & 0xFFF00000) == 0x80000000) {
> +             unsigned int prom_argc = fw_arg0;
> +             const char **prom_argv = (const char **)fw_arg1;
> +
> +             if (prom_argc > 1 && strlen(prom_argv[1]) > 0)
> +                     /* ignore all built-in args if any f/w args given */
> +                     strcpy(arcs_cmdline, prom_argv[1]);
> +     }
> +
> +     return 1;
> +}
> +
> +static __init unsigned int ocelot_measure_hpt_freq(void)
> +{
> +     struct device_node *np;
> +     u32 freq;
> +
> +     np = of_find_node_by_name(NULL, "cpus");
> +     if (!np)
> +             panic("missing 'cpus' DT node");
> +     if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
> +             panic("missing 'mips-hpt-frequency' property");
> +     of_node_put(np);
> +
> +     return freq;
> +}

Is it too late to change this to use the generic mips_hpt_frequency
calculation in plat_time_init()? The DT would have to provide e.g. a
fixed-clock and link to it from the CPU node.

See arch/mips/boot/dts/ni/169445.dts for an example of how it could
look.

That would allow you to eliminate this machine callback altogether, as
well as being more flexible if you ever needed the frequency to be
calculated more dynamically based on platform registers.

Thanks!
James

Attachment: signature.asc
Description: Digital signature

Reply via email to