Merge tag 'signed-efi-2019.01' of git://github.com/agraf/u-boot
authorTom Rini <trini@konsulko.com>
Thu, 27 Dec 2018 17:59:01 +0000 (12:59 -0500)
committerTom Rini <trini@konsulko.com>
Thu, 27 Dec 2018 17:59:01 +0000 (12:59 -0500)
Patch queue for efi v2019.01 - 2018-12-27

Three tiny last minute bug fixes:

  - Fix RTS relocation
  - Avoid read after free
  - Fix RTS data positioning (affects BBB)

204 files changed:
MAINTAINERS
api/api_storage.c
arch/arm/dts/meson-axg-s400-u-boot.dtsi [new file with mode: 0644]
arch/arm/mach-k3/config.mk
arch/arm/mach-mediatek/mt7629/lowlevel_init.S
arch/arm/mach-mvebu/cpu.c
arch/arm/mach-omap2/omap3/Kconfig
arch/arm/mach-omap2/omap3/clock.c
arch/arm/mach-socfpga/Kconfig
arch/arm/mach-socfpga/include/mach/mailbox_s10.h
arch/arm/mach-socfpga/include/mach/misc.h
arch/arm/mach-socfpga/mailbox_s10.c
arch/arm/mach-socfpga/misc.c
arch/arm/mach-socfpga/misc_arria10.c
arch/arm/mach-socfpga/misc_gen5.c
arch/arm/mach-socfpga/misc_s10.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/cpu/cpu.c
arch/mips/dts/Makefile
arch/mips/dts/ar933x.dtsi
arch/mips/dts/brcm,bcm6318.dtsi
arch/mips/dts/brcm,bcm63268.dtsi
arch/mips/dts/brcm,bcm6328.dtsi
arch/mips/dts/brcm,bcm6338.dtsi
arch/mips/dts/brcm,bcm6348.dtsi
arch/mips/dts/brcm,bcm6358.dtsi
arch/mips/dts/brcm,bcm6362.dtsi
arch/mips/dts/brcm,bcm6368.dtsi
arch/mips/dts/ci20.dts [new file with mode: 0644]
arch/mips/dts/comtrend,ar-5315u.dts
arch/mips/dts/comtrend,ar-5387un.dts
arch/mips/dts/comtrend,ct-5361.dts
arch/mips/dts/comtrend,vr-3032u.dts
arch/mips/dts/comtrend,wap-5813n.dts
arch/mips/dts/huawei,hg556a.dts
arch/mips/dts/jz4780.dtsi [new file with mode: 0644]
arch/mips/dts/luton_pcb091.dts [new file with mode: 0644]
arch/mips/dts/mscc,luton.dtsi [new file with mode: 0644]
arch/mips/dts/mscc,ocelot.dtsi [new file with mode: 0644]
arch/mips/dts/mscc,ocelot_pcb.dtsi [new file with mode: 0644]
arch/mips/dts/netgear,dgnd3700v2.dts
arch/mips/dts/nexys4ddr.dts
arch/mips/dts/ocelot_pcb120.dts [new file with mode: 0644]
arch/mips/dts/ocelot_pcb123.dts [new file with mode: 0644]
arch/mips/dts/qca953x.dtsi
arch/mips/dts/sagem,f@st1704.dts
arch/mips/dts/sfr,nb4-ser.dts
arch/mips/include/asm/cacheops.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/spl.h [new file with mode: 0644]
arch/mips/mach-jz47xx/Kconfig [new file with mode: 0644]
arch/mips/mach-jz47xx/Makefile [new file with mode: 0644]
arch/mips/mach-jz47xx/include/mach/jz4780.h [new file with mode: 0644]
arch/mips/mach-jz47xx/include/mach/jz4780_dram.h [new file with mode: 0644]
arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/Makefile [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/TODO [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/gpio.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/jz4780.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/pll.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/reset.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/sdram.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/timer.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds [new file with mode: 0644]
arch/mips/mach-jz47xx/start.S [new file with mode: 0644]
arch/mips/mach-mscc/Kconfig [new file with mode: 0644]
arch/mips/mach-mscc/Makefile [new file with mode: 0644]
arch/mips/mach-mscc/cpu.c [new file with mode: 0644]
arch/mips/mach-mscc/dram.c [new file with mode: 0644]
arch/mips/mach-mscc/include/ioremap.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/common.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/ddr.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/luton/luton.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/ocelot/ocelot.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h [new file with mode: 0644]
arch/mips/mach-mscc/include/mach/tlb.h [new file with mode: 0644]
arch/mips/mach-mscc/lowlevel_init.S [new file with mode: 0644]
arch/mips/mach-mscc/lowlevel_init_luton.S [new file with mode: 0644]
arch/mips/mach-mscc/reset.c [new file with mode: 0644]
arch/mips/mach-mt7620/cpu.c
arch/riscv/Kconfig
arch/riscv/Makefile
arch/riscv/cpu/Makefile
arch/riscv/cpu/ax25/Kconfig
arch/riscv/cpu/ax25/cache.c
arch/riscv/cpu/cpu.c
arch/riscv/cpu/mtrap.S [new file with mode: 0644]
arch/riscv/cpu/qemu/Kconfig [new file with mode: 0644]
arch/riscv/cpu/qemu/cpu.c
arch/riscv/cpu/start.S
arch/riscv/dts/ae350.dts [deleted file]
arch/riscv/include/asm/csr.h
arch/riscv/include/asm/encoding.h
arch/riscv/include/asm/global_data.h
arch/riscv/include/asm/syscon.h [new file with mode: 0644]
arch/riscv/lib/Makefile
arch/riscv/lib/asm-offsets.c [new file with mode: 0644]
arch/riscv/lib/bootm.c
arch/riscv/lib/interrupts.c
arch/riscv/lib/rdtime.c [new file with mode: 0644]
arch/riscv/lib/sifive_clint.c [new file with mode: 0644]
board/AndesTech/ax25-ae350/Kconfig
board/AndesTech/ax25-ae350/MAINTAINERS
board/emulation/qemu-riscv/Kconfig
board/imgtec/ci20/Kconfig [new file with mode: 0644]
board/imgtec/ci20/MAINTAINERS [new file with mode: 0644]
board/imgtec/ci20/Makefile [new file with mode: 0644]
board/imgtec/ci20/README [new file with mode: 0644]
board/imgtec/ci20/ci20.c [new file with mode: 0644]
board/mscc/luton/Kconfig [new file with mode: 0644]
board/mscc/luton/Makefile [new file with mode: 0644]
board/mscc/luton/luton.c [new file with mode: 0644]
board/mscc/ocelot/Kconfig [new file with mode: 0644]
board/mscc/ocelot/Makefile [new file with mode: 0644]
board/mscc/ocelot/ocelot.c [new file with mode: 0644]
configs/a25-ae350_32_defconfig [deleted file]
configs/ae350_rv32_defconfig [new file with mode: 0644]
configs/ae350_rv64_defconfig [new file with mode: 0644]
configs/ax25-ae350_64_defconfig [deleted file]
configs/ci20_mmc_defconfig [new file with mode: 0644]
configs/comtrend_ar5315u_ram_defconfig
configs/comtrend_ar5387un_ram_defconfig
configs/comtrend_ct5361_ram_defconfig
configs/comtrend_vr3032u_ram_defconfig
configs/comtrend_wap5813n_ram_defconfig
configs/db-88f6820-amc_defconfig
configs/gardena-smart-gateway-mt7688-ram_defconfig
configs/gardena-smart-gateway-mt7688_defconfig
configs/huawei_hg556a_ram_defconfig
configs/linkit-smart-7688-ram_defconfig
configs/linkit-smart-7688_defconfig
configs/mscc_luton_defconfig [new file with mode: 0644]
configs/mscc_ocelot_defconfig [new file with mode: 0644]
configs/mscc_ocelot_pcb120_defconfig [new file with mode: 0644]
configs/netgear_dgnd3700v2_ram_defconfig
configs/sagem_f@st1704_ram_defconfig
configs/sfr_nb4-ser_ram_defconfig
doc/README.ae350
doc/README.commands
drivers/cpu/Kconfig
drivers/cpu/Makefile
drivers/cpu/riscv_cpu.c [new file with mode: 0644]
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/dma/bcm6348-iudma.c [new file with mode: 0644]
drivers/fpga/Kconfig
drivers/fpga/Makefile
drivers/fpga/altera.c
drivers/fpga/stratix10.c [new file with mode: 0644]
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-mscc-bitbang-spi.c [new file with mode: 0644]
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/jz4780_efuse.c [new file with mode: 0644]
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/jz_mmc.c [new file with mode: 0644]
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/bcm6348-eth.c [new file with mode: 0644]
drivers/net/bcm6368-eth.c [new file with mode: 0644]
drivers/net/phy/phy.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/mscc/Kconfig [new file with mode: 0644]
drivers/pinctrl/mscc/Makefile [new file with mode: 0644]
drivers/pinctrl/mscc/mscc-common.c [new file with mode: 0644]
drivers/pinctrl/mscc/mscc-common.h [new file with mode: 0644]
drivers/pinctrl/mscc/pinctrl-luton.c [new file with mode: 0644]
drivers/pinctrl/mscc/pinctrl-ocelot.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-uclass.c
drivers/power/regulator/regulator-uclass.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/serial_sifive.c [new file with mode: 0644]
drivers/spi/designware_spi.c
drivers/timer/Kconfig
drivers/timer/Makefile
drivers/timer/riscv_timer.c [new file with mode: 0644]
include/altera.h
include/configs/bmips_common.h
include/configs/ci20.h [new file with mode: 0644]
include/configs/helios4.h
include/configs/mt7623.h
include/configs/omap3_igep00x0.h
include/configs/vcoreiii.h [new file with mode: 0644]
include/cpu.h
include/dt-bindings/clock/bcm6318-clock.h
include/dt-bindings/clock/jz4780-cgu.h [new file with mode: 0644]
include/dt-bindings/dma/bcm6318-dma.h [new file with mode: 0644]
include/dt-bindings/dma/bcm63268-dma.h [new file with mode: 0644]
include/dt-bindings/dma/bcm6328-dma.h [new file with mode: 0644]
include/dt-bindings/dma/bcm6338-dma.h [new file with mode: 0644]
include/dt-bindings/dma/bcm6348-dma.h [new file with mode: 0644]
include/dt-bindings/dma/bcm6358-dma.h [new file with mode: 0644]
include/dt-bindings/dma/bcm6362-dma.h [new file with mode: 0644]
include/dt-bindings/dma/bcm6368-dma.h [new file with mode: 0644]
scripts/check-config.sh
test/overlay/Kconfig

index 0fb089807c57ecf973fa91c8034b8d4c28e0c7ff..ae825014bda9edd2f5ea80f4be0b7163ac4f2ebc 100644 (file)
@@ -512,6 +512,24 @@ S: Maintained
 T:     git git://git.denx.de/u-boot-mips.git
 F:     arch/mips/
 
+MIPS MSCC
+M:     Gregory CLEMENT <gregory.clement@bootlin.com>
+M:     Lars Povlsen <lars.povlsen@microchip.com>
+M:     Horatiu Vultur <horatiu.vultur@microchip.com>
+S:     Maintained
+F:     arch/mips/mach-mscc/
+F:     arch/mips/dts/luton*
+F:     arch/mips/dts/mscc*
+F:     arch/mips/dts/ocelot*
+F:     board/mscc/
+F:     configs/mscc*
+F:     include/configs/vcoreiii.h
+
+MIPS JZ4780
+M:     Ezequiel Garcia <ezequiel@collabora.com>
+S:     Maintained
+F:     arch/mips/mach-jz47xx/
+
 MMC
 M:     Jaehoon Chung <jh80.chung@samsung.com>
 S:     Maintained
index 8aeeda2715f4ebf1971ac5abd6f0b563da2e0bbd..2b90c18aaec93a1dcb8914e80e37d41842d88980 100644 (file)
@@ -99,6 +99,7 @@ static int dev_stor_get(int type, int *more, struct device_info *di)
 {
        struct blk_desc *dd;
        int found = 0;
+       int found_last = 0;
        int i = 0;
 
        /* Wasn't configured for this type, return 0 directly */
@@ -111,9 +112,13 @@ static int dev_stor_get(int type, int *more, struct device_info *di)
                        if (di->cookie ==
                            (void *)blk_get_dev(specs[type].name, i)) {
                                i += 1;
+                               found_last = 1;
                                break;
                        }
                }
+
+               if (!found_last)
+                       i = 0;
        }
 
        for (; i < specs[type].max_dev; i++) {
diff --git a/arch/arm/dts/meson-axg-s400-u-boot.dtsi b/arch/arm/dts/meson-axg-s400-u-boot.dtsi
new file mode 100644 (file)
index 0000000..c46eb3f
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ */
+
+/* wifi module */
+&sd_emmc_b {
+       status = "disabled";
+};
+
+/* emmc storage */
+&sd_emmc_c {
+       status = "okay";
+};
index 7fc0b3f357628fc83007ccfaf2505dd23b14da94..be00d79fb03b4e52631c11d138016cde09f7fc27 100644 (file)
@@ -37,7 +37,7 @@ cmd_gencert = cat $(srctree)/tools/k3_x509template.txt | sed $(SED_OPTS) > u-boo
 ifeq ($(CONFIG_SYS_K3_KEY), "")
 KEY=u-boot-spl-eckey.pem
 else
-KEY=$(patsubst "%",%,$(CONFIG_SYS_K3_KEY))
+KEY=$(patsubst "%",$(srctree)/%,$(CONFIG_SYS_K3_KEY))
 endif
 
 u-boot-spl-eckey.pem: FORCE
index 90dd4ea48e4f7353cb964ef405132c4f94d499a4..3375796b79771d73dce5e36e567dff50cd863b5b 100644 (file)
@@ -5,6 +5,14 @@
 
 #include <linux/linkage.h>
 
+#define WAIT_CODE_SRAM_BASE    0x0010ff00
+
+#define SLAVE_JUMP_REG         0x10202034
+#define SLAVE1_MAGIC_REG       0x10202038
+#define SLAVE1_MAGIC_NUM       0x534c4131
+
+#define GIC_CPU_BASE           0x10320000
+
 ENTRY(lowlevel_init)
 
 #ifndef CONFIG_SPL_BUILD
@@ -28,6 +36,7 @@ ENTRY(lowlevel_init)
        mrc     p15, 0, r0, c0, c0, 5
        ands    r1, r0, #0x40000000
        bne     go                      @ Go if UP
+       /* read slave CPU number */
        ands    r0, r0, #0x0f
        beq     go                      @ Go if core0 on primary core tile
        b       secondary
@@ -37,14 +46,41 @@ go:
        mov     pc, lr
 
 secondary:
-       /* read slave CPU number into r0 firstly */
-       mrc     p15, 0, r0, c0, c0, 5
-       and     r0, r0, #0x0f
+       /* enable GIC as cores will be waken up by IPI */
+       ldr     r2, =GIC_CPU_BASE
+       mov     r1, #0xf0
+       str     r1, [r2, #4]
+       mov     r1, #1
+       str     r1, [r2, #0]
+
+       ldr     r1, [r2]
+       orr     r1, #1
+       str     r1, [r2]
+
+       /* copy wait code into SRAM */
+       ldr     r0, =slave_cpu_wait
+       ldm     r0, {r1 - r8}           @ slave_cpu_wait has eight insns
+       ldr     r0, =WAIT_CODE_SRAM_BASE
+       stm     r0, {r1 - r8}
+
+       /* pass args to slave_cpu_wait */
+       ldr     r0, =SLAVE1_MAGIC_REG
+       ldr     r1, =SLAVE1_MAGIC_NUM
+
+       /* jump to wait code in SRAM */
+       ldr     pc, =WAIT_CODE_SRAM_BASE
 
-loop:
-       dsb
-       isb
-       wfi                             @Zzz...
-       b       loop
 #endif
 ENDPROC(lowlevel_init)
+
+/* This function will be copied into SRAM */
+ENTRY(slave_cpu_wait)
+       wfi
+       ldr     r2, [r0]
+       cmp     r2, r1
+       bne     slave_cpu_wait
+       movw    r0, #:lower16:SLAVE_JUMP_REG
+       movt    r0, #:upper16:SLAVE_JUMP_REG
+       ldr     r1, [r0]
+       mov     pc, r1
+ENDPROC(slave_cpu_wait)
index aa1be8ebabcb4cdb6d712b459cad17f634cd2f46..919d05c88c7724113c512e53ae5f97a427dba1c0 100644 (file)
@@ -283,10 +283,8 @@ int print_cpuinfo(void)
  * and sets the correct windows sizes and base addresses accordingly.
  *
  * These values are set in the scratch registers by the Marvell
- * DDR3 training code, which is executed by the BootROM before the
- * main payload (U-Boot) is executed. This training code is currently
- * only available in the Marvell U-Boot version. It needs to be
- * ported to mainline U-Boot SPL at some point.
+ * DDR3 training code, which is executed by the SPL before the
+ * main payload (U-Boot) is executed.
  */
 static void update_sdram_window_sizes(void)
 {
index e0d02fb4e59a0448104ae03eb24a61af56d5636e..0286b0daa337fb8de757c4d8fe4c3311d68a0556 100644 (file)
@@ -3,18 +3,23 @@ if OMAP34XX
 # We only enable the clocks for the GPIO banks that a given board requies.
 config OMAP3_GPIO_2
        bool
+       default y if CMD_GPIO
 
 config OMAP3_GPIO_3
        bool
+       default y if CMD_GPIO
 
 config OMAP3_GPIO_4
        bool
+       default y if CMD_GPIO
 
 config OMAP3_GPIO_5
        bool
+       default y if CMD_GPIO
 
 config OMAP3_GPIO_6
        bool
+       default y if CMD_GPIO
 
 choice
        prompt "OMAP3 board select"
index 9a03bfa9d3bbbb19616edbd40d6d94e9f7666efb..cb9e91ebc3b375dd7ca7894f6e32d95942eddf20 100644 (file)
@@ -750,23 +750,23 @@ void per_clocks_enable(void)
        setbits_le32(&prcm_base->iclken_per, 0x00000800);
 #endif
 
-#if (CONFIG_IS_ENABLED(OMAP3_GPIO_2) || CONFIG_IS_ENABLED(CMD_GPIO))
+#if defined(CONFIG_OMAP3_GPIO_2)
        setbits_le32(&prcm_base->fclken_per, 0x00002000);
        setbits_le32(&prcm_base->iclken_per, 0x00002000);
 #endif
-#if (CONFIG_IS_ENABLED(OMAP3_GPIO_3) || CONFIG_IS_ENABLED(CMD_GPIO))
+#if defined(CONFIG_OMAP3_GPIO_3)
        setbits_le32(&prcm_base->fclken_per, 0x00004000);
        setbits_le32(&prcm_base->iclken_per, 0x00004000);
 #endif
-#if (CONFIG_IS_ENABLED(OMAP3_GPIO_4) || CONFIG_IS_ENABLED(CMD_GPIO))
+#if defined(CONFIG_OMAP3_GPIO_4)
        setbits_le32(&prcm_base->fclken_per, 0x00008000);
        setbits_le32(&prcm_base->iclken_per, 0x00008000);
 #endif
-#if (CONFIG_IS_ENABLED(OMAP3_GPIO_5) || CONFIG_IS_ENABLED(CMD_GPIO))
+#if defined(CONFIG_OMAP3_GPIO_5)
        setbits_le32(&prcm_base->fclken_per, 0x00010000);
        setbits_le32(&prcm_base->iclken_per, 0x00010000);
 #endif
-#if (CONFIG_IS_ENABLED(OMAP3_GPIO_6) || CONFIG_IS_ENABLED(CMD_GPIO))
+#if defined(CONFIG_OMAP3_GPIO_6)
        setbits_le32(&prcm_base->fclken_per, 0x00020000);
        setbits_le32(&prcm_base->iclken_per, 0x00020000);
 #endif
index 06f8527aa447e5f00e84098f3d5be631363d45ae..5e87371f8ca84dcc5d95c71cdb369a980a57da2b 100644 (file)
@@ -35,6 +35,7 @@ config TARGET_SOCFPGA_STRATIX10
        select ARMV8_MULTIENTRY
        select ARMV8_SET_SMPEN
        select ARMV8_SPIN_TABLE
+       select FPGA_STRATIX10
 
 choice
        prompt "Altera SOCFPGA board select"
index 81a609d2f821c32cb5c1f32f8464eda058003ac9..ae728a5df5f8fa7a4b4885e91c4c4ec7bd9f7625 100644 (file)
@@ -107,6 +107,12 @@ enum ALT_SDM_MBOX_RESP_CODE {
 #define RECONFIG_STATUS_PIN_STATUS                     2
 #define RECONFIG_STATUS_SOFTFUNC_STATUS                        3
 
+/* Macros for specifying number of arguments in mailbox command */
+#define MBOX_NUM_ARGS(n, b)                            (((n) & 0xFF) << (b))
+#define MBOX_DIRECT_COUNT(n)                           MBOX_NUM_ARGS((n), 0)
+#define MBOX_ARG_DESC_COUNT(n)                         MBOX_NUM_ARGS((n), 8)
+#define MBOX_RESP_DESC_COUNT(n)                                MBOX_NUM_ARGS((n), 16)
+
 #define MBOX_CFGSTAT_STATE_IDLE                                0x00000000
 #define MBOX_CFGSTAT_STATE_CONFIG                      0x10000000
 #define MBOX_CFGSTAT_STATE_FAILACK                     0x08000000
@@ -140,5 +146,6 @@ int mbox_qspi_open(void);
 #endif
 
 int mbox_reset_cold(void);
-
+int mbox_get_fpga_config_status(u32 cmd);
+int mbox_get_fpga_config_status_psci(u32 cmd);
 #endif /* _MAILBOX_S10_H_ */
index 26609927c834ae2f035bb8a93bd4c5241ba8018d..86d5d2b62b079aed4afafbb91d9d3c81f3154d4c 100644 (file)
@@ -18,9 +18,9 @@ struct bsel {
 extern struct bsel bsel_str[];
 
 #ifdef CONFIG_FPGA
-void socfpga_fpga_add(void);
+void socfpga_fpga_add(void *fpga_desc);
 #else
-static inline void socfpga_fpga_add(void) {}
+inline void socfpga_fpga_add(void *fpga_desc) {}
 #endif
 
 #ifdef CONFIG_TARGET_SOCFPGA_GEN5
index 0d906c3480f3709b2dee5f4996c900b82a9cb5d8..3c332239361d1c27dda4624b91ab875d83d58229 100644 (file)
@@ -342,6 +342,54 @@ int mbox_reset_cold(void)
        return 0;
 }
 
+/* Accepted commands: CONFIG_STATUS or RECONFIG_STATUS */
+static __always_inline int mbox_get_fpga_config_status_common(u32 cmd)
+{
+       u32 reconfig_status_resp_len;
+       u32 reconfig_status_resp[RECONFIG_STATUS_RESPONSE_LEN];
+       int ret;
+
+       reconfig_status_resp_len = RECONFIG_STATUS_RESPONSE_LEN;
+       ret = mbox_send_cmd_common(MBOX_ID_UBOOT, cmd,
+                                  MBOX_CMD_DIRECT, 0, NULL, 0,
+                                  &reconfig_status_resp_len,
+                                  reconfig_status_resp);
+
+       if (ret)
+               return ret;
+
+       /* Check for any error */
+       ret = reconfig_status_resp[RECONFIG_STATUS_STATE];
+       if (ret && ret != MBOX_CFGSTAT_STATE_CONFIG)
+               return ret;
+
+       /* Make sure nStatus is not 0 */
+       ret = reconfig_status_resp[RECONFIG_STATUS_PIN_STATUS];
+       if (!(ret & RCF_PIN_STATUS_NSTATUS))
+               return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+
+       ret = reconfig_status_resp[RECONFIG_STATUS_SOFTFUNC_STATUS];
+       if (ret & RCF_SOFTFUNC_STATUS_SEU_ERROR)
+               return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+
+       if ((ret & RCF_SOFTFUNC_STATUS_CONF_DONE) &&
+           (ret & RCF_SOFTFUNC_STATUS_INIT_DONE) &&
+           !reconfig_status_resp[RECONFIG_STATUS_STATE])
+               return 0;       /* configuration success */
+
+       return MBOX_CFGSTAT_STATE_CONFIG;
+}
+
+int mbox_get_fpga_config_status(u32 cmd)
+{
+       return mbox_get_fpga_config_status_common(cmd);
+}
+
+int __secure mbox_get_fpga_config_status_psci(u32 cmd)
+{
+       return mbox_get_fpga_config_status_common(cmd);
+}
+
 int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg,
                  u8 urgent, u32 *resp_buf_len, u32 *resp_buf)
 {
index a4f6d5c1ac9967cfb384356d375571223d364c48..78fbe287244bae6bbdc44fc03c0e906a6208af9f 100644 (file)
@@ -88,33 +88,11 @@ int overwrite_console(void)
 #endif
 
 #ifdef CONFIG_FPGA
-/*
- * FPGA programming support for SoC FPGA Cyclone V
- */
-static Altera_desc altera_fpga[] = {
-       {
-               /* Family */
-               Altera_SoCFPGA,
-               /* Interface type */
-               fast_passive_parallel,
-               /* No limitation as additional data will be ignored */
-               -1,
-               /* No device function table */
-               NULL,
-               /* Base interface address specified in driver */
-               NULL,
-               /* No cookie implementation */
-               0
-       },
-};
-
 /* add device descriptor to FPGA device table */
-void socfpga_fpga_add(void)
+void socfpga_fpga_add(void *fpga_desc)
 {
-       int i;
        fpga_init();
-       for (i = 0; i < ARRAY_SIZE(altera_fpga); i++)
-               fpga_add(fpga_altera, &altera_fpga[i]);
+       fpga_add(fpga_altera, fpga_desc);
 }
 #endif
 
index f347ae857e036bee4475f39509a6e9e4cb7861f5..63b8c75d31d134053ac521c62bded724315d8485 100644 (file)
 
 static struct socfpga_system_manager *sysmgr_regs =
        (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
+
+/*
+ * FPGA programming support for SoC FPGA Arria 10
+ */
+static Altera_desc altera_fpga[] = {
+       {
+               /* Family */
+               Altera_SoCFPGA,
+               /* Interface type */
+               fast_passive_parallel,
+               /* No limitation as additional data will be ignored */
+               -1,
+               /* No device function table */
+               NULL,
+               /* Base interface address specified in driver */
+               NULL,
+               /* No cookie implementation */
+               0
+       },
+};
+
 #if defined(CONFIG_SPL_BUILD)
 static struct pl310_regs *const pl310 =
        (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
@@ -73,7 +94,7 @@ void socfpga_sdram_remap_zero(void)
 int arch_early_init_r(void)
 {
        /* Add device descriptor to FPGA device table */
-       socfpga_fpga_add();
+       socfpga_fpga_add(&altera_fpga[0]);
 
        return 0;
 }
index 5fa40937c405da8c0e07ff1b5a9739347a9d84af..04f237d100c61ef1b784f22d8edff8ef38566eb4 100644 (file)
@@ -34,6 +34,26 @@ static struct nic301_registers *nic301_regs =
 static struct scu_registers *scu_regs =
        (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS;
 
+/*
+ * FPGA programming support for SoC FPGA Cyclone V
+ */
+static Altera_desc altera_fpga[] = {
+       {
+               /* Family */
+               Altera_SoCFPGA,
+               /* Interface type */
+               fast_passive_parallel,
+               /* No limitation as additional data will be ignored */
+               -1,
+               /* No device function table */
+               NULL,
+               /* Base interface address specified in driver */
+               NULL,
+               /* No cookie implementation */
+               0
+       },
+};
+
 /*
  * DesignWare Ethernet initialization
  */
@@ -221,7 +241,7 @@ int arch_early_init_r(void)
        socfpga_sdram_remap_zero();
 
        /* Add device descriptor to FPGA device table */
-       socfpga_fpga_add();
+       socfpga_fpga_add(&altera_fpga[0]);
 
 #ifdef CONFIG_DESIGNWARE_SPI
        /* Get Designware SPI controller out of reset */
index e599362f145861abd6f57412c4c8d5784c59d92d..113eace650edcfe12f3afd2566868362d11ab8ea 100644 (file)
@@ -24,6 +24,26 @@ DECLARE_GLOBAL_DATA_PTR;
 static struct socfpga_system_manager *sysmgr_regs =
        (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
 
+/*
+ * FPGA programming support for SoC FPGA Stratix 10
+ */
+static Altera_desc altera_fpga[] = {
+       {
+               /* Family */
+               Intel_FPGA_Stratix10,
+               /* Interface type */
+               secure_device_manager_mailbox,
+               /* No limitation as additional data will be ignored */
+               -1,
+               /* No device function table */
+               NULL,
+               /* Base interface address specified in driver */
+               NULL,
+               /* No cookie implementation */
+               0
+       },
+};
+
 /*
  * DesignWare Ethernet initialization
  */
@@ -125,6 +145,8 @@ int arch_misc_init(void)
 
 int arch_early_init_r(void)
 {
+       socfpga_fpga_add(&altera_fpga[0]);
+
        return 0;
 }
 
index 1b1b1d7d00319145ad1a76392ab05d36f96ccbf7..194f4f349ed5bbb14f08c6ceee5ae4d2116f9f25 100644 (file)
@@ -59,6 +59,11 @@ config ARCH_ATH79
        select OF_CONTROL
        imply CMD_DM
 
+config ARCH_MSCC
+       bool "Support MSCC VCore-III"
+       select OF_CONTROL
+       select DM
+
 config ARCH_BMIPS
        bool "Support BMIPS SoCs"
        select CLK
@@ -79,7 +84,7 @@ config ARCH_MT7620
        select DM_SERIAL
        imply DM_SPI
        imply DM_SPI_FLASH
-       select ARCH_MISC_INIT if WATCHDOG
+       select ARCH_MISC_INIT
        select MIPS_TUNE_24KC
        select OF_CONTROL
        select ROM_EXCEPTION_VECTORS
@@ -88,6 +93,12 @@ config ARCH_MT7620
        select SUPPORTS_LITTLE_ENDIAN
        select SYSRESET
 
+config ARCH_JZ47XX
+       bool "Support Ingenic JZ47xx"
+       select SUPPORT_SPL
+       select OF_CONTROL
+       select DM
+
 config MACH_PIC32
        bool "Support Microchip PIC32"
        select DM
@@ -138,7 +149,9 @@ source "board/imgtec/xilfpga/Kconfig"
 source "board/micronas/vct/Kconfig"
 source "board/qemu-mips/Kconfig"
 source "arch/mips/mach-ath79/Kconfig"
+source "arch/mips/mach-mscc/Kconfig"
 source "arch/mips/mach-bmips/Kconfig"
+source "arch/mips/mach-jz47xx/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
 source "arch/mips/mach-mt7620/Kconfig"
 
index 802244a06e5d5e0fd8d2ba8a68a2b471b079d32d..029d290f1e06665869b80efdfe64c3e64047f73a 100644 (file)
@@ -13,8 +13,10 @@ libs-y += arch/mips/lib/
 
 machine-$(CONFIG_ARCH_ATH79) += ath79
 machine-$(CONFIG_ARCH_BMIPS) += bmips
+machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
 machine-$(CONFIG_MACH_PIC32) += pic32
 machine-$(CONFIG_ARCH_MT7620) += mt7620
+machine-$(CONFIG_ARCH_MSCC) += mscc
 
 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
 libs-y += $(machdirs)
index 5c56ab0289e05173d02e51541abea724468ee590..a403ff729b182cd676016ce6590a9d1adbd95e64 100644 (file)
@@ -28,16 +28,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 }
 #endif
 
-void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
-{
-       write_c0_entrylo0(low0);
-       write_c0_pagemask(pagemask);
-       write_c0_entrylo1(low1);
-       write_c0_entryhi(hi);
-       write_c0_index(index);
-       tlb_write_indexed();
-}
-
 int arch_cpu_init(void)
 {
        mips_cache_probe();
index b447141f8717f238ccc4ca51fb0b044f52b364ef..647d2bf0d53bedfd67e15981c672cf4687dd8809 100644 (file)
@@ -16,6 +16,7 @@ dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
 dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
 dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb
 dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
+dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb
 
 targets += $(dtb-y)
 
index 85fb14b13bd837c13e41f354a6ff18e235dab696..37354324fe0bb44e94fbc62a138902dc87cf23b5 100644 (file)
@@ -3,7 +3,6 @@
  * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
  */
 
-#include <dt-bindings/interrupt-controller/irq.h>
 #include "skeleton.dtsi"
 
 / {
@@ -68,7 +67,6 @@
                        uart0: uart@18020000 {
                                compatible = "qca,ar9330-uart";
                                reg = <0x18020000 0x20>;
-                               interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
 
                                status = "disabled";
                        };
                spi0: spi@1f000000 {
                        compatible = "qca,ar7100-spi";
                        reg = <0x1f000000 0x10>;
-                       interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
 
                        status = "disabled";
 
index f75988be1291fc8a579a7ea8f32f6d5d8ab09746..d678dab242b5175940b00b25d0ff6f23a639ff49 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/dma/bcm6318-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm6318-power-domain.h>
 #include <dt-bindings/reset/bcm6318-reset.h>
                        reg = <0x10000004 0x4>;
                        #clock-cells = <1>;
                };
+
+               ubus_clk: ubus-clk {
+                       compatible = "brcm,bcm6345-clk";
+                       reg = <0x10000008 0x4>;
+                       #clock-cells = <1>;
+               };
        };
 
        ubus {
 
                        status = "disabled";
                };
+
+               enet: ethernet@10080000 {
+                       compatible = "brcm,bcm6368-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x10080000 0x8000>;
+                       clocks = <&periph_clk BCM6318_CLK_ROBOSW250>,
+                                <&periph_clk BCM6318_CLK_ROBOSW025>,
+                                <&ubus_clk BCM6318_UCLK_ROBOSW>;
+                       resets = <&periph_rst BCM6318_RST_ENETSW>,
+                                <&periph_rst BCM6318_RST_EPHY>;
+                       dmas = <&iudma BCM6318_DMA_ENETSW_RX>,
+                              <&iudma BCM6318_DMA_ENETSW_TX>;
+                       dma-names = "rx",
+                                   "tx";
+                       brcm,num-ports = <5>;
+
+                       status = "disabled";
+               };
+
+               iudma: dma-controller@10088000 {
+                       compatible = "brcm,bcm6368-iudma";
+                       reg = <0x10088000 0x80>,
+                             <0x10088200 0x80>,
+                             <0x10088400 0x80>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <8>;
+               };
        };
 };
index 62c440e6759f0f89d7bf2fc3482da3c564888755..f8a72ef535deeff7b816592369f8dc9f1f422e0e 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm63268-clock.h>
+#include <dt-bindings/dma/bcm63268-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm63268-power-domain.h>
 #include <dt-bindings/reset/bcm63268-reset.h>
                        reg = <0x10003000 0x894>;
                        u-boot,dm-pre-reloc;
                };
+
+               iudma: dma-controller@1000d800 {
+                       compatible = "brcm,bcm6368-iudma";
+                       reg = <0x1000d800 0x80>,
+                             <0x1000da00 0x80>,
+                             <0x1000dc00 0x80>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <8>;
+               };
+
+               enet: ethernet@10700000 {
+                       compatible = "brcm,bcm6368-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x10700000 0x10000>;
+                       clocks = <&periph_clk BCM63268_CLK_GMAC>,
+                                <&periph_clk BCM63268_CLK_ROBOSW>,
+                                <&periph_clk BCM63268_CLK_ROBOSW250>,
+                                <&timer_clk BCM63268_TCLK_EPHY1>,
+                                <&timer_clk BCM63268_TCLK_EPHY2>,
+                                <&timer_clk BCM63268_TCLK_EPHY3>,
+                                <&timer_clk BCM63268_TCLK_GPHY>;
+                       resets = <&periph_rst BCM63268_RST_ENETSW>,
+                                <&periph_rst BCM63268_RST_EPHY>,
+                                <&periph_rst BCM63268_RST_GPHY>;
+                       dmas = <&iudma BCM63268_DMA_ENETSW_RX>,
+                              <&iudma BCM63268_DMA_ENETSW_TX>;
+                       dma-names = "rx",
+                                   "tx";
+                       brcm,rgmii-override;
+                       brcm,rgmii-timing;
+
+                       status = "disabled";
+               };
        };
 };
index e00a2950e22a54230555d72254168ad5153ef904..50beed4171ae9247026cd38a06932550aa10b9e8 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/dma/bcm6328-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm6328-power-domain.h>
 #include <dt-bindings/reset/bcm6328-reset.h>
                        reg = <0x10003000 0x864>;
                        u-boot,dm-pre-reloc;
                };
+
+               iudma: dma-controller@1000d800 {
+                       compatible = "brcm,bcm6368-iudma";
+                       reg = <0x1000d800 0x80>,
+                             <0x1000da00 0x80>,
+                             <0x1000dc00 0x80>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <8>;
+               };
+
+               enet: ethernet@10e00000 {
+                       compatible = "brcm,bcm6368-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x10e00000 0x10000>;
+                       clocks = <&periph_clk BCM6328_CLK_ROBOSW>;
+                       resets = <&periph_rst BCM6328_RST_ENETSW>,
+                                <&periph_rst BCM6328_RST_EPHY>;
+                       dmas = <&iudma BCM6328_DMA_ENETSW_RX>,
+                              <&iudma BCM6328_DMA_ENETSW_TX>;
+                       dma-names = "rx",
+                                   "tx";
+                       brcm,num-ports = <5>;
+
+                       status = "disabled";
+               };
        };
 };
index bbd58cf803d1b32bf5e042f2e2124f73bdcc1781..c547e949ddce547d9a2bd00109b520fac5e4852d 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6338-clock.h>
+#include <dt-bindings/dma/bcm6338-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6338-reset.h>
 #include "skeleton.dtsi"
                        reg = <0xfffe3100 0x38>;
                        u-boot,dm-pre-reloc;
                };
+
+               iudma: dma-controller@fffe2400 {
+                       compatible = "brcm,bcm6348-iudma";
+                       reg = <0xfffe2400 0x1c>,
+                             <0xfffe2500 0x60>,
+                             <0xfffe2600 0x60>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <6>;
+                       resets = <&periph_rst BCM6338_RST_DMAMEM>;
+               };
+
+               enet: ethernet@fffe2800 {
+                       compatible = "brcm,bcm6348-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0xfffe2800 0x2dc>;
+                       clocks = <&periph_clk BCM6338_CLK_ENET>;
+                       resets = <&periph_rst BCM6338_RST_ENET>;
+                       dmas = <&iudma BCM6338_DMA_ENET_RX>,
+                              <&iudma BCM6338_DMA_ENET_TX>;
+                       dma-names = "rx",
+                                   "tx";
+
+                       status = "disabled";
+               };
        };
 };
index cc80bbc808d12f6983398aec32d9aa0a20897045..79e7bd892bc648c9b58e63f1e5d0560519eabf70 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6348-clock.h>
+#include <dt-bindings/dma/bcm6348-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6348-reset.h>
 #include "skeleton.dtsi"
                        reg = <0xfffe2300 0x38>;
                        u-boot,dm-pre-reloc;
                };
+
+               enet0: ethernet@fffe6000 {
+                       compatible = "brcm,bcm6348-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0xfffe6000 0x2dc>;
+                       dmas = <&iudma BCM6348_DMA_ENET0_RX>,
+                              <&iudma BCM6348_DMA_ENET0_TX>;
+                       dma-names = "rx",
+                                   "tx";
+
+                       status = "disabled";
+               };
+
+               enet1: ethernet@fffe6800 {
+                       compatible = "brcm,bcm6348-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0xfffe6800 0x2dc>;
+                       dmas = <&iudma BCM6348_DMA_ENET1_RX>,
+                              <&iudma BCM6348_DMA_ENET1_TX>;
+                       dma-names = "rx",
+                                   "tx";
+
+                       status = "disabled";
+               };
+
+               iudma: dma-controller@fffe7000 {
+                       compatible = "brcm,bcm6348-iudma";
+                       reg = <0xfffe7000 0x1c>,
+                             <0xfffe7100 0x40>,
+                             <0xfffe7200 0x40>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <4>;
+                       clocks = <&periph_clk BCM6348_CLK_ENET>;
+                       resets = <&periph_rst BCM6348_RST_ENET>,
+                                <&periph_rst BCM6348_RST_DMAMEM>;
+               };
        };
 };
index 0617b46e92687af1e3b2d30f9868dec558054994..5e9c9ad7698b013d3b5fed13f7c5c3f2e7bb7e01 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6358-clock.h>
+#include <dt-bindings/dma/bcm6358-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6358-reset.h>
 #include "skeleton.dtsi"
 
                        status = "disabled";
                };
+
+               enet0: ethernet@fffe4000 {
+                       compatible = "brcm,bcm6348-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0xfffe4000 0x2dc>;
+                       clocks = <&periph_clk BCM6358_CLK_ENET0>;
+                       dmas = <&iudma BCM6358_DMA_ENET0_RX>,
+                              <&iudma BCM6358_DMA_ENET0_TX>;
+                       dma-names = "rx",
+                                   "tx";
+
+                       status = "disabled";
+               };
+
+               enet1: ethernet@fffe4800 {
+                       compatible = "brcm,bcm6348-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0xfffe4800 0x2dc>;
+                       clocks = <&periph_clk BCM6358_CLK_ENET1>;
+                       dmas = <&iudma BCM6358_DMA_ENET1_RX>,
+                              <&iudma BCM6358_DMA_ENET1_TX>;
+                       dma-names = "rx",
+                                   "tx";
+
+                       status = "disabled";
+               };
+
+               iudma: dma-controller@fffe5000 {
+                       compatible = "brcm,bcm6348-iudma";
+                       reg = <0xfffe5000 0x24>,
+                             <0xfffe5100 0x80>,
+                             <0xfffe5200 0x80>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <8>;
+                       clocks = <&periph_clk BCM6358_CLK_EMUSB>,
+                                <&periph_clk BCM6358_CLK_USBSU>,
+                                <&periph_clk BCM6358_CLK_EPHY>;
+                       resets = <&periph_rst BCM6358_RST_ENET>,
+                                <&periph_rst BCM6358_RST_EPHY>;
+               };
        };
 };
index 3047b82b219079900e9eb1f0a629362b9ba9aee8..c77b80a4ccac88126dc48d619a847f9fccbeecd5 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6362-clock.h>
+#include <dt-bindings/dma/bcm6362-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm6362-power-domain.h>
 #include <dt-bindings/reset/bcm6362-reset.h>
                        reg = <0x10003000 0x864>;
                        u-boot,dm-pre-reloc;
                };
+
+               iudma: dma-controller@1000d800 {
+                       compatible = "brcm,bcm6368-iudma";
+                       reg = <0x1000d800 0x80>,
+                             <0x1000da00 0x80>,
+                             <0x1000dc00 0x80>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <8>;
+               };
+
+               enet: ethernet@10e00000 {
+                       compatible = "brcm,bcm6368-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x10e00000 0x10000>;
+                       clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>,
+                                <&periph_clk BCM6362_CLK_SWPKT_SAR>,
+                                <&periph_clk BCM6362_CLK_ROBOSW>;
+                       resets = <&periph_rst BCM6362_RST_ENETSW>,
+                                <&periph_rst BCM6362_RST_EPHY>;
+                       dmas = <&iudma BCM6362_DMA_ENETSW_RX>,
+                              <&iudma BCM6362_DMA_ENETSW_TX>;
+                       dma-names = "rx",
+                                   "tx";
+                       brcm,num-ports = <6>;
+
+                       status = "disabled";
+               };
        };
 };
index 65d769ab4f2317e3087f27f7c3613ea7ff587d23..89590d6ff9f73158f72ce4fc65ad5b9f67b1baa4 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/dma/bcm6368-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6368-reset.h>
 #include "skeleton.dtsi"
 
                        status = "disabled";
                };
+
+               iudma: dma-controller@10006800 {
+                       compatible = "brcm,bcm6368-iudma";
+                       reg = <0x10006800 0x80>,
+                             <0x10006a00 0x80>,
+                             <0x10006c00 0x80>;
+                       reg-names = "dma",
+                                   "dma-channels",
+                                   "dma-sram";
+                       #dma-cells = <1>;
+                       dma-channels = <8>;
+               };
+
+               enet: ethernet@10f00000 {
+                       compatible = "brcm,bcm6368-enet";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x10f00000 0x10000>;
+                       clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>,
+                                <&periph_clk BCM6368_CLK_SWPKT_SAR>,
+                                <&periph_clk BCM6368_CLK_ROBOSW>;
+                       resets = <&periph_rst BCM6368_RST_SWITCH>,
+                                <&periph_rst BCM6368_RST_EPHY>;
+                       dmas = <&iudma BCM6368_DMA_ENETSW_RX>,
+                              <&iudma BCM6368_DMA_ENETSW_TX>;
+                       dma-names = "rx",
+                                   "tx";
+                       brcm,num-ports = <6>;
+
+                       status = "disabled";
+               };
        };
 };
diff --git a/arch/mips/dts/ci20.dts b/arch/mips/dts/ci20.dts
new file mode 100644 (file)
index 0000000..8d6417a
--- /dev/null
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include "jz4780.dtsi"
+
+/ {
+       compatible = "img,ci20", "ingenic,jz4780";
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial3 = &uart3;
+               serial4 = &uart4;
+       };
+
+       chosen {
+               stdout-path = "serial4:115200n8";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x10000000
+                      0x30000000 0x30000000>;
+       };
+};
+
+&ext {
+       clock-frequency = <48000000>;
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&uart4 {
+       status = "okay";
+};
+
+&nemc {
+       status = "okay";
+
+       nandc: nand-controller@1 {
+               compatible = "ingenic,jz4780-nand";
+               reg = <1 0 0x1000000>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ingenic,bch-controller = <&bch>;
+
+               ingenic,nemc-tAS = <10>;
+               ingenic,nemc-tAH = <5>;
+               ingenic,nemc-tBP = <10>;
+               ingenic,nemc-tAW = <15>;
+               ingenic,nemc-tSTRV = <100>;
+
+               nand@1 {
+                       reg = <1>;
+
+                       nand-ecc-step-size = <1024>;
+                       nand-ecc-strength = <24>;
+                       nand-ecc-mode = "hw";
+                       nand-on-flash-bbt;
+
+                       partitions {
+                               compatible = "fixed-partitions";
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+
+                               partition@0 {
+                                       label = "u-boot-spl";
+                                       reg = <0x0 0x0 0x0 0x800000>;
+                               };
+
+                               partition@0x800000 {
+                                       label = "u-boot";
+                                       reg = <0x0 0x800000 0x0 0x200000>;
+                               };
+
+                               partition@0xa00000 {
+                                       label = "u-boot-env";
+                                       reg = <0x0 0xa00000 0x0 0x200000>;
+                               };
+
+                               partition@0xc00000 {
+                                       label = "boot";
+                                       reg = <0x0 0xc00000 0x0 0x4000000>;
+                               };
+
+                               partition@0x8c00000 {
+                                       label = "system";
+                                       reg = <0x0 0x4c00000 0x1 0xfb400000>;
+                               };
+                       };
+               };
+       };
+};
+
+&bch {
+       status = "okay";
+};
+
+&mmc0 {
+       bus-width = <4>;
+       max-frequency = <50000000>;
+       status = "okay";
+};
+
+&mmc1 {
+       bus-width = <4>;
+       max-frequency = <50000000>;
+       status = "okay";
+};
index 45570189d0bd28505e8a5be7fe9add3ddf13175c..eb60aaa8d5f832f1ff2a094a68eed644f8f3e2d2 100644 (file)
        status = "okay";
 };
 
+&enet {
+       status = "okay";
+
+       port@0 {
+               compatible = "brcm,enetsw-port";
+               reg = <0>;
+               label = "fe4";
+               brcm,phy-id = <1>;
+       };
+
+       port@1 {
+               compatible = "brcm,enetsw-port";
+               reg = <1>;
+               label = "fe3";
+               brcm,phy-id = <2>;
+       };
+
+       port@2 {
+               compatible = "brcm,enetsw-port";
+               reg = <2>;
+               label = "fe2";
+               brcm,phy-id = <3>;
+       };
+
+       port@3 {
+               compatible = "brcm,enetsw-port";
+               reg = <3>;
+               label = "fe1";
+               brcm,phy-id = <4>;
+       };
+};
+
 &leds {
        status = "okay";
 
index e993b5cd89db7182718dac70dd1c0c78004ac1e5..03e3851ab15b61e462e91823778baa8ddd5f9598 100644 (file)
        status = "okay";
 };
 
+&enet {
+       status = "okay";
+
+       port@0 {
+               compatible = "brcm,enetsw-port";
+               reg = <0>;
+               label = "fe1";
+               brcm,phy-id = <1>;
+       };
+
+       port@1 {
+               compatible = "brcm,enetsw-port";
+               reg = <1>;
+               label = "fe2";
+               brcm,phy-id = <2>;
+       };
+
+       port@2 {
+               compatible = "brcm,enetsw-port";
+               reg = <2>;
+               label = "fe3";
+               brcm,phy-id = <3>;
+       };
+
+       port@3 {
+               compatible = "brcm,enetsw-port";
+               reg = <3>;
+               label = "fe4";
+               brcm,phy-id = <4>;
+       };
+};
+
 &leds {
        status = "okay";
 
index 25747ca95d714b3aafee66ad39f08176f3bd33c1..f6b8a94e255d7a7064618f4988b1bbfac00f7890 100644 (file)
        };
 };
 
+&enet1 {
+       status = "okay";
+       phy = <&enet1phy>;
+       phy-mode = "mii";
+
+       enet1phy: fixed-link {
+               reg = <1>;
+               speed = <100>;
+               full-duplex;
+       };
+};
+
 &gpio0 {
        status = "okay";
 };
index 8c6a4a1eac94f6119238a726c88cb5337b921137..512cb52de3002ee7e7f6d590f75fac6d72083cca 100644 (file)
        status = "okay";
 };
 
+&enet {
+       status = "okay";
+
+       port@0 {
+               compatible = "brcm,enetsw-port";
+               reg = <0>;
+               label = "fe2";
+               brcm,phy-id = <1>;
+       };
+
+       port@1 {
+               compatible = "brcm,enetsw-port";
+               reg = <1>;
+               label = "fe3";
+               brcm,phy-id = <2>;
+       };
+
+       port@2 {
+               compatible = "brcm,enetsw-port";
+               reg = <2>;
+               label = "fe4";
+               brcm,phy-id = <3>;
+       };
+
+       port@3 {
+               compatible = "brcm,enetsw-port";
+               reg = <3>;
+               label = "fe1";
+               brcm,phy-id = <4>;
+       };
+};
+
 &leds {
        status = "okay";
        brcm,serial-leds;
index bd41dab9f8e7d732c633abf9289a570a80c953a6..7e835b28d2cbd6d4d92fce0116336abdbe8d14e4 100644 (file)
        status = "okay";
 };
 
+&enet {
+       status = "okay";
+
+       port@4 {
+               compatible = "brcm,enetsw-port";
+               reg = <4>;
+               label = "rgmii";
+               brcm,phy-id = <0xff>;
+               speed = <1000>;
+               full-duplex;
+               bypass-link;
+       };
+};
+
 &gpio0 {
        status = "okay";
 };
index 60455c2ff8a9a2c227d96d90988de21faac38402..6a7fc1df4b94843a1191da1859eb5f75b8fe097e 100644 (file)
        status = "okay";
 };
 
+&enet1 {
+       status = "okay";
+       phy = <&enet1phy>;
+       phy-mode = "mii";
+
+       enet1phy: fixed-link {
+               reg = <1>;
+               speed = <100>;
+               full-duplex;
+       };
+};
+
 &gpio0 {
        status = "okay";
 };
diff --git a/arch/mips/dts/jz4780.dtsi b/arch/mips/dts/jz4780.dtsi
new file mode 100644 (file)
index 0000000..f62a7a9
--- /dev/null
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <dt-bindings/clock/jz4780-cgu.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "ingenic,jz4780";
+
+       cpuintc: interrupt-controller {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       intc: interrupt-controller@10001000 {
+               compatible = "ingenic,jz4780-intc";
+               reg = <0x10001000 0x50>;
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+
+               interrupt-parent = <&cpuintc>;
+               interrupts = <2>;
+       };
+
+       ext: ext {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+       };
+
+       rtc: rtc {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
+
+       cgu: jz4780-cgu@10000000 {
+               compatible = "ingenic,jz4780-cgu";
+               reg = <0x10000000 0x100>;
+
+               clocks = <&ext>, <&rtc>;
+               clock-names = "ext", "rtc";
+
+               #clock-cells = <1>;
+       };
+
+       mmc0: mmc@13450000 {
+               compatible = "ingenic,jz4780-mmc";
+               reg = <0x13450000 0x1000>;
+
+               status = "disabled";
+
+               clocks = <&cgu JZ4780_CLK_MSC0>;
+               clock-names = "mmc";
+       };
+
+       mmc1: mmc@13460000 {
+               compatible = "ingenic,jz4780-mmc";
+               reg = <0x13460000 0x1000>;
+
+               clocks = <&cgu JZ4780_CLK_MSC1>;
+               clock-names = "mmc";
+
+               status = "disabled";
+       };
+
+       uart0: serial@10030000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10030000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <51>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART0>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart1: serial@10031000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10031000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <50>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART1>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart2: serial@10032000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10032000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <49>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART2>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart3: serial@10033000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10033000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <48>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART3>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart4: serial@10034000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10034000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <34>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART4>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       nemc: nemc@13410000 {
+               compatible = "ingenic,jz4780-nemc";
+               reg = <0x13410000 0x10000>;
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <1 0 0x1b000000 0x1000000
+                         2 0 0x1a000000 0x1000000
+                         3 0 0x19000000 0x1000000
+                         4 0 0x18000000 0x1000000
+                         5 0 0x17000000 0x1000000
+                         6 0 0x16000000 0x1000000>;
+
+               clocks = <&cgu JZ4780_CLK_NEMC>;
+
+               status = "disabled";
+       };
+
+       bch: bch@134d0000 {
+               compatible = "ingenic,jz4780-bch";
+               reg = <0x134d0000 0x10000>;
+
+               clocks = <&cgu JZ4780_CLK_BCH>;
+
+               status = "disabled";
+       };
+};
diff --git a/arch/mips/dts/luton_pcb091.dts b/arch/mips/dts/luton_pcb091.dts
new file mode 100644 (file)
index 0000000..74f9274
--- /dev/null
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,luton.dtsi"
+
+/ {
+       model = "Luton10 PCB091 Reference Board";
+       compatible = "mscc,luton-pcb091", "mscc,luton";
+
+       aliases {
+               serial0 = &uart0;
+               spi0 = &spi0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&spi0 {
+       status = "okay";
+       spi-flash@0 {
+               compatible = "spi-flash";
+               spi-max-frequency = <18000000>; /* input clock */
+               reg = <0>; /* CS0 */
+               spi-cs-high;
+       };
+};
+
diff --git a/arch/mips/dts/mscc,luton.dtsi b/arch/mips/dts/mscc,luton.dtsi
new file mode 100644 (file)
index 0000000..6a4ad2a
--- /dev/null
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "mscc,luton";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "mips,mips24KEc";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+       };
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       ahb_clk: ahb-clk {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <208333333>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x60000000 0x10200000>;
+
+               uart0: serial@10100000 {
+                       pinctrl-0 = <&uart_pins>;
+                       pinctrl-names = "default";
+
+                       compatible = "ns16550a";
+                       reg = <0x10100000 0x20>;
+                       clocks = <&ahb_clk>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+
+                       status = "disabled";
+               };
+
+               gpio: pinctrl@70068 {
+                       compatible = "mscc,luton-pinctrl";
+                       reg = <0x70068 0x68>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       gpio-ranges = <&gpio 0 0 32>;
+
+                       uart_pins: uart-pins {
+                               pins = "GPIO_30", "GPIO_31";
+                               function = "uart";
+                       };
+
+               };
+
+               gpio_spi_bitbang: gpio@10000064 {
+                       compatible = "mscc,spi-bitbang-gpio";
+                       reg = <0x10000064 0x4>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+               };
+
+               spi0: spi-bitbang {
+                       compatible = "spi-gpio";
+                       status = "okay";
+                       gpio-sck = <&gpio_spi_bitbang 6 0>;
+                       gpio-miso = <&gpio_spi_bitbang 0 0>;
+                       gpio-mosi = <&gpio_spi_bitbang 5 0>;
+                       cs-gpios = <&gpio_spi_bitbang 1 0>;
+                       num-chipselects = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+};
diff --git a/arch/mips/dts/mscc,ocelot.dtsi b/arch/mips/dts/mscc,ocelot.dtsi
new file mode 100644 (file)
index 0000000..87b4736
--- /dev/null
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "mscc,ocelot";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "mips,mips24KEc";
+                       device_type = "cpu";
+                       clocks = <&cpu_clk>;
+                       reg = <0>;
+               };
+       };
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       cpuintc: interrupt-controller@0 {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       cpu_clk: cpu-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <500000000>;
+       };
+
+       ahb_clk: ahb-clk {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <250000000>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x70000000 0x2000000>;
+
+               interrupt-parent = <&intc>;
+
+               cpu_ctrl: syscon@0 {
+                       compatible = "mscc,ocelot-cpu-syscon", "syscon";
+                       reg = <0x0 0x2c>;
+               };
+
+               intc: interrupt-controller@70 {
+                       compatible = "mscc,ocelot-icpu-intr";
+                       reg = <0x70 0x70>;
+                       #interrupt-cells = <1>;
+                       interrupt-controller;
+                       interrupt-parent = <&cpuintc>;
+                       interrupts = <2>;
+               };
+
+               uart0: serial@100000 {
+                       pinctrl-0 = <&uart_pins>;
+                       pinctrl-names = "default";
+                       compatible = "ns16550a";
+                       reg = <0x100000 0x20>;
+                       interrupts = <6>;
+                       clocks = <&ahb_clk>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+
+                       status = "disabled";
+               };
+
+               uart2: serial@100800 {
+                       pinctrl-0 = <&uart2_pins>;
+                       pinctrl-names = "default";
+                       compatible = "ns16550a";
+                       reg = <0x100800 0x20>;
+                       interrupts = <7>;
+                       clocks = <&ahb_clk>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+
+                       status = "disabled";
+               };
+
+               spi0: spi-master@101000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "snps,dw-apb-ssi";
+                       reg = <0x101000 0x40>;
+                       num-chipselect = <4>;
+                       bus-num = <0>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+                       spi-max-frequency = <18000000>; /* input clock */
+                       clocks = <&ahb_clk>;
+
+                       status = "disabled";
+               };
+
+               reset@1070008 {
+                       compatible = "mscc,ocelot-chip-reset";
+                       reg = <0x1070008 0x4>;
+               };
+
+               gpio: pinctrl@1070034 {
+                       compatible = "mscc,ocelot-pinctrl";
+                       reg = <0x1070034 0x68>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       gpio-ranges = <&gpio 0 0 22>;
+
+                       uart_pins: uart-pins {
+                               pins = "GPIO_6", "GPIO_7";
+                               function = "uart";
+                       };
+
+                       uart2_pins: uart2-pins {
+                               pins = "GPIO_12", "GPIO_13";
+                               function = "uart2";
+                       };
+
+                       spi_cs1_pin: spi-cs1-pin {
+                               pins = "GPIO_8";
+                               function = "si";
+                       };
+
+                       spi_cs2_pin: spi-cs2-pin {
+                               pins = "GPIO_9";
+                               function = "si";
+                       };
+
+                       spi_cs3_pin: spi-cs3-pin {
+                               pins = "GPIO_16";
+                               function = "si";
+                       };
+
+                       spi_cs4_pin: spi-cs4-pin {
+                               pins = "GPIO_17";
+                               function = "si";
+                       };
+               };
+       };
+};
diff --git a/arch/mips/dts/mscc,ocelot_pcb.dtsi b/arch/mips/dts/mscc,ocelot_pcb.dtsi
new file mode 100644 (file)
index 0000000..90725d3
--- /dev/null
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,ocelot.dtsi"
+
+/ {
+       compatible = "mscc,ocelot";
+
+       aliases {
+               spi0 = &spi0;
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&spi0 {
+       status = "okay";
+       pinctrl-0 = <&spi_cs1_pin>;
+       pinctrl-names = "default";
+
+       spi-flash@0 {
+               compatible = "spi-flash";
+               spi-max-frequency = <18000000>; /* input clock */
+               reg = <0>; /* CS0 */
+       };
+
+       spi-nand@1 {
+               compatible = "spi-nand";
+               spi-max-frequency = <18000000>; /* input clock */
+               reg = <1>; /* CS1 */
+       };
+};
index 322d1567ffd77e3ba96d12bde533a4a166004847..2b72491f0b2fdc0c00c7b83a1ffcdfdb1cd3ab84 100644 (file)
        status = "okay";
 };
 
+&enet {
+       status = "okay";
+
+       port@4 {
+               compatible = "brcm,enetsw-port";
+               reg = <4>;
+               label = "rgmii";
+               brcm,phy-id = <0xff>;
+               speed = <1000>;
+               full-duplex;
+               bypass-link;
+       };
+};
+
 &gpio0 {
        status = "okay";
 };
index e254ab1eaafbe867faf9fe9f14c8881b55aa97db..6de8584ea796b28ef2ea5fc1858fd6105e1438ba 100644 (file)
@@ -40,7 +40,6 @@
                        #address-cells = <1>;
                        #size-cells = <0>;
                        phy0: phy@1 {
-                               compatible = <0x0007c0f0 0xfffffff0>;
                                device_type = "ethernet-phy";
                                reg = <1>;
                        } ;
diff --git a/arch/mips/dts/ocelot_pcb120.dts b/arch/mips/dts/ocelot_pcb120.dts
new file mode 100644 (file)
index 0000000..47d305a
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,ocelot_pcb.dtsi"
+
+/ {
+       model = "Ocelot PCB120 Reference Board";
+       compatible = "mscc,ocelot-pcb120", "mscc,ocelot";
+};
diff --git a/arch/mips/dts/ocelot_pcb123.dts b/arch/mips/dts/ocelot_pcb123.dts
new file mode 100644 (file)
index 0000000..17d8d32
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,ocelot_pcb.dtsi"
+
+/ {
+       model = "Ocelot PCB123 Reference Board";
+       compatible = "mscc,ocelot-pcb123", "mscc,ocelot";
+};
index 599e809c4793aa5541283a845307446d0ef3c598..ba29ea287e2bab3dfaddd3b6fdd2ac9740d7c4eb 100644 (file)
@@ -3,7 +3,6 @@
  * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
  */
 
-#include <dt-bindings/interrupt-controller/irq.h>
 #include "skeleton.dtsi"
 
 / {
@@ -63,7 +62,6 @@
                                reg = <0x18020000 0x20>;
                                reg-shift = <2>;
                                clock-frequency = <25000000>;
-                               interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
 
                                status = "disabled";
                        };
@@ -72,7 +70,6 @@
                spi0: spi@1f000000 {
                        compatible = "qca,ar7100-spi";
                        reg = <0x1f000000 0x10>;
-                       interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
 
                        status = "disabled";
 
index 5300f8b6df9fd09db163aee9f42bded824d1c741..ec6846dd9f2577a842b09e070f366690a7cbdff2 100644 (file)
        };
 };
 
+&enet {
+       status = "okay";
+       phy = <&enetphy>;
+       phy-mode = "mii";
+
+       enetphy: fixed-link {
+               reg = <1>;
+               speed = <100>;
+               full-duplex;
+       };
+};
+
 &gpio {
        status = "okay";
 };
index bdc6f8ae4559060a409552c161f1cd3bcf7bea4e..dfbc4148dcdb7133543e8db2996d9b6859cb88dc 100644 (file)
        status = "okay";
 };
 
+&enet0 {
+       status = "okay";
+       phy = <&enet0phy>;
+       phy-mode = "internal";
+
+       enet0phy: fixed-link {
+               reg = <1>;
+               speed = <100>;
+               full-duplex;
+       };
+};
+
+&enet1 {
+       status = "okay";
+       phy = <&enet1phy>;
+       phy-mode = "mii";
+
+       enet1phy: fixed-link {
+               reg = <1>;
+               speed = <100>;
+               full-duplex;
+       };
+};
+
 &gpio0 {
        status = "okay";
 };
index 3161875441c64df03989ee62f0c114461cb85348..98b67ccc8ec701a2dd8b1ea9d31036a540325c5d 100644 (file)
@@ -19,6 +19,25 @@ static inline void mips_cache(int op, const volatile void *addr)
 #endif
 }
 
+#define MIPS32_WHICH_ICACHE                    0x0
+#define MIPS32_FETCH_AND_LOCK                  0x7
+
+#define ICACHE_LOAD_LOCK (MIPS32_WHICH_ICACHE | (MIPS32_FETCH_AND_LOCK << 2))
+
+/* Prefetch and lock instructions into cache */
+static inline void icache_lock(void *func, size_t len)
+{
+       int i, lines = ((len - 1) / ARCH_DMA_MINALIGN) + 1;
+
+       for (i = 0; i < lines; i++) {
+               asm volatile (" cache %0, %1(%2)"
+                             : /* No Output */
+                             : "I" ICACHE_LOAD_LOCK,
+                               "n" (i * ARCH_DMA_MINALIGN),
+                               "r" (func)
+                             : /* No Clobbers */);
+       }
+}
 #endif /* !__ASSEMBLY__ */
 
 /*
index 48fa1f1f7f4e1b82d74576ff4a9e613531cc8256..f80311e64e8c58d25e316b66149cec991d5499de 100644 (file)
@@ -1013,9 +1013,7 @@ do {                                                                      \
 #define __read_64bit_c0_split(source, sel)                             \
 ({                                                                     \
        unsigned long long __val;                                       \
-       unsigned long __flags;                                          \
                                                                        \
-       local_irq_save(__flags);                                        \
        if (sel == 0)                                                   \
                __asm__ __volatile__(                                   \
                        ".set\tmips64\n\t"                              \
@@ -1034,16 +1032,12 @@ do {                                                                    \
                        "dsra\t%L0, %L0, 32\n\t"                        \
                        ".set\tmips0"                                   \
                        : "=r" (__val));                                \
-       local_irq_restore(__flags);                                     \
                                                                        \
        __val;                                                          \
 })
 
 #define __write_64bit_c0_split(source, sel, val)                       \
 do {                                                                   \
-       unsigned long __flags;                                          \
-                                                                       \
-       local_irq_save(__flags);                                        \
        if (sel == 0)                                                   \
                __asm__ __volatile__(                                   \
                        ".set\tmips64\n\t"                              \
@@ -1064,7 +1058,6 @@ do {                                                                      \
                        "dmtc0\t%L0, " #source ", " #sel "\n\t"         \
                        ".set\tmips0"                                   \
                        : : "r" (val));                                 \
-       local_irq_restore(__flags);                                     \
 } while (0)
 
 #define __readx_32bit_c0_register(source)                              \
@@ -2005,6 +1998,17 @@ static inline unsigned int get_ebase_cpunum(void)
        return read_c0_ebase() & 0x3ff;
 }
 
+static inline void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0,
+                                u32 low1)
+{
+       write_c0_entrylo0(low0);
+       write_c0_pagemask(pagemask);
+       write_c0_entrylo1(low1);
+       write_c0_entryhi(hi);
+       write_c0_index(index);
+       tlb_write_indexed();
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_MIPSREGS_H */
diff --git a/arch/mips/include/asm/spl.h b/arch/mips/include/asm/spl.h
new file mode 100644 (file)
index 0000000..0a847ed
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ */
+#ifndef        _ASM_SPL_H_
+#define        _ASM_SPL_H_
+
+enum {
+       BOOT_DEVICE_RAM,
+       BOOT_DEVICE_MMC1,
+       BOOT_DEVICE_MMC2,
+       BOOT_DEVICE_MMC2_2,
+       BOOT_DEVICE_NAND,
+       BOOT_DEVICE_ONENAND,
+       BOOT_DEVICE_NOR,
+       BOOT_DEVICE_UART,
+       BOOT_DEVICE_SPI,
+       BOOT_DEVICE_USB,
+       BOOT_DEVICE_SATA,
+       BOOT_DEVICE_I2C,
+       BOOT_DEVICE_BOARD,
+       BOOT_DEVICE_DFU,
+       BOOT_DEVICE_XIP,
+       BOOT_DEVICE_BOOTROM,
+       BOOT_DEVICE_NONE
+};
+
+#ifndef CONFIG_DM
+extern gd_t gdata;
+#endif
+
+#endif
diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig
new file mode 100644 (file)
index 0000000..dcaac01
--- /dev/null
@@ -0,0 +1,26 @@
+menu "Ingenic JZ47xx platforms"
+       depends on ARCH_JZ47XX
+
+config SYS_SOC
+       default "jz47xx"
+
+config SOC_JZ4780
+       bool
+       select SUPPORTS_LITTLE_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       help
+         Support for Ingenic JZ4780 family SoCs.
+
+choice
+       prompt "Board select"
+
+config TARGET_JZ4780_CI20
+       bool "Creator CI20 Reference Board"
+       select SOC_JZ4780
+
+endchoice
+
+source "board/imgtec/ci20/Kconfig"
+
+endmenu
diff --git a/arch/mips/mach-jz47xx/Makefile b/arch/mips/mach-jz47xx/Makefile
new file mode 100644 (file)
index 0000000..dbb8229
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+extra-$(CONFIG_SPL_BUILD)      := start.o
+
+obj-$(CONFIG_SOC_JZ4780)       += jz4780/
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780.h b/arch/mips/mach-jz47xx/include/mach/jz4780.h
new file mode 100644 (file)
index 0000000..4422e50
--- /dev/null
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * JZ4780 definitions
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#ifndef __JZ4780_H__
+#define __JZ4780_H__
+
+/* AHB0 BUS Devices */
+#define DDRC_BASE      0xb3010000
+
+/* AHB2 BUS Devices */
+#define NEMC_BASE      0xb3410000
+#define BCH_BASE       0xb34d0000
+
+/* APB BUS Devices */
+#define CPM_BASE       0xb0000000
+#define TCU_BASE       0xb0002000
+#define WDT_BASE       0xb0002000
+#define GPIO_BASE      0xb0010000
+#define UART0_BASE     0xb0030000
+#define UART1_BASE     0xb0031000
+#define UART2_BASE     0xb0032000
+#define UART3_BASE     0xb0033000
+#define MSC0_BASE      0xb3450000
+#define MSC1_BASE      0xb3460000
+#define MSC2_BASE      0xb3470000
+
+/*
+ * GPIO
+ */
+/* n = 0,1,2,3,4,5 */
+#define GPIO_PXPIN(n)  (0x00 + (n) * 0x100)
+#define GPIO_PXINT(n)  (0x10 + (n) * 0x100)
+#define GPIO_PXINTS(n) (0x14 + (n) * 0x100)
+#define GPIO_PXINTC(n) (0x18 + (n) * 0x100)
+#define GPIO_PXMASK(n) (0x20 + (n) * 0x100)
+#define GPIO_PXMASKS(n)        (0x24 + (n) * 0x100)
+#define GPIO_PXMASKC(n)        (0x28 + (n) * 0x100)
+#define GPIO_PXPAT1(n) (0x30 + (n) * 0x100)
+#define GPIO_PXPAT1S(n)        (0x34 + (n) * 0x100)
+#define GPIO_PXPAT1C(n)        (0x38 + (n) * 0x100)
+#define GPIO_PXPAT0(n) (0x40 + (n) * 0x100)
+#define GPIO_PXPAT0S(n)        (0x44 + (n) * 0x100)
+#define GPIO_PXPAT0C(n)        (0x48 + (n) * 0x100)
+#define GPIO_PXFLG(n)  (0x50 + (n) * 0x100)
+#define GPIO_PXFLGC(n) (0x54 + (n) * 0x100)
+#define GPIO_PXOEN(n)  (0x60 + (n) * 0x100)
+#define GPIO_PXOENS(n) (0x64 + (n) * 0x100)
+#define GPIO_PXOENC(n) (0x68 + (n) * 0x100)
+#define GPIO_PXPEN(n)  (0x70 + (n) * 0x100)
+#define GPIO_PXPENS(n) (0x74 + (n) * 0x100)
+#define GPIO_PXPENC(n) (0x78 + (n) * 0x100)
+#define GPIO_PXDS(n)   (0x80 + (n) * 0x100)
+#define GPIO_PXDSS(n)  (0x84 + (n) * 0x100)
+#define GPIO_PXDSC(n)  (0x88 + (n) * 0x100)
+
+/* PLL setup */
+#define JZ4780_SYS_EXTAL       48000000
+#define JZ4780_SYS_MEM_SPEED   (CONFIG_SYS_MHZ * 1000000)
+#define JZ4780_SYS_MEM_DIV     3
+#define JZ4780_SYS_AUDIO_SPEED (768 * 1000000)
+
+#define JZ4780_APLL_M  1
+#define JZ4780_APLL_N  1
+#define JZ4780_APLL_OD 1
+
+#define JZ4780_MPLL_M  (JZ4780_SYS_MEM_SPEED / JZ4780_SYS_EXTAL * 2)
+#define JZ4780_MPLL_N  2
+#define JZ4780_MPLL_OD 1
+
+#define JZ4780_EPLL_M  (JZ4780_SYS_AUDIO_SPEED * 2 / JZ4780_SYS_EXTAL)
+#define JZ4780_EPLL_N  1
+#define JZ4780_EPLL_OD 2
+
+#define JZ4780_VPLL_M  ((888 * 1000000) * 2 / JZ4780_SYS_EXTAL)
+#define JZ4780_VPLL_N  1
+#define JZ4780_VPLL_OD 2
+
+#ifndef __ASSEMBLY__
+
+u32 sdram_size(int bank);
+
+const u32 jz4780_clk_get_efuse_clk(void);
+void jz4780_clk_ungate_ethernet(void);
+void jz4780_clk_ungate_mmc(void);
+void jz4780_clk_ungate_uart(const unsigned int uart);
+
+void jz4780_efuse_read(size_t addr, size_t count, u8 *buf);
+void jz4780_efuse_init(u32 ahb2_rate);
+
+void jz4780_tcu_wdt_start(void);
+
+#ifdef CONFIG_SPL_BUILD
+int jz_mmc_init(void __iomem *base);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __JZ4780_H__ */
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h
new file mode 100644 (file)
index 0000000..92d431b
--- /dev/null
@@ -0,0 +1,456 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * JZ4780 DDR initialization - parameters definitions
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ * Author: Matt Redfearn <matt.redfearn.com>
+ */
+
+#ifndef __JZ4780_DRAM_H__
+#define __JZ4780_DRAM_H__
+
+/*
+ * DDR
+ */
+#define DDRC_ST                                0x0
+#define DDRC_CFG                       0x4
+#define DDRC_CTRL                      0x8
+#define DDRC_LMR                       0xc
+#define DDRC_REFCNT                    0x18
+#define DDRC_DQS                       0x1c
+#define DDRC_DQS_ADJ                   0x20
+#define DDRC_MMAP0                     0x24
+#define DDRC_MMAP1                     0x28
+#define DDRC_MDELAY                    0x2c
+#define DDRC_CKEL                      0x30
+#define DDRC_PMEMCTRL0                 0x54
+#define DDRC_PMEMCTRL1                 0x50
+#define DDRC_PMEMCTRL2                 0x58
+#define DDRC_PMEMCTRL3                 0x5c
+
+#define DDRC_TIMING(n)                 (0x60 + 4 * (n))
+#define DDRC_REMMAP(n)                 (0x9c + 4 * (n))
+
+/*
+ * DDR PHY
+ */
+#define DDR_MEM_PHY_BASE               0x20000000
+#define DDR_PHY_OFFSET                 0x1000
+
+#define DDRP_PIR                       0x4
+#define DDRP_PGCR                      0x8
+#define DDRP_PGSR                      0xc
+
+#define DDRP_PTR0                      0x18
+#define DDRP_PTR1                      0x1c
+#define DDRP_PTR2                      0x20
+
+#define DDRP_ACIOCR                    0x24
+#define DDRP_DXCCR                     0x28
+#define DDRP_DSGCR                     0x2c
+#define DDRP_DCR                       0x30
+
+#define DDRP_DTPR0                     0x34
+#define DDRP_DTPR1                     0x38
+#define DDRP_DTPR2                     0x3c
+#define DDRP_MR0                       0x40
+#define DDRP_MR1                       0x44
+#define DDRP_MR2                       0x48
+#define DDRP_MR3                       0x4c
+
+#define DDRP_ODTCR                     0x50
+#define DDRP_DTAR                      0x54
+#define DDRP_DTDR0                     0x58
+#define DDRP_DTDR1                     0x5c
+
+#define DDRP_DCUAR                     0xc0
+#define DDRP_DCUDR                     0xc4
+#define DDRP_DCURR                     0xc8
+#define DDRP_DCULR                     0xcc
+#define DDRP_DCUGCR                    0xd0
+#define DDRP_DCUTPR                    0xd4
+#define DDRP_DCUSR0                    0xd8
+#define DDRP_DCUSR1                    0xdc
+
+#define DDRP_ZQXCR0(n)                 (0x180 + ((n) * 0x10))
+#define DDRP_ZQXCR1(n)                 (0x184 + ((n) * 0x10))
+#define DDRP_ZQXSR0(n)                 (0x188 + ((n) * 0x10))
+#define DDRP_ZQXSR1(n)                 (0x18c + ((n) * 0x10))
+
+#define DDRP_DXGCR(n)                  (0x1c0 + ((n) * 0x40))
+#define DDRP_DXGSR0(n)                 (0x1c4 + ((n) * 0x40))
+#define DDRP_DXGSR1(n)                 (0x1c8 + ((n) * 0x40))
+#define DDRP_DXDQSTR(n)                        (0x1d4 + ((n) * 0x40))
+
+/* DDRC Status Register */
+#define DDRC_ST_ENDIAN                 BIT(7)
+#define DDRC_ST_DPDN                   BIT(5)
+#define DDRC_ST_PDN                    BIT(4)
+#define DDRC_ST_AREF                   BIT(3)
+#define DDRC_ST_SREF                   BIT(2)
+#define DDRC_ST_CKE1                   BIT(1)
+#define DDRC_ST_CKE0                   BIT(0)
+
+/* DDRC Configure Register */
+#define DDRC_CFG_ROW1_BIT              27
+#define DDRC_CFG_ROW1_MASK             (0x7 << DDRC_CFG_ROW1_BIT)
+#define DDRC_CFG_COL1_BIT              24
+#define DDRC_CFG_COL1_MASK             (0x7 << DDRC_CFG_COL1_BIT)
+#define DDRC_CFG_BA1                   BIT(23)
+#define DDRC_CFG_IMBA                  BIT(22)
+#define DDRC_CFG_BL_8                  BIT(21)
+
+#define DDRC_CFG_TYPE_BIT              17
+#define DDRC_CFG_TYPE_MASK             (0x7 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR1             (2 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_MDDR             (3 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR2             (4 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_LPDDR2           (5 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR3             (6 << DDRC_CFG_TYPE_BIT)
+
+#define DDRC_CFG_ODT_EN                        BIT(16)
+
+#define DDRC_CFG_MPRT                  BIT(15)
+
+#define DDRC_CFG_ROW_BIT               11
+#define DDRC_CFG_ROW_MASK              (0x7 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_12                        (0 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_13                        (1 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_14                        (2 << DDRC_CFG_ROW_BIT)
+
+#define DDRC_CFG_COL_BIT               8
+#define DDRC_CFG_COL_MASK              (0x7 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_8                 (0 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_9                 (1 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_10                        (2 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_11                        (3 << DDRC_CFG_COL_BIT)
+
+#define DDRC_CFG_CS1EN                 BIT(7)
+#define DDRC_CFG_CS0EN                 BIT(6)
+#define DDRC_CFG_CL_BIT                        2
+#define DDRC_CFG_CL_MASK               (0xf << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_3                  (0 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_4                  (1 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_5                  (2 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_6                  (3 << DDRC_CFG_CL_BIT)
+
+#define DDRC_CFG_BA                    BIT(1)
+#define DDRC_CFG_DW                    BIT(0)
+
+/* DDRC Control Register */
+#define DDRC_CTRL_DFI_RST              BIT(23)
+#define DDRC_CTRL_DLL_RST              BIT(22)
+#define DDRC_CTRL_CTL_RST              BIT(21)
+#define DDRC_CTRL_CFG_RST              BIT(20)
+#define DDRC_CTRL_ACTPD                        BIT(15)
+#define DDRC_CTRL_PDT_BIT              12
+#define DDRC_CTRL_PDT_MASK             (0x7 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_DIS              (0 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_8                        (1 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_16               (2 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_32               (3 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_64               (4 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_128              (5 << DDRC_CTRL_PDT_BIT)
+
+#define DDRC_CTRL_PRET_BIT             8
+#define DDRC_CTRL_PRET_MASK            (0x7 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_DIS             (0 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_8               (1 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_16              (2 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_32              (3 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_64              (4 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_128             (5 << DDRC_CTRL_PRET_BIT)
+
+#define DDRC_CTRL_DPD                  BIT(6)
+#define DDRC_CTRL_SR                   BIT(5)
+#define DDRC_CTRL_UNALIGN              BIT(4)
+#define DDRC_CTRL_ALH                  BIT(3)
+#define DDRC_CTRL_RDC                  BIT(2)
+#define DDRC_CTRL_CKE                  BIT(1)
+#define DDRC_CTRL_RESET                        BIT(0)
+
+/* DDRC Load-Mode-Register */
+#define DDRC_LMR_DDR_ADDR_BIT          16
+#define DDRC_LMR_DDR_ADDR_MASK         (0x3fff << DDRC_LMR_DDR_ADDR_BIT)
+
+#define DDRC_LMR_BA_BIT                        8
+#define DDRC_LMR_BA_MASK               (0x7 << DDRC_LMR_BA_BIT)
+/* For DDR2 */
+#define DDRC_LMR_BA_MRS                        (0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS1              (1 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS2              (2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS3              (3 << DDRC_LMR_BA_BIT)
+/* For mobile DDR */
+#define DDRC_LMR_BA_M_MRS              (0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_EMRS             (2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_SR               (1 << DDRC_LMR_BA_BIT)
+/* For Normal DDR1 */
+#define DDRC_LMR_BA_N_MRS              (0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_N_EMRS             (1 << DDRC_LMR_BA_BIT)
+
+#define DDRC_LMR_CMD_BIT               4
+#define DDRC_LMR_CMD_MASK              (0x3 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_PREC              (0 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_AUREF             (1 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_LMR               (2 << DDRC_LMR_CMD_BIT)
+
+#define DDRC_LMR_START                 BIT(0)
+
+/* DDRC Timing Config Register 1 */
+#define DDRC_TIMING1_TRTP_BIT          24
+#define DDRC_TIMING1_TRTP_MASK         (0x3f << DDRC_TIMING1_TRTP_BIT)
+#define DDRC_TIMING1_TWTR_BIT          16
+#define DDRC_TIMING1_TWTR_MASK         (0x3f << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_1            (0 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_2            (1 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_3            (2 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_4            (3 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWR_BIT           8
+#define DDRC_TIMING1_TWR_MASK          (0x3f << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_1             (0 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_2             (1 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_3             (2 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_4             (3 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_5             (4 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_6             (5 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWL_BIT           0
+#define DDRC_TIMING1_TWL_MASK          (0x3f << DDRC_TIMING1_TWL_BIT)
+
+/* DDRC Timing Config Register 2 */
+#define DDRC_TIMING2_TCCD_BIT          24
+#define DDRC_TIMING2_TCCD_MASK         (0x3f << DDRC_TIMING2_TCCD_BIT)
+#define DDRC_TIMING2_TRAS_BIT          16
+#define DDRC_TIMING2_TRAS_MASK         (0x3f << DDRC_TIMING2_TRAS_BIT)
+#define DDRC_TIMING2_TRCD_BIT          8
+#define DDRC_TIMING2_TRCD_MASK         (0x3f << DDRC_TIMING2_TRCD_BIT)
+#define DDRC_TIMING2_TRL_BIT           0
+#define DDRC_TIMING2_TRL_MASK          (0x3f << DDRC_TIMING2_TRL_BIT)
+
+/* DDRC Timing Config Register 3 */
+#define DDRC_TIMING3_ONUM              27
+#define DDRC_TIMING3_TCKSRE_BIT                24
+#define DDRC_TIMING3_TCKSRE_MASK       (0x3f << DDRC_TIMING3_TCKSRE_BIT)
+#define DDRC_TIMING3_TRP_BIT           16
+#define DDRC_TIMING3_TRP_MASK          (0x3f << DDRC_TIMING3_TRP_BIT)
+#define DDRC_TIMING3_TRRD_BIT          8
+#define DDRC_TIMING3_TRRD_MASK         (0x3f << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_DISABLE      (0 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_2            (1 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_3            (2 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_4            (3 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRC_BIT           0
+#define DDRC_TIMING3_TRC_MASK          (0x3f << DDRC_TIMING3_TRC_BIT)
+
+/* DDRC Timing Config Register 4 */
+#define DDRC_TIMING4_TRFC_BIT          24
+#define DDRC_TIMING4_TRFC_MASK         (0x3f << DDRC_TIMING4_TRFC_BIT)
+#define DDRC_TIMING4_TEXTRW_BIT                21
+#define DDRC_TIMING4_TEXTRW_MASK       (0x7 << DDRC_TIMING4_TEXTRW_BIT)
+#define DDRC_TIMING4_TRWCOV_BIT                19
+#define DDRC_TIMING4_TRWCOV_MASK       (0x3 << DDRC_TIMING4_TRWCOV_BIT)
+#define DDRC_TIMING4_TCKE_BIT          16
+#define DDRC_TIMING4_TCKE_MASK         (0x7 << DDRC_TIMING4_TCKE_BIT)
+#define DDRC_TIMING4_TMINSR_BIT                8
+#define DDRC_TIMING4_TMINSR_MASK       (0xf << DDRC_TIMING4_TMINSR_BIT)
+#define DDRC_TIMING4_TXP_BIT           4
+#define DDRC_TIMING4_TXP_MASK          (0x7 << DDRC_TIMING4_TXP_BIT)
+#define DDRC_TIMING4_TMRD_BIT          0
+#define DDRC_TIMING4_TMRD_MASK         (0x3 << DDRC_TIMING4_TMRD_BIT)
+
+/* DDRC Timing Config Register 5 */
+#define DDRC_TIMING5_TCTLUPD_BIT       24
+#define DDRC_TIMING4_TCTLUPD_MASK      (0x3f << DDRC_TIMING5_TCTLUDP_BIT)
+#define DDRC_TIMING5_TRTW_BIT          16
+#define DDRC_TIMING5_TRTW_MASK         (0x3f << DDRC_TIMING5_TRTW_BIT)
+#define DDRC_TIMING5_TRDLAT_BIT                8
+#define DDRC_TIMING5_TRDLAT_MASK       (0x3f << DDRC_TIMING5_TRDLAT_BIT)
+#define DDRC_TIMING5_TWDLAT_BIT                0
+#define DDRC_TIMING5_TWDLAT_MASK       (0x3f << DDRC_TIMING5_TWDLAT_BIT)
+
+/* DDRC Timing Config Register 6 */
+#define DDRC_TIMING6_TXSRD_BIT         24
+#define DDRC_TIMING6_TXSRD_MASK                (0x3f << DDRC_TIMING6_TXSRD_BIT)
+#define DDRC_TIMING6_TFAW_BIT          16
+#define DDRC_TIMING6_TFAW_MASK         (0x3f << DDRC_TIMING6_TFAW_BIT)
+#define DDRC_TIMING6_TCFGW_BIT         8
+#define DDRC_TIMING6_TCFGW_MASK                (0x3f << DDRC_TIMING6_TCFGW_BIT)
+#define DDRC_TIMING6_TCFGR_BIT         0
+#define DDRC_TIMING6_TCFGR_MASK                (0x3f << DDRC_TIMING6_TCFGR_BIT)
+
+/* DDRC  Auto-Refresh Counter */
+#define DDRC_REFCNT_CON_BIT            16
+#define DDRC_REFCNT_CON_MASK           (0xff << DDRC_REFCNT_CON_BIT)
+#define DDRC_REFCNT_CNT_BIT            8
+#define DDRC_REFCNT_CNT_MASK           (0xff << DDRC_REFCNT_CNT_BIT)
+#define DDRC_REFCNT_CLKDIV_BIT         1
+#define DDRC_REFCNT_CLKDIV_MASK                (0x7 << DDRC_REFCNT_CLKDIV_BIT)
+#define DDRC_REFCNT_REF_EN             BIT(0)
+
+/* DDRC DQS Delay Control Register */
+#define DDRC_DQS_ERROR                 BIT(29)
+#define DDRC_DQS_READY                 BIT(28)
+#define DDRC_DQS_AUTO                  BIT(23)
+#define DDRC_DQS_DET                   BIT(24)
+#define DDRC_DQS_SRDET                 BIT(25)
+#define DDRC_DQS_CLKD_BIT              16
+#define DDRC_DQS_CLKD_MASK             (0x3f << DDRC_DQS_CLKD_BIT)
+#define DDRC_DQS_WDQS_BIT              8
+#define DDRC_DQS_WDQS_MASK             (0x3f << DDRC_DQS_WDQS_BIT)
+#define DDRC_DQS_RDQS_BIT              0
+#define DDRC_DQS_RDQS_MASK             (0x3f << DDRC_DQS_RDQS_BIT)
+
+/* DDRC DQS Delay Adjust Register */
+#define DDRC_DQS_ADJWDQS_BIT           8
+#define DDRC_DQS_ADJWDQS_MASK          (0x1f << DDRC_DQS_ADJWDQS_BIT)
+#define DDRC_DQS_ADJRDQS_BIT           0
+#define DDRC_DQS_ADJRDQS_MASK          (0x1f << DDRC_DQS_ADJRDQS_BIT)
+
+/* DDRC Memory Map Config Register */
+#define DDRC_MMAP_BASE_BIT             8
+#define DDRC_MMAP_BASE_MASK            (0xff << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP_MASK_BIT             0
+#define DDRC_MMAP_MASK_MASK            (0xff << DDRC_MMAP_MASK_BIT)
+
+#define DDRC_MMAP0_BASE                        (0x20 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_64M            (0x24 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_128M           (0x28 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_256M           (0x30 << DDRC_MMAP_BASE_BIT)
+
+#define DDRC_MMAP_MASK_64_64           (0xfc << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_128_128         (0xf8 << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_256_256         (0xf0 << DDRC_MMAP_MASK_BIT)
+
+/* DDRP PHY Initialization Register */
+#define DDRP_PIR_INIT                  BIT(0)
+#define DDRP_PIR_DLLSRST               BIT(1)
+#define DDRP_PIR_DLLLOCK               BIT(2)
+#define DDRP_PIR_ZCAL                  BIT(3)
+#define DDRP_PIR_ITMSRST               BIT(4)
+#define DDRP_PIR_DRAMRST               BIT(5)
+#define DDRP_PIR_DRAMINT               BIT(6)
+#define DDRP_PIR_QSTRN                 BIT(7)
+#define DDRP_PIR_EYETRN                        BIT(8)
+#define DDRP_PIR_DLLBYP                        BIT(17)
+/* DDRP PHY General Configurate Register */
+#define DDRP_PGCR_ITMDMD               BIT(0)
+#define DDRP_PGCR_DQSCFG               BIT(1)
+#define DDRP_PGCR_DFTCMP               BIT(2)
+#define DDRP_PGCR_DFTLMT_BIT           3
+#define DDRP_PGCR_DTOSEL_BIT           5
+#define DDRP_PGCR_CKEN_BIT             9
+#define DDRP_PGCR_CKDV_BIT             12
+#define DDRP_PGCR_CKINV                        BIT(14)
+#define DDRP_PGCR_RANKEN_BIT           18
+#define DDRP_PGCR_ZCKSEL_32            (2 << 22)
+#define DDRP_PGCR_PDDISDX              BIT(24)
+/* DDRP PHY General Status Register */
+#define DDRP_PGSR_IDONE                        BIT(0)
+#define DDRP_PGSR_DLDONE               BIT(1)
+#define DDRP_PGSR_ZCDONE               BIT(2)
+#define DDRP_PGSR_DIDONE               BIT(3)
+#define DDRP_PGSR_DTDONE               BIT(4)
+#define DDRP_PGSR_DTERR                        BIT(5)
+#define DDRP_PGSR_DTIERR               BIT(6)
+#define DDRP_PGSR_DFTEERR              BIT(7)
+/* DDRP DRAM Configuration Register */
+#define DDRP_DCR_TYPE_BIT              0
+#define DDRP_DCR_TYPE_MASK             (0x7 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_MDDR             (0 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR              (1 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR2             (2 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR3             (3 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_LPDDR2           (4 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_DDR8BNK_BIT           3
+#define DDRP_DCR_DDR8BNK_MASK          (1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK               (1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK_DIS           (0 << DDRP_DCR_DDR8BNK_BIT)
+
+#define DRP_DTRP1_RTODT                        BIT(11)
+
+#define DDRP_DXGCR_DXEN                        BIT(0)
+
+#define DDRP_ZQXCR_ZDEN_BIT            28
+#define DDRP_ZQXCR_ZDEN                        (1 << DDRP_ZQXCR_ZDEN_BIT)
+#define DDRP_ZQXCR_PULLUP_IMPE_BIT     5
+#define DDRP_ZQXCR_PULLDOWN_IMPE_BIT   0
+
+/* DDR3 Mode Register Set */
+#define DDR3_MR0_BL_BIT                        0
+#define DDR3_MR0_BL_MASK               (3 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_8                  (0 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_fly                        (1 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_4                  (2 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BT_BIT                        3
+#define DDR3_MR0_BT_MASK               (1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_SEQ                        (0 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_INTER              (1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_WR_BIT                        9
+
+#define DDR3_MR1_DLL_DISABLE           1
+#define DDR3_MR1_DIC_6                 (0 << 5 | 0 << 1)
+#define DDR3_MR1_DIC_7                 (0 << 5 | BIT(1))
+#define DDR3_MR1_RTT_DIS               (0 << 9 | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_4                 (0 << 9 | 0 << 6 | BIT(2))
+#define DDR3_MR1_RTT_2                 (0 << 9 | BIT(6) | 0 << 2)
+#define DDR3_MR1_RTT_6                 (0 << 9 | BIT(6) | BIT(2))
+#define DDR3_MR1_RTT_12                        (BIT(9) | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_8                 (BIT(9) | 0 << 6 | BIT(2))
+
+#define DDR3_MR2_CWL_BIT               3
+
+/* Parameters common to all RAM devices used */
+
+/* Chip Select */
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS0EN      1
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS1EN      0
+
+/* ROW : 12 to 18 row address, 1G only 512MB */
+#define DDR_ROW                15
+/* COL :  8 to 14 column address */
+#define DDR_COL                10
+/* Banks each chip: 0-4bank, 1-8bank */
+#define DDR_BANK8      1
+/* 0 - 16-bit data width, 1 - 32-bit data width */
+#define DDR_DW32       1
+
+/* Refresh period: 64ms / 32768 = 1.95 us , 2 ^ 15 = 32768 */
+#define DDR_tREFI      7800
+/* Clock Divider */
+#define DDR_CLK_DIV    1
+
+/* DDR3 Burst length: 0 - 8 burst, 2 - 4 burst , 1 - 4 or 8 (on the fly) */
+#define DDR_BL         8
+
+/* CAS latency: 5 to 14, tCK */
+#define DDR_CL         6
+/* DDR3 only: CAS Write Latency, 5 to 8 */
+#define DDR_tCWL       (DDR_CL - 1)
+
+/* Structure representing per-RAM type configuration */
+
+struct jz4780_ddr_config {
+       u32     timing[6];      /* Timing1..6 register value */
+
+       /* DDR PHY control */
+       u16     mr0;    /* Mode Register 0 */
+       u16     mr1;    /* Mode Register 1 */
+
+       u32     ptr0;   /* PHY Timing Register 0 */
+       u32     ptr1;   /* PHY Timing Register 1 */
+       u32     ptr2;   /* PHY Timing Register 1 */
+
+       u32     dtpr0;  /* DRAM Timing Parameters Register 0 */
+       u32     dtpr1;  /* DRAM Timing Parameters Register 1 */
+       u32     dtpr2;  /* DRAM Timing Parameters Register 2 */
+
+       u8      pullup; /* PHY pullup impedance */
+       u8      pulldn; /* PHY pulldown impedance */
+};
+
+void pll_init(void);
+void sdram_init(void);
+
+#endif /* __JZ4780_DRAM_H__ */
+
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h b/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h
new file mode 100644 (file)
index 0000000..37f0892
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __JZ4780_GPIO_H__
+#define __JZ4780_GPIO_H__
+
+#define JZ_GPIO(bank, pin) ((32 * (bank)) + (pin))
+
+int jz47xx_gpio_get_value(unsigned int gpio);
+void jz47xx_gpio_direction_input(unsigned int gpio);
+void jz47xx_gpio_direction_output(unsigned int gpio, int value);
+
+#endif
diff --git a/arch/mips/mach-jz47xx/jz4780/Makefile b/arch/mips/mach-jz47xx/jz4780/Makefile
new file mode 100644 (file)
index 0000000..5b3c354
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y := gpio.o jz4780.o pll.o reset.o sdram.o timer.o
diff --git a/arch/mips/mach-jz47xx/jz4780/TODO b/arch/mips/mach-jz47xx/jz4780/TODO
new file mode 100644 (file)
index 0000000..99ad622
--- /dev/null
@@ -0,0 +1,4 @@
+- dm gpio driver
+- ethernet driver for the dm9000
+- reduce the hundreds of definitions of register addresses to the ones really needed in assembly or SPL.
+- define the remaining register base addresses as physical addresses and establish a mapping with ioremap_nocache()
diff --git a/arch/mips/mach-jz47xx/jz4780/gpio.c b/arch/mips/mach-jz47xx/jz4780/gpio.c
new file mode 100644 (file)
index 0000000..cee2328
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+int jz47xx_gpio_get_value(unsigned int gpio)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+       int port = gpio / 32;
+       int pin = gpio % 32;
+
+       return readl(gpio_regs + GPIO_PXPIN(port)) & BIT(pin);
+}
+
+void jz47xx_gpio_direction_input(unsigned int gpio)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+       int port = gpio / 32;
+       int pin = gpio % 32;
+
+       writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXPAT1S(port));
+}
+
+void jz47xx_gpio_direction_output(unsigned int gpio, int value)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+       int port = gpio / 32;
+       int pin = gpio % 32;
+
+       writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXPAT1C(port));
+       writel(BIT(pin), gpio_regs +
+                        (value ? GPIO_PXPAT0S(port) : GPIO_PXPAT0C(port)));
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c
new file mode 100644 (file)
index 0000000..dbd328c
--- /dev/null
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 common routines
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/sections.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+#include <mmc.h>
+#include <spl.h>
+
+#ifdef CONFIG_SPL_BUILD
+/* Pointer to the global data structure for SPL */
+DECLARE_GLOBAL_DATA_PTR;
+gd_t gdata __attribute__ ((section(".bss")));
+
+void board_init_f(ulong dummy)
+{
+       typedef void __noreturn (*image_entry_noargs_t)(void);
+       struct mmc *mmc;
+       unsigned long count;
+       struct image_header *header;
+       int ret;
+
+       /* Set global data pointer */
+       gd = &gdata;
+
+       timer_init();
+       pll_init();
+       sdram_init();
+       enable_caches();
+
+       /* Clear the BSS */
+       memset(__bss_start, 0, (char *)&__bss_end - __bss_start);
+
+       gd->flags |= GD_FLG_SPL_INIT;
+
+       ret = mmc_initialize(NULL);
+       if (ret)
+               hang();
+
+       mmc = find_mmc_device(BOOT_DEVICE_MMC1);
+       if (ret)
+               hang();
+
+       ret = mmc_init(mmc);
+       if (ret)
+               hang();
+
+       header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+                                        sizeof(struct image_header));
+
+       count = blk_dread(mmc_get_blk_desc(mmc),
+                         CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
+               0x800, header);
+       if (count == 0)
+               hang();
+
+       image_entry_noargs_t image_entry =
+               (image_entry_noargs_t)CONFIG_SYS_TEXT_BASE;
+
+       image_entry();
+
+       hang();
+}
+#endif /* CONFIG_SPL_BUILD */
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+       return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024);
+}
+
+int print_cpuinfo(void)
+{
+       printf("CPU:   Ingenic JZ4780\n");
+       return 0;
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/pll.c b/arch/mips/mach-jz47xx/jz4780/pll.c
new file mode 100644 (file)
index 0000000..9a46198
--- /dev/null
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 PLL setup
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+#define CPM_CPCCR              0x00
+#define CPM_LCR                        0x04
+#define CPM_RSR                        0x08
+#define CPM_CPPCR              0x0c
+#define CPM_CPAPCR             0x10
+#define CPM_CPMPCR             0x14
+#define CPM_CPEPCR             0x18
+#define CPM_CPVPCR             0x1c
+#define CPM_CLKGR0             0x20
+#define CPM_OPCR               0x24
+#define CPM_CLKGR1             0x28
+#define CPM_DDCDR              0x2c
+#define CPM_VPUCDR             0x30
+#define CPM_CPSPR              0x34
+#define CPM_CPSPPR             0x38
+#define CPM_USBPCR             0x3c
+#define CPM_USBRDT             0x40
+#define CPM_USBVBFIL           0x44
+#define CPM_USBPCR1            0x48
+#define CPM_USBCDR             0x50
+#define CPM_LPCDR              0x54
+#define CPM_I2SCDR             0x60
+#define CPM_LPCDR1             0x64
+#define CPM_MSCCDR             0x68
+#define CPM_UHCCDR             0x6c
+#define CPM_SSICDR             0x74
+#define CPM_CIMCDR             0x7c
+#define CPM_PCMCDR             0x84
+#define CPM_GPUCDR             0x88
+#define CPM_HDMICDR            0x8c
+#define CPM_I2S1CDR            0xa0
+#define CPM_MSCCDR1            0xa4
+#define CPM_MSCCDR2            0xa8
+#define CPM_BCHCDR             0xac
+#define CPM_SPCR0              0xb8
+#define CPM_SPCR1              0xbc
+#define CPM_CPCSR              0xd4
+#define CPM_PSWCST(n)          ((0x4 * (n)) + 0x90)
+
+/* Clock control register */
+#define CPM_CPCCR_SEL_SRC_BIT          30
+#define CPM_CPCCR_SEL_SRC_MASK         (0x3 << CPM_CPCCR_SEL_SRC_BIT)
+#define CPM_SRC_SEL_STOP               0
+#define CPM_SRC_SEL_APLL               1
+#define CPM_SRC_SEL_EXCLK              2
+#define CPM_SRC_SEL_RTCLK              3
+#define CPM_CPCCR_SEL_CPLL_BIT         28
+#define CPM_CPCCR_SEL_CPLL_MASK                (0x3 << CPM_CPCCR_SEL_CPLL_BIT)
+#define CPM_CPCCR_SEL_H0PLL_BIT                26
+#define CPM_CPCCR_SEL_H0PLL_MASK       (0x3 << CPM_CPCCR_SEL_H0PLL_BIT)
+#define CPM_CPCCR_SEL_H2PLL_BIT                24
+#define CPM_CPCCR_SEL_H2PLL_MASK       (0x3 << CPM_CPCCR_SEL_H2PLL_BIT)
+#define CPM_PLL_SEL_STOP               0
+#define CPM_PLL_SEL_SRC                        1
+#define CPM_PLL_SEL_MPLL               2
+#define CPM_PLL_SEL_EPLL               3
+#define CPM_CPCCR_CE_CPU               (0x1 << 22)
+#define CPM_CPCCR_CE_AHB0              (0x1 << 21)
+#define CPM_CPCCR_CE_AHB2              (0x1 << 20)
+#define CPM_CPCCR_PDIV_BIT             16
+#define CPM_CPCCR_PDIV_MASK            (0xf << CPM_CPCCR_PDIV_BIT)
+#define CPM_CPCCR_H2DIV_BIT            12
+#define CPM_CPCCR_H2DIV_MASK           (0xf << CPM_CPCCR_H2DIV_BIT)
+#define CPM_CPCCR_H0DIV_BIT            8
+#define CPM_CPCCR_H0DIV_MASK           (0x0f << CPM_CPCCR_H0DIV_BIT)
+#define CPM_CPCCR_L2DIV_BIT            4
+#define CPM_CPCCR_L2DIV_MASK           (0x0f << CPM_CPCCR_L2DIV_BIT)
+#define CPM_CPCCR_CDIV_BIT             0
+#define CPM_CPCCR_CDIV_MASK            (0x0f << CPM_CPCCR_CDIV_BIT)
+
+/* Clock Status register */
+#define CPM_CPCSR_H2DIV_BUSY           BIT(2)
+#define CPM_CPCSR_H0DIV_BUSY           BIT(1)
+#define CPM_CPCSR_CDIV_BUSY            BIT(0)
+
+/* PLL control register */
+#define CPM_CPPCR_PLLST_BIT            0
+#define CPM_CPPCR_PLLST_MASK           (0xff << CPM_CPPCR_PLLST_BIT)
+
+/* XPLL control register */
+#define CPM_CPXPCR_XPLLM_BIT           19
+#define CPM_CPXPCR_XPLLM_MASK          (0x1fff << CPM_CPXPCR_XPLLM_BIT)
+#define CPM_CPXPCR_XPLLN_BIT           13
+#define CPM_CPXPCR_XPLLN_MASK          (0x3f << CPM_CPXPCR_XPLLN_BIT)
+#define CPM_CPXPCR_XPLLOD_BIT          9
+#define CPM_CPXPCR_XPLLOD_MASK         (0xf << CPM_CPXPCR_XPLLOD_BIT)
+#define CPM_CPXPCR_XLOCK               BIT(6)
+#define CPM_CPXPCR_XPLL_ON             BIT(4)
+#define CPM_CPXPCR_XF_MODE             BIT(3)
+#define CPM_CPXPCR_XPLLBP              BIT(1)
+#define CPM_CPXPCR_XPLLEN              BIT(0)
+
+/* CPM scratch protected register */
+#define CPM_CPSPPR_BIT                 0
+#define CPM_CPSPPR_MASK                        (0xffff << CPM_CPSPPR_BIT)
+
+/* USB parameter control register */
+#define CPM_USBPCR_USB_MODE            BIT(31)  /* 1: OTG, 0: UDC*/
+#define CPM_USBPCR_AVLD_REG            BIT(30)
+#define CPM_USBPCR_IDPULLUP_MASK_BIT   28
+#define CPM_USBPCR_IDPULLUP_MASK_MASK  (0x02 << IDPULLUP_MASK_BIT)
+#define CPM_USBPCR_INCR_MASK           BIT(27)
+#define CPM_USBPCR_CLK12_EN            BIT(26)
+#define CPM_USBPCR_COMMONONN           BIT(25)
+#define CPM_USBPCR_VBUSVLDEXT          BIT(24)
+#define CPM_USBPCR_VBUSVLDEXTSEL       BIT(23)
+#define CPM_USBPCR_POR                 BIT(22)
+#define CPM_USBPCR_SIDDQ               BIT(21)
+#define CPM_USBPCR_OTG_DISABLE         BIT(20)
+#define CPM_USBPCR_COMPDISTUNE_BIT     17
+#define CPM_USBPCR_COMPDISTUNE_MASK    (0x07 << COMPDISTUNE_BIT)
+#define CPM_USBPCR_OTGTUNE_BIT         14
+#define CPM_USBPCR_OTGTUNE_MASK                (0x07 << OTGTUNE_BIT)
+#define CPM_USBPCR_SQRXTUNE_BIT                11
+#define CPM_USBPCR_SQRXTUNE_MASK       (0x7x << SQRXTUNE_BIT)
+#define CPM_USBPCR_TXFSLSTUNE_BIT      7
+#define CPM_USBPCR_TXFSLSTUNE_MASK     (0x0f << TXFSLSTUNE_BIT)
+#define CPM_USBPCR_TXPREEMPHTUNE       BIT(6)
+#define CPM_USBPCR_TXRISETUNE_BIT      4
+#define CPM_USBPCR_TXRISETUNE_MASK     (0x03 << TXRISETUNE_BIT)
+#define CPM_USBPCR_TXVREFTUNE_BIT      0
+#define CPM_USBPCR_TXVREFTUNE_MASK     (0x0f << TXVREFTUNE_BIT)
+
+/* DDR memory clock divider register */
+#define CPM_DDRCDR_DCS_BIT             30
+#define CPM_DDRCDR_DCS_MASK            (0x3 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_STOP            (0x0 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_SRC             (0x1 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_MPLL            (0x2 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_CE_DDR              BIT(29)
+#define CPM_DDRCDR_DDR_BUSY            BIT(28)
+#define CPM_DDRCDR_DDR_STOP            BIT(27)
+#define CPM_DDRCDR_DDRDIV_BIT          0
+#define CPM_DDRCDR_DDRDIV_MASK         (0xf << CPM_DDRCDR_DDRDIV_BIT)
+
+/* USB reset detect timer register */
+#define CPM_USBRDT_VBFIL_LD_EN         BIT(25)
+#define CPM_USBRDT_IDDIG_EN            BIT(24)
+#define CPM_USBRDT_IDDIG_REG           BIT(23)
+#define CPM_USBRDT_USBRDT_BIT          0
+#define CPM_USBRDT_USBRDT_MASK         (0x7fffff << CPM_USBRDT_USBRDT_BIT)
+
+/* USB OTG PHY clock divider register */
+#define CPM_USBCDR_UCS                 BIT(31)
+#define CPM_USBCDR_UPCS                        BIT(30)
+#define CPM_USBCDR_CEUSB               BIT(29)
+#define CPM_USBCDR_USB_BUSY            BIT(28)
+#define CPM_USBCDR_OTGDIV_BIT          0
+#define CPM_USBCDR_OTGDIV_MASK         (0xff << CPM_USBCDR_OTGDIV_BIT)
+
+/* I2S device clock divider register */
+#define CPM_I2SCDR_I2CS                        BIT(31)
+#define CPM_I2SCDR_I2PCS               BIT(30)
+#define CPM_I2SCDR_I2SDIV_BIT          0
+#define CPM_I2SCDR_I2SDIV_MASK         (0x1ff << CPM_I2SCDR_I2SDIV_BIT)
+
+/* LCD0 pix clock divider register */
+#define CPM_LPCDR_LPCS_BIT             30
+#define CPM_LPCDR_LPCS_MASK            (0x3 << CPM_LPCDR_LPCS_BIT)
+#define CPM_LPCDR_CELCD                        BIT(28)
+#define CPM_LPCDR_LCD_BUSY             BIT(27)
+#define CPM_LPCDR_LCD_STOP             BIT(26)
+#define CPM_LPCDR_PIXDIV_BIT           0
+#define CPM_LPCDR_PIXDIV_MASK          (0xff << CPM_LPCDR_PIXDIV_BIT)
+
+/* MSC clock divider register */
+#define CPM_MSCCDR_MPCS_BIT            30
+#define CPM_MSCCDR_MPCS_MASK           (3 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_STOP           (0x0 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_SRC            (0x1 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_MPLL           (0x2 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_CE                  BIT(29)
+#define CPM_MSCCDR_MSC_BUSY            BIT(28)
+#define CPM_MSCCDR_MSC_STOP            BIT(27)
+#define CPM_MSCCDR_MSC_CLK0_SEL                BIT(15)
+#define CPM_MSCCDR_MSCDIV_BIT          0
+#define CPM_MSCCDR_MSCDIV_MASK         (0xff << CPM_MSCCDR_MSCDIV_BIT)
+
+/* UHC 48M clock divider register */
+#define CPM_UHCCDR_UHCS_BIT            30
+#define CPM_UHCCDR_UHCS_MASK           (0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_SRC            (0x0 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_MPLL           (0x1 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_EPLL           (0x2 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_OTG            (0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_CE_UHC              BIT(29)
+#define CPM_UHCCDR_UHC_BUSY            BIT(28)
+#define CPM_UHCCDR_UHC_STOP            BIT(27)
+#define CPM_UHCCDR_UHCDIV_BIT          0
+#define CPM_UHCCDR_UHCDIV_MASK         (0xff << CPM_UHCCDR_UHCDIV_BIT)
+
+/* SSI clock divider register */
+#define CPM_SSICDR_SCS                 BIT(31)
+#define CPM_SSICDR_SSIDIV_BIT          0
+#define CPM_SSICDR_SSIDIV_MASK         (0x3f << CPM_SSICDR_SSIDIV_BIT)
+
+/* CIM MCLK clock divider register */
+#define CPM_CIMCDR_CIMDIV_BIT          0
+#define CPM_CIMCDR_CIMDIV_MASK         (0xff << CPM_CIMCDR_CIMDIV_BIT)
+
+/* GPS clock divider register */
+#define CPM_GPSCDR_GPCS                        BIT(31)
+#define CPM_GPSCDR_GPSDIV_BIT          0
+#define CPM_GSPCDR_GPSDIV_MASK         (0xf << CPM_GPSCDR_GPSDIV_BIT)
+
+/* PCM device clock divider register */
+#define CPM_PCMCDR_PCMS                        BIT(31)
+#define CPM_PCMCDR_PCMPCS              BIT(30)
+#define CPM_PCMCDR_PCMDIV_BIT          0
+#define CPM_PCMCDR_PCMDIV_MASK         (0x1ff << CPM_PCMCDR_PCMDIV_BIT)
+
+/* GPU clock divider register */
+#define CPM_GPUCDR_GPCS                        BIT(31)
+#define CPM_GPUCDR_GPUDIV_BIT          0
+#define CPM_GPUCDR_GPUDIV_MASK         (0x7 << CPM_GPUCDR_GPUDIV_BIT)
+
+/* HDMI clock divider register */
+#define CPM_HDMICDR_HPCS_BIT           30
+#define CPM_HDMICDR_HPCS_MASK          (0x3 << CPM_HDMICDR_HPCS_BIT)
+#define CPM_HDMICDR_CEHDMI             BIT(29)
+#define CPM_HDMICDR_HDMI_BUSY          BIT(28)
+#define CPM_HDMICDR_HDMI_STOP          BIT(26)
+#define CPM_HDMICDR_HDMIDIV_BIT                0
+#define CPM_HDMICDR_HDMIDIV_MASK       (0xff << CPM_HDMICDR_HDMIDIV_BIT)
+
+/* Low Power Control Register */
+#define CPM_LCR_PD_SCPU                        BIT(31)
+#define CPM_LCR_PD_VPU                 BIT(30)
+#define CPM_LCR_PD_GPU                 BIT(29)
+#define CPM_LCR_PD_GPS                 BIT(28)
+#define CPM_LCR_SCPUS                  BIT(27)
+#define CPM_LCR_VPUS                   BIT(26)
+#define CPM_LCR_GPUS                   BIT(25)
+#define CPM_LCR_GPSS                   BIT(24)
+#define CPM_LCR_GPU_IDLE               BIT(20)
+#define CPM_LCR_PST_BIT                        8
+#define CPM_LCR_PST_MASK               (0xfff << CPM_LCR_PST_BIT)
+#define CPM_LCR_DOZE_DUTY_BIT          3
+#define CPM_LCR_DOZE_DUTY_MASK         (0x1f << CPM_LCR_DOZE_DUTY_BIT)
+#define CPM_LCR_DOZE_ON                        BIT(2)
+#define CPM_LCR_LPM_BIT                        0
+#define CPM_LCR_LPM_MASK               (0x3 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_IDLE               (0x0 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_SLEEP              (0x1 << CPM_LCR_LPM_BIT)
+
+/* Clock Gate Register0 */
+#define CPM_CLKGR0_DDR1                        BIT(31)
+#define CPM_CLKGR0_DDR0                        BIT(30)
+#define CPM_CLKGR0_IPU                 BIT(29)
+#define CPM_CLKGR0_LCD1                        BIT(28)
+#define CPM_CLKGR0_LCD                 BIT(27)
+#define CPM_CLKGR0_CIM                 BIT(26)
+#define CPM_CLKGR0_I2C2                        BIT(25)
+#define CPM_CLKGR0_UHC                 BIT(24)
+#define CPM_CLKGR0_MAC                 BIT(23)
+#define CPM_CLKGR0_GPS                 BIT(22)
+#define CPM_CLKGR0_PDMAC               BIT(21)
+#define CPM_CLKGR0_SSI2                        BIT(20)
+#define CPM_CLKGR0_SSI1                        BIT(19)
+#define CPM_CLKGR0_UART3               BIT(18)
+#define CPM_CLKGR0_UART2               BIT(17)
+#define CPM_CLKGR0_UART1               BIT(16)
+#define CPM_CLKGR0_UART0               BIT(15)
+#define CPM_CLKGR0_SADC                        BIT(14)
+#define CPM_CLKGR0_KBC                 BIT(13)
+#define CPM_CLKGR0_MSC2                        BIT(12)
+#define CPM_CLKGR0_MSC1                        BIT(11)
+#define CPM_CLKGR0_OWI                 BIT(10)
+#define CPM_CLKGR0_TSSI                        BIT(9)
+#define CPM_CLKGR0_AIC                 BIT(8)
+#define CPM_CLKGR0_SCC                 BIT(7)
+#define CPM_CLKGR0_I2C1                        BIT(6)
+#define CPM_CLKGR0_I2C0                        BIT(5)
+#define CPM_CLKGR0_SSI0                        BIT(4)
+#define CPM_CLKGR0_MSC0                        BIT(3)
+#define CPM_CLKGR0_OTG                 BIT(2)
+#define CPM_CLKGR0_BCH                 BIT(1)
+#define CPM_CLKGR0_NEMC                        BIT(0)
+
+/* Clock Gate Register1 */
+#define CPM_CLKGR1_P1                  BIT(15)
+#define CPM_CLKGR1_X2D                 BIT(14)
+#define CPM_CLKGR1_DES                 BIT(13)
+#define CPM_CLKGR1_I2C4                        BIT(12)
+#define CPM_CLKGR1_AHB                 BIT(11)
+#define CPM_CLKGR1_UART4               BIT(10)
+#define CPM_CLKGR1_HDMI                        BIT(9)
+#define CPM_CLKGR1_OTG1                        BIT(8)
+#define CPM_CLKGR1_GPVLC               BIT(7)
+#define CPM_CLKGR1_AIC1                        BIT(6)
+#define CPM_CLKGR1_COMPRES             BIT(5)
+#define CPM_CLKGR1_GPU                 BIT(4)
+#define CPM_CLKGR1_PCM                 BIT(3)
+#define CPM_CLKGR1_VPU                 BIT(2)
+#define CPM_CLKGR1_TSSI1               BIT(1)
+#define CPM_CLKGR1_I2C3                        BIT(0)
+
+/* Oscillator and Power Control Register */
+#define CPM_OPCR_O1ST_BIT              8
+#define CPM_OPCR_O1ST_MASK             (0xff << CPM_OPCR_O1ST_BIT)
+#define CPM_OPCR_SPENDN                        BIT(7)
+#define CPM_OPCR_GPSEN                 BIT(6)
+#define CPM_OPCR_SPENDH                        BIT(5)
+#define CPM_OPCR_O1SE                  BIT(4)
+#define CPM_OPCR_ERCS                  BIT(2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+#define CPM_OPCR_USBM                  BIT(0) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+
+/* Reset Status Register */
+#define CPM_RSR_P0R                    BIT(2)
+#define CPM_RSR_WR                     BIT(1)
+#define CPM_RSR_PR                     BIT(0)
+
+/* BCH clock divider register */
+#define CPM_BCHCDR_BPCS_BIT            30
+#define CPM_BCHCDR_BPCS_MASK           (0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_STOP           (0X0 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_SRC_CLK                (0x1 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_MPLL           (0x2 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_EPLL           (0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_CE_BCH              BIT(29)
+#define CPM_BCHCDR_BCH_BUSY            BIT(28)
+#define CPM_BCHCDR_BCH_STOP            BIT(27)
+#define CPM_BCHCDR_BCHCDR_BIT          0
+#define CPM_BCHCDR_BCHCDR_MASK         (0x7 << CPM_BCHCDR_BCHCDR_BIT)
+
+/* CPM scratch pad protected register(CPSPPR) */
+#define CPSPPR_CPSPR_WRITABLE          0x00005a5a
+#define RECOVERY_SIGNATURE             0x1a1a  /* means "RECY" */
+#define RECOVERY_SIGNATURE_SEC         0x800   /* means "RECY" */
+
+#define REBOOT_SIGNATURE               0x3535  /* means reboot */
+
+/* XPLL control register */
+#define XLOCK          (1 << 6)
+#define XPLL_ON                (1 << 4)
+#define XF_MODE                (1 << 3)
+#define XPLLBP         (1 << 1)
+#define XPLLEN         (1 << 0)
+
+enum PLLS {
+       EXTCLK = 0,
+       APLL,
+       MPLL,
+       EPLL,
+       VPLL,
+};
+
+#define M_N_OD(m, n, od)               \
+               ((((m) - 1) << 19) | (((n) - 1) << 13) | (((od) - 1) << 9))
+
+struct cgu_pll_select {
+       u8      reg;
+       u8      pll;
+       u8      pll_shift;
+};
+
+static void pll_init_one(int pll, int m, int n, int od)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       void __iomem *pll_reg = cpm_regs + CPM_CPAPCR + ((pll - 1) * 4);
+
+       setbits_le32(pll_reg, M_N_OD(m, n, od) | XPLLEN);
+
+       /* FIXME */
+       while (!(readl(pll_reg) & XPLL_ON))
+               ;
+}
+
+static void cpu_mux_select(int pll)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 clk_ctrl;
+       unsigned int selectplls[] = {
+               CPM_PLL_SEL_STOP,
+               CPM_PLL_SEL_SRC,
+               CPM_PLL_SEL_MPLL,
+               CPM_PLL_SEL_EPLL
+       };
+
+       /* Init CPU, L2CACHE, AHB0, AHB2, APB clock */
+       clk_ctrl = CPM_CPCCR_CE_CPU | CPM_CPCCR_CE_AHB0 | CPM_CPCCR_CE_AHB2 |
+                       ((6 - 1) << CPM_CPCCR_H2DIV_BIT) |
+                       ((3 - 1) << CPM_CPCCR_H0DIV_BIT) |
+                       ((2 - 1) << CPM_CPCCR_L2DIV_BIT) |
+                       ((1 - 1) << CPM_CPCCR_CDIV_BIT);
+
+       if (CONFIG_SYS_MHZ >= 1000)
+               clk_ctrl |= (12 - 1) << CPM_CPCCR_PDIV_BIT;
+       else
+               clk_ctrl |= (6 - 1) << CPM_CPCCR_PDIV_BIT;
+
+       clrsetbits_le32(cpm_regs + CPM_CPCCR, 0x00ffffff, clk_ctrl);
+
+       while (readl(cpm_regs + CPM_CPCSR) & (CPM_CPCSR_CDIV_BUSY |
+              CPM_CPCSR_H0DIV_BUSY | CPM_CPCSR_H2DIV_BUSY))
+               ;
+
+       clk_ctrl = (selectplls[pll] << CPM_CPCCR_SEL_CPLL_BIT) |
+                  (selectplls[MPLL] << CPM_CPCCR_SEL_H0PLL_BIT) |
+                  (selectplls[MPLL] << CPM_CPCCR_SEL_H2PLL_BIT);
+       if (pll == APLL)
+               clk_ctrl |= CPM_PLL_SEL_SRC << CPM_CPCCR_SEL_SRC_BIT;
+       else
+               clk_ctrl |= CPM_SRC_SEL_EXCLK << CPM_CPCCR_SEL_SRC_BIT;
+
+       clrsetbits_le32(cpm_regs + CPM_CPCCR, 0xff << 24, clk_ctrl);
+}
+
+static void ddr_mux_select(int pll)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       int selectplls[] = { CPM_DDRCDR_DCS_STOP,
+                            CPM_DDRCDR_DCS_SRC,
+                            CPM_DDRCDR_DCS_MPLL};
+
+       writel(selectplls[pll] | CPM_DDRCDR_CE_DDR | (JZ4780_SYS_MEM_DIV - 1),
+              cpm_regs + CPM_DDCDR);
+
+       while (readl(cpm_regs + CPM_DDCDR) & CPM_DDRCDR_DDR_BUSY)
+               ;
+
+       clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_DDR0);
+
+       mdelay(200);
+}
+
+static void cgu_mux_init(struct cgu_pll_select *cgu, unsigned int num)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       unsigned int selectplls[] = {0, 1, 2, 3, 2, 6};
+       int i;
+
+       for (i = 0; i < num; i++)
+               writel(selectplls[cgu[i].pll] << cgu[i].pll_shift,
+                      cpm_regs + cgu[i].reg);
+}
+
+void pll_init(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       struct cgu_pll_select cgu_mux[] = {
+               { CPM_MSCCDR,  MPLL, 30 },
+               { CPM_LPCDR,   VPLL, 30 },
+               { CPM_LPCDR1,  VPLL, 30 },
+               { CPM_GPUCDR,  MPLL, 30 },
+               { CPM_HDMICDR, VPLL, 30 },
+               { CPM_I2SCDR,  EPLL, 30 },
+               { CPM_BCHCDR,  MPLL, 30 },
+               { CPM_VPUCDR,  0x1,  30 },
+               { CPM_UHCCDR,  0x3,  30 },
+               { CPM_CIMCDR,  0x1,  31 },
+               { CPM_PCMCDR,  0x5,  29 },
+               { CPM_SSICDR,  0x3,  30 },
+       };
+
+       /* PLL stable time set to default -- 1ms */
+       clrsetbits_le32(cpm_regs + CPM_CPPCR, 0xfffff, (16 << 8) | 0x20);
+
+       pll_init_one(APLL, JZ4780_APLL_M, JZ4780_APLL_N, JZ4780_APLL_OD);
+       pll_init_one(MPLL, JZ4780_MPLL_M, JZ4780_MPLL_N, JZ4780_MPLL_OD);
+       pll_init_one(VPLL, JZ4780_VPLL_M, JZ4780_VPLL_N, JZ4780_VPLL_OD);
+       pll_init_one(EPLL, JZ4780_EPLL_M, JZ4780_EPLL_N, JZ4780_EPLL_OD);
+
+       cpu_mux_select(MPLL);
+       ddr_mux_select(MPLL);
+       cgu_mux_init(cgu_mux, ARRAY_SIZE(cgu_mux));
+}
+
+const u32 jz4780_clk_get_efuse_clk(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 cpccr = readl(cpm_regs + CPM_CPCCR);
+       u32 ahb2_div = ((cpccr & CPM_CPCCR_H2DIV_MASK) >>
+                       CPM_CPCCR_H2DIV_BIT) + 1;
+       return JZ4780_SYS_MEM_SPEED / ahb2_div;
+}
+
+void jz4780_clk_ungate_ethernet(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+
+       clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_MAC);
+       clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_NEMC);
+}
+
+void jz4780_clk_ungate_mmc(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 msc_cdr = JZ4780_SYS_MEM_SPEED / 24000000 / 2 - 1;
+
+       msc_cdr |= CPM_MSCCDR_MPCS_MPLL | CPM_MSCCDR_CE;
+       writel(msc_cdr, cpm_regs + CPM_MSCCDR);
+       writel(msc_cdr, cpm_regs + CPM_MSCCDR1);
+       writel(msc_cdr, cpm_regs + CPM_MSCCDR2);
+
+       /* The wait_for_bit() won't fit, thus unbounded loop here. */
+       while (readl(cpm_regs + CPM_MSCCDR1) & CPM_MSCCDR_MSC_BUSY)
+               ;
+}
+
+void jz4780_clk_ungate_uart(const unsigned int uart)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+
+       if (uart == 0)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART0);
+       else if (uart == 1)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART1);
+       else if (uart == 2)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART2);
+       else if (uart == 3)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART3);
+       else if (uart == 4)
+               clrbits_le32(cpm_regs + CPM_CLKGR1, CPM_CLKGR1_UART4);
+       else
+               printf("%s[%i]: Invalid UART %d\n", __func__, __LINE__, uart);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/reset.c b/arch/mips/mach-jz47xx/jz4780/reset.c
new file mode 100644 (file)
index 0000000..73af347
--- /dev/null
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 common routines
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+/* WDT */
+#define WDT_TDR                0x00
+#define WDT_TCER       0x04
+#define WDT_TCNT       0x08
+#define WDT_TCSR       0x0C
+
+/* Register definition */
+#define WDT_TCSR_PRESCALE_BIT  3
+#define WDT_TCSR_PRESCALE_MASK (0x7 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1   (0x0 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE4   (0x1 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE16  (0x2 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE64  (0x3 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE256 (0x4 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1024        (0x5 << WDT_TCSR_PRESCALE_BIT)
+#define WDT_TCSR_EXT_EN                BIT(2)
+#define WDT_TCSR_RTC_EN                BIT(1)
+#define WDT_TCSR_PCK_EN                BIT(0)
+
+#define WDT_TCER_TCEN          BIT(0)
+
+void _machine_restart(void)
+{
+       void __iomem *wdt_regs = (void __iomem *)WDT_BASE;
+
+       /* EXTAL as the timer clock input. */
+       writew(WDT_TCSR_PRESCALE1 | WDT_TCSR_EXT_EN, wdt_regs + WDT_TCSR);
+
+       /* Reset the WDT counter and timeout. */
+       writew(0, wdt_regs + WDT_TCNT);
+       writew(0, wdt_regs + WDT_TDR);
+
+       jz4780_tcu_wdt_start();
+
+       /* WDT start */
+       writeb(WDT_TCER_TCEN, wdt_regs + WDT_TCER);
+
+       for (;;)
+               ;
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/sdram.c b/arch/mips/mach-jz47xx/jz4780/sdram.c
new file mode 100644 (file)
index 0000000..5b25c8d
--- /dev/null
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 DDR initialization
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * Based on spl/common/{jz4780_ddr,jz_ddr3_init}.c from X-Boot
+ * Copyright (c) 2006-2013 Ingenic Semiconductor
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+
+static const u32 get_mem_clk(void)
+{
+       const u32 mpll_out = ((u64)JZ4780_SYS_EXTAL * JZ4780_MPLL_M) /
+                            (JZ4780_MPLL_N * JZ4780_MPLL_OD);
+       return mpll_out / JZ4780_SYS_MEM_DIV;
+}
+
+u32 sdram_size(int cs)
+{
+       u32 dw = DDR_DW32 ? 4 : 2;
+       u32 banks = DDR_BANK8 ? 8 : 4;
+       u32 size = 0;
+
+       if ((cs == 0) && DDR_CS0EN) {
+               size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+               if (DDR_CS1EN && (size > 0x20000000))
+                       size = 0x20000000;
+       } else if ((cs == 1) && DDR_CS1EN) {
+               size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+       }
+
+       return size;
+}
+
+static void ddr_cfg_init(void)
+{
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       u32 ddrc_cfg, tmp;
+
+       tmp = DDR_CL;
+       if (tmp)
+               tmp--;
+       if (tmp > 4)
+               tmp = 4;
+
+       ddrc_cfg = DDRC_CFG_TYPE_DDR3 | DDRC_CFG_IMBA |
+                  DDR_DW32 | DDRC_CFG_MPRT | ((tmp | 0x8) << 2) |
+                  ((DDR_ROW - 12) << 11) | ((DDR_COL - 8) << 8) |
+                  (DDR_CS0EN << 6) | (DDR_BANK8 << 1) |
+                  ((DDR_ROW - 12) << 27) | ((DDR_COL - 8) << 24) |
+                  (DDR_CS1EN << 7) | (DDR_BANK8 << 23);
+
+       if (DDR_BL > 4)
+               ddrc_cfg |= BIT(21);
+
+       writel(ddrc_cfg, ddr_ctl_regs + DDRC_CFG);
+}
+
+static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config)
+{
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+       unsigned int count = 0, i;
+       u32 reg, mask;
+
+       writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), ddr_phy_regs + DDRP_DCR);
+
+       writel(ddr_config->mr0, ddr_phy_regs + DDRP_MR0);
+       writel(ddr_config->mr1, ddr_phy_regs + DDRP_MR1);
+       writel(0, ddr_phy_regs + DDRP_ODTCR);
+       writel(0, ddr_phy_regs + DDRP_MR2);
+
+       writel(ddr_config->ptr0, ddr_phy_regs + DDRP_PTR0);
+       writel(ddr_config->ptr1, ddr_phy_regs + DDRP_PTR1);
+       writel(ddr_config->ptr2, ddr_phy_regs + DDRP_PTR2);
+
+       writel(ddr_config->dtpr0, ddr_phy_regs + DDRP_DTPR0);
+       writel(ddr_config->dtpr1, ddr_phy_regs + DDRP_DTPR1);
+       writel(ddr_config->dtpr2, ddr_phy_regs + DDRP_DTPR2);
+
+       writel(DDRP_PGCR_DQSCFG | (7 << DDRP_PGCR_CKEN_BIT) |
+              (2 << DDRP_PGCR_CKDV_BIT) |
+              (DDR_CS0EN | (DDR_CS1EN << 1)) << DDRP_PGCR_RANKEN_BIT |
+              DDRP_PGCR_ZCKSEL_32 | DDRP_PGCR_PDDISDX,
+              ddr_phy_regs + DDRP_PGCR);
+
+       for (i = 0; i < 8; i++)
+               clrbits_le32(ddr_phy_regs + DDRP_DXGCR(i), 0x3 << 9);
+
+       count = 0;
+       mask = DDRP_PGSR_IDONE | DDRP_PGSR_DLDONE | DDRP_PGSR_ZCDONE;
+       for (;;) {
+               reg = readl(ddr_phy_regs + DDRP_PGSR);
+               if ((reg == mask) || (reg == 0x1f))
+                       break;
+               if (count++ == 10000)
+                       hang();
+       }
+
+       /* DQS extension and early set to 1 */
+       clrsetbits_le32(ddr_phy_regs + DDRP_DSGCR, 0x7E << 4, 0x12 << 4);
+
+       /* 500 pull up and 500 pull down */
+       clrsetbits_le32(ddr_phy_regs + DDRP_DXCCR, 0xFF << 4, 0xC4 << 4);
+
+       /* Initialise phy */
+       writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST,
+              ddr_phy_regs + DDRP_PIR);
+
+       count = 0;
+       mask |= DDRP_PGSR_DIDONE;
+       for (;;) {
+               reg = readl(ddr_phy_regs + DDRP_PGSR);
+               if ((reg == mask) || (reg == 0x1f))
+                       break;
+               if (count++ == 20000)
+                       hang();
+       }
+
+       writel(DDRP_PIR_INIT | DDRP_PIR_QSTRN, ddr_phy_regs + DDRP_PIR);
+
+       count = 0;
+       mask |= DDRP_PGSR_DTDONE;
+       for (;;) {
+               reg = readl(ddr_phy_regs + DDRP_PGSR);
+               if (reg == mask)
+                       break;
+               if (count++ != 50000)
+                       continue;
+               reg &= DDRP_PGSR_DTDONE | DDRP_PGSR_DTERR | DDRP_PGSR_DTIERR;
+               if (reg)
+                       hang();
+               count = 0;
+       }
+
+       /* Override impedance */
+       clrsetbits_le32(ddr_phy_regs + DDRP_ZQXCR0(0), 0x3ff,
+               ((ddr_config->pullup & 0x1f) << DDRP_ZQXCR_PULLUP_IMPE_BIT) |
+               ((ddr_config->pulldn & 0x1f) << DDRP_ZQXCR_PULLDOWN_IMPE_BIT) |
+               DDRP_ZQXCR_ZDEN);
+}
+
+#define JZBIT(bit) ((bit % 4) * 8)
+#define JZMASK(bit) (0x1f << JZBIT(bit))
+
+static void remap_swap(int a, int b)
+{
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       u32 remmap[2], tmp[2];
+
+       remmap[0] = readl(ddr_ctl_regs + DDRC_REMMAP(a / 4));
+       remmap[1] = readl(ddr_ctl_regs + DDRC_REMMAP(b / 4));
+
+       tmp[0] = (remmap[0] & JZMASK(a)) >> JZBIT(a);
+       tmp[1] = (remmap[1] & JZMASK(b)) >> JZBIT(b);
+
+       remmap[0] &= ~JZMASK(a);
+       remmap[1] &= ~JZMASK(b);
+
+       writel(remmap[0] | (tmp[1] << JZBIT(a)),
+              ddr_ctl_regs + DDRC_REMMAP(a / 4));
+       writel(remmap[1] | (tmp[0] << JZBIT(b)),
+              ddr_ctl_regs + DDRC_REMMAP(b / 4));
+}
+
+static void mem_remap(void)
+{
+       u32 start = (DDR_ROW + DDR_COL + (DDR_DW32 ? 4 : 2) / 2) - 12;
+       u32 num = DDR_BANK8 ? 3 : 2;
+
+       if (DDR_CS0EN && DDR_CS1EN)
+               num++;
+
+       for (; num > 0; num--)
+               remap_swap(0 + num - 1, start + num - 1);
+}
+
+/* Fetch DRAM config from board file */
+__weak const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
+{
+       return NULL;
+}
+
+void sdram_init(void)
+{
+       const struct jz4780_ddr_config *ddr_config = jz4780_get_ddr_config();
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 mem_clk, tmp, i;
+       u32 mem_base0, mem_base1;
+       u32 mem_mask0, mem_mask1;
+       u32 mem_size0, mem_size1;
+
+       if (!ddr_config)
+               hang();
+
+       /* Reset DLL in DDR PHY */
+       writel(0x3, cpm_regs + 0xd0);
+       mdelay(400);
+       writel(0x1, cpm_regs + 0xd0);
+       mdelay(400);
+
+       /* Enter reset */
+       writel(0xf << 20, ddr_ctl_regs + DDRC_CTRL);
+
+       mem_clk = get_mem_clk();
+
+       tmp = 1000000000 / mem_clk;
+       if (1000000000 % mem_clk)
+               tmp++;
+       tmp = DDR_tREFI / tmp;
+       tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1;
+       if (tmp > 0xff)
+               tmp = 0xff;
+       if (tmp < 1)
+               tmp = 1;
+
+       writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+       writel(0x150000, ddr_phy_regs + DDRP_DTAR);
+       ddr_phy_init(ddr_config);
+
+       writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+       writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+       ddr_cfg_init();
+
+       for (i = 0; i < 6; i++)
+               writel(ddr_config->timing[i], ddr_ctl_regs + DDRC_TIMING(i));
+
+       mem_size0 = sdram_size(0);
+       mem_size1 = sdram_size(1);
+
+       if (!mem_size1 && mem_size0 > 0x20000000) {
+               mem_base0 = 0x0;
+               mem_mask0 = ~(((mem_size0 * 2) >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+       } else {
+               mem_base0 = (DDR_MEM_PHY_BASE >> 24) & 0xff;
+               mem_mask0 = ~((mem_size0 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+       }
+
+       if (mem_size1) {
+               mem_mask1 = ~((mem_size1 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+               mem_base1 = ((DDR_MEM_PHY_BASE + mem_size0) >> 24) & 0xff;
+       } else {
+               mem_mask1 = 0;
+               mem_base1 = 0xff;
+       }
+
+       writel(mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0,
+              ddr_ctl_regs + DDRC_MMAP0);
+       writel(mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1,
+              ddr_ctl_regs + DDRC_MMAP1);
+       writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+       writel((DDR_CLK_DIV << 1) | DDRC_REFCNT_REF_EN |
+              (tmp << DDRC_REFCNT_CON_BIT),
+              ddr_ctl_regs + DDRC_REFCNT);
+       writel((1 << 15) | (4 << 12) | (1 << 11) | (1 << 8) | (0 << 6) |
+              (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1),
+              ddr_ctl_regs + DDRC_CTRL);
+       mem_remap();
+       clrbits_le32(ddr_ctl_regs + DDRC_ST, 0x40);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/timer.c b/arch/mips/mach-jz47xx/jz4780/timer.c
new file mode 100644 (file)
index 0000000..a689b9d
--- /dev/null
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 timer
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <mach/jz4780.h>
+
+#define TCU_TSR                0x1C    /* Timer Stop Register */
+#define TCU_TSSR       0x2C    /* Timer Stop Set Register */
+#define TCU_TSCR       0x3C    /* Timer Stop Clear Register */
+#define TCU_TER                0x10    /* Timer Counter Enable Register */
+#define TCU_TESR       0x14    /* Timer Counter Enable Set Register */
+#define TCU_TECR       0x18    /* Timer Counter Enable Clear Register */
+#define TCU_TFR                0x20    /* Timer Flag Register */
+#define TCU_TFSR       0x24    /* Timer Flag Set Register */
+#define TCU_TFCR       0x28    /* Timer Flag Clear Register */
+#define TCU_TMR                0x30    /* Timer Mask Register */
+#define TCU_TMSR       0x34    /* Timer Mask Set Register */
+#define TCU_TMCR       0x38    /* Timer Mask Clear Register */
+/* n = 0,1,2,3,4,5 */
+#define TCU_TDFR(n)    (0x40 + (n) * 0x10)     /* Timer Data Full Reg */
+#define TCU_TDHR(n)    (0x44 + (n) * 0x10)     /* Timer Data Half Reg */
+#define TCU_TCNT(n)    (0x48 + (n) * 0x10)     /* Timer Counter Reg */
+#define TCU_TCSR(n)    (0x4C + (n) * 0x10)     /* Timer Control Reg */
+
+#define TCU_OSTCNTL    0xe4
+#define TCU_OSTCNTH    0xe8
+#define TCU_OSTCSR     0xec
+#define TCU_OSTCNTHBUF 0xfc
+
+/* Register definitions */
+#define TCU_TCSR_PWM_SD                BIT(9)
+#define TCU_TCSR_PWM_INITL_HIGH        BIT(8)
+#define TCU_TCSR_PWM_EN                BIT(7)
+#define TCU_TCSR_PRESCALE_BIT  3
+#define TCU_TCSR_PRESCALE_MASK (0x7 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1     (0x0 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE4     (0x1 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE16    (0x2 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE64    (0x3 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE256   (0x4 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1024  (0x5 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_EXT_EN                BIT(2)
+#define TCU_TCSR_RTC_EN                BIT(1)
+#define TCU_TCSR_PCK_EN                BIT(0)
+
+#define TCU_TER_TCEN5          BIT(5)
+#define TCU_TER_TCEN4          BIT(4)
+#define TCU_TER_TCEN3          BIT(3)
+#define TCU_TER_TCEN2          BIT(2)
+#define TCU_TER_TCEN1          BIT(1)
+#define TCU_TER_TCEN0          BIT(0)
+
+#define TCU_TESR_TCST5         BIT(5)
+#define TCU_TESR_TCST4         BIT(4)
+#define TCU_TESR_TCST3         BIT(3)
+#define TCU_TESR_TCST2         BIT(2)
+#define TCU_TESR_TCST1         BIT(1)
+#define TCU_TESR_TCST0         BIT(0)
+
+#define TCU_TECR_TCCL5         BIT(5)
+#define TCU_TECR_TCCL4         BIT(4)
+#define TCU_TECR_TCCL3         BIT(3)
+#define TCU_TECR_TCCL2         BIT(2)
+#define TCU_TECR_TCCL1         BIT(1)
+#define TCU_TECR_TCCL0         BIT(0)
+
+#define TCU_TFR_HFLAG5         BIT(21)
+#define TCU_TFR_HFLAG4         BIT(20)
+#define TCU_TFR_HFLAG3         BIT(19)
+#define TCU_TFR_HFLAG2         BIT(18)
+#define TCU_TFR_HFLAG1         BIT(17)
+#define TCU_TFR_HFLAG0         BIT(16)
+#define TCU_TFR_FFLAG5         BIT(5)
+#define TCU_TFR_FFLAG4         BIT(4)
+#define TCU_TFR_FFLAG3         BIT(3)
+#define TCU_TFR_FFLAG2         BIT(2)
+#define TCU_TFR_FFLAG1         BIT(1)
+#define TCU_TFR_FFLAG0         BIT(0)
+
+#define TCU_TFSR_HFLAG5                BIT(21)
+#define TCU_TFSR_HFLAG4                BIT(20)
+#define TCU_TFSR_HFLAG3                BIT(19)
+#define TCU_TFSR_HFLAG2                BIT(18)
+#define TCU_TFSR_HFLAG1                BIT(17)
+#define TCU_TFSR_HFLAG0                BIT(16)
+#define TCU_TFSR_FFLAG5                BIT(5)
+#define TCU_TFSR_FFLAG4                BIT(4)
+#define TCU_TFSR_FFLAG3                BIT(3)
+#define TCU_TFSR_FFLAG2                BIT(2)
+#define TCU_TFSR_FFLAG1                BIT(1)
+#define TCU_TFSR_FFLAG0                BIT(0)
+
+#define TCU_TFCR_HFLAG5                BIT(21)
+#define TCU_TFCR_HFLAG4                BIT(20)
+#define TCU_TFCR_HFLAG3                BIT(19)
+#define TCU_TFCR_HFLAG2                BIT(18)
+#define TCU_TFCR_HFLAG1                BIT(17)
+#define TCU_TFCR_HFLAG0                BIT(16)
+#define TCU_TFCR_FFLAG5                BIT(5)
+#define TCU_TFCR_FFLAG4                BIT(4)
+#define TCU_TFCR_FFLAG3                BIT(3)
+#define TCU_TFCR_FFLAG2                BIT(2)
+#define TCU_TFCR_FFLAG1                BIT(1)
+#define TCU_TFCR_FFLAG0                BIT(0)
+
+#define TCU_TMR_HMASK5         BIT(21)
+#define TCU_TMR_HMASK4         BIT(20)
+#define TCU_TMR_HMASK3         BIT(19)
+#define TCU_TMR_HMASK2         BIT(18)
+#define TCU_TMR_HMASK1         BIT(17)
+#define TCU_TMR_HMASK0         BIT(16)
+#define TCU_TMR_FMASK5         BIT(5)
+#define TCU_TMR_FMASK4         BIT(4)
+#define TCU_TMR_FMASK3         BIT(3)
+#define TCU_TMR_FMASK2         BIT(2)
+#define TCU_TMR_FMASK1         BIT(1)
+#define TCU_TMR_FMASK0         BIT(0)
+
+#define TCU_TMSR_HMST5         BIT(21)
+#define TCU_TMSR_HMST4         BIT(20)
+#define TCU_TMSR_HMST3         BIT(19)
+#define TCU_TMSR_HMST2         BIT(18)
+#define TCU_TMSR_HMST1         BIT(17)
+#define TCU_TMSR_HMST0         BIT(16)
+#define TCU_TMSR_FMST5         BIT(5)
+#define TCU_TMSR_FMST4         BIT(4)
+#define TCU_TMSR_FMST3         BIT(3)
+#define TCU_TMSR_FMST2         BIT(2)
+#define TCU_TMSR_FMST1         BIT(1)
+#define TCU_TMSR_FMST0         BIT(0)
+
+#define TCU_TMCR_HMCL5         BIT(21)
+#define TCU_TMCR_HMCL4         BIT(20)
+#define TCU_TMCR_HMCL3         BIT(19)
+#define TCU_TMCR_HMCL2         BIT(18)
+#define TCU_TMCR_HMCL1         BIT(17)
+#define TCU_TMCR_HMCL0         BIT(16)
+#define TCU_TMCR_FMCL5         BIT(5)
+#define TCU_TMCR_FMCL4         BIT(4)
+#define TCU_TMCR_FMCL3         BIT(3)
+#define TCU_TMCR_FMCL2         BIT(2)
+#define TCU_TMCR_FMCL1         BIT(1)
+#define TCU_TMCR_FMCL0         BIT(0)
+
+#define TCU_TSR_WDTS           BIT(16)
+#define TCU_TSR_STOP5          BIT(5)
+#define TCU_TSR_STOP4          BIT(4)
+#define TCU_TSR_STOP3          BIT(3)
+#define TCU_TSR_STOP2          BIT(2)
+#define TCU_TSR_STOP1          BIT(1)
+#define TCU_TSR_STOP0          BIT(0)
+
+#define TCU_TSSR_WDTSS         BIT(16)
+#define TCU_TSSR_STPS5         BIT(5)
+#define TCU_TSSR_STPS4         BIT(4)
+#define TCU_TSSR_STPS3         BIT(3)
+#define TCU_TSSR_STPS2         BIT(2)
+#define TCU_TSSR_STPS1         BIT(1)
+#define TCU_TSSR_STPS0         BIT(0)
+
+#define TCU_TSSR_WDTSC         BIT(16)
+#define TCU_TSSR_STPC5         BIT(5)
+#define TCU_TSSR_STPC4         BIT(4)
+#define TCU_TSSR_STPC3         BIT(3)
+#define TCU_TSSR_STPC2         BIT(2)
+#define TCU_TSSR_STPC1         BIT(1)
+#define TCU_TSSR_STPC0         BIT(0)
+
+#define TER_OSTEN              BIT(15)
+
+#define OSTCSR_CNT_MD          BIT(15)
+#define OSTCSR_SD              BIT(9)
+#define OSTCSR_PRESCALE_16     (0x2 << 3)
+#define OSTCSR_EXT_EN          BIT(2)
+
+int timer_init(void)
+{
+       void __iomem *regs = (void __iomem *)TCU_BASE;
+
+       writel(OSTCSR_SD, regs + TCU_OSTCSR);
+       reset_timer();
+       writel(OSTCSR_CNT_MD | OSTCSR_EXT_EN | OSTCSR_PRESCALE_16,
+              regs + TCU_OSTCSR);
+       writew(TER_OSTEN, regs + TCU_TESR);
+       return 0;
+}
+
+void reset_timer(void)
+{
+       void __iomem *regs = (void __iomem *)TCU_BASE;
+
+       writel(0, regs + TCU_OSTCNTH);
+       writel(0, regs + TCU_OSTCNTL);
+}
+
+static u64 get_timer64(void)
+{
+       void __iomem *regs = (void __iomem *)TCU_BASE;
+       u32 low = readl(regs + TCU_OSTCNTL);
+       u32 high = readl(regs + TCU_OSTCNTHBUF);
+
+       return ((u64)high << 32) | low;
+}
+
+ulong get_timer(ulong base)
+{
+       return lldiv(get_timer64(), 3000) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+       /* OST count increments at 3MHz */
+       u64 end = get_timer64() + ((u64)usec * 3);
+
+       while (get_timer64() < end)
+               ;
+}
+
+unsigned long long get_ticks(void)
+{
+       return get_timer64();
+}
+
+void jz4780_tcu_wdt_start(void)
+{
+       void __iomem *tcu_regs = (void __iomem *)TCU_BASE;
+
+       /* Enable WDT clock */
+       writel(TCU_TSSR_WDTSC, tcu_regs + TCU_TSCR);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds
new file mode 100644 (file)
index 0000000..347cabc
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+               LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+               LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+       .text :
+       {
+               __image_copy_start = .;
+               arch/mips/mach-jz47xx/start.o   (.text*)
+               *(.text*)
+       } >.sram
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+       . = ALIGN(4);
+       .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+       . = ALIGN(4);
+       __image_copy_end = .;
+
+       .bss : {
+               . = ALIGN(4);
+               __bss_start = .;
+               *(.sbss.*)
+               *(.bss.*)
+               *(COMMON)
+               . = ALIGN(4);
+               __bss_end = .;
+       } >.sdram
+
+       /DISCARD/ : {
+               *(.dynbss)
+               *(.dynstr)
+               *(.dynamic)
+               *(.interp)
+               *(.hash)
+               *(.gnu.*)
+               *(.plt)
+               *(.got.plt)
+               *(.rel.plt)
+               *(.rel.dyn)
+       }
+}
diff --git a/arch/mips/mach-jz47xx/start.S b/arch/mips/mach-jz47xx/start.S
new file mode 100644 (file)
index 0000000..760d021
--- /dev/null
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Startup Code for MIPS32 XBURST CPU-core
+ *
+ *  Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
+ */
+
+#include <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+#include <asm/cache.h>
+#include <mach/jz4780.h>
+
+       .set noreorder
+
+       .globl _start
+       .text
+_start:
+#ifdef CONFIG_SPL_BUILD
+
+       /* magic value ("MSPL") */
+       .word 0x4d53504c
+
+       /* Invalidate BTB */
+       mfc0    t0, CP0_CONFIG, 7
+       nop
+       ori     t0, 2
+       mtc0    t0, CP0_CONFIG, 7
+       nop
+
+       /*
+        * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
+        */
+       li      t0, 0x0040FC04
+       mtc0    t0, CP0_STATUS
+
+       /* CAUSE register */
+       /* IV=1, use the specical interrupt vector (0x200) */
+       li      t1, 0x00800000
+       mtc0    t1, CP0_CAUSE
+
+#ifdef CONFIG_SOC_JZ4780
+       /* enable bridge radical mode */
+       la      t0, CPM_BASE
+       lw      t1, 0x24(t0)
+       ori     t1, t1, 0x22
+       sw      t1, 0x24(t0)
+#endif
+
+       /* Set up stack */
+       li      sp, CONFIG_SPL_STACK
+
+       b               board_init_f
+        nop
+
+#ifdef CONFIG_SOC_JZ4780
+
+       .globl enable_caches
+       .ent enable_caches
+enable_caches:
+       mtc0    zero, CP0_TAGLO
+       mtc0    zero, CP0_TAGHI
+
+       li      t0, KSEG0
+       addu    t1, t0, CONFIG_SYS_DCACHE_SIZE
+1:
+       cache   INDEX_STORE_TAG_D, 0(t0)
+       bne     t0, t1, 1b
+       addiu   t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+       li      t0, KSEG0
+       addu    t1, t0, CONFIG_SYS_ICACHE_SIZE
+2:
+       cache   INDEX_STORE_TAG_I, 0(t0)
+       bne     t0, t1, 2b
+       addiu   t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+       /* Invalidate BTB */
+       mfc0    t0, CP0_CONFIG, 7
+       nop
+       ori     t0, 2
+       mtc0    t0, CP0_CONFIG, 7
+       nop
+
+       /* Enable caches */
+       li      t0, CONF_CM_CACHABLE_NONCOHERENT
+       mtc0    t0, CP0_CONFIG
+       nop
+
+       jr      ra
+        nop
+
+       .end enable_caches
+
+#endif /* CONFIG_SOC_JZ4780 */
+#endif /* !CONFIG_SPL_BUILD */
diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig
new file mode 100644 (file)
index 0000000..0e35b77
--- /dev/null
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+menu "MSCC VCore-III platforms"
+       depends on ARCH_MSCC
+
+config SOC_VCOREIII
+       select MIPS_TUNE_24KC
+       select ROM_EXCEPTION_VECTORS
+       select SUPPORTS_BIG_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       select SUPPORTS_LITTLE_ENDIAN
+       bool
+
+config SYS_SOC
+       default "mscc"
+
+config SOC_OCELOT
+       bool
+       select SOC_VCOREIII
+       help
+         This supports MSCC Ocelot family of SOCs.
+
+config SOC_LUTON
+       bool
+       select SOC_VCOREIII
+       help
+         This supports MSCC Luton family of SOCs.
+
+config SYS_CONFIG_NAME
+       default "vcoreiii"
+
+choice
+       prompt "Board select"
+
+config TARGET_OCELOT_PCB120
+       bool "MSCC PCB120 Reference Board (aka VSC5635EV)"
+       select SOC_OCELOT
+       help
+         When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to
+         ocelot_pcb120
+
+config TARGET_OCELOT_PCB123
+       bool "MSCC PCB123 Reference Board (aka VSC7514EV))"
+       select SOC_OCELOT
+       help
+         When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to
+         ocelot_pcb123
+
+config TARGET_LUTON_PCB091
+       bool "MSCC PCB091 Reference Board"
+       select SOC_LUTON
+       select MSCC_BITBANG_SPI_GPIO
+       help
+         When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to
+         luton_pcb091
+endchoice
+
+choice
+       prompt "DDR type"
+
+config DDRTYPE_H5TQ4G63MFR
+       bool "Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16)"
+
+config DDRTYPE_MT41K256M16
+       bool "Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16)"
+
+config DDRTYPE_H5TQ1G63BFA
+       bool "Hynix H5TQ1G63BFA (1Gbit DDR3, x16)"
+
+config DDRTYPE_MT41J128M16HA
+       bool "Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16)"
+
+config DDRTYPE_MT41K128M16JT
+       bool "Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16)"
+
+config DDRTYPE_MT47H128M8HQ
+       bool "Micron MT47H128M8-3 (1Gbit, DDR-533@CL4 @ 4.80ns 16Mbisx8x8)"
+
+endchoice
+
+source "board/mscc/ocelot/Kconfig"
+
+source "board/mscc/luton/Kconfig"
+
+endmenu
diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile
new file mode 100644 (file)
index 0000000..6c60f26
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+CFLAGS_cpu.o += -finline-limit=64000
+
+obj-y += cpu.o dram.o reset.o lowlevel_init.o
+obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o
diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c
new file mode 100644 (file)
index 0000000..5be8ff6
--- /dev/null
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+
+#include <asm/io.h>
+#include <asm/types.h>
+
+#include <mach/tlb.h>
+#include <mach/ddr.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if CONFIG_SYS_SDRAM_SIZE <= SZ_64M
+#define MSCC_RAM_TLB_SIZE   SZ_64M
+#define MSCC_ATTRIB2   MMU_REGIO_INVAL
+#elif CONFIG_SYS_SDRAM_SIZE <= SZ_128M
+#define MSCC_RAM_TLB_SIZE   SZ_64M
+#define MSCC_ATTRIB2   MMU_REGIO_RW
+#elif CONFIG_SYS_SDRAM_SIZE <= SZ_256M
+#define MSCC_RAM_TLB_SIZE   SZ_256M
+#define MSCC_ATTRIB2   MMU_REGIO_INVAL
+#elif CONFIG_SYS_SDRAM_SIZE <= SZ_512M
+#define MSCC_RAM_TLB_SIZE   SZ_256M
+#define MSCC_ATTRIB2   MMU_REGIO_RW
+#else
+#define MSCC_RAM_TLB_SIZE   SZ_512M
+#define MSCC_ATTRIB2   MMU_REGIO_RW
+#endif
+
+/* NOTE: lowlevel_init() function does not have access to the
+ * stack. Thus, all called functions must be inlined, and (any) local
+ * variables must be kept in registers.
+ */
+void vcoreiii_tlb_init(void)
+{
+       register int tlbix = 0;
+
+       /*
+        * Unlike most of the MIPS based SoCs, the IO register address
+        * are not in KSEG0. The mainline linux kernel built in legacy
+        * mode needs to access some of the registers very early in
+        * the boot and make the assumption that the bootloader has
+        * already configured them, so we have to match this
+        * expectation.
+        */
+       create_tlb(tlbix++, MSCC_IO_ORIGIN1_OFFSET, SZ_16M, MMU_REGIO_RW,
+                  MMU_REGIO_RW);
+#ifdef CONFIG_SOC_LUTON
+       create_tlb(tlbix++, MSCC_IO_ORIGIN2_OFFSET, SZ_16M, MMU_REGIO_RW,
+                  MMU_REGIO_RW);
+#endif
+
+#if  CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO
+       /*
+        * If U-Boot is located in NOR then we want to be able to use
+        * the data cache in order to boot in a decent duration
+        */
+       create_tlb(tlbix++, MSCC_FLASH_TO, SZ_16M, MMU_REGIO_RO_C,
+                  MMU_REGIO_RO_C);
+       create_tlb(tlbix++, MSCC_FLASH_TO + SZ_32M, SZ_16M, MMU_REGIO_RO_C,
+                  MMU_REGIO_RO_C);
+
+       /*
+        * Using cache for RAM also helps to improve boot time. Thanks
+        * to this the time to relocate U-Boot in RAM went from 2.092
+        * secs to 0.104 secs.
+        */
+       create_tlb(tlbix++, MSCC_DDR_TO, MSCC_RAM_TLB_SIZE, MMU_REGIO_RW,
+                  MSCC_ATTRIB2);
+
+       /* Enable caches by clearing the bit ERL, which is set on reset */
+       write_c0_status(read_c0_status() & ~BIT(2));
+#endif /* CONFIG_SYS_TEXT_BASE */
+}
+
+int mach_cpu_init(void)
+{
+       /* Speed up NOR flash access */
+#ifdef CONFIG_SOC_LUTON
+       writel(ICPU_PI_MST_CFG_TRISTATE_CTRL +
+              ICPU_PI_MST_CFG_CLK_DIV(4), BASE_CFG + ICPU_PI_MST_CFG);
+
+       writel(ICPU_SPI_MST_CFG_FAST_READ_ENA +
+              ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
+              ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG);
+#else
+       writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
+              ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG);
+       /*
+        * Legacy and mainline linux kernel expect that the
+        * interruption map was set as it was done by redboot.
+        */
+       writel(~0, BASE_CFG + ICPU_DST_INTR_MAP(0));
+       writel(0, BASE_CFG + ICPU_DST_INTR_MAP(1));
+       writel(0, BASE_CFG + ICPU_DST_INTR_MAP(2));
+       writel(0, BASE_CFG + ICPU_DST_INTR_MAP(3));
+#endif
+       return 0;
+}
diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c
new file mode 100644 (file)
index 0000000..309007c
--- /dev/null
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+
+#include <asm/io.h>
+#include <asm/types.h>
+
+#include <mach/tlb.h>
+#include <mach/ddr.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline int vcoreiii_train_bytelane(void)
+{
+       int ret;
+
+       ret = hal_vcoreiii_train_bytelane(0);
+
+#ifdef CONFIG_SOC_OCELOT
+       if (ret)
+               return ret;
+       ret = hal_vcoreiii_train_bytelane(1);
+#endif
+
+       return ret;
+}
+
+int vcoreiii_ddr_init(void)
+{
+       int res;
+
+       if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT)
+             & ICPU_MEMCTRL_STAT_INIT_DONE)) {
+               hal_vcoreiii_init_memctl();
+               hal_vcoreiii_wait_memctl();
+               if (hal_vcoreiii_init_dqs() || vcoreiii_train_bytelane())
+                       hal_vcoreiii_ddr_failed();
+       }
+#if (CONFIG_SYS_TEXT_BASE != 0x20000000)
+       res = dram_check();
+       if (res == 0)
+               hal_vcoreiii_ddr_verified();
+       else
+               hal_vcoreiii_ddr_failed();
+
+       /* Clear boot-mode and read-back to activate/verify */
+       clrbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+                    ICPU_GENERAL_CTRL_BOOT_MODE_ENA);
+       readl(BASE_CFG + ICPU_GENERAL_CTRL);
+#else
+       res = 0;
+#endif
+       return res;
+}
+
+int print_cpuinfo(void)
+{
+       printf("MSCC VCore-III MIPS 24Kec\n");
+
+       return 0;
+}
+
+int dram_init(void)
+{
+       while (vcoreiii_ddr_init())
+               ;
+
+       gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+       return 0;
+}
diff --git a/arch/mips/mach-mscc/include/ioremap.h b/arch/mips/mach-mscc/include/ioremap.h
new file mode 100644 (file)
index 0000000..9024364
--- /dev/null
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_MSCC_IOREMAP_H
+#define __ASM_MACH_MSCC_IOREMAP_H
+
+#include <linux/types.h>
+#include <mach/common.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 int is_vcoreiii_internal_registers(phys_addr_t offset)
+{
+       if ((offset >= MSCC_IO_ORIGIN1_OFFSET &&
+            offset < (MSCC_IO_ORIGIN1_OFFSET + MSCC_IO_ORIGIN1_SIZE)) ||
+           (offset >= MSCC_IO_ORIGIN2_OFFSET &&
+            offset < (MSCC_IO_ORIGIN2_OFFSET + MSCC_IO_ORIGIN2_SIZE)))
+               return 1;
+
+       return 0;
+}
+
+static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
+                                        unsigned long flags)
+{
+       if (is_vcoreiii_internal_registers(offset))
+               return (void __iomem *)offset;
+
+       return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+       return is_vcoreiii_internal_registers((unsigned long)addr);
+}
+
+#define _page_cachable_default _CACHE_CACHABLE_NONCOHERENT
+
+#endif                         /* __ASM_MACH_MSCC_IOREMAP_H */
diff --git a/arch/mips/mach-mscc/include/mach/common.h b/arch/mips/mach-mscc/include/mach/common.h
new file mode 100644 (file)
index 0000000..931ecd7
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_COMMON_H
+#define __ASM_MACH_COMMON_H
+
+#if defined(CONFIG_SOC_OCELOT)
+#include <mach/ocelot/ocelot.h>
+#include <mach/ocelot/ocelot_devcpu_gcb.h>
+#include <mach/ocelot/ocelot_icpu_cfg.h>
+#elif defined(CONFIG_SOC_LUTON)
+#include <mach/luton/luton.h>
+#include <mach/luton/luton_devcpu_gcb.h>
+#include <mach/luton/luton_icpu_cfg.h>
+#else
+#error Unsupported platform
+#endif
+
+#define MSCC_DDR_TO    0x20000000      /* DDR RAM base offset */
+#define MSCC_MEMCTL1_TO        0x40000000      /* SPI/PI base offset */
+#define MSCC_MEMCTL2_TO        0x50000000      /* SPI/PI base offset */
+#define MSCC_FLASH_TO  MSCC_MEMCTL1_TO /* Flash base offset */
+
+#define VCOREIII_TIMER_DIVIDER 25      /* Clock tick ~ 0.1 us */
+
+#endif                         /* __ASM_MACH_COMMON_H */
diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h
new file mode 100644 (file)
index 0000000..f445e63
--- /dev/null
@@ -0,0 +1,814 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_DDR_H
+#define __ASM_MACH_DDR_H
+
+#include <asm/cacheops.h>
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <mach/common.h>
+
+#define MIPS_VCOREIII_MEMORY_DDR3
+#define MIPS_VCOREIII_DDR_SIZE CONFIG_SYS_SDRAM_SIZE
+
+#if defined(CONFIG_DDRTYPE_H5TQ1G63BFA)        /* Serval1 Refboard */
+
+/* Hynix H5TQ1G63BFA (1Gbit DDR3, x16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     13
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               6
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             35
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             38
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT41J128M16HA)    /* Validation board */
+
+/* Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     14
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               5
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             50
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             54
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT41K256M16)      /* JR2 Validation board */
+
+/* Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     15
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               5
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             82
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             85
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_H5TQ4G63MFR)      /* JR2 Reference board */
+
+/* Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16) - 2kb pages @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     15
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               6
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              17
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             82
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             85
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT41K128M16JT)
+
+/* Micron Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     14
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               6
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             82
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             85
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT47H128M8HQ)     /* Luton10/26 Refboards */
+
+/* Micron 1Gb MT47H128M8-3 16Meg x 8 x 8 banks, DDR-533@CL4 @ 4.80ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     14
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            1625
+#define VC3_MPAR_tRAS_min         9
+#define VC3_MPAR_CL               4
+#define VC3_MPAR_tWTR             2
+#define VC3_MPAR_tRC              12
+#define VC3_MPAR_tFAW             8
+#define VC3_MPAR_tRP              4
+#define VC3_MPAR_tRRD             2
+#define VC3_MPAR_tRCD             4
+
+#define VC3_MPAR_tRPA             4
+#define VC3_MPAR_tRP              4
+
+#define VC3_MPAR_tMRD             2
+#define VC3_MPAR_tRFC             27
+
+#define VC3_MPAR__400_ns_dly      84
+
+#define VC3_MPAR_tWR              4
+#undef MIPS_VCOREIII_MEMORY_DDR3
+#else
+
+#error Unknown DDR system configuration - please add!
+
+#endif
+
+#ifdef CONFIG_SOC_OCELOT
+#define MIPS_VCOREIII_MEMORY_16BIT 1
+#endif
+
+#define MIPS_VCOREIII_MEMORY_SSTL_ODT 7
+#define MIPS_VCOREIII_MEMORY_SSTL_DRIVE 7
+#define VCOREIII_DDR_DQS_MODE_CALIBRATE
+
+#ifdef MIPS_VCOREIII_MEMORY_16BIT
+#define VC3_MPAR_16BIT       1
+#else
+#define VC3_MPAR_16BIT       0
+#endif
+
+#ifdef MIPS_VCOREIII_MEMORY_DDR3
+#define VC3_MPAR_DDR3_MODE    1        /* DDR3 */
+#define VC3_MPAR_BURST_LENGTH 8        /* Always 8 (1) for DDR3 */
+#ifdef MIPS_VCOREIII_MEMORY_16BIT
+#define VC3_MPAR_BURST_SIZE   1        /* Always 1 for DDR3/16bit */
+#else
+#define VC3_MPAR_BURST_SIZE   0
+#endif
+#else
+#define VC3_MPAR_DDR3_MODE    0        /* DDR2 */
+#ifdef MIPS_VCOREIII_MEMORY_16BIT
+#define VC3_MPAR_BURST_LENGTH 4        /* in DDR2 16-bit mode, use burstlen 4 */
+#else
+#define VC3_MPAR_BURST_LENGTH 8        /* For 8-bit IF we must run burst-8 */
+#endif
+#define VC3_MPAR_BURST_SIZE   0        /* Always 0 for DDR2 */
+#endif
+
+#define VC3_MPAR_RL VC3_MPAR_CL
+#if !defined(MIPS_VCOREIII_MEMORY_DDR3)
+#define VC3_MPAR_WL (VC3_MPAR_RL - 1)
+#define VC3_MPAR_MD VC3_MPAR_tMRD
+#define VC3_MPAR_ID VC3_MPAR__400_ns_dly
+#define VC3_MPAR_SD VC3_MPAR_tXSRD
+#define VC3_MPAR_OW (VC3_MPAR_WL - 2)
+#define VC3_MPAR_OR (VC3_MPAR_WL - 3)
+#define VC3_MPAR_RP (VC3_MPAR_bank_addr_cnt < 3 ? VC3_MPAR_tRP : VC3_MPAR_tRPA)
+#define VC3_MPAR_FAW (VC3_MPAR_bank_addr_cnt < 3 ? 1 : VC3_MPAR_tFAW)
+#define VC3_MPAR_BL (VC3_MPAR_BURST_LENGTH == 4 ? 2 : 4)
+#define MSCC_MEMPARM_MR0 \
+       (VC3_MPAR_BURST_LENGTH == 8 ? 3 : 2) | (VC3_MPAR_CL << 4) | \
+       ((VC3_MPAR_tWR - 1) << 9)
+/* DLL-on, Full-OD, AL=0, RTT=off, nDQS-on, RDQS-off, out-en */
+#define MSCC_MEMPARM_MR1 0x382
+#define MSCC_MEMPARM_MR2 0
+#define MSCC_MEMPARM_MR3 0
+#else
+#define VC3_MPAR_WL VC3_MPAR_CWL
+#define VC3_MPAR_MD VC3_MPAR_tMOD
+#define VC3_MPAR_ID VC3_MPAR_tXPR
+#define VC3_MPAR_SD VC3_MPAR_tDLLK
+#define VC3_MPAR_OW 2
+#define VC3_MPAR_OR 2
+#define VC3_MPAR_RP VC3_MPAR_tRP
+#define VC3_MPAR_FAW VC3_MPAR_tFAW
+#define VC3_MPAR_BL 4
+#define MSCC_MEMPARM_MR0 ((VC3_MPAR_RL - 4) << 4) | ((VC3_MPAR_tWR - 4) << 9)
+/* ODT_RTT: “0x0040” for 120ohm, and “0x0004” for 60ohm. */
+#define MSCC_MEMPARM_MR1 0x0040
+#define MSCC_MEMPARM_MR2 ((VC3_MPAR_WL - 5) << 3)
+#define MSCC_MEMPARM_MR3 0
+#endif                         /* MIPS_VCOREIII_MEMORY_DDR3 */
+
+#define MSCC_MEMPARM_MEMCFG                                             \
+       ((MIPS_VCOREIII_DDR_SIZE > SZ_512M) ?                           \
+        ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS : 0) |                      \
+       (VC3_MPAR_16BIT ? ICPU_MEMCTRL_CFG_DDR_WIDTH : 0) |             \
+       (VC3_MPAR_DDR3_MODE ? ICPU_MEMCTRL_CFG_DDR_MODE : 0) |          \
+       (VC3_MPAR_BURST_SIZE ? ICPU_MEMCTRL_CFG_BURST_SIZE : 0) |       \
+       (VC3_MPAR_BURST_LENGTH == 8 ? ICPU_MEMCTRL_CFG_BURST_LEN : 0) | \
+       (VC3_MPAR_bank_addr_cnt == 3 ? ICPU_MEMCTRL_CFG_BANK_CNT : 0) | \
+       ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(VC3_MPAR_row_addr_cnt - 1) |      \
+       ICPU_MEMCTRL_CFG_MSB_COL_ADDR(VC3_MPAR_col_addr_cnt - 1)
+
+#ifdef CONFIG_SOC_OCELOT
+#define MSCC_MEMPARM_PERIOD                                    \
+       ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(8) |               \
+       ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI)
+
+#define MSCC_MEMPARM_TIMING0                                            \
+       ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(VC3_MPAR_RL + VC3_MPAR_BL + 1 - \
+                                         VC3_MPAR_WL) |                \
+       ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(VC3_MPAR_BL - 1) |        \
+       ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(VC3_MPAR_BL) |            \
+       ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) |  \
+       ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_WL +              \
+                                            VC3_MPAR_BL +              \
+                                            VC3_MPAR_tWR - 1) |        \
+       ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BL - 1) |         \
+               ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_WL - 1) | \
+       ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_RL - 3)
+
+#define MSCC_MEMPARM_TIMING1                                            \
+       ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \
+       ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_FAW - 1) |          \
+       ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_RP - 1) |        \
+       ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) |        \
+       ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) |        \
+       ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_WL +                 \
+                                         VC3_MPAR_BL +                 \
+                                         VC3_MPAR_tWTR - 1)
+
+#define MSCC_MEMPARM_TIMING2                                   \
+       ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_RP - 1) |   \
+       ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_MD - 1) |               \
+       ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) |               \
+       ICPU_MEMCTRL_TIMING2_INIT_DLY(VC3_MPAR_ID - 1)
+
+#define MSCC_MEMPARM_TIMING3                                           \
+       ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_WL +       \
+                                                   VC3_MPAR_tWTR - 1) |\
+       ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(VC3_MPAR_OR - 1) |              \
+       ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_OW - 1) |              \
+       ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_RL - 3)
+
+#else
+#define MSCC_MEMPARM_PERIOD                                    \
+       ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(1) |               \
+       ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI)
+
+#define MSCC_MEMPARM_TIMING0                                            \
+       ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) |  \
+       ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_CL +              \
+                                            (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \
+                                            VC3_MPAR_tWR) |            \
+       ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BURST_LENGTH == 8 ? 3 : 1) | \
+       ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_CL - 3) |         \
+       ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_CL - 3)
+
+#define MSCC_MEMPARM_TIMING1                                            \
+       ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \
+       ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_tFAW - 1) |         \
+       ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_tRP - 1) |       \
+       ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) |        \
+       ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) |        \
+       ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_CL +                 \
+                                         (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \
+                                         VC3_MPAR_tWTR)
+#define MSCC_MEMPARM_TIMING2                                            \
+       ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_tRPA - 1) |         \
+       ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_tMRD - 1) |             \
+       ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) |               \
+       ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(VC3_MPAR__400_ns_dly)
+
+#define MSCC_MEMPARM_TIMING3                                           \
+       ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_CL - 1) |  \
+       ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_CL - 1) |              \
+       ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_CL - 1)
+
+#endif
+
+enum {
+       DDR_TRAIN_OK,
+       DDR_TRAIN_CONTINUE,
+       DDR_TRAIN_ERROR,
+};
+
+/*
+ * We actually have very few 'pause' possibilities apart from
+ * these assembly nops (at this very early stage).
+ */
+#define PAUSE() asm volatile("nop; nop; nop; nop; nop; nop; nop; nop")
+
+/* NB: Assumes inlining as no stack is available! */
+static inline void set_dly(u32 bytelane, u32 dly)
+{
+       register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+
+       r &= ~ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M;
+       r |= ICPU_MEMCTRL_DQS_DLY_DQS_DLY(dly);
+       writel(r, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+}
+
+static inline bool incr_dly(u32 bytelane)
+{
+       register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+
+       if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) {
+               writel(r + 1, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+               return true;
+       }
+
+       return false;
+}
+
+static inline bool adjust_dly(int adjust)
+{
+       register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0));
+
+       if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) {
+               writel(r + adjust, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0));
+               return true;
+       }
+
+       return false;
+}
+
+/* NB: Assumes inlining as no stack is available! */
+static inline void center_dly(u32 bytelane, u32 start)
+{
+       register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)) - start;
+
+       writel(start + (r >> 1), BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+}
+
+static inline void memphy_soft_reset(void)
+{
+       setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST);
+       PAUSE();
+       clrbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST);
+       PAUSE();
+}
+
+#ifdef CONFIG_SOC_OCELOT
+static u8 training_data[] = { 0xfe, 0x11, 0x33, 0x55, 0x77, 0x99, 0xbb, 0xdd };
+
+static inline void sleep_100ns(u32 val)
+{
+       /* Set the timer tick generator to 100 ns */
+       writel(VCOREIII_TIMER_DIVIDER - 1, BASE_CFG + ICPU_TIMER_TICK_DIV);
+
+       /* Set the timer value */
+       writel(val, BASE_CFG + ICPU_TIMER_VALUE(0));
+
+       /* Enable timer 0 for one-shot */
+       writel(ICPU_TIMER_CTRL_ONE_SHOT_ENA | ICPU_TIMER_CTRL_TIMER_ENA,
+              BASE_CFG + ICPU_TIMER_CTRL(0));
+
+       /* Wait for timer 0 to reach 0 */
+       while (readl(BASE_CFG + ICPU_TIMER_VALUE(0)) != 0)
+               ;
+}
+
+static inline void hal_vcoreiii_ddr_reset_assert(void)
+{
+       /* DDR has reset pin on GPIO 19 toggle Low-High to release */
+       setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19));
+       writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_CLR);
+       sleep_100ns(10000);
+}
+
+static inline void hal_vcoreiii_ddr_reset_release(void)
+{
+       /* DDR has reset pin on GPIO 19 toggle Low-High to release */
+       setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19));
+       writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_SET);
+       sleep_100ns(10000);
+}
+
+/*
+ * DDR memory sanity checking failed, tally and do hard reset
+ *
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline void hal_vcoreiii_ddr_failed(void)
+{
+       register u32 reset;
+
+       writel(readl(BASE_CFG + ICPU_GPR(6)) + 1, BASE_CFG + ICPU_GPR(6));
+
+       clrbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19));
+
+       /* We have to execute the reset function from cache. Indeed,
+        * the reboot workaround in _machine_restart() will change the
+        * SPI NOR into SW bitbang.
+        *
+        * This will render the CPU unable to execute directly from
+        * the NOR, which is why the reset instructions are prefetched
+        * into the I-cache.
+        *
+        * When failing the DDR initialization we are executing from
+        * NOR.
+        *
+        * The last instruction in _machine_restart() will reset the
+        * MIPS CPU (and the cache), and the CPU will start executing
+        * from the reset vector.
+        */
+       reset = KSEG0ADDR(_machine_restart);
+       icache_lock((void *)reset, 128);
+       asm volatile ("jr %0"::"r" (reset));
+
+       panic("DDR init failed\n");
+}
+
+/*
+ * DDR memory sanity checking done, possibly enable ECC.
+ *
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline void hal_vcoreiii_ddr_verified(void)
+{
+#ifdef MIPS_VCOREIII_MEMORY_ECC
+       /* Finally, enable ECC */
+       register u32 val = readl(BASE_CFG + ICPU_MEMCTRL_CFG);
+
+       val |= ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA;
+       val &= ~ICPU_MEMCTRL_CFG_BURST_SIZE;
+
+       writel(val, BASE_CFG + ICPU_MEMCTRL_CFG);
+#endif
+
+       /* Reset Status register - sticky bits */
+       writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), BASE_CFG + ICPU_MEMCTRL_STAT);
+}
+
+/* NB: Assumes inlining as no stack is available! */
+static inline int look_for(u32 bytelane)
+{
+       register u32 i;
+
+       /* Reset FIFO in case any previous access failed */
+       for (i = 0; i < sizeof(training_data); i++) {
+               register u32 byte;
+
+               memphy_soft_reset();
+               /* Reset sticky bits */
+               writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT),
+                      BASE_CFG + ICPU_MEMCTRL_STAT);
+               /* Read data */
+               byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane +
+                                  (i * 4));
+
+               /*
+                * Prevent the compiler reordering the instruction so
+                * the read of RAM happens after the check of the
+                * errors.
+                */
+               rmb();
+               if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) &
+                   (ICPU_MEMCTRL_STAT_RDATA_MASKED |
+                    ICPU_MEMCTRL_STAT_RDATA_DUMMY)) {
+                       /* Noise on the line */
+                       goto read_error;
+               }
+               /* If mismatch, increment DQS - if possible */
+               if (byte != training_data[i]) {
+ read_error:
+                       if (!incr_dly(bytelane))
+                               return DDR_TRAIN_ERROR;
+                       return DDR_TRAIN_CONTINUE;
+               }
+       }
+       return DDR_TRAIN_OK;
+}
+
+/* NB: Assumes inlining as no stack is available! */
+static inline int look_past(u32 bytelane)
+{
+       register u32 i;
+
+       /* Reset FIFO in case any previous access failed */
+       for (i = 0; i < sizeof(training_data); i++) {
+               register u32 byte;
+
+               memphy_soft_reset();
+               /* Ack sticky bits */
+               writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT),
+                      BASE_CFG + ICPU_MEMCTRL_STAT);
+               byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane +
+                                  (i * 4));
+               /*
+                * Prevent the compiler reordering the instruction so
+                * the read of RAM happens after the check of the
+                * errors.
+                */
+               rmb();
+               if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) &
+                   (ICPU_MEMCTRL_STAT_RDATA_MASKED |
+                    ICPU_MEMCTRL_STAT_RDATA_DUMMY)) {
+                       /* Noise on the line */
+                       goto read_error;
+               }
+               /* Bail out when we see first mismatch */
+               if (byte != training_data[i]) {
+ read_error:
+                       return DDR_TRAIN_OK;
+               }
+       }
+       /* All data compares OK, increase DQS and retry */
+       if (!incr_dly(bytelane))
+               return DDR_TRAIN_ERROR;
+
+       return DDR_TRAIN_CONTINUE;
+}
+
+static inline int hal_vcoreiii_train_bytelane(u32 bytelane)
+{
+       register int res;
+       register u32 dqs_s;
+
+       set_dly(bytelane, 0);   /* Start training at DQS=0 */
+       while ((res = look_for(bytelane)) == DDR_TRAIN_CONTINUE)
+               ;
+       if (res != DDR_TRAIN_OK)
+               return res;
+
+       dqs_s = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+       while ((res = look_past(bytelane)) == DDR_TRAIN_CONTINUE)
+               ;
+       if (res != DDR_TRAIN_OK)
+               return res;
+       /* Reset FIFO - for good measure */
+       memphy_soft_reset();
+       /* Adjust to center [dqs_s;cur] */
+       center_dly(bytelane, dqs_s);
+       return DDR_TRAIN_OK;
+}
+
+/* This algorithm is converted from the TCL training algorithm used
+ * during silicon simulation.
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline int hal_vcoreiii_init_dqs(void)
+{
+#define MAX_DQS 32
+       register u32 i, j;
+
+       for (i = 0; i < MAX_DQS; i++) {
+               set_dly(0, i);  /* Byte-lane 0 */
+               for (j = 0; j < MAX_DQS; j++) {
+                       __maybe_unused register u32  byte;
+
+                       set_dly(1, j);  /* Byte-lane 1 */
+                       /* Reset FIFO in case any previous access failed */
+                       memphy_soft_reset();
+                       writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT),
+                              BASE_CFG + ICPU_MEMCTRL_STAT);
+                       byte = __raw_readb((void __iomem *)MSCC_DDR_TO);
+                       byte = __raw_readb((void __iomem *)(MSCC_DDR_TO + 1));
+                       if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) &
+                           (ICPU_MEMCTRL_STAT_RDATA_MASKED |
+                            ICPU_MEMCTRL_STAT_RDATA_DUMMY)))
+                               return 0;
+               }
+       }
+       return -1;
+}
+
+static inline int dram_check(void)
+{
+       register u32 i;
+
+       for (i = 0; i < 8; i++) {
+               __raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4)));
+               if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i)
+                       return 1;
+       }
+       return 0;
+}
+#else                          /* Luton */
+
+static inline void sleep_100ns(u32 val)
+{
+}
+
+static inline void hal_vcoreiii_ddr_reset_assert(void)
+{
+       setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_RST);
+       setbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE);
+}
+
+static inline void hal_vcoreiii_ddr_reset_release(void)
+{
+}
+
+static inline void hal_vcoreiii_ddr_failed(void)
+{
+       register u32 memphy_cfg = readl(BASE_CFG + ICPU_MEMPHY_CFG);
+
+       /* Do a fifo reset and start over */
+       writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+              BASE_CFG + ICPU_MEMPHY_CFG);
+       writel(memphy_cfg & ~ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+              BASE_CFG + ICPU_MEMPHY_CFG);
+       writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+              BASE_CFG + ICPU_MEMPHY_CFG);
+}
+
+static inline void hal_vcoreiii_ddr_verified(void)
+{
+}
+
+static inline int look_for(u32 data)
+{
+       register u32 byte = __raw_readb((void __iomem *)MSCC_DDR_TO);
+
+       if (data != byte) {
+               if (!incr_dly(0))
+                       return DDR_TRAIN_ERROR;
+               return DDR_TRAIN_CONTINUE;
+       }
+
+       return DDR_TRAIN_OK;
+}
+
+/* This algorithm is converted from the TCL training algorithm used
+ * during silicon simulation.
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline int hal_vcoreiii_train_bytelane(u32 bytelane)
+{
+       register int res;
+
+       set_dly(bytelane, 0);   /* Start training at DQS=0 */
+       while ((res = look_for(0xff)) == DDR_TRAIN_CONTINUE)
+               ;
+       if (res != DDR_TRAIN_OK)
+               return res;
+
+       set_dly(bytelane, 0);   /* Start training at DQS=0 */
+       while ((res = look_for(0x00)) == DDR_TRAIN_CONTINUE)
+
+               ;
+
+       if (res != DDR_TRAIN_OK)
+               return res;
+
+       adjust_dly(-3);
+
+       return DDR_TRAIN_OK;
+}
+
+static inline int hal_vcoreiii_init_dqs(void)
+{
+       return 0;
+}
+
+static inline int dram_check(void)
+{
+       register u32 i;
+
+       for (i = 0; i < 8; i++) {
+               __raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4)));
+
+               if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i)
+                       return 1;
+       }
+
+       return 0;
+}
+#endif
+
+/*
+ * NB: Called *early* to init memory controller - assumes inlining as
+ * no stack is available!
+ */
+static inline void hal_vcoreiii_init_memctl(void)
+{
+       /* Ensure DDR is in reset */
+       hal_vcoreiii_ddr_reset_assert();
+
+       /* Wait maybe not needed, but ... */
+       PAUSE();
+
+       /* Drop sys ctl memory controller forced reset */
+       clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE);
+
+       PAUSE();
+
+       /* Drop Reset, enable SSTL */
+       writel(ICPU_MEMPHY_CFG_PHY_SSTL_ENA, BASE_CFG + ICPU_MEMPHY_CFG);
+       PAUSE();
+
+       /* Start the automatic SSTL output and ODT drive-strength calibration */
+       writel(ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(MIPS_VCOREIII_MEMORY_SSTL_ODT) |
+              /* drive strength */
+              ICPU_MEMPHY_ZCAL_ZCAL_PROG(MIPS_VCOREIII_MEMORY_SSTL_DRIVE) |
+              /* Start calibration process */
+              ICPU_MEMPHY_ZCAL_ZCAL_ENA, BASE_CFG + ICPU_MEMPHY_ZCAL);
+
+       /* Wait for ZCAL to clear */
+       while (readl(BASE_CFG + ICPU_MEMPHY_ZCAL) & ICPU_MEMPHY_ZCAL_ZCAL_ENA)
+               ;
+#ifdef CONFIG_SOC_OCELOT
+       /* Check no ZCAL_ERR */
+       if (readl(BASE_CFG + ICPU_MEMPHY_ZCAL_STAT)
+           & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR)
+               hal_vcoreiii_ddr_failed();
+#endif
+       /* Drive CL, CK, ODT */
+       setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_ODT_OE |
+                    ICPU_MEMPHY_CFG_PHY_CK_OE | ICPU_MEMPHY_CFG_PHY_CL_OE);
+
+       /* Initialize memory controller */
+       writel(MSCC_MEMPARM_MEMCFG, BASE_CFG + ICPU_MEMCTRL_CFG);
+       writel(MSCC_MEMPARM_PERIOD, BASE_CFG + ICPU_MEMCTRL_REF_PERIOD);
+
+#ifdef CONFIG_SOC_OCELOT
+       writel(MSCC_MEMPARM_TIMING0, BASE_CFG + ICPU_MEMCTRL_TIMING0);
+#else /* Luton */
+       clrbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, ((1 << 20) - 1));
+       setbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, MSCC_MEMPARM_TIMING0);
+#endif
+
+       writel(MSCC_MEMPARM_TIMING1, BASE_CFG + ICPU_MEMCTRL_TIMING1);
+       writel(MSCC_MEMPARM_TIMING2, BASE_CFG + ICPU_MEMCTRL_TIMING2);
+       writel(MSCC_MEMPARM_TIMING3, BASE_CFG + ICPU_MEMCTRL_TIMING3);
+       writel(MSCC_MEMPARM_MR0, BASE_CFG + ICPU_MEMCTRL_MR0_VAL);
+       writel(MSCC_MEMPARM_MR1, BASE_CFG + ICPU_MEMCTRL_MR1_VAL);
+       writel(MSCC_MEMPARM_MR2, BASE_CFG + ICPU_MEMCTRL_MR2_VAL);
+       writel(MSCC_MEMPARM_MR3, BASE_CFG + ICPU_MEMCTRL_MR3_VAL);
+
+#ifdef CONFIG_SOC_OCELOT
+       /* Termination setup - enable ODT */
+       writel(ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA |
+              /* Assert ODT0 for any write */
+              ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(3),
+              BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL);
+
+       /* Release Reset from DDR */
+       hal_vcoreiii_ddr_reset_release();
+
+       writel(readl(BASE_CFG + ICPU_GPR(7)) + 1, BASE_CFG + ICPU_GPR(7));
+#else                          /* Luton */
+       /* Termination setup - disable ODT */
+       writel(0, BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL);
+
+#endif
+}
+
+static inline void hal_vcoreiii_wait_memctl(void)
+{
+       /* Now, rip it! */
+       writel(ICPU_MEMCTRL_CTRL_INITIALIZE, BASE_CFG + ICPU_MEMCTRL_CTRL);
+
+       while (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT)
+                & ICPU_MEMCTRL_STAT_INIT_DONE))
+               ;
+
+       /* Settle...? */
+       sleep_100ns(10000);
+#ifdef CONFIG_SOC_OCELOT
+       /* Establish data contents in DDR RAM for training */
+
+       __raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO));
+       __raw_writel(0x22221111, ((void __iomem *)MSCC_DDR_TO + 0x4));
+       __raw_writel(0x44443333, ((void __iomem *)MSCC_DDR_TO + 0x8));
+       __raw_writel(0x66665555, ((void __iomem *)MSCC_DDR_TO + 0xC));
+       __raw_writel(0x88887777, ((void __iomem *)MSCC_DDR_TO + 0x10));
+       __raw_writel(0xaaaa9999, ((void __iomem *)MSCC_DDR_TO + 0x14));
+       __raw_writel(0xccccbbbb, ((void __iomem *)MSCC_DDR_TO + 0x18));
+       __raw_writel(0xeeeedddd, ((void __iomem *)MSCC_DDR_TO + 0x1C));
+#else
+       __raw_writel(0xff, ((void __iomem *)MSCC_DDR_TO));
+#endif
+}
+#endif                         /* __ASM_MACH_DDR_H */
diff --git a/arch/mips/mach-mscc/include/mach/luton/luton.h b/arch/mips/mach-mscc/include/mach/luton/luton.h
new file mode 100644 (file)
index 0000000..19f02ed
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_H_
+#define _MSCC_OCELOT_H_
+
+#include <linux/bitops.h>
+#include <dm.h>
+
+/*
+ * Target offset base(s)
+ */
+#define MSCC_IO_ORIGIN1_OFFSET 0x60000000
+#define MSCC_IO_ORIGIN1_SIZE   0x01000000
+#define MSCC_IO_ORIGIN2_OFFSET 0x70000000
+#define MSCC_IO_ORIGIN2_SIZE   0x00200000
+#define BASE_CFG        ((void __iomem *)0x70000000)
+#define BASE_DEVCPU_GCB ((void __iomem *)0x60070000)
+
+#endif
diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h
new file mode 100644 (file)
index 0000000..8c0b612
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_
+#define _MSCC_OCELOT_DEVCPU_GCB_H_
+
+#define PERF_SOFT_RST                                     0x90
+
+#define PERF_SOFT_RST_SOFT_SWC_RST                        BIT(1)
+#define PERF_SOFT_RST_SOFT_CHIP_RST                       BIT(0)
+
+#endif
diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h
new file mode 100644 (file)
index 0000000..9233f03
--- /dev/null
@@ -0,0 +1,245 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_ICPU_CFG_H_
+#define _MSCC_OCELOT_ICPU_CFG_H_
+
+#define ICPU_GPR(x) (0x4 * (x))
+#define ICPU_GPR_RSZ                                      0x4
+
+#define ICPU_RESET                                        0x20
+
+#define ICPU_RESET_CORE_RST_CPU_ONLY                      BIT(3)
+#define ICPU_RESET_CORE_RST_PROTECT                       BIT(2)
+#define ICPU_RESET_CORE_RST_FORCE                         BIT(1)
+#define ICPU_RESET_MEM_RST_FORCE                          BIT(0)
+
+#define ICPU_GENERAL_CTRL                                 0x24
+
+#define ICPU_GENERAL_CTRL_SWC_CLEAR_IF                    BIT(6)
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS             BIT(5)
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA              BIT(4)
+#define ICPU_GENERAL_CTRL_IF_MASTER_DIS                   BIT(3)
+#define ICPU_GENERAL_CTRL_IF_MASTER_SPI_ENA               BIT(2)
+#define ICPU_GENERAL_CTRL_IF_MASTER_PI_ENA                BIT(1)
+
+#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA                   BIT(0)
+
+#define ICPU_PI_MST_CFG                                   0x2c
+
+#define ICPU_PI_MST_CFG_ATE_MODE_DIS                      BIT(7)
+#define ICPU_PI_MST_CFG_CLK_POL                           BIT(6)
+#define ICPU_PI_MST_CFG_TRISTATE_CTRL                     BIT(5)
+#define ICPU_PI_MST_CFG_CLK_DIV(x)                        ((x) & GENMASK(4, 0))
+#define ICPU_PI_MST_CFG_CLK_DIV_M                         GENMASK(4, 0)
+
+#define ICPU_SPI_MST_CFG                                  0x50
+
+#define ICPU_SPI_MST_CFG_FAST_READ_ENA                    BIT(10)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x)              (((x) << 5) & GENMASK(9, 5))
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M               GENMASK(9, 5)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x)            (((x) & GENMASK(9, 5)) >> 5)
+#define ICPU_SPI_MST_CFG_CLK_DIV(x)                       ((x) & GENMASK(4, 0))
+#define ICPU_SPI_MST_CFG_CLK_DIV_M                        GENMASK(4, 0)
+
+#define ICPU_SW_MODE                                      0x64
+
+#define ICPU_SW_MODE_SW_PIN_CTRL_MODE                     BIT(13)
+#define ICPU_SW_MODE_SW_SPI_SCK                           BIT(12)
+#define ICPU_SW_MODE_SW_SPI_SCK_OE                        BIT(11)
+#define ICPU_SW_MODE_SW_SPI_SDO                           BIT(10)
+#define ICPU_SW_MODE_SW_SPI_SDO_OE                        BIT(9)
+#define ICPU_SW_MODE_SW_SPI_CS(x)                         (((x) << 5) & GENMASK(8, 5))
+#define ICPU_SW_MODE_SW_SPI_CS_M                          GENMASK(8, 5)
+#define ICPU_SW_MODE_SW_SPI_CS_X(x)                       (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_SW_MODE_SW_SPI_CS_OE(x)                      (((x) << 1) & GENMASK(4, 1))
+#define ICPU_SW_MODE_SW_SPI_CS_OE_M                       GENMASK(4, 1)
+#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x)                    (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_SW_MODE_SW_SPI_SDI                           BIT(0)
+
+#define ICPU_INTR_ENA                                     0x88
+
+#define ICPU_INTR_IRQ0_ENA                                0x98
+#define ICPU_INTR_IRQ0_ENA_IRQ0_ENA                       BIT(0)
+
+#define ICPU_MEMCTRL_CTRL                                 0x234
+
+#define ICPU_MEMCTRL_CTRL_PWR_DOWN                        BIT(3)
+#define ICPU_MEMCTRL_CTRL_MDSET                           BIT(2)
+#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA                   BIT(1)
+#define ICPU_MEMCTRL_CTRL_INITIALIZE                      BIT(0)
+
+#define ICPU_MEMCTRL_CFG                                  0x238
+
+#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS                BIT(16)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA                  BIT(15)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA                  BIT(14)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA                      BIT(13)
+#define ICPU_MEMCTRL_CFG_DDR_WIDTH                        BIT(12)
+#define ICPU_MEMCTRL_CFG_DDR_MODE                         BIT(11)
+#define ICPU_MEMCTRL_CFG_BURST_SIZE                       BIT(10)
+#define ICPU_MEMCTRL_CFG_BURST_LEN                        BIT(9)
+#define ICPU_MEMCTRL_CFG_BANK_CNT                         BIT(8)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x)                  (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M                   GENMASK(7, 4)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x)                (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x)                  ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M                   GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_STAT                                 0x23C
+
+#define ICPU_MEMCTRL_STAT_RDATA_MASKED                    BIT(5)
+#define ICPU_MEMCTRL_STAT_RDATA_DUMMY                     BIT(4)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR                   BIT(3)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR                   BIT(2)
+#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK                    BIT(1)
+#define ICPU_MEMCTRL_STAT_INIT_DONE                       BIT(0)
+
+#define ICPU_MEMCTRL_REF_PERIOD                           0x240
+
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x)           (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M            GENMASK(19, 16)
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x)         (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x)             ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M              GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING0                              0x248
+
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x)              (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M               GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x)            (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x)          (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M           GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x)          (((x) << 20) & GENMASK(23, 20))
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M           GENMASK(23, 20)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(23, 20)) >> 20)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x)          (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M           GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x)        (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x)           (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M            GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x)         (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x)           (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M            GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x)         (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x)           (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M            GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x)         (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x)           ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M            GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING1                              0x24c
+
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x)  (((x) << 24) & GENMASK(31, 24))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M   GENMASK(31, 24)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x)             (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M              GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x)           (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x)          (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M           GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x)        (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x)            (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M             GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x)          (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x)            (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M             GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x)          (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x)              ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M               GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING2                              0x250
+
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x)             (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M              GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x)           (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x)                 (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M                  GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x)               (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY(x)                   (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_M                    GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x)                 (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(x)       ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY_M        GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING3                              0x254
+
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x)                   (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M                    GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x)                 (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x)                (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M                 GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x)              (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x)                (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M                 GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x)              (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x)          (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M           GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x)        (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x)    ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M     GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_MR0_VAL                              0x258
+
+#define ICPU_MEMCTRL_MR1_VAL                              0x25c
+
+#define ICPU_MEMCTRL_MR2_VAL                              0x260
+
+#define ICPU_MEMCTRL_MR3_VAL                              0x264
+
+#define ICPU_MEMCTRL_TERMRES_CTRL                         0x268
+
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT              BIT(11)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x)           (((x) << 7) & GENMASK(10, 7))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M            GENMASK(10, 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x)         (((x) & GENMASK(10, 7)) >> 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT              BIT(6)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x)           (((x) << 2) & GENMASK(5, 2))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M            GENMASK(5, 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x)         (((x) & GENMASK(5, 2)) >> 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT        BIT(1)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA        BIT(0)
+
+#define ICPU_MEMCTRL_DQS_DLY(x) (0x270)
+
+#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA                 BIT(11)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x)              (((x) << 8) & GENMASK(10, 8))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M               GENMASK(10, 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x)            (((x) & GENMASK(10, 8)) >> 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x)              (((x) << 5) & GENMASK(7, 5))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M               GENMASK(7, 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x)            (((x) & GENMASK(7, 5)) >> 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x)                   ((x) & GENMASK(4, 0))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M                    GENMASK(4, 0)
+
+#define ICPU_MEMPHY_CFG                                   0x278
+
+#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS                     BIT(10)
+#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS                    BIT(9)
+#define ICPU_MEMPHY_CFG_PHY_DQS_EXT                       BIT(8)
+#define ICPU_MEMPHY_CFG_PHY_FIFO_RST                      BIT(7)
+#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST                    BIT(6)
+#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST                    BIT(5)
+#define ICPU_MEMPHY_CFG_PHY_ODT_OE                        BIT(4)
+#define ICPU_MEMPHY_CFG_PHY_CK_OE                         BIT(3)
+#define ICPU_MEMPHY_CFG_PHY_CL_OE                         BIT(2)
+#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA                      BIT(1)
+#define ICPU_MEMPHY_CFG_PHY_RST                           BIT(0)
+#define ICPU_MEMPHY_DQ_DLY_TRM                            0x180
+#define ICPU_MEMPHY_DQ_DLY_TRM_RSZ                        0x4
+
+#define ICPU_MEMPHY_ZCAL                                  0x294
+
+#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL                     BIT(9)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x)                 (((x) << 5) & GENMASK(8, 5))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M                  GENMASK(8, 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x)               (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x)                     (((x) << 1) & GENMASK(4, 1))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M                      GENMASK(4, 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x)                   (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_ENA                         BIT(0)
+
+#endif
diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h
new file mode 100644 (file)
index 0000000..2cb2135
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_H_
+#define _MSCC_OCELOT_H_
+
+#include <linux/bitops.h>
+#include <dm.h>
+
+/*
+ * Target offset base(s)
+ */
+#define MSCC_IO_ORIGIN1_OFFSET 0x70000000
+#define MSCC_IO_ORIGIN1_SIZE   0x00200000
+#define MSCC_IO_ORIGIN2_OFFSET 0x71000000
+#define MSCC_IO_ORIGIN2_SIZE   0x01000000
+#define BASE_CFG        ((void __iomem *)0x70000000)
+#define BASE_DEVCPU_GCB ((void __iomem *)0x71070000)
+
+#endif
diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h
new file mode 100644 (file)
index 0000000..f8aa97b
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_
+#define _MSCC_OCELOT_DEVCPU_GCB_H_
+
+#define PERF_SOFT_RST                                     0x8
+
+#define PERF_SOFT_RST_SOFT_NON_CFG_RST                    BIT(2)
+#define PERF_SOFT_RST_SOFT_SWC_RST                        BIT(1)
+#define PERF_SOFT_RST_SOFT_CHIP_RST                       BIT(0)
+
+#define PERF_GPIO_OUT_SET                                 0x34
+
+#define PERF_GPIO_OUT_CLR                                 0x38
+
+#define PERF_GPIO_OE                                      0x44
+
+#endif
diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h
new file mode 100644 (file)
index 0000000..04cf70b
--- /dev/null
@@ -0,0 +1,274 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_ICPU_CFG_H_
+#define _MSCC_OCELOT_ICPU_CFG_H_
+
+#define ICPU_GPR(x) (0x4 * (x))
+#define ICPU_GPR_RSZ                                      0x4
+
+#define ICPU_RESET                                        0x20
+
+#define ICPU_RESET_CORE_RST_CPU_ONLY                      BIT(3)
+#define ICPU_RESET_CORE_RST_PROTECT                       BIT(2)
+#define ICPU_RESET_CORE_RST_FORCE                         BIT(1)
+#define ICPU_RESET_MEM_RST_FORCE                          BIT(0)
+
+#define ICPU_GENERAL_CTRL                                 0x24
+
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS             BIT(14)
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA              BIT(13)
+#define ICPU_GENERAL_CTRL_CPU_8051_IROM_ENA               BIT(12)
+#define ICPU_GENERAL_CTRL_CPU_MIPS_DIS                    BIT(11)
+#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ADDR_SEL            BIT(10)
+#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ENA                 BIT(9)
+#define ICPU_GENERAL_CTRL_IF_PI_SLV_DONEPOL               BIT(8)
+#define ICPU_GENERAL_CTRL_IF_PI_MST_ENA                   BIT(7)
+#define ICPU_GENERAL_CTRL_IF_PI_SLV_ENA                   BIT(6)
+#define ICPU_GENERAL_CTRL_IF_SI_OWNER(x)                  (((x) << 4) & GENMASK(5, 4))
+#define ICPU_GENERAL_CTRL_IF_SI_OWNER_M                   GENMASK(5, 4)
+#define ICPU_GENERAL_CTRL_IF_SI_OWNER_X(x)                (((x) & GENMASK(5, 4)) >> 4)
+#define ICPU_GENERAL_CTRL_SSI_MST_CONTENTION              BIT(3)
+#define ICPU_GENERAL_CTRL_CPU_BE_ENA                      BIT(2)
+#define ICPU_GENERAL_CTRL_CPU_DIS                         BIT(1)
+#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA                   BIT(0)
+#define ICPU_SPI_MST_CFG                                  0x3c
+
+#define ICPU_SPI_MST_CFG_A32B_ENA                         BIT(11)
+#define ICPU_SPI_MST_CFG_FAST_READ_ENA                    BIT(10)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x)              (((x) << 5) & GENMASK(9, 5))
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M               GENMASK(9, 5)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x)            (((x) & GENMASK(9, 5)) >> 5)
+#define ICPU_SPI_MST_CFG_CLK_DIV(x)                       ((x) & GENMASK(4, 0))
+#define ICPU_SPI_MST_CFG_CLK_DIV_M                        GENMASK(4, 0)
+
+#define ICPU_SW_MODE                                      0x50
+
+#define ICPU_SW_MODE_SW_PIN_CTRL_MODE                     BIT(13)
+#define ICPU_SW_MODE_SW_SPI_SCK                           BIT(12)
+#define ICPU_SW_MODE_SW_SPI_SCK_OE                        BIT(11)
+#define ICPU_SW_MODE_SW_SPI_SDO                           BIT(10)
+#define ICPU_SW_MODE_SW_SPI_SDO_OE                        BIT(9)
+#define ICPU_SW_MODE_SW_SPI_CS(x)                         (((x) << 5) & GENMASK(8, 5))
+#define ICPU_SW_MODE_SW_SPI_CS_M                          GENMASK(8, 5)
+#define ICPU_SW_MODE_SW_SPI_CS_X(x)                       (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_SW_MODE_SW_SPI_CS_OE(x)                      (((x) << 1) & GENMASK(4, 1))
+#define ICPU_SW_MODE_SW_SPI_CS_OE_M                       GENMASK(4, 1)
+#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x)                    (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_SW_MODE_SW_SPI_SDI                           BIT(0)
+
+#define ICPU_INTR_ENA                                    0x88
+
+#define ICPU_DST_INTR_MAP(x)  (0x98 + 0x4 * (x))
+#define ICPU_DST_INTR_MAP_RSZ                             0x4
+
+#define ICPU_DST_INTR_IDENT                               0xa8
+#define ICPU_DST_INTR_IDENT_RSZ                           0x4
+
+#define ICPU_TIMER_TICK_DIV                               0xe8
+#define ICPU_TIMER_VALUE(x) (0xec + 0x4 * (x))
+
+#define ICPU_TIMER_CTRL(x) (0x104 + 0x4 * (x))
+#define ICPU_TIMER_CTRL_MAX_FREQ_ENA                     BIT(3)
+#define ICPU_TIMER_CTRL_ONE_SHOT_ENA                     BIT(2)
+#define ICPU_TIMER_CTRL_TIMER_ENA                        BIT(1)
+#define ICPU_TIMER_CTRL_FORCE_RELOAD                     BIT(0)
+
+#define ICPU_MEMCTRL_CTRL                                 0x110
+#define ICPU_MEMCTRL_CTRL_PWR_DOWN                        BIT(3)
+#define ICPU_MEMCTRL_CTRL_MDSET                           BIT(2)
+#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA                   BIT(1)
+#define ICPU_MEMCTRL_CTRL_INITIALIZE                      BIT(0)
+
+#define ICPU_MEMCTRL_CFG                                  0x114
+
+#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS                BIT(16)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA                  BIT(15)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA                  BIT(14)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA                      BIT(13)
+#define ICPU_MEMCTRL_CFG_DDR_WIDTH                        BIT(12)
+#define ICPU_MEMCTRL_CFG_DDR_MODE                         BIT(11)
+#define ICPU_MEMCTRL_CFG_BURST_SIZE                       BIT(10)
+#define ICPU_MEMCTRL_CFG_BURST_LEN                        BIT(9)
+#define ICPU_MEMCTRL_CFG_BANK_CNT                         BIT(8)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x)                  (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M                   GENMASK(7, 4)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x)                (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x)                  ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M                   GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_STAT                                 0x118
+
+#define ICPU_MEMCTRL_STAT_RDATA_MASKED                    BIT(5)
+#define ICPU_MEMCTRL_STAT_RDATA_DUMMY                     BIT(4)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR                   BIT(3)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR                   BIT(2)
+#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK                    BIT(1)
+#define ICPU_MEMCTRL_STAT_INIT_DONE                       BIT(0)
+
+#define ICPU_MEMCTRL_REF_PERIOD                           0x11c
+
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x)           (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M            GENMASK(19, 16)
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x)         (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x)             ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M              GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING0                              0x124
+
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x)              (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M               GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x)            (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x)          (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M           GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x)          (((x) << 20) & GENMASK(23, 20))
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M           GENMASK(23, 20)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(23, 20)) >> 20)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x)          (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M           GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x)        (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x)           (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M            GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x)         (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x)           (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M            GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x)         (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x)           (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M            GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x)         (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x)           ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M            GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING1                              0x128
+
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x)  (((x) << 24) & GENMASK(31, 24))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M   GENMASK(31, 24)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x)             (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M              GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x)           (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x)          (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M           GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x)        (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x)            (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M             GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x)          (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x)            (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M             GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x)          (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x)              ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M               GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING2                              0x12c
+
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x)             (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M              GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x)           (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x)                 (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M                  GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x)               (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY(x)                   (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_M                    GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x)                 (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING2_INIT_DLY(x)                  ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_TIMING2_INIT_DLY_M                   GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING3                              0x130
+
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x)                   (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M                    GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x)                 (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x)                (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M                 GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x)              (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x)                (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M                 GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x)              (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x)          (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M           GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x)        (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x)    ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M     GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_MR0_VAL                              0x138
+
+#define ICPU_MEMCTRL_MR1_VAL                              0x13c
+
+#define ICPU_MEMCTRL_MR2_VAL                              0x140
+
+#define ICPU_MEMCTRL_MR3_VAL                              0x144
+
+#define ICPU_MEMCTRL_TERMRES_CTRL                         0x148
+
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT              BIT(11)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x)           (((x) << 7) & GENMASK(10, 7))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M            GENMASK(10, 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x)         (((x) & GENMASK(10, 7)) >> 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT              BIT(6)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x)           (((x) << 2) & GENMASK(5, 2))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M            GENMASK(5, 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x)         (((x) & GENMASK(5, 2)) >> 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT        BIT(1)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA        BIT(0)
+
+#define ICPU_MEMCTRL_DQS_DLY(x) (0x150 + 0x4 * (x))
+#define ICPU_MEMCTRL_DQS_DLY_RSZ                          0x4
+
+#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA                 BIT(11)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x)              (((x) << 8) & GENMASK(10, 8))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M               GENMASK(10, 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x)            (((x) & GENMASK(10, 8)) >> 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x)              (((x) << 5) & GENMASK(7, 5))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M               GENMASK(7, 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x)            (((x) & GENMASK(7, 5)) >> 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x)                   ((x) & GENMASK(4, 0))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M                    GENMASK(4, 0)
+
+#define ICPU_MEMPHY_CFG                                   0x160
+
+#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS                     BIT(10)
+#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS                    BIT(9)
+#define ICPU_MEMPHY_CFG_PHY_DQS_EXT                       BIT(8)
+#define ICPU_MEMPHY_CFG_PHY_FIFO_RST                      BIT(7)
+#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST                    BIT(6)
+#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST                    BIT(5)
+#define ICPU_MEMPHY_CFG_PHY_ODT_OE                        BIT(4)
+#define ICPU_MEMPHY_CFG_PHY_CK_OE                         BIT(3)
+#define ICPU_MEMPHY_CFG_PHY_CL_OE                         BIT(2)
+#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA                      BIT(1)
+#define ICPU_MEMPHY_CFG_PHY_RST                           BIT(0)
+
+#define ICPU_MEMPHY_ZCAL                                  0x188
+
+#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL                     BIT(9)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x)                 (((x) << 5) & GENMASK(8, 5))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M                  GENMASK(8, 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x)               (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x)                     (((x) << 1) & GENMASK(4, 1))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M                      GENMASK(4, 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x)                   (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_ENA                         BIT(0)
+
+#define ICPU_MEMPHY_ZCAL_STAT                             0x18c
+
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL(x)               (((x) << 12) & GENMASK(31, 12))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_M                GENMASK(31, 12)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_X(x)             (((x) & GENMASK(31, 12)) >> 12)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU(x)          (((x) << 8) & GENMASK(9, 8))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_M           GENMASK(9, 8)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_X(x)        (((x) & GENMASK(9, 8)) >> 8)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD(x)          (((x) << 6) & GENMASK(7, 6))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_M           GENMASK(7, 6)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_X(x)        (((x) & GENMASK(7, 6)) >> 6)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU(x)             (((x) << 4) & GENMASK(5, 4))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_M              GENMASK(5, 4)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_X(x)           (((x) & GENMASK(5, 4)) >> 4)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD(x)             (((x) << 2) & GENMASK(3, 2))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_M              GENMASK(3, 2)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_X(x)           (((x) & GENMASK(3, 2)) >> 2)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR                    BIT(1)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_DONE                   BIT(0)
+#endif
diff --git a/arch/mips/mach-mscc/include/mach/tlb.h b/arch/mips/mach-mscc/include/mach/tlb.h
new file mode 100644 (file)
index 0000000..fdb554f
--- /dev/null
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_TLB_H
+#define __ASM_MACH_TLB_H
+
+#include <asm/mipsregs.h>
+#include <mach/common.h>
+#include <linux/sizes.h>
+
+#define TLB_HI_MASK      0xffffe000
+#define TLB_LO_MASK      0x3fffffff    /* Masks off Fill bits */
+#define TLB_LO_SHIFT     6     /* PFN Start bit */
+
+#define PAGEMASK_SHIFT   13
+
+#define MMU_PAGE_CACHED   (3 << 3)     /* C(5:3) Cache Coherency Attributes */
+#define MMU_PAGE_UNCACHED (2 << 3)     /* C(5:3) Cache Coherency Attributes */
+#define MMU_PAGE_DIRTY    BIT(2)       /* = Writeable */
+#define MMU_PAGE_VALID    BIT(1)
+#define MMU_PAGE_GLOBAL   BIT(0)
+#define MMU_REGIO_RO_C    (MMU_PAGE_CACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL)
+#define MMU_REGIO_RO      (MMU_PAGE_UNCACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL)
+#define MMU_REGIO_RW      (MMU_PAGE_DIRTY | MMU_REGIO_RO)
+#define MMU_REGIO_INVAL   (MMU_PAGE_GLOBAL)
+
+#define TLB_COUNT_MASK   GENMASK(5, 0)
+#define TLB_COUNT_OFF    25
+
+static inline u32 get_tlb_count(void)
+{
+       register u32 config1;
+
+       config1 = read_c0_config1();
+       config1 >>= TLB_COUNT_OFF;
+       config1 &= TLB_COUNT_MASK;
+
+       return 1 + config1;
+}
+
+static inline void create_tlb(int index, u32 offset, u32 size, u32 tlb_attrib1,
+                             u32 tlb_attrib2)
+{
+       register u32 tlb_mask, tlb_lo0, tlb_lo1;
+
+       tlb_mask = ((size >> 12) - 1) << PAGEMASK_SHIFT;
+       tlb_lo0 = tlb_attrib1 | (offset >> TLB_LO_SHIFT);
+       tlb_lo1 = tlb_attrib2 | ((offset + size) >> TLB_LO_SHIFT);
+
+       write_one_tlb(index, tlb_mask, offset & TLB_HI_MASK,
+                     tlb_lo0 & TLB_LO_MASK, tlb_lo1 & TLB_LO_MASK);
+}
+#endif                         /* __ASM_MACH_TLB_H */
diff --git a/arch/mips/mach-mscc/lowlevel_init.S b/arch/mips/mach-mscc/lowlevel_init.S
new file mode 100644 (file)
index 0000000..dfbe067
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+    .set noreorder
+    .extern     vcoreiii_tlb_init
+#ifdef CONFIG_SOC_LUTON
+    .extern     pll_init
+#endif
+
+LEAF(lowlevel_init)
+       /*
+        * As we have no stack yet, we can assume the restricted
+        * luxury of the sX-registers without saving them
+        */
+       move    s0,ra
+
+       jal     vcoreiii_tlb_init
+        nop
+#ifdef CONFIG_SOC_LUTON
+       jal     pll_init
+        nop
+#endif
+       jr      s0
+        nop
+       END(lowlevel_init)
diff --git a/arch/mips/mach-mscc/lowlevel_init_luton.S b/arch/mips/mach-mscc/lowlevel_init_luton.S
new file mode 100644 (file)
index 0000000..8a528fa
--- /dev/null
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define BASE_MACRO      0x600a0000
+#define REG_OFFSET(t, o) (t + (o*4))
+#define REG_MACRO(x) REG_OFFSET(BASE_MACRO, x)
+#define BIT(nr)                        (1 << (nr))
+
+#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 REG_MACRO(6)
+#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS BIT(0)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 REG_MACRO(2)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 REG_MACRO(0)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV (0x3F << 6)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(x) (x << 6)
+
+    .set noreorder
+LEAF(pll_init)
+       /* Make sure PLL is locked */
+       lw      v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0
+       andi    v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS
+       bne     v1, zero, 1f
+        nop
+
+       /* Black magic from frontend */
+       li      v1, 0x00610400
+       sw      v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+       li      v1, 0x00610c00
+       sw      v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+       li      v1, 0x00610800
+       sw      v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+       li      v1, 0x00610000
+       sw      v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+       /* Wait for lock */
+2:     lw      v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0
+       andi    v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS
+       /* Keep looping if zero (no lock bit yet) */
+       beq     v1, zero, 2b
+        nop
+
+       /* Setup PLL CPU clock divider for 416MHz */
+1:     lw      v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0
+
+       /* Keep reserved bits */
+       li      v1, ~MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV
+       and     v0, v0, v1
+
+       /* Set code 6 ~ 416.66 MHz */
+       ori     v0, v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(6)
+
+       sw      v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0
+       jr      ra
+        nop
+       END(pll_init)
diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c
new file mode 100644 (file)
index 0000000..390bbd0
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+
+#include <asm/reboot.h>
+
+void _machine_restart(void)
+{
+       register u32 resetbits = PERF_SOFT_RST_SOFT_CHIP_RST;
+       (void)readl(BASE_DEVCPU_GCB + PERF_SOFT_RST);
+
+       /* Make sure VCore is NOT protected from reset */
+       clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_CORE_RST_PROTECT);
+
+       /* Change to SPI bitbang for SPI reset workaround... */
+       writel(ICPU_SW_MODE_SW_SPI_CS_OE(1) | ICPU_SW_MODE_SW_SPI_CS(1) |
+              ICPU_SW_MODE_SW_PIN_CTRL_MODE, BASE_CFG + ICPU_SW_MODE);
+
+       /* Do the global reset */
+       writel(resetbits, BASE_DEVCPU_GCB + PERF_SOFT_RST);
+
+       while (1)
+               ; /* NOP */
+}
index 87cc973b756ea712f03d814c6428a4552ff39f4a..9e0ca716f72bc101a00aeffc30a7c472f405f8c4 100644 (file)
@@ -89,9 +89,21 @@ void watchdog_reset(void)
                wdt_reset(watchdog_dev);
        }
 }
+#endif
 
 int arch_misc_init(void)
 {
+       /*
+        * It has been noticed, that sometimes the d-cache is not in a
+        * "clean-state" when U-Boot is running on MT7688. This was
+        * detected when using the ethernet driver (which uses d-cache)
+        * and a TFTP command does not complete. Flushing the complete
+        * d-cache (again?) here seems to fix this issue.
+        */
+       flush_dcache_range(gd->bd->bi_memstart,
+                          gd->bd->bi_memstart + gd->ram_size - 1);
+
+#ifdef CONFIG_WATCHDOG
        /* Init watchdog */
        if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
                debug("Watchdog: Not found by seq!\n");
@@ -103,7 +115,7 @@ int arch_misc_init(void)
 
        wdt_start(watchdog_dev, 60000, 0);      /* 60 seconds */
        printf("Watchdog: Started\n");
+#endif
 
        return 0;
 }
-#endif
index 732a357a99b93682eb71fbbada1e31dff8ba7dda..c45e4d73a8ccbda296fdeff4aa583c42f650e1e8 100644 (file)
@@ -22,6 +22,7 @@ source "board/emulation/qemu-riscv/Kconfig"
 
 # platform-specific options below
 source "arch/riscv/cpu/ax25/Kconfig"
+source "arch/riscv/cpu/qemu/Kconfig"
 
 # architecture-specific options below
 
@@ -44,6 +45,40 @@ config ARCH_RV64I
 
 endchoice
 
+choice
+       prompt "Code Model"
+       default CMODEL_MEDLOW
+
+config CMODEL_MEDLOW
+       bool "medium low code model"
+       help
+         U-Boot and its statically defined symbols must lie within a single 2 GiB
+         address range and must lie between absolute addresses -2 GiB and +2 GiB.
+
+config CMODEL_MEDANY
+       bool "medium any code model"
+       help
+         U-Boot and its statically defined symbols must be within any single 2 GiB
+         address range.
+
+endchoice
+
+choice
+       prompt "Run Mode"
+       default RISCV_MMODE
+
+config RISCV_MMODE
+       bool "Machine"
+       help
+         Choose this option to build U-Boot for RISC-V M-Mode.
+
+config RISCV_SMODE
+       bool "Supervisor"
+       help
+         Choose this option to build U-Boot for RISC-V S-Mode.
+
+endchoice
+
 config RISCV_ISA_C
        bool "Emit compressed instructions"
        default y
@@ -55,15 +90,30 @@ config RISCV_ISA_C
 config RISCV_ISA_A
        def_bool y
 
-config RISCV_SMODE
-       bool "Run in S-Mode"
-       help
-         Enable this option to build U-Boot for RISC-V S-Mode
-
 config 32BIT
        bool
 
 config 64BIT
        bool
 
+config SIFIVE_CLINT
+       bool
+       depends on RISCV_MMODE
+       select REGMAP
+       select SYSCON
+       help
+         The SiFive CLINT block holds memory-mapped control and status registers
+         associated with software and timer interrupts.
+
+config RISCV_RDTIME
+       bool
+       default y if RISCV_SMODE
+       help
+         The provides the riscv_get_time() API that is implemented using the
+         standard rdtime instruction. This is the case for S-mode U-Boot, and
+         is useful for processors that support rdtime in M-mode too.
+
+config SYS_MALLOC_F_LEN
+       default 0x1000
+
 endmenu
index 55d7c6550e98bab450c706ade18feeb4343b40d4..0b80eb8d864582fb67babd325dc793fe164eed68 100644 (file)
@@ -17,8 +17,15 @@ endif
 ifeq ($(CONFIG_RISCV_ISA_C),y)
        ARCH_C = c
 endif
+ifeq ($(CONFIG_CMODEL_MEDLOW),y)
+       CMODEL = medlow
+endif
+ifeq ($(CONFIG_CMODEL_MEDANY),y)
+       CMODEL = medany
+endif
 
-ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI)
+ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) \
+            -mcmodel=$(CMODEL)
 
 PLATFORM_CPPFLAGS      += $(ARCH_FLAGS)
 CFLAGS_EFI             += $(ARCH_FLAGS)
index 2cc6757fcf8db245977ee0dc08debcf8fe30af62..6bf6f911c674e2a2d314a29b32c74993683b5251 100644 (file)
@@ -4,4 +4,4 @@
 
 extra-y = start.o
 
-obj-y += cpu.o
+obj-y += cpu.o mtrap.o
index 6c7022f0f5cf75399ad7b24d65effd8e108f8251..e9dbca2faeadac5cf6a2adbae1762c48d377922c 100644 (file)
@@ -1,7 +1,14 @@
 config RISCV_NDS
-       bool "AndeStar V5 ISA support"
-       default n
+       bool
        help
-               Say Y here if you plan to run U-Boot on AndeStar v5
-               platforms and use some specific features which are
-               provided by Andes Technology AndeStar V5 Families.
+         Run U-Boot on AndeStar V5 platforms and use some specific features
+         which are provided by Andes Technology AndeStar V5 families.
+
+if RISCV_NDS
+
+config RISCV_NDS_CACHE
+       bool "AndeStar V5 families specific cache support"
+       help
+         Provide Andes Technology AndeStar V5 families specific cache support.
+
+endif
index 6600ac2fac138c84c1215a5bfd189cc5b49c3d86..8d6ae170b8c5a02463c14f6a0e7eacc28a40eab4 100644 (file)
@@ -9,7 +9,7 @@
 void icache_enable(void)
 {
 #ifndef CONFIG_SYS_ICACHE_OFF
-#ifdef CONFIG_RISCV_NDS
+#ifdef CONFIG_RISCV_NDS_CACHE
        asm volatile (
                "csrr t1, mcache_ctl\n\t"
                "ori t0, t1, 0x1\n\t"
@@ -22,7 +22,7 @@ void icache_enable(void)
 void icache_disable(void)
 {
 #ifndef CONFIG_SYS_ICACHE_OFF
-#ifdef CONFIG_RISCV_NDS
+#ifdef CONFIG_RISCV_NDS_CACHE
        asm volatile (
                "fence.i\n\t"
                "csrr t1, mcache_ctl\n\t"
@@ -36,7 +36,7 @@ void icache_disable(void)
 void dcache_enable(void)
 {
 #ifndef CONFIG_SYS_DCACHE_OFF
-#ifdef CONFIG_RISCV_NDS
+#ifdef CONFIG_RISCV_NDS_CACHE
        asm volatile (
                "csrr t1, mcache_ctl\n\t"
                "ori t0, t1, 0x2\n\t"
@@ -49,7 +49,7 @@ void dcache_enable(void)
 void dcache_disable(void)
 {
 #ifndef CONFIG_SYS_DCACHE_OFF
-#ifdef CONFIG_RISCV_NDS
+#ifdef CONFIG_RISCV_NDS_CACHE
        asm volatile (
                "fence\n\t"
                "csrr t1, mcache_ctl\n\t"
@@ -64,7 +64,7 @@ int icache_status(void)
 {
        int ret = 0;
 
-#ifdef CONFIG_RISCV_NDS
+#ifdef CONFIG_RISCV_NDS_CACHE
        asm volatile (
                "csrr t1, mcache_ctl\n\t"
                "andi   %0, t1, 0x01\n\t"
@@ -81,7 +81,7 @@ int dcache_status(void)
 {
        int ret = 0;
 
-#ifdef CONFIG_RISCV_NDS
+#ifdef CONFIG_RISCV_NDS_CACHE
        asm volatile (
                "csrr t1, mcache_ctl\n\t"
                "andi   %0, t1, 0x02\n\t"
index d9f820c44c054dba9b6412e7d7a731d508ed6f5e..e662140427a563caaef8c1ffe5c2e710db4811ca 100644 (file)
@@ -4,7 +4,12 @@
  */
 
 #include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <log.h>
 #include <asm/csr.h>
+#include <asm/encoding.h>
+#include <dm/uclass-internal.h>
 
 /*
  * prior_stage_fdt_address must be stored in the data section since it is used
  */
 phys_addr_t prior_stage_fdt_address __attribute__((section(".data")));
 
-enum {
-       ISA_INVALID = 0,
-       ISA_32BIT,
-       ISA_64BIT,
-       ISA_128BIT
-};
-
-static const char * const isa_bits[] = {
-       [ISA_INVALID] = NULL,
-       [ISA_32BIT]   = "32",
-       [ISA_64BIT]   = "64",
-       [ISA_128BIT]  = "128"
-};
-
 static inline bool supports_extension(char ext)
 {
+#ifdef CONFIG_CPU
+       struct udevice *dev;
+       char desc[32];
+
+       uclass_find_first_device(UCLASS_CPU, &dev);
+       if (!dev) {
+               debug("unable to find the RISC-V cpu device\n");
+               return false;
+       }
+       if (!cpu_get_desc(dev, desc, sizeof(desc))) {
+               /* skip the first 4 characters (rv32|rv64) */
+               if (strchr(desc + 4, ext))
+                       return true;
+       }
+
+       return false;
+#else  /* !CONFIG_CPU */
+#ifdef CONFIG_RISCV_MMODE
        return csr_read(misa) & (1 << (ext - 'a'));
+#else  /* !CONFIG_RISCV_MMODE */
+#warning "There is no way to determine the available extensions in S-mode."
+#warning "Please convert your board to use the RISC-V CPU driver."
+       return false;
+#endif /* CONFIG_RISCV_MMODE */
+#endif /* CONFIG_CPU */
+}
+
+static int riscv_cpu_probe(void)
+{
+#ifdef CONFIG_CPU
+       int ret;
+
+       /* probe cpus so that RISC-V timer can be bound */
+       ret = cpu_probe_all();
+       if (ret)
+               return log_msg_ret("RISC-V cpus probe failed\n", ret);
+#endif
+
+       return 0;
 }
 
-int print_cpuinfo(void)
+int arch_cpu_init_dm(void)
 {
-       char name[32];
-       char *s = name;
-       int bit;
+       int ret;
+
+       ret = riscv_cpu_probe();
+       if (ret)
+               return ret;
 
-       s += sprintf(name, "rv");
-       bit = csr_read(misa) >> (sizeof(long) * 8 - 2);
-       s += sprintf(s, isa_bits[bit]);
+       /* Enable FPU */
+       if (supports_extension('d') || supports_extension('f')) {
+               csr_set(MODE_PREFIX(status), MSTATUS_FS);
+               csr_write(fcsr, 0);
+       }
 
-       supports_extension('i') ? *s++ = 'i' : 'r';
-       supports_extension('m') ? *s++ = 'm' : 'i';
-       supports_extension('a') ? *s++ = 'a' : 's';
-       supports_extension('f') ? *s++ = 'f' : 'c';
-       supports_extension('d') ? *s++ = 'd' : '-';
-       supports_extension('c') ? *s++ = 'c' : 'v';
-       *s++ = '\0';
+       if (CONFIG_IS_ENABLED(RISCV_MMODE)) {
+               /*
+                * Enable perf counters for cycle, time,
+                * and instret counters only
+                */
+               csr_write(mcounteren, GENMASK(2, 0));
 
-       printf("CPU:   %s\n", name);
+               /* Disable paging */
+               if (supports_extension('s'))
+                       csr_write(satp, 0);
+       }
 
        return 0;
 }
+
+int arch_early_init_r(void)
+{
+       return riscv_cpu_probe();
+}
diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S
new file mode 100644 (file)
index 0000000..407ecfa
--- /dev/null
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * M-mode Trap Handler Code for RISC-V Core
+ *
+ * Copyright (c) 2017 Microsemi Corporation.
+ * Copyright (c) 2017 Padmarao Begari <Padmarao.Begari@microsemi.com>
+ *
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/encoding.h>
+
+#ifdef CONFIG_32BIT
+#define LREG           lw
+#define SREG           sw
+#define REGBYTES       4
+#else
+#define LREG           ld
+#define SREG           sd
+#define REGBYTES       8
+#endif
+
+       .text
+
+       /* trap entry */
+       .align 2
+       .global trap_entry
+trap_entry:
+       addi sp, sp, -32 * REGBYTES
+       SREG x1,   1 * REGBYTES(sp)
+       SREG x2,   2 * REGBYTES(sp)
+       SREG x3,   3 * REGBYTES(sp)
+       SREG x4,   4 * REGBYTES(sp)
+       SREG x5,   5 * REGBYTES(sp)
+       SREG x6,   6 * REGBYTES(sp)
+       SREG x7,   7 * REGBYTES(sp)
+       SREG x8,   8 * REGBYTES(sp)
+       SREG x9,   9 * REGBYTES(sp)
+       SREG x10, 10 * REGBYTES(sp)
+       SREG x11, 11 * REGBYTES(sp)
+       SREG x12, 12 * REGBYTES(sp)
+       SREG x13, 13 * REGBYTES(sp)
+       SREG x14, 14 * REGBYTES(sp)
+       SREG x15, 15 * REGBYTES(sp)
+       SREG x16, 16 * REGBYTES(sp)
+       SREG x17, 17 * REGBYTES(sp)
+       SREG x18, 18 * REGBYTES(sp)
+       SREG x19, 19 * REGBYTES(sp)
+       SREG x20, 20 * REGBYTES(sp)
+       SREG x21, 21 * REGBYTES(sp)
+       SREG x22, 22 * REGBYTES(sp)
+       SREG x23, 23 * REGBYTES(sp)
+       SREG x24, 24 * REGBYTES(sp)
+       SREG x25, 25 * REGBYTES(sp)
+       SREG x26, 26 * REGBYTES(sp)
+       SREG x27, 27 * REGBYTES(sp)
+       SREG x28, 28 * REGBYTES(sp)
+       SREG x29, 29 * REGBYTES(sp)
+       SREG x30, 30 * REGBYTES(sp)
+       SREG x31, 31 * REGBYTES(sp)
+       csrr a0, MODE_PREFIX(cause)
+       csrr a1, MODE_PREFIX(epc)
+       mv a2, sp
+       jal handle_trap
+       csrw MODE_PREFIX(epc), a0
+
+       LREG x1,   1 * REGBYTES(sp)
+       LREG x3,   3 * REGBYTES(sp)
+       LREG x4,   4 * REGBYTES(sp)
+       LREG x5,   5 * REGBYTES(sp)
+       LREG x6,   6 * REGBYTES(sp)
+       LREG x7,   7 * REGBYTES(sp)
+       LREG x8,   8 * REGBYTES(sp)
+       LREG x9,   9 * REGBYTES(sp)
+       LREG x10, 10 * REGBYTES(sp)
+       LREG x11, 11 * REGBYTES(sp)
+       LREG x12, 12 * REGBYTES(sp)
+       LREG x13, 13 * REGBYTES(sp)
+       LREG x14, 14 * REGBYTES(sp)
+       LREG x15, 15 * REGBYTES(sp)
+       LREG x16, 16 * REGBYTES(sp)
+       LREG x17, 17 * REGBYTES(sp)
+       LREG x18, 18 * REGBYTES(sp)
+       LREG x19, 19 * REGBYTES(sp)
+       LREG x20, 20 * REGBYTES(sp)
+       LREG x21, 21 * REGBYTES(sp)
+       LREG x22, 22 * REGBYTES(sp)
+       LREG x23, 23 * REGBYTES(sp)
+       LREG x24, 24 * REGBYTES(sp)
+       LREG x25, 25 * REGBYTES(sp)
+       LREG x26, 26 * REGBYTES(sp)
+       LREG x27, 27 * REGBYTES(sp)
+       LREG x28, 28 * REGBYTES(sp)
+       LREG x29, 29 * REGBYTES(sp)
+       LREG x30, 30 * REGBYTES(sp)
+       LREG x31, 31 * REGBYTES(sp)
+       LREG x2,   2 * REGBYTES(sp)
+       addi sp, sp, 32 * REGBYTES
+       MODE_PREFIX(ret)
diff --git a/arch/riscv/cpu/qemu/Kconfig b/arch/riscv/cpu/qemu/Kconfig
new file mode 100644 (file)
index 0000000..f48751e
--- /dev/null
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+
+config QEMU_RISCV
+       bool
+       select ARCH_EARLY_INIT_R
+       imply CPU
+       imply CPU_RISCV
+       imply RISCV_TIMER
+       imply SIFIVE_CLINT if RISCV_MMODE
+       imply CMD_CPU
index 25d97d0b416d90f4ee63423a0f3115d6b9c4d85c..ad2950ce40ae7dbad48e2a4821c58b049752c13f 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 
 /*
  * cleanup_before_linux() is called just before we call linux
@@ -19,3 +20,16 @@ int cleanup_before_linux(void)
 
        return 0;
 }
+
+/* To enumerate devices on the /soc/ node, create a "simple-bus" driver */
+static const struct udevice_id riscv_virtio_soc_ids[] = {
+       { .compatible = "riscv-virtio-soc" },
+       { }
+};
+
+U_BOOT_DRIVER(riscv_virtio_soc) = {
+       .name = "riscv_virtio_soc",
+       .id = UCLASS_SIMPLE_BUS,
+       .of_match = riscv_virtio_soc_ids,
+       .flags = DM_FLAG_PRE_RELOC,
+};
index 64246a4e093eb65722f98b8ba783bd9a3a73ccd0..81ea52b170f7f898e56b32c2ace08a602609ecf8 100644 (file)
@@ -14,6 +14,7 @@
 #include <common.h>
 #include <elf.h>
 #include <asm/encoding.h>
+#include <generated/asm-offsets.h>
 
 #ifdef CONFIG_32BIT
 #define LREG                   lw
@@ -70,6 +71,9 @@ call_board_init_f_0:
 
        jal     board_init_f_init_reserve
 
+       /* save the boot hart id to global_data */
+       SREG    s0, GD_BOOT_HART(gp)
+
        mv      a0, zero                /* a0 <-- boot_flags = 0 */
        la      t5, board_init_f
        jr      t5                      /* jump to board_init_f() */
@@ -198,92 +202,3 @@ call_board_init_r:
  * jump to it ...
  */
        jr      t4                      /* jump to board_init_r() */
-
-/*
- * trap entry
- */
-.align 2
-trap_entry:
-       addi    sp, sp, -32*REGBYTES
-       SREG    x1, 1*REGBYTES(sp)
-       SREG    x2, 2*REGBYTES(sp)
-       SREG    x3, 3*REGBYTES(sp)
-       SREG    x4, 4*REGBYTES(sp)
-       SREG    x5, 5*REGBYTES(sp)
-       SREG    x6, 6*REGBYTES(sp)
-       SREG    x7, 7*REGBYTES(sp)
-       SREG    x8, 8*REGBYTES(sp)
-       SREG    x9, 9*REGBYTES(sp)
-       SREG    x10, 10*REGBYTES(sp)
-       SREG    x11, 11*REGBYTES(sp)
-       SREG    x12, 12*REGBYTES(sp)
-       SREG    x13, 13*REGBYTES(sp)
-       SREG    x14, 14*REGBYTES(sp)
-       SREG    x15, 15*REGBYTES(sp)
-       SREG    x16, 16*REGBYTES(sp)
-       SREG    x17, 17*REGBYTES(sp)
-       SREG    x18, 18*REGBYTES(sp)
-       SREG    x19, 19*REGBYTES(sp)
-       SREG    x20, 20*REGBYTES(sp)
-       SREG    x21, 21*REGBYTES(sp)
-       SREG    x22, 22*REGBYTES(sp)
-       SREG    x23, 23*REGBYTES(sp)
-       SREG    x24, 24*REGBYTES(sp)
-       SREG    x25, 25*REGBYTES(sp)
-       SREG    x26, 26*REGBYTES(sp)
-       SREG    x27, 27*REGBYTES(sp)
-       SREG    x28, 28*REGBYTES(sp)
-       SREG    x29, 29*REGBYTES(sp)
-       SREG    x30, 30*REGBYTES(sp)
-       SREG    x31, 31*REGBYTES(sp)
-       csrr    a0, MODE_PREFIX(cause)
-       csrr    a1, MODE_PREFIX(epc)
-       mv      a2, sp
-       jal     handle_trap
-       csrw    MODE_PREFIX(epc), a0
-
-#ifdef CONFIG_RISCV_SMODE
-/*
- * Remain in S-mode after sret
- */
-       li      t0, SSTATUS_SPP
-#else
-/*
- * Remain in M-mode after mret
- */
-       li      t0, MSTATUS_MPP
-#endif
-       csrs    MODE_PREFIX(status), t0
-       LREG    x1, 1*REGBYTES(sp)
-       LREG    x2, 2*REGBYTES(sp)
-       LREG    x3, 3*REGBYTES(sp)
-       LREG    x4, 4*REGBYTES(sp)
-       LREG    x5, 5*REGBYTES(sp)
-       LREG    x6, 6*REGBYTES(sp)
-       LREG    x7, 7*REGBYTES(sp)
-       LREG    x8, 8*REGBYTES(sp)
-       LREG    x9, 9*REGBYTES(sp)
-       LREG    x10, 10*REGBYTES(sp)
-       LREG    x11, 11*REGBYTES(sp)
-       LREG    x12, 12*REGBYTES(sp)
-       LREG    x13, 13*REGBYTES(sp)
-       LREG    x14, 14*REGBYTES(sp)
-       LREG    x15, 15*REGBYTES(sp)
-       LREG    x16, 16*REGBYTES(sp)
-       LREG    x17, 17*REGBYTES(sp)
-       LREG    x18, 18*REGBYTES(sp)
-       LREG    x19, 19*REGBYTES(sp)
-       LREG    x20, 20*REGBYTES(sp)
-       LREG    x21, 21*REGBYTES(sp)
-       LREG    x22, 22*REGBYTES(sp)
-       LREG    x23, 23*REGBYTES(sp)
-       LREG    x24, 24*REGBYTES(sp)
-       LREG    x25, 25*REGBYTES(sp)
-       LREG    x26, 26*REGBYTES(sp)
-       LREG    x27, 27*REGBYTES(sp)
-       LREG    x28, 28*REGBYTES(sp)
-       LREG    x29, 29*REGBYTES(sp)
-       LREG    x30, 30*REGBYTES(sp)
-       LREG    x31, 31*REGBYTES(sp)
-       addi    sp, sp, 32*REGBYTES
-       MODE_PREFIX(ret)
diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts
deleted file mode 100644 (file)
index e48c298..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-/dts-v1/;
-
-/ {
-       #address-cells = <2>;
-       #size-cells = <2>;
-       compatible = "andestech,ax25";
-       model = "andestech,ax25";
-
-       aliases {
-               uart0 = &serial0;
-               spi0 = &spi;
-       };
-
-       chosen {
-               bootargs = "console=ttyS0,38400n8  debug loglevel=7";
-               stdout-path = "uart0:38400n8";
-       };
-
-       cpus {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               timebase-frequency = <60000000>;
-               CPU0: cpu@0 {
-                       device_type = "cpu";
-                       reg = <0>;
-                       status = "okay";
-                       compatible = "riscv";
-                       riscv,isa = "rv64imafdc";
-                       mmu-type = "riscv,sv39";
-                       clock-frequency = <60000000>;
-                       d-cache-size = <0x8000>;
-                       d-cache-line-size = <32>;
-                       CPU0_intc: interrupt-controller {
-                               #interrupt-cells = <1>;
-                               interrupt-controller;
-                               compatible = "riscv,cpu-intc";
-                       };
-               };
-       };
-
-       memory@0 {
-               device_type = "memory";
-               reg = <0x0 0x00000000 0x0 0x40000000>;
-       };
-
-       soc {
-               #address-cells = <2>;
-               #size-cells = <2>;
-               compatible = "andestech,riscv-ae350-soc";
-               ranges;
-
-       plic0: interrupt-controller@e4000000 {
-               compatible = "riscv,plic0";
-               #address-cells = <2>;
-               #interrupt-cells = <2>;
-               interrupt-controller;
-               reg = <0x0 0xe4000000 0x0 0x2000000>;
-               riscv,ndev=<71>;
-               interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
-       };
-
-       plic1: interrupt-controller@e6400000 {
-               compatible = "riscv,plic1";
-               #address-cells = <2>;
-               #interrupt-cells = <2>;
-               interrupt-controller;
-               reg = <0x0 0xe6400000 0x0 0x400000>;
-               riscv,ndev=<1>;
-               interrupts-extended = <&CPU0_intc 3>;
-       };
-
-       plmt0@e6000000 {
-               compatible = "riscv,plmt0";
-                       interrupts-extended = <&CPU0_intc 7>;
-                       reg = <0x0 0xe6000000 0x0 0x100000>;
-               };
-       };
-
-       spiclk: virt_100mhz {
-               #clock-cells = <0>;
-               compatible = "fixed-clock";
-               clock-frequency = <100000000>;
-       };
-
-       timer0: timer@f0400000 {
-               compatible = "andestech,atcpit100";
-               reg = <0x0 0xf0400000 0x0 0x1000>;
-               clock-frequency = <60000000>;
-               interrupts = <3 4>;
-               interrupt-parent = <&plic0>;
-       };
-
-       serial0: serial@f0300000 {
-               compatible = "andestech,uart16550", "ns16550a";
-               reg = <0x0 0xf0300000 0x0 0x1000>;
-               interrupts = <9 4>;
-               clock-frequency = <19660800>;
-               reg-shift = <2>;
-               reg-offset = <32>;
-               no-loopback-test = <1>;
-               interrupt-parent = <&plic0>;
-       };
-
-       mac0: mac@e0100000 {
-               compatible = "andestech,atmac100";
-               reg = <0x0 0xe0100000 0x0 0x1000>;
-               interrupts = <19 4>;
-               interrupt-parent = <&plic0>;
-       };
-
-       mmc0: mmc@f0e00000 {
-               compatible = "andestech,atfsdc010";
-               max-frequency = <100000000>;
-               clock-freq-min-max = <400000 100000000>;
-               fifo-depth = <0x10>;
-               reg = <0x0 0xf0e00000 0x0 0x1000>;
-               interrupts = <18 4>;
-               cap-sd-highspeed;
-               interrupt-parent = <&plic0>;
-       };
-
-       dma0: dma@f0c00000 {
-               compatible = "andestech,atcdmac300";
-               reg = <0x0 0xf0c00000 0x0 0x1000>;
-               interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>;
-               dma-channels = <8>;
-               interrupt-parent = <&plic0>;
-       };
-
-       lcd0: lcd@e0200000 {
-               compatible = "andestech,atflcdc100";
-               reg = <0x0 0xe0200000 0x0 0x1000>;
-               interrupts = <20 4>;
-               interrupt-parent = <&plic0>;
-       };
-
-       smc0: smc@e0400000 {
-               compatible = "andestech,atfsmc020";
-               reg = <0x0 0xe0400000 0x0 0x1000>;
-       };
-
-       snd0: snd@f0d00000 {
-               compatible = "andestech,atfac97";
-               reg = <0x0 0xf0d00000 0x0 0x1000>;
-               interrupts = <17 4>;
-               interrupt-parent = <&plic0>;
-       };
-
-       virtio_mmio@fe007000 {
-               interrupts = <0x17 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe007000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       virtio_mmio@fe006000 {
-               interrupts = <0x16 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe006000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       virtio_mmio@fe005000 {
-               interrupts = <0x15 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe005000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       virtio_mmio@fe004000 {
-               interrupts = <0x14 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe004000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       virtio_mmio@fe003000 {
-               interrupts = <0x13 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe003000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       virtio_mmio@fe002000 {
-               interrupts = <0x12 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe002000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       virtio_mmio@fe001000 {
-               interrupts = <0x11 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe001000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       virtio_mmio@fe000000 {
-               interrupts = <0x10 0x4>;
-               interrupt-parent = <0x2>;
-               reg = <0x0 0xfe000000 0x0 0x1000>;
-               compatible = "virtio,mmio";
-       };
-
-       nor@0,0 {
-               compatible = "cfi-flash";
-               reg = <0x0 0x88000000 0x0 0x1000>;
-               bank-width = <2>;
-               device-width = <1>;
-       };
-
-       spi: spi@f0b00000 {
-               compatible = "andestech,atcspi200";
-               reg = <0x0 0xf0b00000 0x0 0x1000>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-               num-cs = <1>;
-               clocks = <&spiclk>;
-               interrupts = <4 4>;
-               interrupt-parent = <&plic0>;
-               flash@0 {
-                       compatible = "spi-flash";
-                       spi-max-frequency = <50000000>;
-                       reg = <0>;
-                       spi-cpol;
-                       spi-cpha;
-               };
-       };
-};
index 29624fdbb555490791a57d0e3092c5ff51603748..86136f542c7aac89e7221b429a912206d890e8db 100644 (file)
 
 #ifndef __ASSEMBLY__
 
+#define xcsr(csr)      #csr
+
 #define csr_swap(csr, val)                                     \
 ({                                                             \
        unsigned long __v = (unsigned long)(val);               \
-       __asm__ __volatile__ ("csrrw %0, " #csr ", %1"          \
+       __asm__ __volatile__ ("csrrw %0, " xcsr(csr) ", %1"     \
                              : "=r" (__v) : "rK" (__v)         \
                              : "memory");                      \
        __v;                                                    \
@@ -73,7 +75,7 @@
 #define csr_read(csr)                                          \
 ({                                                             \
        register unsigned long __v;                             \
-       __asm__ __volatile__ ("csrr %0, " #csr                  \
+       __asm__ __volatile__ ("csrr %0, " xcsr(csr)             \
                              : "=r" (__v) :                    \
                              : "memory");                      \
        __v;                                                    \
@@ -82,7 +84,7 @@
 #define csr_write(csr, val)                                    \
 ({                                                             \
        unsigned long __v = (unsigned long)(val);               \
-       __asm__ __volatile__ ("csrw " #csr ", %0"               \
+       __asm__ __volatile__ ("csrw " xcsr(csr) ", %0"          \
                              : : "rK" (__v)                    \
                              : "memory");                      \
 })
@@ -90,7 +92,7 @@
 #define csr_read_set(csr, val)                                 \
 ({                                                             \
        unsigned long __v = (unsigned long)(val);               \
-       __asm__ __volatile__ ("csrrs %0, " #csr ", %1"          \
+       __asm__ __volatile__ ("csrrs %0, " xcsr(csr) ", %1"     \
                              : "=r" (__v) : "rK" (__v)         \
                              : "memory");                      \
        __v;                                                    \
 #define csr_set(csr, val)                                      \
 ({                                                             \
        unsigned long __v = (unsigned long)(val);               \
-       __asm__ __volatile__ ("csrs " #csr ", %0"               \
+       __asm__ __volatile__ ("csrs " xcsr(csr) ", %0"          \
                              : : "rK" (__v)                    \
                              : "memory");                      \
 })
 #define csr_read_clear(csr, val)                               \
 ({                                                             \
        unsigned long __v = (unsigned long)(val);               \
-       __asm__ __volatile__ ("csrrc %0, " #csr ", %1"          \
+       __asm__ __volatile__ ("csrrc %0, " xcsr(csr) ", %1"     \
                              : "=r" (__v) : "rK" (__v)         \
                              : "memory");                      \
        __v;                                                    \
 #define csr_clear(csr, val)                                    \
 ({                                                             \
        unsigned long __v = (unsigned long)(val);               \
-       __asm__ __volatile__ ("csrc " #csr ", %0"               \
+       __asm__ __volatile__ ("csrc " xcsr(csr) ", %0"          \
                              : : "rK" (__v)                    \
                              : "memory");                      \
 })
index 97cf906aa63b9ce5e4384a9b4b3e581d6d08d408..772668c74e6a840c3fb7beeaf5c6cfc8f9ea115b 100644 (file)
 #define IRQ_COP                12
 #define IRQ_HOST       13
 
+#define CAUSE_MISALIGNED_FETCH         0
+#define CAUSE_FETCH_ACCESS             1
+#define CAUSE_ILLEGAL_INSTRUCTION      2
+#define CAUSE_BREAKPOINT               3
+#define CAUSE_MISALIGNED_LOAD          4
+#define CAUSE_LOAD_ACCESS              5
+#define CAUSE_MISALIGNED_STORE         6
+#define CAUSE_STORE_ACCESS             7
+#define CAUSE_USER_ECALL               8
+#define CAUSE_SUPERVISOR_ECALL         9
+#define CAUSE_MACHINE_ECALL            11
+#define CAUSE_FETCH_PAGE_FAULT         12
+#define CAUSE_LOAD_PAGE_FAULT          13
+#define CAUSE_STORE_PAGE_FAULT         15
+
 #define DEFAULT_RSTVEC         0x00001000
 #define DEFAULT_NMIVEC         0x00001004
 #define DEFAULT_MTVEC          0x00001010
 #define RISCV_PGSHIFT 12
 #define RISCV_PGSIZE BIT(RISCV_PGSHIFT)
 
+/* CSR numbers */
+#define CSR_FFLAGS             0x1
+#define CSR_FRM                        0x2
+#define CSR_FCSR               0x3
+
+#define CSR_SSTATUS            0x100
+#define CSR_SEDELEG            0x102
+#define CSR_SIDELEG            0x103
+#define CSR_SIE                        0x104
+#define CSR_STVEC              0x105
+#define CSR_SCOUNTEREN         0x106
+#define CSR_SSCRATCH           0x140
+#define CSR_SEPC               0x141
+#define CSR_SCAUSE             0x142
+#define CSR_STVAL              0x143
+#define CSR_SIP                        0x144
+#define CSR_SATP               0x180
+
+#define CSR_MSTATUS            0x300
+#define CSR_MISA               0x301
+#define CSR_MEDELEG            0x302
+#define CSR_MIDELEG            0x303
+#define CSR_MIE                        0x304
+#define CSR_MTVEC              0x305
+#define CSR_MCOUNTEREN         0x306
+#define CSR_MHPMEVENT3         0x323
+#define CSR_MHPMEVENT4         0x324
+#define CSR_MHPMEVENT5         0x325
+#define CSR_MHPMEVENT6         0x326
+#define CSR_MHPMEVENT7         0x327
+#define CSR_MHPMEVENT8         0x328
+#define CSR_MHPMEVENT9         0x329
+#define CSR_MHPMEVENT10                0x32a
+#define CSR_MHPMEVENT11                0x32b
+#define CSR_MHPMEVENT12                0x32c
+#define CSR_MHPMEVENT13                0x32d
+#define CSR_MHPMEVENT14                0x32e
+#define CSR_MHPMEVENT15                0x32f
+#define CSR_MHPMEVENT16                0x330
+#define CSR_MHPMEVENT17                0x331
+#define CSR_MHPMEVENT18                0x332
+#define CSR_MHPMEVENT19                0x333
+#define CSR_MHPMEVENT20                0x334
+#define CSR_MHPMEVENT21                0x335
+#define CSR_MHPMEVENT22                0x336
+#define CSR_MHPMEVENT23                0x337
+#define CSR_MHPMEVENT24                0x338
+#define CSR_MHPMEVENT25                0x339
+#define CSR_MHPMEVENT26                0x33a
+#define CSR_MHPMEVENT27                0x33b
+#define CSR_MHPMEVENT28                0x33c
+#define CSR_MHPMEVENT29                0x33d
+#define CSR_MHPMEVENT30                0x33e
+#define CSR_MHPMEVENT31                0x33f
+#define CSR_MSCRATCH           0x340
+#define CSR_MEPC               0x341
+#define CSR_MCAUSE             0x342
+#define CSR_MTVAL              0x343
+#define CSR_MIP                        0x344
+#define CSR_PMPCFG0            0x3a0
+#define CSR_PMPCFG1            0x3a1
+#define CSR_PMPCFG2            0x3a2
+#define CSR_PMPCFG3            0x3a3
+#define CSR_PMPADDR0           0x3b0
+#define CSR_PMPADDR1           0x3b1
+#define CSR_PMPADDR2           0x3b2
+#define CSR_PMPADDR3           0x3b3
+#define CSR_PMPADDR4           0x3b4
+#define CSR_PMPADDR5           0x3b5
+#define CSR_PMPADDR6           0x3b6
+#define CSR_PMPADDR7           0x3b7
+#define CSR_PMPADDR8           0x3b8
+#define CSR_PMPADDR9           0x3b9
+#define CSR_PMPADDR10          0x3ba
+#define CSR_PMPADDR11          0x3bb
+#define CSR_PMPADDR12          0x3bc
+#define CSR_PMPADDR13          0x3bd
+#define CSR_PMPADDR14          0x3be
+#define CSR_PMPADDR15          0x3bf
+
+#define CSR_TSELECT            0x7a0
+#define CSR_TDATA1             0x7a1
+#define CSR_TDATA2             0x7a2
+#define CSR_TDATA3             0x7a3
+#define CSR_DCSR               0x7b0
+#define CSR_DPC                        0x7b1
+#define CSR_DSCRATCH           0x7b2
+
+#define CSR_MCYCLE             0xb00
+#define CSR_MINSTRET           0xb02
+#define CSR_MHPMCOUNTER3       0xb03
+#define CSR_MHPMCOUNTER4       0xb04
+#define CSR_MHPMCOUNTER5       0xb05
+#define CSR_MHPMCOUNTER6       0xb06
+#define CSR_MHPMCOUNTER7       0xb07
+#define CSR_MHPMCOUNTER8       0xb08
+#define CSR_MHPMCOUNTER9       0xb09
+#define CSR_MHPMCOUNTER10      0xb0a
+#define CSR_MHPMCOUNTER11      0xb0b
+#define CSR_MHPMCOUNTER12      0xb0c
+#define CSR_MHPMCOUNTER13      0xb0d
+#define CSR_MHPMCOUNTER14      0xb0e
+#define CSR_MHPMCOUNTER15      0xb0f
+#define CSR_MHPMCOUNTER16      0xb10
+#define CSR_MHPMCOUNTER17      0xb11
+#define CSR_MHPMCOUNTER18      0xb12
+#define CSR_MHPMCOUNTER19      0xb13
+#define CSR_MHPMCOUNTER20      0xb14
+#define CSR_MHPMCOUNTER21      0xb15
+#define CSR_MHPMCOUNTER22      0xb16
+#define CSR_MHPMCOUNTER23      0xb17
+#define CSR_MHPMCOUNTER24      0xb18
+#define CSR_MHPMCOUNTER25      0xb19
+#define CSR_MHPMCOUNTER26      0xb1a
+#define CSR_MHPMCOUNTER27      0xb1b
+#define CSR_MHPMCOUNTER28      0xb1c
+#define CSR_MHPMCOUNTER29      0xb1d
+#define CSR_MHPMCOUNTER30      0xb1e
+#define CSR_MHPMCOUNTER31      0xb1f
+#define CSR_MCYCLEH            0xb80
+#define CSR_MINSTRETH          0xb82
+#define CSR_MHPMCOUNTER3H      0xb83
+#define CSR_MHPMCOUNTER4H      0xb84
+#define CSR_MHPMCOUNTER5H      0xb85
+#define CSR_MHPMCOUNTER6H      0xb86
+#define CSR_MHPMCOUNTER7H      0xb87
+#define CSR_MHPMCOUNTER8H      0xb88
+#define CSR_MHPMCOUNTER9H      0xb89
+#define CSR_MHPMCOUNTER10H     0xb8a
+#define CSR_MHPMCOUNTER11H     0xb8b
+#define CSR_MHPMCOUNTER12H     0xb8c
+#define CSR_MHPMCOUNTER13H     0xb8d
+#define CSR_MHPMCOUNTER14H     0xb8e
+#define CSR_MHPMCOUNTER15H     0xb8f
+#define CSR_MHPMCOUNTER16H     0xb90
+#define CSR_MHPMCOUNTER17H     0xb91
+#define CSR_MHPMCOUNTER18H     0xb92
+#define CSR_MHPMCOUNTER19H     0xb93
+#define CSR_MHPMCOUNTER20H     0xb94
+#define CSR_MHPMCOUNTER21H     0xb95
+#define CSR_MHPMCOUNTER22H     0xb96
+#define CSR_MHPMCOUNTER23H     0xb97
+#define CSR_MHPMCOUNTER24H     0xb98
+#define CSR_MHPMCOUNTER25H     0xb99
+#define CSR_MHPMCOUNTER26H     0xb9a
+#define CSR_MHPMCOUNTER27H     0xb9b
+#define CSR_MHPMCOUNTER28H     0xb9c
+#define CSR_MHPMCOUNTER29H     0xb9d
+#define CSR_MHPMCOUNTER30H     0xb9e
+#define CSR_MHPMCOUNTER31H     0xb9f
+
+#define CSR_CYCLE              0xc00
+#define CSR_TIME               0xc01
+#define CSR_INSTRET            0xc02
+#define CSR_HPMCOUNTER3                0xc03
+#define CSR_HPMCOUNTER4                0xc04
+#define CSR_HPMCOUNTER5                0xc05
+#define CSR_HPMCOUNTER6                0xc06
+#define CSR_HPMCOUNTER7                0xc07
+#define CSR_HPMCOUNTER8                0xc08
+#define CSR_HPMCOUNTER9                0xc09
+#define CSR_HPMCOUNTER10       0xc0a
+#define CSR_HPMCOUNTER11       0xc0b
+#define CSR_HPMCOUNTER12       0xc0c
+#define CSR_HPMCOUNTER13       0xc0d
+#define CSR_HPMCOUNTER14       0xc0e
+#define CSR_HPMCOUNTER15       0xc0f
+#define CSR_HPMCOUNTER16       0xc10
+#define CSR_HPMCOUNTER17       0xc11
+#define CSR_HPMCOUNTER18       0xc12
+#define CSR_HPMCOUNTER19       0xc13
+#define CSR_HPMCOUNTER20       0xc14
+#define CSR_HPMCOUNTER21       0xc15
+#define CSR_HPMCOUNTER22       0xc16
+#define CSR_HPMCOUNTER23       0xc17
+#define CSR_HPMCOUNTER24       0xc18
+#define CSR_HPMCOUNTER25       0xc19
+#define CSR_HPMCOUNTER26       0xc1a
+#define CSR_HPMCOUNTER27       0xc1b
+#define CSR_HPMCOUNTER28       0xc1c
+#define CSR_HPMCOUNTER29       0xc1d
+#define CSR_HPMCOUNTER30       0xc1e
+#define CSR_HPMCOUNTER31       0xc1f
+#define CSR_CYCLEH             0xc80
+#define CSR_TIMEH              0xc81
+#define CSR_INSTRETH           0xc82
+#define CSR_HPMCOUNTER3H       0xc83
+#define CSR_HPMCOUNTER4H       0xc84
+#define CSR_HPMCOUNTER5H       0xc85
+#define CSR_HPMCOUNTER6H       0xc86
+#define CSR_HPMCOUNTER7H       0xc87
+#define CSR_HPMCOUNTER8H       0xc88
+#define CSR_HPMCOUNTER9H       0xc89
+#define CSR_HPMCOUNTER10H      0xc8a
+#define CSR_HPMCOUNTER11H      0xc8b
+#define CSR_HPMCOUNTER12H      0xc8c
+#define CSR_HPMCOUNTER13H      0xc8d
+#define CSR_HPMCOUNTER14H      0xc8e
+#define CSR_HPMCOUNTER15H      0xc8f
+#define CSR_HPMCOUNTER16H      0xc90
+#define CSR_HPMCOUNTER17H      0xc91
+#define CSR_HPMCOUNTER18H      0xc92
+#define CSR_HPMCOUNTER19H      0xc93
+#define CSR_HPMCOUNTER20H      0xc94
+#define CSR_HPMCOUNTER21H      0xc95
+#define CSR_HPMCOUNTER22H      0xc96
+#define CSR_HPMCOUNTER23H      0xc97
+#define CSR_HPMCOUNTER24H      0xc98
+#define CSR_HPMCOUNTER25H      0xc99
+#define CSR_HPMCOUNTER26H      0xc9a
+#define CSR_HPMCOUNTER27H      0xc9b
+#define CSR_HPMCOUNTER28H      0xc9c
+#define CSR_HPMCOUNTER29H      0xc9d
+#define CSR_HPMCOUNTER30H      0xc9e
+#define CSR_HPMCOUNTER31H      0xc9f
+
+#define CSR_MVENDORID          0xf11
+#define CSR_MARCHID            0xf12
+#define CSR_MIMPID             0xf13
+#define CSR_MHARTID            0xf14
+
 #endif /* __riscv */
 
 #endif /* RISCV_CSR_ENCODING_H */
index 4d5d623725e9337e4c63806563b1e3fe7adae5b5..a3a342c6e1cbe106ad78137b781537a061c1770d 100644 (file)
 
 /* Architecture-specific global data */
 struct arch_global_data {
+       long boot_hart;         /* boot hart id */
+#ifdef CONFIG_SIFIVE_CLINT
+       void __iomem *clint;    /* clint base address */
+#endif
 };
 
 #include <asm-generic/global_data.h>
diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h
new file mode 100644 (file)
index 0000000..d311ee6
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#ifndef _ASM_SYSCON_H
+#define _ASM_SYSCON_H
+
+/*
+ * System controllers in a RISC-V system
+ *
+ * So far only SiFive's Core Local Interruptor (CLINT) is defined.
+ */
+enum {
+       RISCV_NONE,
+       RISCV_SYSCON_CLINT,     /* Core Local Interruptor (CLINT) */
+};
+
+#endif /* _ASM_SYSCON_H */
index b58db89752219b0c197981821db247cf160ce8c4..edfa61690c7db86c8dac8d4bfca08d48097ef5d0 100644 (file)
@@ -9,6 +9,8 @@
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_GO) += boot.o
 obj-y  += cache.o
+obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
+obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
 obj-y  += interrupts.o
 obj-y  += reset.o
 obj-y   += setjmp.o
diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
new file mode 100644 (file)
index 0000000..e0b71f5
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * From arch/x86/lib/asm-offsets.c
+ *
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ */
+
+#include <common.h>
+#include <linux/kbuild.h>
+
+int main(void)
+{
+       DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
+
+       return 0;
+}
index 124aeefff83cf29acad2f001fab02a0dc222ac1c..60b32cca818acce8fd5624c496028893b62055fc 100644 (file)
@@ -93,7 +93,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 
        if (!fake) {
                if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
-                       kernel(csr_read(mhartid), images->ft_addr);
+                       kernel(gd->arch.boot_hart, images->ft_addr);
        }
 }
 
index 3aff00697732fe5a1950d53d9a9c42f3be4ae722..e185933b01ef04cde12988058d137dda9bd363cd 100644 (file)
 #include <asm/system.h>
 #include <asm/encoding.h>
 
-static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs);
+static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
+{
+       static const char * const exception_code[] = {
+               "Instruction address misaligned",
+               "Instruction access fault",
+               "Illegal instruction",
+               "Breakpoint",
+               "Load address misaligned",
+               "Load access fault",
+               "Store/AMO address misaligned",
+               "Store/AMO access fault",
+               "Environment call from U-mode",
+               "Environment call from S-mode",
+               "Reserved",
+               "Environment call from M-mode",
+               "Instruction page fault",
+               "Load page fault",
+               "Reserved",
+               "Store/AMO page fault",
+       };
+
+       if (code < ARRAY_SIZE(exception_code)) {
+               printf("exception code: %ld , %s , epc %lx , ra %lx\n",
+                      code, exception_code[code], epc, regs->ra);
+       } else {
+               printf("Reserved\n");
+       }
+
+       hang();
+}
 
 int interrupt_init(void)
 {
@@ -72,34 +101,3 @@ __attribute__((weak)) void external_interrupt(struct pt_regs *regs)
 __attribute__((weak)) void timer_interrupt(struct pt_regs *regs)
 {
 }
-
-static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
-{
-       static const char * const exception_code[] = {
-               "Instruction address misaligned",
-               "Instruction access fault",
-               "Illegal instruction",
-               "Breakpoint",
-               "Load address misaligned",
-               "Load access fault",
-               "Store/AMO address misaligned",
-               "Store/AMO access fault",
-               "Environment call from U-mode",
-               "Environment call from S-mode",
-               "Reserved",
-               "Environment call from M-mode",
-               "Instruction page fault",
-               "Load page fault",
-               "Reserved",
-               "Store/AMO page fault",
-       };
-
-       if (code < ARRAY_SIZE(exception_code)) {
-               printf("exception code: %ld , %s , epc %lx , ra %lx\n",
-                      code, exception_code[code], epc, regs->ra);
-       } else {
-               printf("Reserved\n");
-       }
-
-       hang();
-}
diff --git a/arch/riscv/lib/rdtime.c b/arch/riscv/lib/rdtime.c
new file mode 100644 (file)
index 0000000..e128d7f
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Anup Patel <anup@brainfault.org>
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * The riscv_get_time() API implementation that is using the
+ * standard rdtime instruction.
+ */
+
+#include <common.h>
+
+/* Implement the API required by RISC-V timer driver */
+int riscv_get_time(u64 *time)
+{
+#ifdef CONFIG_64BIT
+       u64 n;
+
+       __asm__ __volatile__ (
+               "rdtime %0"
+               : "=r" (n));
+
+       *time = n;
+#else
+       u32 lo, hi, tmp;
+
+       __asm__ __volatile__ (
+               "1:\n"
+               "rdtimeh %0\n"
+               "rdtime %1\n"
+               "rdtimeh %2\n"
+               "bne %0, %2, 1b"
+               : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
+
+       *time = ((u64)hi << 32) | lo;
+#endif
+
+       return 0;
+}
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
new file mode 100644 (file)
index 0000000..d24e0d5
--- /dev/null
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * U-Boot syscon driver for SiFive's Core Local Interruptor (CLINT).
+ * The CLINT block holds memory-mapped control and status registers
+ * associated with software and timer interrupts.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/syscon.h>
+
+/* MSIP registers */
+#define MSIP_REG(base, hart)           ((ulong)(base) + (hart) * 4)
+/* mtime compare register */
+#define MTIMECMP_REG(base, hart)       ((ulong)(base) + 0x4000 + (hart) * 8)
+/* mtime register */
+#define MTIME_REG(base)                        ((ulong)(base) + 0xbff8)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CLINT_BASE_GET(void)                                           \
+       do {                                                            \
+               long *ret;                                              \
+                                                                       \
+               if (!gd->arch.clint) {                                  \
+                       ret = syscon_get_first_range(RISCV_SYSCON_CLINT); \
+                       if (IS_ERR(ret))                                \
+                               return PTR_ERR(ret);                    \
+                       gd->arch.clint = ret;                           \
+               }                                                       \
+       } while (0)
+
+int riscv_get_time(u64 *time)
+{
+       CLINT_BASE_GET();
+
+       *time = readq((void __iomem *)MTIME_REG(gd->arch.clint));
+
+       return 0;
+}
+
+int riscv_set_timecmp(int hart, u64 cmp)
+{
+       CLINT_BASE_GET();
+
+       writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart));
+
+       return 0;
+}
+
+int riscv_send_ipi(int hart)
+{
+       CLINT_BASE_GET();
+
+       writel(1, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
+
+       return 0;
+}
+
+int riscv_clear_ipi(int hart)
+{
+       CLINT_BASE_GET();
+
+       writel(0, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
+
+       return 0;
+}
+
+static const struct udevice_id sifive_clint_ids[] = {
+       { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT },
+       { }
+};
+
+U_BOOT_DRIVER(sifive_clint) = {
+       .name           = "sifive_clint",
+       .id             = UCLASS_SYSCON,
+       .of_match       = sifive_clint_ids,
+       .flags          = DM_FLAG_PRE_RELOC,
+};
index bb69ea348926315aef49305e3041afede311429f..44cb302f708cd15d3c6b0e8e45334f411de53fec 100644 (file)
@@ -21,4 +21,8 @@ config ENV_SIZE
 config ENV_OFFSET
        default 0x140000 if ENV_IS_IN_SPI_FLASH
 
+config BOARD_SPECIFIC_OPTIONS # dummy
+       def_bool y
+       select RISCV_NDS
+
 endif
index d87446ee1c366c4a72a324504e5ac08c7d2e9ac1..b0a99e4ac4005f5814023ad3d6a28ce7c2259231 100644 (file)
@@ -3,6 +3,5 @@ M:      Rick Chen <rick@andestech.com>
 S:     Maintained
 F:     board/AndesTech/ax25-ae350/
 F:     include/configs/ax25-ae350.h
-F:     configs/a25-ae350_32_defconfig
-F:     configs/ax25-ae350_64_defconfig
-F:     configs/ax25-ae350_defconfig
+F:     configs/ae350_rv32_defconfig
+F:     configs/ae350_rv64_defconfig
index 56bb5337d4c8130bd2d22951776404791d467d3b..0d865acf100704f87b6245c54d5f02a8cf98add0 100644 (file)
@@ -18,6 +18,7 @@ config SYS_TEXT_BASE
 
 config BOARD_SPECIFIC_OPTIONS # dummy
        def_bool y
+       select QEMU_RISCV
        imply SYS_NS16550
        imply VIRTIO_MMIO
        imply VIRTIO_NET
@@ -32,5 +33,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
        imply CMD_FAT
        imply BOARD_LATE_INIT
        imply OF_BOARD_SETUP
+       imply SIFIVE_SERIAL
 
 endif
diff --git a/board/imgtec/ci20/Kconfig b/board/imgtec/ci20/Kconfig
new file mode 100644 (file)
index 0000000..82bf65d
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_JZ4780_CI20
+
+config SYS_BOARD
+       default "ci20"
+
+config SYS_VENDOR
+       default "imgtec"
+
+config SYS_CONFIG_NAME
+       default "ci20"
+
+config SYS_TEXT_BASE
+       default 0x80000000
+
+endif
diff --git a/board/imgtec/ci20/MAINTAINERS b/board/imgtec/ci20/MAINTAINERS
new file mode 100644 (file)
index 0000000..dca6bf3
--- /dev/null
@@ -0,0 +1,6 @@
+Creator CI20 BOARD
+M:      Ezequiel Garcia <ezequiel@collabora.com>
+S:      Maintained
+F:      board/imgtec/ci20/
+F:      include/configs/ci20.h
+F:      configs/ci20_mmc_defconfig
diff --git a/board/imgtec/ci20/Makefile b/board/imgtec/ci20/Makefile
new file mode 100644 (file)
index 0000000..7843b46
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y := ci20.o
diff --git a/board/imgtec/ci20/README b/board/imgtec/ci20/README
new file mode 100644 (file)
index 0000000..07d89d7
--- /dev/null
@@ -0,0 +1,10 @@
+CI20 U-Boot
+
+Installation to an SD card:
+  Repartition your card with an MBR such that the first partition starts at an
+  offset of no less than 270KB. Then install U-Boot SPL & the full U-Boot image
+  to the card like so:
+
+    dd if=spl/u-boot-spl.bin of=/dev/sdX obs=512 seek=1
+    dd if=u-boot-dtb.img of=/dev/sdX obs=1K seek=14
+    sync
diff --git a/board/imgtec/ci20/ci20.c b/board/imgtec/ci20/ci20.c
new file mode 100644 (file)
index 0000000..9811ef5
--- /dev/null
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CI20 setup code
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <common.h>
+#include <environment.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+#include <mach/jz4780_gpio.h>
+
+struct ci20_otp {
+       u32     serial_number;
+       u32     date;
+       u8      manufacturer[2];
+       u8      mac[6];
+} __packed;
+
+static void ci20_mux_mmc(void)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+       /* setup MSC1 pins */
+       writel(0x30f00000, gpio_regs + GPIO_PXINTC(4));
+       writel(0x30f00000, gpio_regs + GPIO_PXMASKC(4));
+       writel(0x30f00000, gpio_regs + GPIO_PXPAT1C(4));
+       writel(0x30f00000, gpio_regs + GPIO_PXPAT0C(4));
+       writel(0x30f00000, gpio_regs + GPIO_PXPENC(4));
+       jz4780_clk_ungate_mmc();
+}
+
+#ifndef CONFIG_SPL_BUILD
+
+static void ci20_mux_eth(void)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+#ifdef CONFIG_NAND
+       /* setup pins (some already setup for NAND) */
+       writel(0x04030000, gpio_regs + GPIO_PXINTC(0));
+       writel(0x04030000, gpio_regs + GPIO_PXMASKC(0));
+       writel(0x04030000, gpio_regs + GPIO_PXPAT1C(0));
+       writel(0x04030000, gpio_regs + GPIO_PXPAT0C(0));
+       writel(0x04030000, gpio_regs + GPIO_PXPENS(0));
+#else
+       /* setup pins (as above +NAND CS +RD/WE +SDx +SAx) */
+       writel(0x0dff00ff, gpio_regs + GPIO_PXINTC(0));
+       writel(0x0dff00ff, gpio_regs + GPIO_PXMASKC(0));
+       writel(0x0dff00ff, gpio_regs + GPIO_PXPAT1C(0));
+       writel(0x0dff00ff, gpio_regs + GPIO_PXPAT0C(0));
+       writel(0x0dff00ff, gpio_regs + GPIO_PXPENS(0));
+       writel(0x00000003, gpio_regs + GPIO_PXINTC(1));
+       writel(0x00000003, gpio_regs + GPIO_PXMASKC(1));
+       writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1));
+       writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1));
+       writel(0x00000003, gpio_regs + GPIO_PXPENS(1));
+#endif
+}
+
+static void ci20_mux_jtag(void)
+{
+#ifdef CONFIG_JTAG
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+       /* enable JTAG */
+       writel(3 << 30, gpio_regs + GPIO_PXINTC(0));
+       writel(3 << 30, gpio_regs + GPIO_PXMASKC(0));
+       writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0));
+       writel(3 << 30, gpio_regs + GPIO_PXPAT0C(0));
+#endif
+}
+
+static void ci20_mux_nand(void)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+       /* setup pins */
+       writel(0x002c00ff, gpio_regs + GPIO_PXINTC(0));
+       writel(0x002c00ff, gpio_regs + GPIO_PXMASKC(0));
+       writel(0x002c00ff, gpio_regs + GPIO_PXPAT1C(0));
+       writel(0x002c00ff, gpio_regs + GPIO_PXPAT0C(0));
+       writel(0x002c00ff, gpio_regs + GPIO_PXPENS(0));
+       writel(0x00000003, gpio_regs + GPIO_PXINTC(1));
+       writel(0x00000003, gpio_regs + GPIO_PXMASKC(1));
+       writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1));
+       writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1));
+       writel(0x00000003, gpio_regs + GPIO_PXPENS(1));
+
+       /* FRB0_N */
+       jz47xx_gpio_direction_input(JZ_GPIO(0, 20));
+       writel(20, gpio_regs + GPIO_PXPENS(0));
+
+       /* disable write protect */
+       jz47xx_gpio_direction_output(JZ_GPIO(5, 22), 1);
+}
+
+static void ci20_mux_uart(void)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+       /* UART0 */
+       writel(0x9, gpio_regs + GPIO_PXINTC(5));
+       writel(0x9, gpio_regs + GPIO_PXMASKC(5));
+       writel(0x9, gpio_regs + GPIO_PXPAT1C(5));
+       writel(0x9, gpio_regs + GPIO_PXPAT0C(5));
+       writel(0x9, gpio_regs + GPIO_PXPENC(5));
+       jz4780_clk_ungate_uart(0);
+
+       /* UART 1 and 2 */
+       jz4780_clk_ungate_uart(1);
+       jz4780_clk_ungate_uart(2);
+
+#ifndef CONFIG_JTAG
+       /* UART3 */
+       writel(1 << 12, gpio_regs + GPIO_PXINTC(3));
+       writel(1 << 12, gpio_regs + GPIO_PXMASKS(3));
+       writel(1 << 12, gpio_regs + GPIO_PXPAT1S(3));
+       writel(1 << 12, gpio_regs + GPIO_PXPAT0C(3));
+       writel(3 << 30, gpio_regs + GPIO_PXINTC(0));
+       writel(3 << 30, gpio_regs + GPIO_PXMASKC(0));
+       writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0));
+       writel(1 << 30, gpio_regs + GPIO_PXPAT0C(0));
+       writel(1 << 31, gpio_regs + GPIO_PXPAT0S(0));
+       jz4780_clk_ungate_uart(3);
+#endif
+
+       /* UART4 */
+       writel(0x100400, gpio_regs + GPIO_PXINTC(2));
+       writel(0x100400, gpio_regs + GPIO_PXMASKC(2));
+       writel(0x100400, gpio_regs + GPIO_PXPAT1S(2));
+       writel(0x100400, gpio_regs + GPIO_PXPAT0C(2));
+       writel(0x100400, gpio_regs + GPIO_PXPENC(2));
+       jz4780_clk_ungate_uart(4);
+}
+
+int board_early_init_f(void)
+{
+       ci20_mux_jtag();
+       ci20_mux_uart();
+
+       ci20_mux_eth();
+       ci20_mux_mmc();
+       ci20_mux_nand();
+
+       /* SYS_POWER_IND high (LED blue, VBUS off) */
+       jz47xx_gpio_direction_output(JZ_GPIO(5, 15), 0);
+
+       /* LEDs off */
+       jz47xx_gpio_direction_output(JZ_GPIO(2, 0), 0);
+       jz47xx_gpio_direction_output(JZ_GPIO(2, 1), 0);
+       jz47xx_gpio_direction_output(JZ_GPIO(2, 2), 0);
+       jz47xx_gpio_direction_output(JZ_GPIO(2, 3), 0);
+
+       return 0;
+}
+
+int misc_init_r(void)
+{
+       const u32 efuse_clk = jz4780_clk_get_efuse_clk();
+       struct ci20_otp otp;
+       char manufacturer[3];
+
+       /* Read the board OTP data */
+       jz4780_efuse_init(efuse_clk);
+       jz4780_efuse_read(0x18, 16, (u8 *)&otp);
+
+       /* Set MAC address */
+       if (!is_valid_ethaddr(otp.mac)) {
+               /* no MAC assigned, generate one from the unique chip ID */
+               jz4780_efuse_read(0x8, 4, &otp.mac[0]);
+               jz4780_efuse_read(0x12, 2, &otp.mac[4]);
+               otp.mac[0] = (otp.mac[0] | 0x02) & ~0x01;
+       }
+       eth_env_set_enetaddr("ethaddr", otp.mac);
+
+       /* Put other board information into the environment */
+       env_set_ulong("serial#", otp.serial_number);
+       env_set_ulong("board_date", otp.date);
+       manufacturer[0] = otp.manufacturer[0];
+       manufacturer[1] = otp.manufacturer[1];
+       manufacturer[2] = 0;
+       env_set("board_mfr", manufacturer);
+
+       return 0;
+}
+
+#ifdef CONFIG_DRIVER_DM9000
+int board_eth_init(bd_t *bis)
+{
+       /* Enable clock */
+       jz4780_clk_ungate_ethernet();
+
+       /* Enable power (PB25) */
+       jz47xx_gpio_direction_output(JZ_GPIO(1, 25), 1);
+
+       /* Reset (PF12) */
+       mdelay(10);
+       jz47xx_gpio_direction_output(JZ_GPIO(5, 12), 0);
+       mdelay(10);
+       jz47xx_gpio_direction_output(JZ_GPIO(5, 12), 1);
+       mdelay(10);
+
+       return dm9000_initialize(bis);
+}
+#endif /* CONFIG_DRIVER_DM9000 */
+#endif
+
+static u8 ci20_revision(void)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+       int val;
+
+       jz47xx_gpio_direction_input(JZ_GPIO(2, 18));
+       jz47xx_gpio_direction_input(JZ_GPIO(2, 19));
+
+       /* Enable pullups */
+       writel(BIT(18) | BIT(19), gpio_regs + GPIO_PXPENC(2));
+
+       /* Read PC18/19 for version */
+       val = (!!jz47xx_gpio_get_value(JZ_GPIO(2, 18))) |
+            ((!!jz47xx_gpio_get_value(JZ_GPIO(2, 19))) << 1);
+
+       if (val == 3)   /* Rev 1 boards had no pulldowns - giving 3 */
+               return 1;
+       if (val == 1)   /* Rev 2 boards pulldown port C bit 18 giving 1 */
+               return 2;
+
+       return 0;
+}
+
+int dram_init(void)
+{
+       gd->ram_size = sdram_size(0) + sdram_size(1);
+       return 0;
+}
+
+/* U-Boot common routines */
+int checkboard(void)
+{
+       printf("Board: Creator CI20 (rev.%d)\n", ci20_revision());
+       return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+int board_mmc_init(bd_t *bd)
+{
+       ci20_mux_mmc();
+       return jz_mmc_init((void __iomem *)MSC0_BASE);
+}
+#endif
+
+static const struct jz4780_ddr_config K4B2G0846Q_48_config = {
+       .timing = {
+               (4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) |
+               (6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT),
+
+               (4 << DDRC_TIMING2_TCCD_BIT) | (15 << DDRC_TIMING2_TRAS_BIT) |
+               (6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT),
+
+               (4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) |
+               (6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) |
+               (21 << DDRC_TIMING3_TRC_BIT),
+
+               (31 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) |
+               (4 << DDRC_TIMING4_TCKE_BIT) | (9 << DDRC_TIMING4_TMINSR_BIT) |
+               (8 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT),
+
+               (8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) |
+               (4 << DDRC_TIMING5_TWDLAT_BIT),
+
+               (25 << DDRC_TIMING6_TXSRD_BIT) | (12 << DDRC_TIMING6_TFAW_BIT) |
+               (2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT),
+       },
+
+       /* PHY */
+       /* Mode Register 0 */
+       .mr0 = 0x420,
+#ifdef SDRAM_DISABLE_DLL
+       .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE),
+#else
+       .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS),
+#endif
+
+       .ptr0 = 0x002000d4,
+       .ptr1 = 0x02230d40,
+       .ptr2 = 0x04013880,
+
+       .dtpr0 = 0x2a8f6690,
+       .dtpr1 = 0x00400860,
+       .dtpr2 = 0x10042a00,
+
+       .pullup = 0x0b,
+       .pulldn = 0x0b,
+};
+
+static const struct jz4780_ddr_config H5TQ2G83CFR_48_config = {
+       .timing = {
+               (4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) |
+               (6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT),
+
+               (4 << DDRC_TIMING2_TCCD_BIT) | (16 << DDRC_TIMING2_TRAS_BIT) |
+               (6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT),
+
+               (4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) |
+               (6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) |
+               (22 << DDRC_TIMING3_TRC_BIT),
+
+               (42 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) |
+               (4 << DDRC_TIMING4_TCKE_BIT) | (7 << DDRC_TIMING4_TMINSR_BIT) |
+               (3 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT),
+
+               (8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) |
+               (4 << DDRC_TIMING5_TWDLAT_BIT),
+
+               (25 << DDRC_TIMING6_TXSRD_BIT) | (20 << DDRC_TIMING6_TFAW_BIT) |
+               (2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT),
+       },
+
+       /* PHY */
+       /* Mode Register 0 */
+       .mr0 = 0x420,
+#ifdef SDRAM_DISABLE_DLL
+       .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE),
+#else
+       .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS),
+#endif
+
+       .ptr0 = 0x002000d4,
+       .ptr1 = 0x02d30d40,
+       .ptr2 = 0x04013880,
+
+       .dtpr0 = 0x2c906690,
+       .dtpr1 = 0x005608a0,
+       .dtpr2 = 0x10042a00,
+
+       .pullup = 0x0e,
+       .pulldn = 0x0e,
+};
+
+#if (CONFIG_SYS_MHZ != 1200)
+#error No DDR configuration for CPU speed
+#endif
+
+const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
+{
+       const int board_revision = ci20_revision();
+
+       if (board_revision == 2)
+               return &K4B2G0846Q_48_config;
+       else /* Fall back to H5TQ2G83CFR RAM */
+               return &H5TQ2G83CFR_48_config;
+}
+#endif
diff --git a/board/mscc/luton/Kconfig b/board/mscc/luton/Kconfig
new file mode 100644 (file)
index 0000000..e119980
--- /dev/null
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+if SOC_LUTON
+
+config SYS_VENDOR
+       default "mscc"
+
+config SYS_BOARD
+       default "luton"
+
+config SYS_CONFIG_NAME
+       default "luton"
+
+endif
diff --git a/board/mscc/luton/Makefile b/board/mscc/luton/Makefile
new file mode 100644 (file)
index 0000000..b27f7c7
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+obj-$(CONFIG_SOC_LUTON)        := luton.o
diff --git a/board/mscc/luton/luton.c b/board/mscc/luton/luton.c
new file mode 100644 (file)
index 0000000..41fc6d5
--- /dev/null
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#define MSCC_GPIO_ALT0         0x88
+#define MSCC_GPIO_ALT1         0x8C
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_debug_uart_init(void)
+{
+       /* too early for the pinctrl driver, so configure the UART pins here */
+       setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(30) | BIT(31));
+}
+
+int board_early_init_r(void)
+{
+       /* Prepare SPI controller to be used in master mode */
+       writel(0, BASE_CFG + ICPU_SW_MODE);
+
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
+       return 0;
+}
diff --git a/board/mscc/ocelot/Kconfig b/board/mscc/ocelot/Kconfig
new file mode 100644 (file)
index 0000000..9ddc088
--- /dev/null
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+config SYS_VENDOR
+       default "mscc"
+
+if SOC_OCELOT
+
+config SYS_BOARD
+       default "ocelot"
+
+config SYS_CONFIG_NAME
+       default "ocelot"
+
+endif
diff --git a/board/mscc/ocelot/Makefile b/board/mscc/ocelot/Makefile
new file mode 100644 (file)
index 0000000..9f28c81
--- /dev/null
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+obj-$(CONFIG_SOC_OCELOT)       := ocelot.o
+
diff --git a/board/mscc/ocelot/ocelot.c b/board/mscc/ocelot/ocelot.c
new file mode 100644 (file)
index 0000000..d521a61
--- /dev/null
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <environment.h>
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MSCC_GPIO_ALT0         0x54
+#define MSCC_GPIO_ALT1         0x58
+
+void external_cs_manage(struct udevice *dev, bool enable)
+{
+       u32 cs = spi_chip_select(dev);
+       /* IF_SI0_OWNER, select the owner of the SI interface
+        * Encoding: 0: SI Slave
+        *           1: SI Boot Master
+        *           2: SI Master Controller
+        */
+       if (!enable) {
+               writel(ICPU_SW_MODE_SW_PIN_CTRL_MODE |
+                      ICPU_SW_MODE_SW_SPI_CS(BIT(cs)), BASE_CFG + ICPU_SW_MODE);
+               clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+                               ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
+                               ICPU_GENERAL_CTRL_IF_SI_OWNER(2));
+       } else {
+               writel(0, BASE_CFG + ICPU_SW_MODE);
+               clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+                               ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
+                               ICPU_GENERAL_CTRL_IF_SI_OWNER(1));
+       }
+}
+
+void board_debug_uart_init(void)
+{
+       /* too early for the pinctrl driver, so configure the UART pins here */
+       setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(6) | BIT(7));
+       clrbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT1, BIT(6) | BIT(7));
+}
+
+int board_early_init_r(void)
+{
+       /* Prepare SPI controller to be used in master mode */
+       writel(0, BASE_CFG + ICPU_SW_MODE);
+       clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+                       ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
+                       ICPU_GENERAL_CTRL_IF_SI_OWNER(2));
+
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
+       return 0;
+}
diff --git a/configs/a25-ae350_32_defconfig b/configs/a25-ae350_32_defconfig
deleted file mode 100644 (file)
index 5837b48..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-CONFIG_RISCV=y
-CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_TARGET_AX25_AE350=y
-CONFIG_DISTRO_DEFAULTS=y
-CONFIG_NR_DRAM_BANKS=2
-CONFIG_FIT=y
-CONFIG_BOOTDELAY=3
-CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_SYS_PROMPT="RISC-V # "
-CONFIG_CMD_IMLS=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SF_TEST=y
-# CONFIG_CMD_SETEXPR is not set
-CONFIG_BOOTP_PREFER_SERVERIP=y
-CONFIG_CMD_CACHE=y
-CONFIG_OF_BOARD=y
-CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
-CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_MMC=y
-CONFIG_FTSDC010=y
-CONFIG_FTSDC010_SDIO=y
-CONFIG_MTD_NOR_FLASH=y
-CONFIG_FLASH_CFI_DRIVER=y
-CONFIG_CFI_FLASH=y
-CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
-CONFIG_SYS_FLASH_CFI=y
-CONFIG_SPI_FLASH=y
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_FTMAC100=y
-CONFIG_BAUDRATE=38400
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_ATCSPI200_SPI=y
-CONFIG_ATCPIT100_TIMER=y
diff --git a/configs/ae350_rv32_defconfig b/configs/ae350_rv32_defconfig
new file mode 100644 (file)
index 0000000..5837b48
--- /dev/null
@@ -0,0 +1,36 @@
+CONFIG_RISCV=y
+CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_TARGET_AX25_AE350=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_CMD_IMLS=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SF_TEST=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_BOOTP_PREFER_SERVERIP=y
+CONFIG_CMD_CACHE=y
+CONFIG_OF_BOARD=y
+CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_MMC=y
+CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_CFI_DRIVER=y
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_FTMAC100=y
+CONFIG_BAUDRATE=38400
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_ATCSPI200_SPI=y
+CONFIG_ATCPIT100_TIMER=y
diff --git a/configs/ae350_rv64_defconfig b/configs/ae350_rv64_defconfig
new file mode 100644 (file)
index 0000000..b250d3f
--- /dev/null
@@ -0,0 +1,37 @@
+CONFIG_RISCV=y
+CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_TARGET_AX25_AE350=y
+CONFIG_ARCH_RV64I=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_CMD_IMLS=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SF_TEST=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_BOOTP_PREFER_SERVERIP=y
+CONFIG_CMD_CACHE=y
+CONFIG_OF_BOARD=y
+CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_MMC=y
+CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_CFI_DRIVER=y
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_FTMAC100=y
+CONFIG_BAUDRATE=38400
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_ATCSPI200_SPI=y
+CONFIG_ATCPIT100_TIMER=y
diff --git a/configs/ax25-ae350_64_defconfig b/configs/ax25-ae350_64_defconfig
deleted file mode 100644 (file)
index b250d3f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-CONFIG_RISCV=y
-CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_TARGET_AX25_AE350=y
-CONFIG_ARCH_RV64I=y
-CONFIG_DISTRO_DEFAULTS=y
-CONFIG_NR_DRAM_BANKS=2
-CONFIG_FIT=y
-CONFIG_BOOTDELAY=3
-CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_SYS_PROMPT="RISC-V # "
-CONFIG_CMD_IMLS=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SF_TEST=y
-# CONFIG_CMD_SETEXPR is not set
-CONFIG_BOOTP_PREFER_SERVERIP=y
-CONFIG_CMD_CACHE=y
-CONFIG_OF_BOARD=y
-CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
-CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_MMC=y
-CONFIG_FTSDC010=y
-CONFIG_FTSDC010_SDIO=y
-CONFIG_MTD_NOR_FLASH=y
-CONFIG_FLASH_CFI_DRIVER=y
-CONFIG_CFI_FLASH=y
-CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
-CONFIG_SYS_FLASH_CFI=y
-CONFIG_SPI_FLASH=y
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_FTMAC100=y
-CONFIG_BAUDRATE=38400
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_ATCSPI200_SPI=y
-CONFIG_ATCPIT100_TIMER=y
diff --git a/configs/ci20_mmc_defconfig b/configs/ci20_mmc_defconfig
new file mode 100644 (file)
index 0000000..c1b1c3f
--- /dev/null
@@ -0,0 +1,48 @@
+CONFIG_MIPS=y
+CONFIG_SPL_LDSCRIPT="arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds"
+CONFIG_SYS_TEXT_BASE=0x80010000
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL=y
+CONFIG_ARCH_JZ47XX=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS4,115200 rw rootwait root=/dev/mmcblk0p1"
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="ext4load mmc 0:1 0x88000000 /boot/uImage; bootm 0x88000000"
+CONFIG_MISC_INIT_R=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_BOARD_EARLY_INIT_F=y
+# CONFIG_SPL_BANNER_PRINT is not set
+# CONFIG_TPL_BANNER_PRINT is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_DM=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ci20"
+CONFIG_ENV_IS_IN_MMC=y
+# CONFIG_DM_WARN is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_JZ4780_EFUSE=y
+CONFIG_MMC=y
+CONFIG_MMC_BROKEN_CD=y
+CONFIG_DM_MMC=y
+# CONFIG_MMC_HW_PARTITIONING is not set
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+# CONFIG_MMC_VERBOSE is not set
+CONFIG_SPL_MMC_TINY=y
+CONFIG_JZ47XX_MMC=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_LZO=y
index d9ef52e68d205fed6724cb1eae1c378d73dfda41..1b8e4e43c4cd1f38b1d78ac1768f78b84150c798 100644 (file)
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6318_USBH_PHY=y
 CONFIG_BCM6328_POWER_DOMAIN=y
index f129870ca06eb0be8a1cecd9172972b03415c915..5ba401a4419a444b39b924c2cb710c937ba29520 100644 (file)
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_POWER_DOMAIN=y
index 82f207071363dcc4d571fea281afa6a6a6ed2b28..6297e78fd947df8122297e591180b56acff8fad3 100644 (file)
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6348_USBH_PHY=y
 CONFIG_DM_RESET=y
index 1689eecec150f94b029d88f7257953ab904b90f0..47f53998e12aba9c2af88bf5b926368d95ad3606 100644 (file)
@@ -26,15 +26,20 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
 CONFIG_LED_BLINK=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_POWER_DOMAIN=y
index 987e4c3fbce1286eda8a970cbf4c08a1446ddf2b..fd5107bb7d8bbbb0934d25b18bde623778830bec 100644 (file)
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_DM_RESET=y
index dd58198a54699367d60fd1d4fea60c4f6698eb2d..9068a584060a0d4162284da1674f66e2fa5e6212 100644 (file)
@@ -43,6 +43,9 @@ CONFIG_EFI_PARTITION=y
 CONFIG_DEFAULT_DEVICE_TREE="armada-385-amc"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_BLK=y
+# CONFIG_SPL_BLK is not set
+# CONFIG_BLOCK_CACHE is not set
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 # CONFIG_MMC is not set
index 05e7cf9f8843c155052269de74c5c3523f0c231f..ae8bf2981f330f7b0db2962ae5bd6bbb47250c27 100644 (file)
@@ -36,7 +36,6 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
 CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
index a08d1dbc9c77c9c55e61b326295da8ebfb8918b4..b7024e3dec166f03da74cdf0eda45bd30419a153 100644 (file)
@@ -39,7 +39,6 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
 CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
index 6bb14ba736faeb4ff08a98a9799e6822edf2ad85..d4e6144319b72fda665bb431ee674e10945fafdc 100644 (file)
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6358_USBH_PHY=y
 CONFIG_DM_RESET=y
index 2d20e9edd98e232713f35a3f3056d0f14eb67d57..2d3ab7e35c3ca0cdabf821e13d141842f8034164 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_TIME=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
index 5add29fb3334df9b6125ab781173a7745b3dd80f..ad34aaf640c41b157e684e7b1c4b5d61b6d8d80d 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_TIME=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig
new file mode 100644 (file)
index 0000000..d7476c4
--- /dev/null
@@ -0,0 +1,64 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x40000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x70100000
+CONFIG_DEBUG_UART_CLOCK=208333333
+CONFIG_ARCH_MSCC=y
+CONFIG_TARGET_LUTON_PCB091=y
+CONFIG_DDRTYPE_MT47H128M8HQ=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200"
+CONFIG_LOGLEVEL=7
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_SYS_PROMPT="pcb091 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),6m@1m(linux)"
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="luton_pcb091"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SOFT_SPI=y
+CONFIG_LZMA=y
diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig
new file mode 100644 (file)
index 0000000..5fa74db
--- /dev/null
@@ -0,0 +1,67 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x40000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x70100000
+CONFIG_DEBUG_UART_CLOCK=250000000
+CONFIG_ARCH_MSCC=y
+CONFIG_TARGET_OCELOT_PCB123=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200"
+CONFIG_LOGLEVEL=7
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_SYS_PROMPT="pcb123 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),15m(linux),15m(linux.bk)"
+CONFIG_CMD_UBI=y
+# CONFIG_CMD_UBIFS is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb123"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_DESIGNWARE_SPI=y
+CONFIG_LZMA=y
diff --git a/configs/mscc_ocelot_pcb120_defconfig b/configs/mscc_ocelot_pcb120_defconfig
new file mode 100644 (file)
index 0000000..c5a9f96
--- /dev/null
@@ -0,0 +1,60 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x40000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ARCH_MSCC=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200"
+CONFIG_LOGLEVEL=7
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_SYS_PROMPT="pcb120 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),15m(linux),15m(linux.bk)"
+CONFIG_CMD_UBI=y
+# CONFIG_CMD_UBIFS is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb120"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_DESIGNWARE_SPI=y
+CONFIG_LZMA=y
index 1abc8698560b1a34f265fbafde7cfb5a86e8f9cd..0f3914fe7e21eb437c4a12d0694dfc3c28dda60e 100644 (file)
@@ -27,17 +27,23 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2"
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
 CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_POWER_DOMAIN=y
index 91a966327acb2bd8008944f0d39872da0c0dae0c..8c36f5dbf83788d41228ba19e04bcdfd50b7e796 100644 (file)
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="sagem,f@st1704"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_BCM6345=y
 # CONFIG_SPL_SERIAL_PRESENT is not set
index 12adfb01e7f900e88dbf174f4bb9ef3cc4c52cc2..39622875b15b5309a376c837a10491be07706a88 100644 (file)
@@ -26,11 +26,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -42,6 +45,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6358_USBH_PHY=y
 CONFIG_DM_RESET=y
index fe75b80eb775c9c0ccadd6369cef34f9a0eaf552..189a6b7ec324df7f7b2ca65cb399c45598fb0c34 100644 (file)
@@ -25,7 +25,7 @@ Build and boot steps
 
 build:
 1. Prepare the toolchains and make sure the $PATH to toolchains is correct.
-2. Use `make ax25-ae350_defconfig` in u-boot root to build the image.
+2. Use `make ae350_rv[32|64]_defconfig` in u-boot root to build the image for 32 or 64 bit.
 
 Verification
 ====================
index 1d29c4d91dddf9b1552f8b8f26aa5596a94f9077..0ccadae0b718a65a736001255240f44ea82a6859 100644 (file)
@@ -28,6 +28,42 @@ comp:                Pointer to the completion function. May be NULL.
                entering the command arguments to complete the entry. Command
                completion is only available if CONFIG_AUTO_COMPLETE is defined.
 
+Sub-command definition
+----------------------
+
+Likewise an array of cmd_tbl_t holding sub-commands can be created using either
+of the following macros:
+
+* U_BOOT_CMD_MKENT(name, maxargs, repeatable, command, "usage", "help")
+* U_BOOT_CMD_MKENTCOMPLETE(name, maxargs, repeatable, command, "usage, "help",
+  comp)
+
+This table has to be evaluated in the command function of the main command, e.g.
+
+    static cmd_tbl_t cmd_sub[] = {
+        U_BOOT_CMD_MKENT(foo, CONFIG_SYS_MAXARGS, 1, do_foo, "", ""),
+        U_BOOT_CMD_MKENT(bar, CONFIG_SYS_MAXARGS, 1, do_bar, "", ""),
+    };
+
+    static int do_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+    {
+        cmd_tbl_t *cp;
+
+        if (argc < 2)
+                return CMD_RET_USAGE;
+
+        /* drop sub-command argument */
+        argc--;
+        argv++;
+
+        cp = find_cmd_tbl(argv[0], cmd_ut_sub, ARRAY_SIZE(cmd_sub));
+
+        if (cp)
+            return cp->cmd(cmdtp, flag, argc, argv);
+
+        return CMD_RET_USAGE;
+    }
+
 Command function
 ----------------
 
index d4052005e246808fac29bc5c489231c095b4ac49..3d5729f6dca8b4ec56228cca98225ca309c4c713 100644 (file)
@@ -13,3 +13,9 @@ config CPU_MPC83XX
        select CLK_MPC83XX
        help
          Support CPU cores for SoCs of the MPC83xx series.
+
+config CPU_RISCV
+       bool "Enable RISC-V CPU driver"
+       depends on CPU && RISCV
+       help
+         Support CPU cores for RISC-V architecture.
index 858b03755f52d57bfd7a5d237c20113231139630..be0300cd4a86745e57bea67dd02cafb64acb99c6 100644 (file)
@@ -8,4 +8,5 @@ obj-$(CONFIG_CPU) += cpu-uclass.o
 
 obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
 obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o
+obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o
 obj-$(CONFIG_SANDBOX) += cpu_sandbox.o
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
new file mode 100644 (file)
index 0000000..5e15df5
--- /dev/null
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <errno.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+
+static int riscv_cpu_get_desc(struct udevice *dev, char *buf, int size)
+{
+       const char *isa;
+
+       isa = dev_read_string(dev, "riscv,isa");
+       if (size < (strlen(isa) + 1))
+               return -ENOSPC;
+
+       strcpy(buf, isa);
+
+       return 0;
+}
+
+static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info)
+{
+       const char *mmu;
+
+       dev_read_u32(dev, "clock-frequency", (u32 *)&info->cpu_freq);
+
+       mmu = dev_read_string(dev, "mmu-type");
+       if (!mmu)
+               info->features |= BIT(CPU_FEAT_MMU);
+
+       return 0;
+}
+
+static int riscv_cpu_get_count(struct udevice *dev)
+{
+       ofnode node;
+       int num = 0;
+
+       ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
+               const char *device_type;
+
+               device_type = ofnode_read_string(node, "device_type");
+               if (!device_type)
+                       continue;
+               if (strcmp(device_type, "cpu") == 0)
+                       num++;
+       }
+
+       return num;
+}
+
+static int riscv_cpu_bind(struct udevice *dev)
+{
+       struct cpu_platdata *plat = dev_get_parent_platdata(dev);
+       struct driver *drv;
+       int ret;
+
+       /* save the hart id */
+       plat->cpu_id = dev_read_addr(dev);
+
+       /* first examine the property in current cpu node */
+       ret = dev_read_u32(dev, "timebase-frequency", &plat->timebase_freq);
+       /* if not found, then look at the parent /cpus node */
+       if (ret)
+               dev_read_u32(dev->parent, "timebase-frequency",
+                            &plat->timebase_freq);
+
+       /*
+        * Bind riscv-timer driver on hart 0
+        *
+        * We only instantiate one timer device which is enough for U-Boot.
+        * Pass the "timebase-frequency" value as the driver data for the
+        * timer device.
+        *
+        * Return value is not checked since it's possible that the timer
+        * driver is not included.
+        */
+       if (!plat->cpu_id && plat->timebase_freq) {
+               drv = lists_driver_lookup_name("riscv_timer");
+               if (!drv) {
+                       debug("Cannot find the timer driver, not included?\n");
+                       return 0;
+               }
+
+               device_bind_with_driver_data(dev, drv, "riscv_timer",
+                                            plat->timebase_freq, ofnode_null(),
+                                            NULL);
+       }
+
+       return 0;
+}
+
+static const struct cpu_ops riscv_cpu_ops = {
+       .get_desc       = riscv_cpu_get_desc,
+       .get_info       = riscv_cpu_get_info,
+       .get_count      = riscv_cpu_get_count,
+};
+
+static const struct udevice_id riscv_cpu_ids[] = {
+       { .compatible = "riscv" },
+       { }
+};
+
+U_BOOT_DRIVER(riscv_cpu) = {
+       .name = "riscv_cpu",
+       .id = UCLASS_CPU,
+       .of_match = riscv_cpu_ids,
+       .bind = riscv_cpu_bind,
+       .ops = &riscv_cpu_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
index 8a4162eccdb910ed95f3476fb91aab997d4a7fc0..1820676d7a18d089571c7c4f38fc1b996604e82c 100644 (file)
@@ -26,6 +26,15 @@ config SANDBOX_DMA
          Enable support for a test DMA uclass implementation. It stimulates
          DMA transfer by simple copying data between channels.
 
+config BCM6348_IUDMA
+       bool "BCM6348 IUDMA driver"
+       depends on ARCH_BMIPS
+       select DMA_CHANNELS
+       help
+         Enable the BCM6348 IUDMA driver.
+         This driver support data transfer from devices to
+         memory and from memory to devices.
+
 config TI_EDMA3
        bool "TI EDMA3 driver"
        help
index aff31f986a1427aad191fa86bd964e4b4c5e6f86..b5f9147e0a54a0868f4ab639c4495a5c02885ff1 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o
 
 obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
 obj-$(CONFIG_APBH_DMA) += apbh_dma.o
+obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o
 obj-$(CONFIG_FSL_DMA) += fsl_dma.o
 obj-$(CONFIG_SANDBOX_DMA) += sandbox-dma-test.o
 obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
new file mode 100644 (file)
index 0000000..1d3c192
--- /dev/null
@@ -0,0 +1,642 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/dma/bcm63xx-iudma.c:
+ *     Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ *     Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
+ *     Copyright (C) 2000-2010 Broadcom Corporation
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
+ *     Copyright (C) 2010 Broadcom Corporation
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma-uclass.h>
+#include <memalign.h>
+#include <reset.h>
+#include <asm/io.h>
+
+#define DMA_RX_DESC    6
+#define DMA_TX_DESC    1
+
+/* DMA Channels */
+#define DMA_CHAN_FLOWC(x)              ((x) >> 1)
+#define DMA_CHAN_MAX                   16
+#define DMA_CHAN_SIZE                  0x10
+#define DMA_CHAN_TOUT                  500
+
+/* DMA Global Configuration register */
+#define DMA_CFG_REG                    0x00
+#define  DMA_CFG_ENABLE_SHIFT          0
+#define  DMA_CFG_ENABLE_MASK           (1 << DMA_CFG_ENABLE_SHIFT)
+#define  DMA_CFG_FLOWC_ENABLE(x)       BIT(DMA_CHAN_FLOWC(x) + 1)
+#define  DMA_CFG_NCHANS_SHIFT          24
+#define  DMA_CFG_NCHANS_MASK           (0xf << DMA_CFG_NCHANS_SHIFT)
+
+/* DMA Global Flow Control registers */
+#define DMA_FLOWC_THR_LO_REG(x)                (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_THR_HI_REG(x)                (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_REG(x)         (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
+#define  DMA_FLOWC_ALLOC_FORCE_SHIFT   31
+#define  DMA_FLOWC_ALLOC_FORCE_MASK    (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
+
+/* DMA Global Reset register */
+#define DMA_RST_REG                    0x34
+#define  DMA_RST_CHAN_SHIFT            0
+#define  DMA_RST_CHAN_MASK(x)          (1 << x)
+
+/* DMA Channel Configuration register */
+#define DMAC_CFG_REG(x)                        (DMA_CHAN_SIZE * (x) + 0x00)
+#define  DMAC_CFG_ENABLE_SHIFT         0
+#define  DMAC_CFG_ENABLE_MASK          (1 << DMAC_CFG_ENABLE_SHIFT)
+#define  DMAC_CFG_PKT_HALT_SHIFT       1
+#define  DMAC_CFG_PKT_HALT_MASK                (1 << DMAC_CFG_PKT_HALT_SHIFT)
+#define  DMAC_CFG_BRST_HALT_SHIFT      2
+#define  DMAC_CFG_BRST_HALT_MASK       (1 << DMAC_CFG_BRST_HALT_SHIFT)
+
+/* DMA Channel Max Burst Length register */
+#define DMAC_BURST_REG(x)              (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA SRAM Descriptor Ring Start register */
+#define DMAS_RSTART_REG(x)             (DMA_CHAN_SIZE * (x) + 0x00)
+
+/* DMA SRAM State/Bytes done/ring offset register */
+#define DMAS_STATE_DATA_REG(x)         (DMA_CHAN_SIZE * (x) + 0x04)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_LEN_STATUS_REG(x)    (DMA_CHAN_SIZE * (x) + 0x08)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_BASE_BUFPTR_REG(x)   (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA Descriptor Status */
+#define DMAD_ST_CRC_SHIFT              8
+#define DMAD_ST_CRC_MASK               (1 << DMAD_ST_CRC_SHIFT)
+#define DMAD_ST_WRAP_SHIFT             12
+#define DMAD_ST_WRAP_MASK              (1 << DMAD_ST_WRAP_SHIFT)
+#define DMAD_ST_SOP_SHIFT              13
+#define DMAD_ST_SOP_MASK               (1 << DMAD_ST_SOP_SHIFT)
+#define DMAD_ST_EOP_SHIFT              14
+#define DMAD_ST_EOP_MASK               (1 << DMAD_ST_EOP_SHIFT)
+#define DMAD_ST_OWN_SHIFT              15
+#define DMAD_ST_OWN_MASK               (1 << DMAD_ST_OWN_SHIFT)
+
+#define DMAD6348_ST_OV_ERR_SHIFT       0
+#define DMAD6348_ST_OV_ERR_MASK                (1 << DMAD6348_ST_OV_ERR_SHIFT)
+#define DMAD6348_ST_CRC_ERR_SHIFT      1
+#define DMAD6348_ST_CRC_ERR_MASK       (1 << DMAD6348_ST_CRC_ERR_SHIFT)
+#define DMAD6348_ST_RX_ERR_SHIFT       2
+#define DMAD6348_ST_RX_ERR_MASK                (1 << DMAD6348_ST_RX_ERR_SHIFT)
+#define DMAD6348_ST_OS_ERR_SHIFT       4
+#define DMAD6348_ST_OS_ERR_MASK                (1 << DMAD6348_ST_OS_ERR_SHIFT)
+#define DMAD6348_ST_UN_ERR_SHIFT       9
+#define DMAD6348_ST_UN_ERR_MASK                (1 << DMAD6348_ST_UN_ERR_SHIFT)
+
+struct bcm6348_dma_desc {
+       uint16_t length;
+       uint16_t status;
+       uint32_t address;
+};
+
+struct bcm6348_chan_priv {
+       void __iomem *dma_ring;
+       uint8_t dma_ring_size;
+       uint8_t desc_id;
+       uint8_t desc_cnt;
+       bool *busy_desc;
+       bool running;
+};
+
+struct bcm6348_iudma_hw {
+       uint16_t err_mask;
+};
+
+struct bcm6348_iudma_priv {
+       const struct bcm6348_iudma_hw *hw;
+       void __iomem *base;
+       void __iomem *chan;
+       void __iomem *sram;
+       struct bcm6348_chan_priv **ch_priv;
+       uint8_t n_channels;
+};
+
+static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
+{
+       return !(ch & 1);
+}
+
+static inline void bcm6348_iudma_fdc(void *ptr, ulong size)
+{
+       ulong start = (ulong) ptr;
+
+       flush_dcache_range(start, start + size);
+}
+
+static inline void bcm6348_iudma_idc(void *ptr, ulong size)
+{
+       ulong start = (ulong) ptr;
+
+       invalidate_dcache_range(start, start + size);
+}
+
+static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
+                                   uint8_t ch)
+{
+       unsigned int timeout = DMA_CHAN_TOUT;
+
+       do {
+               uint32_t cfg, halt;
+
+               if (timeout > DMA_CHAN_TOUT / 2)
+                       halt = DMAC_CFG_PKT_HALT_MASK;
+               else
+                       halt = DMAC_CFG_BRST_HALT_MASK;
+
+               /* try to stop dma channel */
+               writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
+               mb();
+
+               /* check if channel was stopped */
+               cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
+               if (!(cfg & DMAC_CFG_ENABLE_MASK))
+                       break;
+
+               udelay(1);
+       } while (--timeout);
+
+       if (!timeout)
+               pr_err("unable to stop channel %u\n", ch);
+
+       /* reset dma channel */
+       setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+       mb();
+       clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+}
+
+static int bcm6348_iudma_disable(struct dma *dma)
+{
+       struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+       /* stop dma channel */
+       bcm6348_iudma_chan_stop(priv, dma->id);
+
+       /* dma flow control */
+       if (bcm6348_iudma_chan_is_rx(dma->id))
+               writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
+                         DMA_FLOWC_ALLOC_REG(dma->id));
+
+       /* init channel config */
+       ch_priv->running = false;
+       ch_priv->desc_id = 0;
+       if (bcm6348_iudma_chan_is_rx(dma->id))
+               ch_priv->desc_cnt = 0;
+       else
+               ch_priv->desc_cnt = ch_priv->dma_ring_size;
+
+       return 0;
+}
+
+static int bcm6348_iudma_enable(struct dma *dma)
+{
+       const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+       struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
+       uint8_t i;
+
+       /* dma ring init */
+       for (i = 0; i < ch_priv->desc_cnt; i++) {
+               if (bcm6348_iudma_chan_is_rx(dma->id)) {
+                       ch_priv->busy_desc[i] = false;
+                       dma_desc->status |= DMAD_ST_OWN_MASK;
+               } else {
+                       dma_desc->status = 0;
+                       dma_desc->length = 0;
+                       dma_desc->address = 0;
+               }
+
+               if (i == ch_priv->desc_cnt - 1)
+                       dma_desc->status |= DMAD_ST_WRAP_MASK;
+
+               dma_desc++;
+       }
+
+       /* init to first descriptor */
+       ch_priv->desc_id = 0;
+
+       /* force cache writeback */
+       bcm6348_iudma_fdc(ch_priv->dma_ring,
+                         sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+       /* clear sram */
+       writel_be(0, priv->sram + DMAS_STATE_DATA_REG(dma->id));
+       writel_be(0, priv->sram + DMAS_DESC_LEN_STATUS_REG(dma->id));
+       writel_be(0, priv->sram + DMAS_DESC_BASE_BUFPTR_REG(dma->id));
+
+       /* set dma ring start */
+       writel_be(virt_to_phys(ch_priv->dma_ring),
+                 priv->sram + DMAS_RSTART_REG(dma->id));
+
+       /* set flow control */
+       if (bcm6348_iudma_chan_is_rx(dma->id)) {
+               u32 val;
+
+               setbits_be32(priv->base + DMA_CFG_REG,
+                            DMA_CFG_FLOWC_ENABLE(dma->id));
+
+               val = ch_priv->desc_cnt / 3;
+               writel_be(val, priv->base + DMA_FLOWC_THR_LO_REG(dma->id));
+
+               val = (ch_priv->desc_cnt * 2) / 3;
+               writel_be(val, priv->base + DMA_FLOWC_THR_HI_REG(dma->id));
+
+               writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
+       }
+
+       /* set dma max burst */
+       writel_be(ch_priv->desc_cnt,
+                 priv->chan + DMAC_BURST_REG(dma->id));
+
+       /* kick rx dma channel */
+       if (bcm6348_iudma_chan_is_rx(dma->id))
+               setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+                            DMAC_CFG_ENABLE_MASK);
+
+       /* channel is now enabled */
+       ch_priv->running = true;
+
+       return 0;
+}
+
+static int bcm6348_iudma_request(struct dma *dma)
+{
+       const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       struct bcm6348_chan_priv *ch_priv;
+
+       /* check if channel is valid */
+       if (dma->id >= priv->n_channels)
+               return -ENODEV;
+
+       /* alloc channel private data */
+       priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
+       if (!priv->ch_priv[dma->id])
+               return -ENOMEM;
+       ch_priv = priv->ch_priv[dma->id];
+
+       /* alloc dma ring */
+       if (bcm6348_iudma_chan_is_rx(dma->id))
+               ch_priv->dma_ring_size = DMA_RX_DESC;
+       else
+               ch_priv->dma_ring_size = DMA_TX_DESC;
+
+       ch_priv->dma_ring =
+               malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
+                                    ch_priv->dma_ring_size);
+       if (!ch_priv->dma_ring)
+               return -ENOMEM;
+
+       /* init channel config */
+       ch_priv->running = false;
+       ch_priv->desc_id = 0;
+       if (bcm6348_iudma_chan_is_rx(dma->id)) {
+               ch_priv->desc_cnt = 0;
+               ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool));
+       } else {
+               ch_priv->desc_cnt = ch_priv->dma_ring_size;
+               ch_priv->busy_desc = NULL;
+       }
+
+       return 0;
+}
+
+static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
+{
+       const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       const struct bcm6348_iudma_hw *hw = priv->hw;
+       struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+       struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring;
+       int ret;
+
+       /* get dma ring descriptor address */
+       dma_desc += ch_priv->desc_id;
+
+       /* invalidate cache data */
+       bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+       /* check dma own */
+       if (dma_desc->status & DMAD_ST_OWN_MASK)
+               return -EAGAIN;
+
+       /* check pkt */
+       if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
+           !(dma_desc->status & DMAD_ST_SOP_MASK) ||
+           (dma_desc->status & hw->err_mask)) {
+               pr_err("invalid pkt received (ch=%ld desc=%u) (st=%04x)\n",
+                      dma->id, ch_priv->desc_id, dma_desc->status);
+               ret = -EAGAIN;
+       } else {
+               /* set dma buffer address */
+               *dst = phys_to_virt(dma_desc->address);
+
+               /* invalidate cache data */
+               bcm6348_iudma_idc(*dst, dma_desc->length);
+
+               /* return packet length */
+               ret = dma_desc->length;
+       }
+
+       /* busy dma descriptor */
+       ch_priv->busy_desc[ch_priv->desc_id] = true;
+
+       /* increment dma descriptor */
+       ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+       return ret;
+}
+
+static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
+                             void *metadata)
+{
+       const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+       struct bcm6348_dma_desc *dma_desc;
+       uint16_t status;
+
+       /* flush cache */
+       bcm6348_iudma_fdc(src, len);
+
+       /* get dma ring descriptor address */
+       dma_desc = ch_priv->dma_ring;
+       dma_desc += ch_priv->desc_id;
+
+       /* config dma descriptor */
+       status = (DMAD_ST_OWN_MASK |
+                 DMAD_ST_EOP_MASK |
+                 DMAD_ST_CRC_MASK |
+                 DMAD_ST_SOP_MASK);
+       if (ch_priv->desc_id == ch_priv->desc_cnt - 1)
+               status |= DMAD_ST_WRAP_MASK;
+
+       /* set dma descriptor */
+       dma_desc->address = virt_to_phys(src);
+       dma_desc->length = len;
+       dma_desc->status = status;
+
+       /* flush cache */
+       bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+       /* kick tx dma channel */
+       setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+       /* poll dma status */
+       do {
+               /* invalidate cache */
+               bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+               if (!(dma_desc->status & DMAD_ST_OWN_MASK))
+                       break;
+       } while(1);
+
+       /* increment dma descriptor */
+       ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+       return 0;
+}
+
+static int bcm6348_iudma_free_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+       const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+       struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
+       uint16_t status;
+       uint8_t i;
+       u32 cfg;
+
+       /* get dirty dma descriptor */
+       for (i = 0; i < ch_priv->desc_cnt; i++) {
+               if (phys_to_virt(dma_desc->address) == dst)
+                       break;
+
+               dma_desc++;
+       }
+
+       /* dma descriptor not found */
+       if (i == ch_priv->desc_cnt) {
+               pr_err("dirty dma descriptor not found\n");
+               return -ENOENT;
+       }
+
+       /* invalidate cache */
+       bcm6348_iudma_idc(ch_priv->dma_ring,
+                         sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+       /* free dma descriptor */
+       ch_priv->busy_desc[i] = false;
+
+       status = DMAD_ST_OWN_MASK;
+       if (i == ch_priv->desc_cnt - 1)
+               status |= DMAD_ST_WRAP_MASK;
+
+       dma_desc->status |= status;
+       dma_desc->length = PKTSIZE_ALIGN;
+
+       /* tell dma we allocated one buffer */
+       writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
+
+       /* flush cache */
+       bcm6348_iudma_fdc(ch_priv->dma_ring,
+                         sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+       /* kick rx dma channel if disabled */
+       cfg = readl_be(priv->chan + DMAC_CFG_REG(dma->id));
+       if (!(cfg & DMAC_CFG_ENABLE_MASK))
+               setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+                            DMAC_CFG_ENABLE_MASK);
+
+       return 0;
+}
+
+static int bcm6348_iudma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+       const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+       struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
+
+       /* no more dma descriptors available */
+       if (ch_priv->desc_cnt == ch_priv->dma_ring_size) {
+               pr_err("max number of buffers reached\n");
+               return -EINVAL;
+       }
+
+       /* get next dma descriptor */
+       dma_desc += ch_priv->desc_cnt;
+
+       /* init dma descriptor */
+       dma_desc->address = virt_to_phys(dst);
+       dma_desc->length = size;
+       dma_desc->status = 0;
+
+       /* flush cache */
+       bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+       /* increment dma descriptors */
+       ch_priv->desc_cnt++;
+
+       return 0;
+}
+
+static int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst,
+                                        size_t size)
+{
+       const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+       struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+       /* only add new rx buffers if channel isn't running */
+       if (ch_priv->running)
+               return bcm6348_iudma_free_rcv_buf(dma, dst, size);
+       else
+               return bcm6348_iudma_add_rcv_buf(dma, dst, size);
+}
+
+static const struct dma_ops bcm6348_iudma_ops = {
+       .disable = bcm6348_iudma_disable,
+       .enable = bcm6348_iudma_enable,
+       .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
+       .request = bcm6348_iudma_request,
+       .receive = bcm6348_iudma_receive,
+       .send = bcm6348_iudma_send,
+};
+
+static const struct bcm6348_iudma_hw bcm6348_hw = {
+       .err_mask = (DMAD6348_ST_OV_ERR_MASK |
+                    DMAD6348_ST_CRC_ERR_MASK |
+                    DMAD6348_ST_RX_ERR_MASK |
+                    DMAD6348_ST_OS_ERR_MASK |
+                    DMAD6348_ST_UN_ERR_MASK),
+};
+
+static const struct bcm6348_iudma_hw bcm6368_hw = {
+       .err_mask = 0,
+};
+
+static const struct udevice_id bcm6348_iudma_ids[] = {
+       {
+               .compatible = "brcm,bcm6348-iudma",
+               .data = (ulong)&bcm6348_hw,
+       }, {
+               .compatible = "brcm,bcm6368-iudma",
+               .data = (ulong)&bcm6368_hw,
+       }, { /* sentinel */ }
+};
+
+static int bcm6348_iudma_probe(struct udevice *dev)
+{
+       struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
+       const struct bcm6348_iudma_hw *hw =
+               (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
+       uint8_t ch;
+       int i;
+
+       uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
+                             DMA_SUPPORTS_MEM_TO_DEV);
+       priv->hw = hw;
+
+       /* dma global base address */
+       priv->base = dev_remap_addr_name(dev, "dma");
+       if (!priv->base)
+               return -EINVAL;
+
+       /* dma channels base address */
+       priv->chan = dev_remap_addr_name(dev, "dma-channels");
+       if (!priv->chan)
+               return -EINVAL;
+
+       /* dma sram base address */
+       priv->sram = dev_remap_addr_name(dev, "dma-sram");
+       if (!priv->sram)
+               return -EINVAL;
+
+       /* get number of channels */
+       priv->n_channels = dev_read_u32_default(dev, "dma-channels", 8);
+       if (priv->n_channels > DMA_CHAN_MAX)
+               return -EINVAL;
+
+       /* try to enable clocks */
+       for (i = 0; ; i++) {
+               struct clk clk;
+               int ret;
+
+               ret = clk_get_by_index(dev, i, &clk);
+               if (ret < 0)
+                       break;
+
+               ret = clk_enable(&clk);
+               if (ret < 0) {
+                       pr_err("error enabling clock %d\n", i);
+                       return ret;
+               }
+
+               ret = clk_free(&clk);
+               if (ret < 0) {
+                       pr_err("error freeing clock %d\n", i);
+                       return ret;
+               }
+       }
+
+       /* try to perform resets */
+       for (i = 0; ; i++) {
+               struct reset_ctl reset;
+               int ret;
+
+               ret = reset_get_by_index(dev, i, &reset);
+               if (ret < 0)
+                       break;
+
+               ret = reset_deassert(&reset);
+               if (ret < 0) {
+                       pr_err("error deasserting reset %d\n", i);
+                       return ret;
+               }
+
+               ret = reset_free(&reset);
+               if (ret < 0) {
+                       pr_err("error freeing reset %d\n", i);
+                       return ret;
+               }
+       }
+
+       /* disable dma controller */
+       clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+       /* alloc channel private data pointers */
+       priv->ch_priv = calloc(priv->n_channels,
+                              sizeof(struct bcm6348_chan_priv*));
+       if (!priv->ch_priv)
+               return -ENOMEM;
+
+       /* stop dma channels */
+       for (ch = 0; ch < priv->n_channels; ch++)
+               bcm6348_iudma_chan_stop(priv, ch);
+
+       /* enable dma controller */
+       setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(bcm6348_iudma) = {
+       .name = "bcm6348_iudma",
+       .id = UCLASS_DMA,
+       .of_match = bcm6348_iudma_ids,
+       .ops = &bcm6348_iudma_ops,
+       .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
+       .probe = bcm6348_iudma_probe,
+};
index 50e901973d1369ba86d4574b8e40389ea201902d..8f59193e3c2c92c22b290329021f71289bead33a 100644 (file)
@@ -31,6 +31,17 @@ config FPGA_CYCLON2
          Enable FPGA driver for loading bitstream in BIT and BIN format
          on Altera Cyclone II device.
 
+config FPGA_STRATIX10
+       bool "Enable Altera FPGA driver for Stratix 10"
+       depends on TARGET_SOCFPGA_STRATIX10
+       select FPGA_ALTERA
+       help
+         Say Y here to enable the Altera Stratix 10 FPGA specific driver
+
+         This provides common functionality for Altera Stratix 10 devices.
+         Enable FPGA driver for writing bitstream into Altera Stratix10
+         device.
+
 config FPGA_XILINX
        bool "Enable Xilinx FPGA drivers"
        select FPGA
index 97d7d5d9be3aefba7ff623a1ba6756fbcdd3f88a..5a778c10e801aaa6562433eac5b1322fd39e3042 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o
 obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o
 obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o
 obj-$(CONFIG_FPGA_STRATIX_V) += stratixv.o
+obj-$(CONFIG_FPGA_STRATIX10) += stratix10.o
 obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o
 obj-$(CONFIG_TARGET_SOCFPGA_GEN5) += socfpga_gen5.o
 obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += socfpga_arria10.o
index 9605554c6aa571a11bc65f1f9f42fd712024cfe6..7c8f5185095a16d64bd491d76aa0bf639134e5cd 100644 (file)
@@ -39,6 +39,9 @@ static const struct altera_fpga {
 #if defined(CONFIG_FPGA_STRATIX_V)
        { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL },
 #endif
+#if defined(CONFIG_FPGA_STRATIX10)
+       { Intel_FPGA_Stratix10, "Stratix10", stratix10_load, NULL, NULL },
+#endif
 #if defined(CONFIG_FPGA_SOCFPGA)
        { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL },
 #endif
@@ -154,6 +157,9 @@ int altera_info(Altera_desc *desc)
        case fast_passive_parallel_security:
                printf("Fast Passive Parallel with Security (FPPS)\n");
                break;
+       case secure_device_manager_mailbox:
+               puts("Secure Device Manager (SDM) Mailbox\n");
+               break;
                /* Add new interface types here */
        default:
                printf("Unsupported interface type, %d\n", desc->iface);
diff --git a/drivers/fpga/stratix10.c b/drivers/fpga/stratix10.c
new file mode 100644 (file)
index 0000000..aae0521
--- /dev/null
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Intel Corporation <www.intel.com>
+ */
+
+#include <common.h>
+#include <altera.h>
+#include <asm/arch/mailbox_s10.h>
+
+#define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS           60000
+#define RECONFIG_STATUS_INTERVAL_DELAY_US              1000000
+
+static const struct mbox_cfgstat_state {
+       int                     err_no;
+       const char              *error_name;
+} mbox_cfgstat_state[] = {
+       {MBOX_CFGSTAT_STATE_IDLE, "FPGA in idle mode."},
+       {MBOX_CFGSTAT_STATE_CONFIG, "FPGA in config mode."},
+       {MBOX_CFGSTAT_STATE_FAILACK, "Acknowledgment failed!"},
+       {MBOX_CFGSTAT_STATE_ERROR_INVALID, "Invalid bitstream!"},
+       {MBOX_CFGSTAT_STATE_ERROR_CORRUPT, "Corrupted bitstream!"},
+       {MBOX_CFGSTAT_STATE_ERROR_AUTH, "Authentication failed!"},
+       {MBOX_CFGSTAT_STATE_ERROR_CORE_IO, "I/O error!"},
+       {MBOX_CFGSTAT_STATE_ERROR_HARDWARE, "Hardware error!"},
+       {MBOX_CFGSTAT_STATE_ERROR_FAKE, "Fake error!"},
+       {MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO, "Error in boot info!"},
+       {MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR, "Error in QSPI!"},
+       {MBOX_RESP_ERROR, "Mailbox general error!"},
+       {-ETIMEDOUT, "I/O timeout error"},
+       {-1, "Unknown error!"}
+};
+
+#define MBOX_CFGSTAT_MAX ARRAY_SIZE(mbox_cfgstat_state)
+
+static const char *mbox_cfgstat_to_str(int err)
+{
+       int i;
+
+       for (i = 0; i < MBOX_CFGSTAT_MAX - 1; i++) {
+               if (mbox_cfgstat_state[i].err_no == err)
+                       return mbox_cfgstat_state[i].error_name;
+       }
+
+       return mbox_cfgstat_state[MBOX_CFGSTAT_MAX - 1].error_name;
+}
+
+/*
+ * Add the ongoing transaction's command ID into pending list and return
+ * the command ID for next transfer.
+ */
+static u8 add_transfer(u32 *xfer_pending_list, size_t list_size, u8 id)
+{
+       int i;
+
+       for (i = 0; i < list_size; i++) {
+               if (xfer_pending_list[i])
+                       continue;
+               xfer_pending_list[i] = id;
+               debug("ID(%d) added to transaction pending list\n", id);
+               /*
+                * Increment command ID for next transaction.
+                * Valid command ID (4 bits) is from 1 to 15.
+                */
+               id = (id % 15) + 1;
+               break;
+       }
+
+       return id;
+}
+
+/*
+ * Check whether response ID match the command ID in the transfer
+ * pending list. If a match is found in the transfer pending list,
+ * it clears the transfer pending list and return the matched
+ * command ID.
+ */
+static int get_and_clr_transfer(u32 *xfer_pending_list, size_t list_size,
+                               u8 id)
+{
+       int i;
+
+       for (i = 0; i < list_size; i++) {
+               if (id != xfer_pending_list[i])
+                       continue;
+               xfer_pending_list[i] = 0;
+               return id;
+       }
+
+       return 0;
+}
+
+/*
+ * Polling the FPGA configuration status.
+ * Return 0 for success, non-zero for error.
+ */
+static int reconfig_status_polling_resp(void)
+{
+       int ret;
+       unsigned long start = get_timer(0);
+
+       while (1) {
+               ret = mbox_get_fpga_config_status(MBOX_RECONFIG_STATUS);
+               if (!ret)
+                       return 0;       /* configuration success */
+
+               if (ret != MBOX_CFGSTAT_STATE_CONFIG)
+                       return ret;
+
+               if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS)
+                       break;  /* time out */
+
+               puts(".");
+               udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
+       }
+
+       return -ETIMEDOUT;
+}
+
+static u32 get_resp_hdr(u32 *r_index, u32 *w_index, u32 *resp_count,
+                       u32 *resp_buf, u32 buf_size, u32 client_id)
+{
+       u32 buf[MBOX_RESP_BUFFER_SIZE];
+       u32 mbox_hdr;
+       u32 resp_len;
+       u32 hdr_len;
+       u32 i;
+
+       if (*resp_count < buf_size) {
+               u32 rcv_len_max = buf_size - *resp_count;
+
+               if (rcv_len_max > MBOX_RESP_BUFFER_SIZE)
+                       rcv_len_max = MBOX_RESP_BUFFER_SIZE;
+               resp_len = mbox_rcv_resp(buf, rcv_len_max);
+
+               for (i = 0; i < resp_len; i++) {
+                       resp_buf[(*w_index)++] = buf[i];
+                       *w_index %= buf_size;
+                       (*resp_count)++;
+               }
+       }
+
+       /* No response in buffer */
+       if (*resp_count == 0)
+               return 0;
+
+       mbox_hdr = resp_buf[*r_index];
+
+       hdr_len = MBOX_RESP_LEN_GET(mbox_hdr);
+
+       /* Insufficient header length to return a mailbox header */
+       if ((*resp_count - 1) < hdr_len)
+               return 0;
+
+       *r_index += (hdr_len + 1);
+       *r_index %= buf_size;
+       *resp_count -= (hdr_len + 1);
+
+       /* Make sure response belongs to us */
+       if (MBOX_RESP_CLIENT_GET(mbox_hdr) != client_id)
+               return 0;
+
+       return mbox_hdr;
+}
+
+/* Send bit stream data to SDM via RECONFIG_DATA mailbox command */
+static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
+                             u32 xfer_max, u32 buf_size_max)
+{
+       u32 response_buffer[MBOX_RESP_BUFFER_SIZE];
+       u32 xfer_pending[MBOX_RESP_BUFFER_SIZE];
+       u32 resp_rindex = 0;
+       u32 resp_windex = 0;
+       u32 resp_count = 0;
+       u32 xfer_count = 0;
+       u8 resp_err = 0;
+       u8 cmd_id = 1;
+       u32 args[3];
+       int ret;
+
+       debug("SDM xfer_max = %d\n", xfer_max);
+       debug("SDM buf_size_max = %x\n\n", buf_size_max);
+
+       memset(xfer_pending, 0, sizeof(xfer_pending));
+
+       while (rbf_size || xfer_count) {
+               if (!resp_err && rbf_size && xfer_count < xfer_max) {
+                       args[0] = MBOX_ARG_DESC_COUNT(1);
+                       args[1] = (u64)rbf_data;
+                       if (rbf_size >= buf_size_max) {
+                               args[2] = buf_size_max;
+                               rbf_size -= buf_size_max;
+                               rbf_data += buf_size_max;
+                       } else {
+                               args[2] = (u64)rbf_size;
+                               rbf_size = 0;
+                       }
+
+                       ret = mbox_send_cmd_only(cmd_id, MBOX_RECONFIG_DATA,
+                                                MBOX_CMD_INDIRECT, 3, args);
+                       if (ret) {
+                               resp_err = 1;
+                       } else {
+                               xfer_count++;
+                               cmd_id = add_transfer(xfer_pending,
+                                                     MBOX_RESP_BUFFER_SIZE,
+                                                     cmd_id);
+                       }
+                       puts(".");
+               } else {
+                       u32 resp_hdr = get_resp_hdr(&resp_rindex, &resp_windex,
+                                                   &resp_count,
+                                                   response_buffer,
+                                                   MBOX_RESP_BUFFER_SIZE,
+                                                   MBOX_CLIENT_ID_UBOOT);
+
+                       /*
+                        * If no valid response header found or
+                        * non-zero length from RECONFIG_DATA
+                        */
+                       if (!resp_hdr || MBOX_RESP_LEN_GET(resp_hdr))
+                               continue;
+
+                       /* Check for response's status */
+                       if (!resp_err) {
+                               ret = MBOX_RESP_ERR_GET(resp_hdr);
+                               debug("Response error code: %08x\n", ret);
+                               /* Error in response */
+                               if (ret)
+                                       resp_err = 1;
+                       }
+
+                       ret = get_and_clr_transfer(xfer_pending,
+                                                  MBOX_RESP_BUFFER_SIZE,
+                                                  MBOX_RESP_ID_GET(resp_hdr));
+                       if (ret) {
+                               /* Claim and reuse the ID */
+                               cmd_id = (u8)ret;
+                               xfer_count--;
+                       }
+
+                       if (resp_err && !xfer_count)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * This is the interface used by FPGA driver.
+ * Return 0 for success, non-zero for error.
+ */
+int stratix10_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
+{
+       int ret;
+       u32 resp_len = 2;
+       u32 resp_buf[2];
+
+       debug("Sending MBOX_RECONFIG...\n");
+       ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RECONFIG, MBOX_CMD_DIRECT, 0,
+                           NULL, 0, &resp_len, resp_buf);
+       if (ret) {
+               puts("Failure in RECONFIG mailbox command!\n");
+               return ret;
+       }
+
+       ret = send_reconfig_data(rbf_data, rbf_size, resp_buf[0], resp_buf[1]);
+       if (ret) {
+               printf("RECONFIG_DATA error: %08x, %s\n", ret,
+                      mbox_cfgstat_to_str(ret));
+               return ret;
+       }
+
+       /* Make sure we don't send MBOX_RECONFIG_STATUS too fast */
+       udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
+
+       debug("Polling with MBOX_RECONFIG_STATUS...\n");
+       ret = reconfig_status_polling_resp();
+       if (ret) {
+               printf("RECONFIG_STATUS Error: %08x, %s\n", ret,
+                      mbox_cfgstat_to_str(ret));
+               return ret;
+       }
+
+       puts("FPGA reconfiguration OK!\n");
+
+       return ret;
+}
index 35344e57c6c6e16f07313d563b7c7940a339831c..c8c6c60623ed33ed355afced6bab84214e6d33f2 100644 (file)
@@ -99,6 +99,13 @@ config LPC32XX_GPIO
        help
          Support for the LPC32XX GPIO driver.
 
+config MSCC_BITBANG_SPI_GPIO
+       bool "Microsemi bitbang spi GPIO driver"
+       depends on DM_GPIO && SOC_VCOREIII
+       help
+         Support controlling the GPIO used for SPI bitbang by software. Can
+         be used by the VCoreIII SoCs, but it was mainly useful for Luton.
+
 config MSM_GPIO
        bool "Qualcomm GPIO driver"
        depends on DM_GPIO
index 7ed9a4ec422175807276aaaf729c1a226a1b9ded..61feda15372d209c953576eb5ce22b450fa3f26d 100644 (file)
@@ -59,3 +59,4 @@ obj-$(CONFIG_MSM_GPIO)                += msm_gpio.o
 obj-$(CONFIG_$(SPL_)PCF8575_GPIO)      += pcf8575_gpio.o
 obj-$(CONFIG_PM8916_GPIO)      += pm8916_gpio.o
 obj-$(CONFIG_MT7621_GPIO)      += mt7621_gpio.o
+obj-$(CONFIG_MSCC_BITBANG_SPI_GPIO)    += gpio-mscc-bitbang-spi.o
diff --git a/drivers/gpio/gpio-mscc-bitbang-spi.c b/drivers/gpio/gpio-mscc-bitbang-spi.c
new file mode 100644 (file)
index 0000000..b675f90
--- /dev/null
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Microsemi SoCs pinctrl driver
+ *
+ * Author: <gregory.clement@bootlin.com>
+ * License: Dual MIT/GPL
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <asm-generic/gpio.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+
+enum {
+       SDI,
+       CS0,
+       CS1,
+       CS2,
+       CS3,
+       SDO,
+       SCK
+};
+
+static const int pinmap[] = { 0, 5, 6, 7, 8, 10, 12 };
+
+#define SW_SPI_CSn_OE   0x1E   /* bits 1 to 4 */
+#define SW_SPI_CS0_OE   BIT(1)
+#define SW_SPI_SDO_OE   BIT(9)
+#define SW_SPI_SCK_OE   BIT(11)
+#define SW_PIN_CTRL_MODE BIT(13)
+
+struct mscc_bb_spi_gpio {
+       void __iomem *regs;
+       u32 cache_val;
+};
+
+static int mscc_bb_spi_gpio_set(struct udevice *dev, unsigned oft, int val)
+{
+       struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev);
+
+       if (val)
+               gpio->cache_val |= BIT(pinmap[oft]);
+       else
+               gpio->cache_val &= ~BIT(pinmap[oft]);
+
+       writel(gpio->cache_val, gpio->regs);
+
+       return 0;
+}
+
+static int mscc_bb_spi_gpio_direction_output(struct udevice *dev, unsigned oft,
+                                            int val)
+{
+       if (oft == 0) {
+               pr_err("SW_SPI_DSI can't be used as output\n");
+               return -ENOTSUPP;
+       }
+
+       mscc_bb_spi_gpio_set(dev, oft, val);
+
+       return 0;
+}
+
+static int mscc_bb_spi_gpio_direction_input(struct udevice *dev, unsigned oft)
+{
+       return 0;
+}
+
+static int mscc_bb_spi_gpio_get(struct udevice *dev, unsigned int oft)
+{
+       struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev);
+       u32 val = readl(gpio->regs);
+
+       return !!(val & BIT(pinmap[oft]));
+}
+
+static const struct dm_gpio_ops mscc_bb_spi_gpio_ops = {
+       .direction_output       = mscc_bb_spi_gpio_direction_output,
+       .direction_input        = mscc_bb_spi_gpio_direction_input,
+       .set_value              = mscc_bb_spi_gpio_set,
+       .get_value              = mscc_bb_spi_gpio_get,
+};
+
+static int mscc_bb_spi_gpio_probe(struct udevice *dev)
+{
+       struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev);
+       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+       gpio->regs = dev_remap_addr(dev);
+       if (!gpio->regs)
+               return -EINVAL;
+
+       uc_priv->bank_name = dev->name;
+       uc_priv->gpio_count = ARRAY_SIZE(pinmap);
+       /*
+        * Enable software mode to control the SPI pin, enables the
+        * output mode for most of the pin and initialize the cache
+        * value in the same time
+        */
+
+       gpio->cache_val = SW_PIN_CTRL_MODE | SW_SPI_SCK_OE | SW_SPI_SDO_OE |
+           SW_SPI_CS0_OE;
+       writel(gpio->cache_val, gpio->regs);
+
+       return 0;
+}
+
+static const struct udevice_id mscc_bb_spi_gpio_ids[] = {
+       {.compatible = "mscc,spi-bitbang-gpio"},
+       {}
+};
+
+U_BOOT_DRIVER(gpio_mscc_bb_spi) = {
+       .name   = "gpio-mscc-spi-bitbang",
+       .id     = UCLASS_GPIO,
+       .ops    = &mscc_bb_spi_gpio_ops,
+       .probe  = mscc_bb_spi_gpio_probe,
+       .of_match = of_match_ptr(mscc_bb_spi_gpio_ids),
+       .priv_auto_alloc_size = sizeof(struct mscc_bb_spi_gpio),
+};
index 48febc47d263b9be2dd1439901e6fe03ba581062..704c8dd1955f57aa3927df88980afa03686e8e63 100644 (file)
@@ -120,6 +120,12 @@ config FSL_SEC_MON
          Security Monitor can be transitioned on any security failures,
          like software violations or hardware security violations.
 
+config JZ4780_EFUSE
+       bool "Ingenic JZ4780 eFUSE support"
+       depends on ARCH_JZ47XX
+       help
+         This selects support for the eFUSE on Ingenic JZ4780 SoCs.
+
 config MXC_OCOTP
        bool "Enable MXC OCOTP Driver"
        help
index 302d4415927431ab593eea03b4c2366fcc22ff67..6bdf5054f47510a80aa1e27c9008b10b5b4d0570 100644 (file)
@@ -62,3 +62,4 @@ obj-$(CONFIG_TEGRA_CAR) += tegra_car.o
 obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
 obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o
 obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
+obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o
diff --git a/drivers/misc/jz4780_efuse.c b/drivers/misc/jz4780_efuse.c
new file mode 100644 (file)
index 0000000..bc3dc93
--- /dev/null
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 EFUSE driver
+ *
+ * Copyright (c) 2014 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <errno.h>
+#include <mach/jz4780.h>
+#include <wait_bit.h>
+
+#define EFUSE_EFUCTRL                  0xd0
+#define EFUSE_EFUCFG                   0xd4
+#define EFUSE_EFUSTATE                 0xd8
+#define EFUSE_EFUDATA(n)               (0xdc + ((n) * 4))
+
+#define EFUSE_EFUCTRL_RD_EN            BIT(0)
+#define EFUSE_EFUCTRL_LEN_BIT          16
+#define EFUSE_EFUCTRL_LEN_MASK         0x1f
+#define EFUSE_EFUCTRL_ADDR_BIT         21
+#define EFUSE_EFUCTRL_ADDR_MASK                0x1ff
+#define EFUSE_EFUCTRL_CS               BIT(30)
+
+#define EFUSE_EFUCFG_RD_STROBE_BIT     16
+#define EFUSE_EFUCFG_RD_STROBE_MASK    0xf
+#define EFUSE_EFUCFG_RD_ADJ_BIT                20
+#define EFUSE_EFUCFG_RD_ADJ_MASK       0xf
+
+#define EFUSE_EFUSTATE_RD_DONE         BIT(0)
+
+static void jz4780_efuse_read_chunk(size_t addr, size_t count, u8 *buf)
+{
+       void __iomem *regs = (void __iomem *)NEMC_BASE;
+       size_t i;
+       u32 val;
+       int ret;
+
+       val = EFUSE_EFUCTRL_RD_EN |
+               ((count - 1) << EFUSE_EFUCTRL_LEN_BIT) |
+               (addr << EFUSE_EFUCTRL_ADDR_BIT) |
+               ((addr > 0x200) ? EFUSE_EFUCTRL_CS : 0);
+       writel(val, regs + EFUSE_EFUCTRL);
+
+       ret = wait_for_bit_le32(regs + EFUSE_EFUSTATE,
+                               EFUSE_EFUSTATE_RD_DONE, true, 10000, false);
+       if (ret)
+               return;
+
+       if ((count % 4) == 0) {
+               for (i = 0; i < count / 4; i++) {
+                       val = readl(regs + EFUSE_EFUDATA(i));
+                       put_unaligned(val, (u32 *)(buf + (i * 4)));
+               }
+       } else {
+               val = readl(regs + EFUSE_EFUDATA(0));
+               if (count > 2)
+                       buf[2] = (val >> 16) & 0xff;
+               if (count > 1)
+                       buf[1] = (val >> 8) & 0xff;
+               buf[0] = val & 0xff;
+       }
+}
+
+static inline int jz4780_efuse_chunk_size(size_t count)
+{
+       if (count >= 32)
+               return 32;
+       else if ((count / 4) > 0)
+               return (count / 4) * 4;
+       else
+               return count % 4;
+}
+
+void jz4780_efuse_read(size_t addr, size_t count, u8 *buf)
+{
+       size_t chunk;
+
+       while (count > 0) {
+               chunk = jz4780_efuse_chunk_size(count);
+               jz4780_efuse_read_chunk(addr, chunk, buf);
+               addr += chunk;
+               buf += chunk;
+               count -= chunk;
+       }
+}
+
+void jz4780_efuse_init(u32 ahb2_rate)
+{
+       void __iomem *regs = (void __iomem *)NEMC_BASE;
+       u32 rd_adj, rd_strobe, tmp;
+
+       rd_adj = (((6500 * (ahb2_rate / 1000000)) / 1000000) + 0xf) / 2;
+       tmp = (((35000 * (ahb2_rate / 1000000)) / 1000000) - 4) - rd_adj;
+       rd_strobe = ((tmp + 0xf) / 2 < 7) ? 7 : (tmp + 0xf) / 2;
+
+       tmp = (rd_adj << EFUSE_EFUCFG_RD_ADJ_BIT) |
+             (rd_strobe << EFUSE_EFUCFG_RD_STROBE_BIT);
+       writel(tmp, regs + EFUSE_EFUCFG);
+}
index fbd13964a0842b9a40963a2b8511876f69281956..496b2cba64053bd9f1151c23ce395576b678832f 100644 (file)
@@ -332,6 +332,12 @@ config MMC_BCM2835
 
          If unsure, say N.
 
+config JZ47XX_MMC
+       bool "Ingenic JZ47xx SD/MMC Host Controller support"
+       depends on ARCH_JZ47XX
+       help
+         This selects support for the SD Card Controller on Ingenic JZ47xx SoCs.
+
 config MMC_SANDBOX
        bool "Sandbox MMC support"
        depends on SANDBOX
index 801a26d82192de4317f8640b996e6e4b777d24f9..7892c468f05cb500249f7c54956249292199306a 100644 (file)
@@ -40,6 +40,7 @@ obj-$(CONFIG_MMC_SANDBOX)             += sandbox_mmc.o
 obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
 obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
+obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
 
 # SDHCI
 obj-$(CONFIG_MMC_SDHCI)                        += sdhci.o
diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
new file mode 100644 (file)
index 0000000..3132c3e
--- /dev/null
@@ -0,0 +1,488 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Ingenic JZ MMC driver
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <errno.h>
+#include <mach/jz4780.h>
+#include <wait_bit.h>
+
+/* Registers */
+#define MSC_STRPCL                     0x000
+#define MSC_STAT                       0x004
+#define MSC_CLKRT                      0x008
+#define MSC_CMDAT                      0x00c
+#define MSC_RESTO                      0x010
+#define MSC_RDTO                       0x014
+#define MSC_BLKLEN                     0x018
+#define MSC_NOB                                0x01c
+#define MSC_SNOB                       0x020
+#define MSC_IMASK                      0x024
+#define MSC_IREG                       0x028
+#define MSC_CMD                                0x02c
+#define MSC_ARG                                0x030
+#define MSC_RES                                0x034
+#define MSC_RXFIFO                     0x038
+#define MSC_TXFIFO                     0x03c
+#define MSC_LPM                                0x040
+#define MSC_DMAC                       0x044
+#define MSC_DMANDA                     0x048
+#define MSC_DMADA                      0x04c
+#define MSC_DMALEN                     0x050
+#define MSC_DMACMD                     0x054
+#define MSC_CTRL2                      0x058
+#define MSC_RTCNT                      0x05c
+#define MSC_DBG                                0x0fc
+
+/* MSC Clock and Control Register (MSC_STRPCL) */
+#define MSC_STRPCL_EXIT_MULTIPLE       BIT(7)
+#define MSC_STRPCL_EXIT_TRANSFER       BIT(6)
+#define MSC_STRPCL_START_READWAIT      BIT(5)
+#define MSC_STRPCL_STOP_READWAIT       BIT(4)
+#define MSC_STRPCL_RESET               BIT(3)
+#define MSC_STRPCL_START_OP            BIT(2)
+#define MSC_STRPCL_CLOCK_CONTROL_STOP  BIT(0)
+#define MSC_STRPCL_CLOCK_CONTROL_START BIT(1)
+
+/* MSC Status Register (MSC_STAT) */
+#define MSC_STAT_AUTO_CMD_DONE         BIT(31)
+#define MSC_STAT_IS_RESETTING          BIT(15)
+#define MSC_STAT_SDIO_INT_ACTIVE       BIT(14)
+#define MSC_STAT_PRG_DONE              BIT(13)
+#define MSC_STAT_DATA_TRAN_DONE                BIT(12)
+#define MSC_STAT_END_CMD_RES           BIT(11)
+#define MSC_STAT_DATA_FIFO_AFULL       BIT(10)
+#define MSC_STAT_IS_READWAIT           BIT(9)
+#define MSC_STAT_CLK_EN                        BIT(8)
+#define MSC_STAT_DATA_FIFO_FULL                BIT(7)
+#define MSC_STAT_DATA_FIFO_EMPTY       BIT(6)
+#define MSC_STAT_CRC_RES_ERR           BIT(5)
+#define MSC_STAT_CRC_READ_ERROR                BIT(4)
+#define MSC_STAT_CRC_WRITE_ERROR       BIT(2)
+#define MSC_STAT_CRC_WRITE_ERROR_NOSTS BIT(4)
+#define MSC_STAT_TIME_OUT_RES          BIT(1)
+#define MSC_STAT_TIME_OUT_READ         BIT(0)
+
+/* MSC Bus Clock Control Register (MSC_CLKRT) */
+#define MSC_CLKRT_CLK_RATE_MASK                0x7
+
+/* MSC Command Sequence Control Register (MSC_CMDAT) */
+#define MSC_CMDAT_IO_ABORT             BIT(11)
+#define MSC_CMDAT_BUS_WIDTH_1BIT       (0x0 << 9)
+#define MSC_CMDAT_BUS_WIDTH_4BIT       (0x2 << 9)
+#define MSC_CMDAT_DMA_EN               BIT(8)
+#define MSC_CMDAT_INIT                 BIT(7)
+#define MSC_CMDAT_BUSY                 BIT(6)
+#define MSC_CMDAT_STREAM_BLOCK         BIT(5)
+#define MSC_CMDAT_WRITE                        BIT(4)
+#define MSC_CMDAT_DATA_EN              BIT(3)
+#define MSC_CMDAT_RESPONSE_MASK                (0x7 << 0)
+#define MSC_CMDAT_RESPONSE_NONE                (0x0 << 0) /* No response */
+#define MSC_CMDAT_RESPONSE_R1          (0x1 << 0) /* Format R1 and R1b */
+#define MSC_CMDAT_RESPONSE_R2          (0x2 << 0) /* Format R2 */
+#define MSC_CMDAT_RESPONSE_R3          (0x3 << 0) /* Format R3 */
+#define MSC_CMDAT_RESPONSE_R4          (0x4 << 0) /* Format R4 */
+#define MSC_CMDAT_RESPONSE_R5          (0x5 << 0) /* Format R5 */
+#define MSC_CMDAT_RESPONSE_R6          (0x6 << 0) /* Format R6 */
+
+/* MSC Interrupts Mask Register (MSC_IMASK) */
+#define MSC_IMASK_TIME_OUT_RES         BIT(9)
+#define MSC_IMASK_TIME_OUT_READ                BIT(8)
+#define MSC_IMASK_SDIO                 BIT(7)
+#define MSC_IMASK_TXFIFO_WR_REQ                BIT(6)
+#define MSC_IMASK_RXFIFO_RD_REQ                BIT(5)
+#define MSC_IMASK_END_CMD_RES          BIT(2)
+#define MSC_IMASK_PRG_DONE             BIT(1)
+#define MSC_IMASK_DATA_TRAN_DONE       BIT(0)
+
+/* MSC Interrupts Status Register (MSC_IREG) */
+#define MSC_IREG_TIME_OUT_RES          BIT(9)
+#define MSC_IREG_TIME_OUT_READ         BIT(8)
+#define MSC_IREG_SDIO                  BIT(7)
+#define MSC_IREG_TXFIFO_WR_REQ         BIT(6)
+#define MSC_IREG_RXFIFO_RD_REQ         BIT(5)
+#define MSC_IREG_END_CMD_RES           BIT(2)
+#define MSC_IREG_PRG_DONE              BIT(1)
+#define MSC_IREG_DATA_TRAN_DONE                BIT(0)
+
+struct jz_mmc_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
+struct jz_mmc_priv {
+       void __iomem            *regs;
+       u32                     flags;
+/* priv flags */
+#define JZ_MMC_BUS_WIDTH_MASK  0x3
+#define JZ_MMC_BUS_WIDTH_1     0x0
+#define JZ_MMC_BUS_WIDTH_4     0x2
+#define JZ_MMC_BUS_WIDTH_8     0x3
+#define JZ_MMC_SENT_INIT       BIT(2)
+};
+
+static int jz_mmc_clock_rate(void)
+{
+       return 24000000;
+}
+
+static int jz_mmc_send_cmd(struct mmc *mmc, struct jz_mmc_priv *priv,
+                          struct mmc_cmd *cmd, struct mmc_data *data)
+{
+       u32 stat, mask, cmdat = 0;
+       int i, ret;
+
+       /* stop the clock */
+       writel(MSC_STRPCL_CLOCK_CONTROL_STOP, priv->regs + MSC_STRPCL);
+       ret = wait_for_bit_le32(priv->regs + MSC_STAT,
+                               MSC_STAT_CLK_EN, false, 10000, false);
+       if (ret)
+               return ret;
+
+       writel(0, priv->regs + MSC_DMAC);
+
+       /* setup command */
+       writel(cmd->cmdidx, priv->regs + MSC_CMD);
+       writel(cmd->cmdarg, priv->regs + MSC_ARG);
+
+       if (data) {
+               /* setup data */
+               cmdat |= MSC_CMDAT_DATA_EN;
+               if (data->flags & MMC_DATA_WRITE)
+                       cmdat |= MSC_CMDAT_WRITE;
+
+               writel(data->blocks, priv->regs + MSC_NOB);
+               writel(data->blocksize, priv->regs + MSC_BLKLEN);
+       } else {
+               writel(0, priv->regs + MSC_NOB);
+               writel(0, priv->regs + MSC_BLKLEN);
+       }
+
+       /* setup response */
+       switch (cmd->resp_type) {
+       case MMC_RSP_NONE:
+               break;
+       case MMC_RSP_R1:
+       case MMC_RSP_R1b:
+               cmdat |= MSC_CMDAT_RESPONSE_R1;
+               break;
+       case MMC_RSP_R2:
+               cmdat |= MSC_CMDAT_RESPONSE_R2;
+               break;
+       case MMC_RSP_R3:
+               cmdat |= MSC_CMDAT_RESPONSE_R3;
+               break;
+       default:
+               break;
+       }
+
+       if (cmd->resp_type & MMC_RSP_BUSY)
+               cmdat |= MSC_CMDAT_BUSY;
+
+       /* set init for the first command only */
+       if (!(priv->flags & JZ_MMC_SENT_INIT)) {
+               cmdat |= MSC_CMDAT_INIT;
+               priv->flags |= JZ_MMC_SENT_INIT;
+       }
+
+       cmdat |= (priv->flags & JZ_MMC_BUS_WIDTH_MASK) << 9;
+
+       /* write the data setup */
+       writel(cmdat, priv->regs + MSC_CMDAT);
+
+       /* unmask interrupts */
+       mask = 0xffffffff & ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_TIME_OUT_RES);
+       if (data) {
+               mask &= ~MSC_IMASK_DATA_TRAN_DONE;
+               if (data->flags & MMC_DATA_WRITE) {
+                       mask &= ~MSC_IMASK_TXFIFO_WR_REQ;
+               } else {
+                       mask &= ~(MSC_IMASK_RXFIFO_RD_REQ |
+                                 MSC_IMASK_TIME_OUT_READ);
+               }
+       }
+       writel(mask, priv->regs + MSC_IMASK);
+
+       /* clear interrupts */
+       writel(0xffffffff, priv->regs + MSC_IREG);
+
+       /* start the command (& the clock) */
+       writel(MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START,
+              priv->regs + MSC_STRPCL);
+
+       /* wait for completion */
+       for (i = 0; i < 100; i++) {
+               stat = readl(priv->regs + MSC_IREG);
+               stat &= MSC_IREG_END_CMD_RES | MSC_IREG_TIME_OUT_RES;
+               if (stat)
+                       break;
+               mdelay(1);
+       }
+       writel(stat, priv->regs + MSC_IREG);
+       if (stat & MSC_IREG_TIME_OUT_RES)
+               return -ETIMEDOUT;
+
+       if (cmd->resp_type & MMC_RSP_PRESENT) {
+               /* read the response */
+               if (cmd->resp_type & MMC_RSP_136) {
+                       u16 a, b, c, i;
+
+                       a = readw(priv->regs + MSC_RES);
+                       for (i = 0; i < 4; i++) {
+                               b = readw(priv->regs + MSC_RES);
+                               c = readw(priv->regs + MSC_RES);
+                               cmd->response[i] =
+                                       (a << 24) | (b << 8) | (c >> 8);
+                               a = c;
+                       }
+               } else {
+                       cmd->response[0] = readw(priv->regs + MSC_RES) << 24;
+                       cmd->response[0] |= readw(priv->regs + MSC_RES) << 8;
+                       cmd->response[0] |= readw(priv->regs + MSC_RES) & 0xff;
+               }
+       }
+
+       if (data && (data->flags & MMC_DATA_WRITE)) {
+               /* write the data */
+               int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4);
+               const void *buf = data->src;
+
+               while (sz--) {
+                       u32 val = get_unaligned_le32(buf);
+
+                       wait_for_bit_le32(priv->regs + MSC_IREG,
+                                         MSC_IREG_TXFIFO_WR_REQ,
+                                         true, 10000, false);
+                       writel(val, priv->regs + MSC_TXFIFO);
+                       buf += 4;
+               }
+       } else if (data && (data->flags & MMC_DATA_READ)) {
+               /* read the data */
+               int sz = data->blocks * data->blocksize;
+               void *buf = data->dest;
+
+               do {
+                       stat = readl(priv->regs + MSC_STAT);
+
+                       if (stat & MSC_STAT_TIME_OUT_READ)
+                               return -ETIMEDOUT;
+                       if (stat & MSC_STAT_CRC_READ_ERROR)
+                               return -EINVAL;
+                       if (stat & MSC_STAT_DATA_FIFO_EMPTY) {
+                               udelay(10);
+                               continue;
+                       }
+                       do {
+                               u32 val = readl(priv->regs + MSC_RXFIFO);
+
+                               if (sz == 1)
+                                       *(u8 *)buf = (u8)val;
+                               else if (sz == 2)
+                                       put_unaligned_le16(val, buf);
+                               else if (sz >= 4)
+                                       put_unaligned_le32(val, buf);
+                               buf += 4;
+                               sz -= 4;
+                               stat = readl(priv->regs + MSC_STAT);
+                       } while (!(stat & MSC_STAT_DATA_FIFO_EMPTY));
+               } while (!(stat & MSC_STAT_DATA_TRAN_DONE));
+       }
+
+       return 0;
+}
+
+static int jz_mmc_set_ios(struct mmc *mmc, struct jz_mmc_priv *priv)
+{
+       u32 real_rate = jz_mmc_clock_rate();
+       u8 clk_div = 0;
+
+       /* calculate clock divide */
+       while ((real_rate > mmc->clock) && (clk_div < 7)) {
+               real_rate >>= 1;
+               clk_div++;
+       }
+       writel(clk_div & MSC_CLKRT_CLK_RATE_MASK, priv->regs + MSC_CLKRT);
+
+       /* set the bus width for the next command */
+       priv->flags &= ~JZ_MMC_BUS_WIDTH_MASK;
+       if (mmc->bus_width == 8)
+               priv->flags |= JZ_MMC_BUS_WIDTH_8;
+       else if (mmc->bus_width == 4)
+               priv->flags |= JZ_MMC_BUS_WIDTH_4;
+       else
+               priv->flags |= JZ_MMC_BUS_WIDTH_1;
+
+       return 0;
+}
+
+static int jz_mmc_core_init(struct mmc *mmc)
+{
+       struct jz_mmc_priv *priv = mmc->priv;
+       int ret;
+
+       /* Reset */
+       writel(MSC_STRPCL_RESET, priv->regs + MSC_STRPCL);
+       ret = wait_for_bit_le32(priv->regs + MSC_STAT,
+                               MSC_STAT_IS_RESETTING, false, 10000, false);
+       if (ret)
+               return ret;
+
+       /* Maximum timeouts */
+       writel(0xffff, priv->regs + MSC_RESTO);
+       writel(0xffffffff, priv->regs + MSC_RDTO);
+
+       /* Enable low power mode */
+       writel(0x1, priv->regs + MSC_LPM);
+
+       return 0;
+}
+
+#if !CONFIG_IS_ENABLED(DM_MMC)
+
+static int jz_mmc_legacy_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+                                 struct mmc_data *data)
+{
+       struct jz_mmc_priv *priv = mmc->priv;
+
+       return jz_mmc_send_cmd(mmc, priv, cmd, data);
+}
+
+static int jz_mmc_legacy_set_ios(struct mmc *mmc)
+{
+       struct jz_mmc_priv *priv = mmc->priv;
+
+       return jz_mmc_set_ios(mmc, priv);
+};
+
+static const struct mmc_ops jz_msc_ops = {
+       .send_cmd       = jz_mmc_legacy_send_cmd,
+       .set_ios        = jz_mmc_legacy_set_ios,
+       .init           = jz_mmc_core_init,
+};
+
+static struct jz_mmc_priv jz_mmc_priv_static;
+static struct jz_mmc_plat jz_mmc_plat_static = {
+       .cfg = {
+               .name = "MSC",
+               .ops = &jz_msc_ops,
+
+               .voltages = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
+                           MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
+                           MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36,
+               .host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
+
+               .f_min = 375000,
+               .f_max = 48000000,
+               .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+       },
+};
+
+int jz_mmc_init(void __iomem *base)
+{
+       struct mmc *mmc;
+
+       jz_mmc_priv_static.regs = base;
+
+       mmc = mmc_create(&jz_mmc_plat_static.cfg, &jz_mmc_priv_static);
+
+       return mmc ? 0 : -ENODEV;
+}
+
+#else /* CONFIG_DM_MMC */
+
+#include <dm.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+static int jz_mmc_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+                             struct mmc_data *data)
+{
+       struct jz_mmc_priv *priv = dev_get_priv(dev);
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+       return jz_mmc_send_cmd(mmc, priv, cmd, data);
+}
+
+static int jz_mmc_dm_set_ios(struct udevice *dev)
+{
+       struct jz_mmc_priv *priv = dev_get_priv(dev);
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+       return jz_mmc_set_ios(mmc, priv);
+};
+
+static const struct dm_mmc_ops jz_msc_ops = {
+       .send_cmd       = jz_mmc_dm_send_cmd,
+       .set_ios        = jz_mmc_dm_set_ios,
+};
+
+static int jz_mmc_ofdata_to_platdata(struct udevice *dev)
+{
+       struct jz_mmc_priv *priv = dev_get_priv(dev);
+       struct jz_mmc_plat *plat = dev_get_platdata(dev);
+       struct mmc_config *cfg;
+       int ret;
+
+       priv->regs = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE);
+       cfg = &plat->cfg;
+
+       cfg->name = "MSC";
+       cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
+
+       ret = mmc_of_parse(dev, cfg);
+       if (ret < 0) {
+               dev_err(dev, "failed to parse host caps\n");
+               return ret;
+       }
+
+       cfg->f_min = 400000;
+       cfg->f_max = 52000000;
+
+       cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+       cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+       return 0;
+}
+
+static int jz_mmc_bind(struct udevice *dev)
+{
+       struct jz_mmc_plat *plat = dev_get_platdata(dev);
+
+       return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static int jz_mmc_probe(struct udevice *dev)
+{
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct jz_mmc_priv *priv = dev_get_priv(dev);
+       struct jz_mmc_plat *plat = dev_get_platdata(dev);
+
+       plat->mmc.priv = priv;
+       upriv->mmc = &plat->mmc;
+       return jz_mmc_core_init(&plat->mmc);
+}
+
+static const struct udevice_id jz_mmc_ids[] = {
+       { .compatible = "ingenic,jz4780-mmc" },
+       { }
+};
+
+U_BOOT_DRIVER(jz_mmc_drv) = {
+       .name                   = "jz_mmc",
+       .id                     = UCLASS_MMC,
+       .of_match               = jz_mmc_ids,
+       .ofdata_to_platdata     = jz_mmc_ofdata_to_platdata,
+       .bind                   = jz_mmc_bind,
+       .probe                  = jz_mmc_probe,
+       .priv_auto_alloc_size   = sizeof(struct jz_mmc_priv),
+       .platdata_auto_alloc_size = sizeof(struct jz_mmc_plat),
+       .ops                    = &jz_msc_ops,
+};
+#endif /* CONFIG_DM_MMC */
index 8fb365fc5d2a64165dff2a4f003499f73759e68a..7044c6adf3273985b0675d79094c15830955bb73 100644 (file)
@@ -72,6 +72,24 @@ config BCM_SF2_ETH_GMAC
          by the BCM_SF2_ETH driver.
          Say Y to any bcmcygnus based platforms.
 
+config BCM6348_ETH
+       bool "BCM6348 EMAC support"
+       depends on DM_ETH && ARCH_BMIPS
+       select DMA
+       select DMA_CHANNELS
+       select MII
+       select PHYLIB
+       help
+         This driver supports the BCM6348 Ethernet MAC.
+
+config BCM6368_ETH
+       bool "BCM6368 EMAC support"
+       depends on DM_ETH && ARCH_BMIPS
+       select DMA
+       select MII
+       help
+         This driver supports the BCM6368 Ethernet MAC.
+
 config DWC_ETH_QOS
        bool "Synopsys DWC Ethernet QOS device support"
        depends on DM_ETH
index 99056aa041d08e3fd959d5bdcfbf6a713a7cb795..0dbfa0330688402318b3a4d03f82e7abac8a6c37 100644 (file)
@@ -6,6 +6,8 @@
 obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
 obj-$(CONFIG_AG7XXX) += ag7xxx.o
 obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o
+obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o
+obj-$(CONFIG_BCM6368_ETH) += bcm6368-eth.o
 obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
 obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
 obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
new file mode 100644 (file)
index 0000000..7100e68
--- /dev/null
@@ -0,0 +1,537 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ *     Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma.h>
+#include <miiphy.h>
+#include <net.h>
+#include <phy.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+#define ETH_RX_DESC                    PKTBUFSRX
+#define ETH_MAX_MTU_SIZE               1518
+#define ETH_TIMEOUT                    100
+#define ETH_TX_WATERMARK               32
+
+/* ETH Receiver Configuration register */
+#define ETH_RXCFG_REG                  0x00
+#define ETH_RXCFG_ENFLOW_SHIFT         5
+#define ETH_RXCFG_ENFLOW_MASK          (1 << ETH_RXCFG_ENFLOW_SHIFT)
+
+/* ETH Receive Maximum Length register */
+#define ETH_RXMAXLEN_REG               0x04
+#define ETH_RXMAXLEN_SHIFT             0
+#define ETH_RXMAXLEN_MASK              (0x7ff << ETH_RXMAXLEN_SHIFT)
+
+/* ETH Transmit Maximum Length register */
+#define ETH_TXMAXLEN_REG               0x08
+#define ETH_TXMAXLEN_SHIFT             0
+#define ETH_TXMAXLEN_MASK              (0x7ff << ETH_TXMAXLEN_SHIFT)
+
+/* MII Status/Control register */
+#define MII_SC_REG                     0x10
+#define MII_SC_MDCFREQDIV_SHIFT                0
+#define MII_SC_MDCFREQDIV_MASK         (0x7f << MII_SC_MDCFREQDIV_SHIFT)
+#define MII_SC_PREAMBLE_EN_SHIFT       7
+#define MII_SC_PREAMBLE_EN_MASK                (1 << MII_SC_PREAMBLE_EN_SHIFT)
+
+/* MII Data register */
+#define MII_DAT_REG                    0x14
+#define MII_DAT_DATA_SHIFT             0
+#define MII_DAT_DATA_MASK              (0xffff << MII_DAT_DATA_SHIFT)
+#define MII_DAT_TA_SHIFT               16
+#define MII_DAT_TA_MASK                        (0x3 << MII_DAT_TA_SHIFT)
+#define MII_DAT_REG_SHIFT              18
+#define MII_DAT_REG_MASK               (0x1f << MII_DAT_REG_SHIFT)
+#define MII_DAT_PHY_SHIFT              23
+#define MII_DAT_PHY_MASK               (0x1f << MII_DAT_PHY_SHIFT)
+#define MII_DAT_OP_SHIFT               28
+#define MII_DAT_OP_WRITE               (0x5 << MII_DAT_OP_SHIFT)
+#define MII_DAT_OP_READ                        (0x6 << MII_DAT_OP_SHIFT)
+
+/* ETH Interrupts Mask register */
+#define ETH_IRMASK_REG                 0x18
+
+/* ETH Interrupts register */
+#define ETH_IR_REG                     0x1c
+#define ETH_IR_MII_SHIFT               0
+#define ETH_IR_MII_MASK                        (1 << ETH_IR_MII_SHIFT)
+
+/* ETH Control register */
+#define ETH_CTL_REG                    0x2c
+#define ETH_CTL_ENABLE_SHIFT           0
+#define ETH_CTL_ENABLE_MASK            (1 << ETH_CTL_ENABLE_SHIFT)
+#define ETH_CTL_DISABLE_SHIFT          1
+#define ETH_CTL_DISABLE_MASK           (1 << ETH_CTL_DISABLE_SHIFT)
+#define ETH_CTL_RESET_SHIFT            2
+#define ETH_CTL_RESET_MASK             (1 << ETH_CTL_RESET_SHIFT)
+#define ETH_CTL_EPHY_SHIFT             3
+#define ETH_CTL_EPHY_MASK              (1 << ETH_CTL_EPHY_SHIFT)
+
+/* ETH Transmit Control register */
+#define ETH_TXCTL_REG                  0x30
+#define ETH_TXCTL_FD_SHIFT             0
+#define ETH_TXCTL_FD_MASK              (1 << ETH_TXCTL_FD_SHIFT)
+
+/* ETH Transmit Watermask register */
+#define ETH_TXWMARK_REG                        0x34
+#define ETH_TXWMARK_WM_SHIFT           0
+#define ETH_TXWMARK_WM_MASK            (0x3f << ETH_TXWMARK_WM_SHIFT)
+
+/* MIB Control register */
+#define MIB_CTL_REG                    0x38
+#define MIB_CTL_RDCLEAR_SHIFT          0
+#define MIB_CTL_RDCLEAR_MASK           (1 << MIB_CTL_RDCLEAR_SHIFT)
+
+/* ETH Perfect Match registers */
+#define ETH_PM_CNT                     4
+#define ETH_PML_REG(x)                 (0x58 + (x) * 0x8)
+#define ETH_PMH_REG(x)                 (0x5c + (x) * 0x8)
+#define ETH_PMH_VALID_SHIFT            16
+#define ETH_PMH_VALID_MASK             (1 << ETH_PMH_VALID_SHIFT)
+
+/* MIB Counters registers */
+#define MIB_REG_CNT                    55
+#define MIB_REG(x)                     (0x200 + (x) * 4)
+
+/* ETH data */
+struct bcm6348_eth_priv {
+       void __iomem *base;
+       /* DMA */
+       struct dma rx_dma;
+       struct dma tx_dma;
+       /* PHY */
+       int phy_id;
+       struct phy_device *phy_dev;
+};
+
+static void bcm6348_eth_mac_disable(struct bcm6348_eth_priv *priv)
+{
+       /* disable emac */
+       clrsetbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK,
+                       ETH_CTL_DISABLE_MASK);
+
+       /* wait until emac is disabled */
+       if (wait_for_bit_be32(priv->base + ETH_CTL_REG,
+                             ETH_CTL_DISABLE_MASK, false,
+                             ETH_TIMEOUT, false))
+               pr_err("%s: error disabling emac\n", __func__);
+}
+
+static void bcm6348_eth_mac_enable(struct bcm6348_eth_priv *priv)
+{
+       setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK);
+}
+
+static void bcm6348_eth_mac_reset(struct bcm6348_eth_priv *priv)
+{
+       /* reset emac */
+       writel_be(ETH_CTL_RESET_MASK, priv->base + ETH_CTL_REG);
+       wmb();
+
+       /* wait until emac is reset */
+       if (wait_for_bit_be32(priv->base + ETH_CTL_REG,
+                             ETH_CTL_RESET_MASK, false,
+                             ETH_TIMEOUT, false))
+               pr_err("%s: error resetting emac\n", __func__);
+}
+
+static int bcm6348_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
+{
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+       return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
+}
+
+static int bcm6348_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+       return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
+}
+
+static int bcm6348_eth_send(struct udevice *dev, void *packet, int length)
+{
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+       return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+static int bcm6348_eth_adjust_link(struct udevice *dev,
+                                  struct phy_device *phydev)
+{
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+       /* mac duplex parameters */
+       if (phydev->duplex)
+               setbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK);
+       else
+               clrbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK);
+
+       /* rx flow control (pause frame handling) */
+       if (phydev->pause)
+               setbits_be32(priv->base + ETH_RXCFG_REG,
+                            ETH_RXCFG_ENFLOW_MASK);
+       else
+               clrbits_be32(priv->base + ETH_RXCFG_REG,
+                            ETH_RXCFG_ENFLOW_MASK);
+
+       return 0;
+}
+
+static int bcm6348_eth_start(struct udevice *dev)
+{
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+       int ret, i;
+
+       /* prepare rx dma buffers */
+       for (i = 0; i < ETH_RX_DESC; i++) {
+               ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
+                                         PKTSIZE_ALIGN);
+               if (ret < 0)
+                       break;
+       }
+
+       /* enable dma rx channel */
+       dma_enable(&priv->rx_dma);
+
+       /* enable dma tx channel */
+       dma_enable(&priv->tx_dma);
+
+       ret = phy_startup(priv->phy_dev);
+       if (ret) {
+               pr_err("%s: could not initialize phy\n", __func__);
+               return ret;
+       }
+
+       if (!priv->phy_dev->link) {
+               pr_err("%s: no phy link\n", __func__);
+               return -EIO;
+       }
+
+       bcm6348_eth_adjust_link(dev, priv->phy_dev);
+
+       /* zero mib counters */
+       for (i = 0; i < MIB_REG_CNT; i++)
+               writel_be(0, MIB_REG(i));
+
+       /* enable rx flow control */
+       setbits_be32(priv->base + ETH_RXCFG_REG, ETH_RXCFG_ENFLOW_MASK);
+
+       /* set max rx/tx length */
+       writel_be((ETH_MAX_MTU_SIZE << ETH_RXMAXLEN_SHIFT) &
+                 ETH_RXMAXLEN_MASK, priv->base + ETH_RXMAXLEN_REG);
+       writel_be((ETH_MAX_MTU_SIZE << ETH_TXMAXLEN_SHIFT) &
+                 ETH_TXMAXLEN_MASK, priv->base + ETH_TXMAXLEN_REG);
+
+       /* set correct transmit fifo watermark */
+       writel_be((ETH_TX_WATERMARK << ETH_TXWMARK_WM_SHIFT) &
+                 ETH_TXWMARK_WM_MASK, priv->base + ETH_TXWMARK_REG);
+
+       /* enable emac */
+       bcm6348_eth_mac_enable(priv);
+
+       /* clear interrupts */
+       writel_be(0, priv->base + ETH_IRMASK_REG);
+
+       return 0;
+}
+
+static void bcm6348_eth_stop(struct udevice *dev)
+{
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+       /* disable dma rx channel */
+       dma_disable(&priv->rx_dma);
+
+       /* disable dma tx channel */
+       dma_disable(&priv->tx_dma);
+
+       /* disable emac */
+       bcm6348_eth_mac_disable(priv);
+}
+
+static int bcm6348_eth_write_hwaddr(struct udevice *dev)
+{
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+       bool running = false;
+
+       /* check if emac is running */
+       if (readl_be(priv->base + ETH_CTL_REG) & ETH_CTL_ENABLE_MASK)
+               running = true;
+
+       /* disable emac */
+       if (running)
+               bcm6348_eth_mac_disable(priv);
+
+       /* set mac address */
+       writel_be((pdata->enetaddr[2] << 24) | (pdata->enetaddr[3]) << 16 |
+                 (pdata->enetaddr[4]) << 8 | (pdata->enetaddr[5]),
+                 priv->base + ETH_PML_REG(0));
+       writel_be((pdata->enetaddr[1]) | (pdata->enetaddr[0] << 8) |
+                 ETH_PMH_VALID_MASK, priv->base + ETH_PMH_REG(0));
+
+       /* enable emac */
+       if (running)
+               bcm6348_eth_mac_enable(priv);
+
+       return 0;
+}
+
+static const struct eth_ops bcm6348_eth_ops = {
+       .free_pkt = bcm6348_eth_free_pkt,
+       .recv = bcm6348_eth_recv,
+       .send = bcm6348_eth_send,
+       .start = bcm6348_eth_start,
+       .stop = bcm6348_eth_stop,
+       .write_hwaddr = bcm6348_eth_write_hwaddr,
+};
+
+static const struct udevice_id bcm6348_eth_ids[] = {
+       { .compatible = "brcm,bcm6348-enet", },
+       { /* sentinel */ }
+};
+
+static int bcm6348_mdio_op(void __iomem *base, uint32_t data)
+{
+       /* make sure mii interrupt status is cleared */
+       writel_be(ETH_IR_MII_MASK, base + ETH_IR_REG);
+
+       /* issue mii op */
+       writel_be(data, base + MII_DAT_REG);
+
+       /* wait until emac is disabled */
+       return wait_for_bit_be32(base + ETH_IR_REG,
+                                ETH_IR_MII_MASK, true,
+                                ETH_TIMEOUT, false);
+}
+
+static int bcm6348_mdio_read(struct mii_dev *bus, int addr, int devaddr,
+                            int reg)
+{
+       void __iomem *base = bus->priv;
+       uint32_t val;
+
+       val = MII_DAT_OP_READ;
+       val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK;
+       val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK;
+       val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK;
+
+       if (bcm6348_mdio_op(base, val)) {
+               pr_err("%s: timeout\n", __func__);
+               return -EINVAL;
+       }
+
+       val = readl_be(base + MII_DAT_REG) & MII_DAT_DATA_MASK;
+       val >>= MII_DAT_DATA_SHIFT;
+
+       return val;
+}
+
+static int bcm6348_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
+                             int reg, u16 value)
+{
+       void __iomem *base = bus->priv;
+       uint32_t val;
+
+       val = MII_DAT_OP_WRITE;
+       val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK;
+       val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK;
+       val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK;
+       val |= (value << MII_DAT_DATA_SHIFT) & MII_DAT_DATA_MASK;
+
+       if (bcm6348_mdio_op(base, val)) {
+               pr_err("%s: timeout\n", __func__);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int bcm6348_mdio_init(const char *name, void __iomem *base)
+{
+       struct mii_dev *bus;
+
+       bus = mdio_alloc();
+       if (!bus) {
+               pr_err("%s: failed to allocate MDIO bus\n", __func__);
+               return -ENOMEM;
+       }
+
+       bus->read = bcm6348_mdio_read;
+       bus->write = bcm6348_mdio_write;
+       bus->priv = base;
+       snprintf(bus->name, sizeof(bus->name), "%s", name);
+
+       return mdio_register(bus);
+}
+
+static int bcm6348_phy_init(struct udevice *dev)
+{
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+       struct mii_dev *bus;
+
+       /* get mii bus */
+       bus = miiphy_get_dev_by_name(dev->name);
+
+       /* phy connect */
+       priv->phy_dev = phy_connect(bus, priv->phy_id, dev,
+                                   pdata->phy_interface);
+       if (!priv->phy_dev) {
+               pr_err("%s: no phy device\n", __func__);
+               return -ENODEV;
+       }
+
+       priv->phy_dev->supported = (SUPPORTED_10baseT_Half |
+                                   SUPPORTED_10baseT_Full |
+                                   SUPPORTED_100baseT_Half |
+                                   SUPPORTED_100baseT_Full |
+                                   SUPPORTED_Autoneg |
+                                   SUPPORTED_Pause |
+                                   SUPPORTED_MII);
+       priv->phy_dev->advertising = priv->phy_dev->supported;
+
+       /* phy config */
+       phy_config(priv->phy_dev);
+
+       return 0;
+}
+
+static int bcm6348_eth_probe(struct udevice *dev)
+{
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+       struct ofnode_phandle_args phy;
+       const char *phy_mode;
+       int ret, i;
+
+       /* get base address */
+       priv->base = dev_remap_addr(dev);
+       if (!priv->base)
+               return -EINVAL;
+       pdata->iobase = (phys_addr_t) priv->base;
+
+       /* get phy mode */
+       pdata->phy_interface = PHY_INTERFACE_MODE_NONE;
+       phy_mode = dev_read_string(dev, "phy-mode");
+       if (phy_mode)
+               pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+       if (pdata->phy_interface == PHY_INTERFACE_MODE_NONE)
+               return -ENODEV;
+
+       /* get phy */
+       if (dev_read_phandle_with_args(dev, "phy", NULL, 0, 0, &phy))
+               return -ENOENT;
+       priv->phy_id = ofnode_read_u32_default(phy.node, "reg", -1);
+
+       /* get dma channels */
+       ret = dma_get_by_name(dev, "tx", &priv->tx_dma);
+       if (ret)
+               return -EINVAL;
+
+       ret = dma_get_by_name(dev, "rx", &priv->rx_dma);
+       if (ret)
+               return -EINVAL;
+
+       /* try to enable clocks */
+       for (i = 0; ; i++) {
+               struct clk clk;
+               int ret;
+
+               ret = clk_get_by_index(dev, i, &clk);
+               if (ret < 0)
+                       break;
+
+               ret = clk_enable(&clk);
+               if (ret < 0) {
+                       pr_err("%s: error enabling clock %d\n", __func__, i);
+                       return ret;
+               }
+
+               ret = clk_free(&clk);
+               if (ret < 0) {
+                       pr_err("%s: error freeing clock %d\n", __func__, i);
+                       return ret;
+               }
+       }
+
+       /* try to perform resets */
+       for (i = 0; ; i++) {
+               struct reset_ctl reset;
+               int ret;
+
+               ret = reset_get_by_index(dev, i, &reset);
+               if (ret < 0)
+                       break;
+
+               ret = reset_deassert(&reset);
+               if (ret < 0) {
+                       pr_err("%s: error deasserting reset %d\n", __func__, i);
+                       return ret;
+               }
+
+               ret = reset_free(&reset);
+               if (ret < 0) {
+                       pr_err("%s: error freeing reset %d\n", __func__, i);
+                       return ret;
+               }
+       }
+
+       /* disable emac */
+       bcm6348_eth_mac_disable(priv);
+
+       /* reset emac */
+       bcm6348_eth_mac_reset(priv);
+
+       /* select correct mii interface */
+       if (pdata->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
+               clrbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK);
+       else
+               setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK);
+
+       /* turn on mdc clock */
+       writel_be((0x1f << MII_SC_MDCFREQDIV_SHIFT) |
+                 MII_SC_PREAMBLE_EN_MASK, priv->base + MII_SC_REG);
+
+       /* set mib counters to not clear when read */
+       clrbits_be32(priv->base + MIB_CTL_REG, MIB_CTL_RDCLEAR_MASK);
+
+       /* initialize perfect match registers */
+       for (i = 0; i < ETH_PM_CNT; i++) {
+               writel_be(0, priv->base + ETH_PML_REG(i));
+               writel_be(0, priv->base + ETH_PMH_REG(i));
+       }
+
+       /* init mii bus */
+       ret = bcm6348_mdio_init(dev->name, priv->base);
+       if (ret)
+               return ret;
+
+       /* init phy */
+       ret = bcm6348_phy_init(dev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(bcm6348_eth) = {
+       .name = "bcm6348_eth",
+       .id = UCLASS_ETH,
+       .of_match = bcm6348_eth_ids,
+       .ops = &bcm6348_eth_ops,
+       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+       .priv_auto_alloc_size = sizeof(struct bcm6348_eth_priv),
+       .probe = bcm6348_eth_probe,
+};
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
new file mode 100644 (file)
index 0000000..a31efba
--- /dev/null
@@ -0,0 +1,625 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ *     Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma.h>
+#include <miiphy.h>
+#include <net.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+#define ETH_PORT_STR                   "brcm,enetsw-port"
+
+#define ETH_RX_DESC                    PKTBUFSRX
+#define ETH_ZLEN                       60
+#define ETH_TIMEOUT                    100
+
+#define ETH_MAX_PORT                   8
+#define ETH_RGMII_PORT0                        4
+
+/* Port traffic control */
+#define ETH_PTCTRL_REG(x)              (0x0 + (x))
+#define ETH_PTCTRL_RXDIS_SHIFT         0
+#define ETH_PTCTRL_RXDIS_MASK          (1 << ETH_PTCTRL_RXDIS_SHIFT)
+#define ETH_PTCTRL_TXDIS_SHIFT         1
+#define ETH_PTCTRL_TXDIS_MASK          (1 << ETH_PTCTRL_TXDIS_SHIFT)
+
+/* Switch mode register */
+#define ETH_SWMODE_REG                 0xb
+#define ETH_SWMODE_FWD_EN_SHIFT                1
+#define ETH_SWMODE_FWD_EN_MASK         (1 << ETH_SWMODE_FWD_EN_SHIFT)
+
+/* IMP override Register */
+#define ETH_IMPOV_REG                  0xe
+#define ETH_IMPOV_LINKUP_SHIFT         0
+#define ETH_IMPOV_LINKUP_MASK          (1 << ETH_IMPOV_LINKUP_SHIFT)
+#define ETH_IMPOV_FDX_SHIFT            1
+#define ETH_IMPOV_FDX_MASK             (1 << ETH_IMPOV_FDX_SHIFT)
+#define ETH_IMPOV_100_SHIFT            2
+#define ETH_IMPOV_100_MASK             (1 << ETH_IMPOV_100_SHIFT)
+#define ETH_IMPOV_1000_SHIFT           3
+#define ETH_IMPOV_1000_MASK            (1 << ETH_IMPOV_1000_SHIFT)
+#define ETH_IMPOV_RXFLOW_SHIFT         4
+#define ETH_IMPOV_RXFLOW_MASK          (1 << ETH_IMPOV_RXFLOW_SHIFT)
+#define ETH_IMPOV_TXFLOW_SHIFT         5
+#define ETH_IMPOV_TXFLOW_MASK          (1 << ETH_IMPOV_TXFLOW_SHIFT)
+#define ETH_IMPOV_FORCE_SHIFT          7
+#define ETH_IMPOV_FORCE_MASK           (1 << ETH_IMPOV_FORCE_SHIFT)
+
+/* Port override Register */
+#define ETH_PORTOV_REG(x)              (0x58 + (x))
+#define ETH_PORTOV_LINKUP_SHIFT                0
+#define ETH_PORTOV_LINKUP_MASK         (1 << ETH_PORTOV_LINKUP_SHIFT)
+#define ETH_PORTOV_FDX_SHIFT           1
+#define ETH_PORTOV_FDX_MASK            (1 << ETH_PORTOV_FDX_SHIFT)
+#define ETH_PORTOV_100_SHIFT           2
+#define ETH_PORTOV_100_MASK            (1 << ETH_PORTOV_100_SHIFT)
+#define ETH_PORTOV_1000_SHIFT          3
+#define ETH_PORTOV_1000_MASK           (1 << ETH_PORTOV_1000_SHIFT)
+#define ETH_PORTOV_RXFLOW_SHIFT                4
+#define ETH_PORTOV_RXFLOW_MASK         (1 << ETH_PORTOV_RXFLOW_SHIFT)
+#define ETH_PORTOV_TXFLOW_SHIFT                5
+#define ETH_PORTOV_TXFLOW_MASK         (1 << ETH_PORTOV_TXFLOW_SHIFT)
+#define ETH_PORTOV_ENABLE_SHIFT                6
+#define ETH_PORTOV_ENABLE_MASK         (1 << ETH_PORTOV_ENABLE_SHIFT)
+
+/* Port RGMII control register */
+#define ETH_RGMII_CTRL_REG(x)          (0x60 + (x))
+#define ETH_RGMII_CTRL_GMII_CLK_EN     (1 << 7)
+#define ETH_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6)
+#define ETH_RGMII_CTRL_MII_MODE_MASK   (3 << 4)
+#define ETH_RGMII_CTRL_RGMII_MODE      (0 << 4)
+#define ETH_RGMII_CTRL_MII_MODE                (1 << 4)
+#define ETH_RGMII_CTRL_RVMII_MODE      (2 << 4)
+#define ETH_RGMII_CTRL_TIMING_SEL_EN   (1 << 0)
+
+/* Port RGMII timing register */
+#define ENETSW_RGMII_TIMING_REG(x)     (0x68 + (x))
+
+/* MDIO control register */
+#define MII_SC_REG                     0xb0
+#define MII_SC_EXT_SHIFT               16
+#define MII_SC_EXT_MASK                        (1 << MII_SC_EXT_SHIFT)
+#define MII_SC_REG_SHIFT               20
+#define MII_SC_PHYID_SHIFT             25
+#define MII_SC_RD_SHIFT                        30
+#define MII_SC_RD_MASK                 (1 << MII_SC_RD_SHIFT)
+#define MII_SC_WR_SHIFT                        31
+#define MII_SC_WR_MASK                 (1 << MII_SC_WR_SHIFT)
+
+/* MDIO data register */
+#define MII_DAT_REG                    0xb4
+
+/* Global Management Configuration Register */
+#define ETH_GMCR_REG                   0x200
+#define ETH_GMCR_RST_MIB_SHIFT         0
+#define ETH_GMCR_RST_MIB_MASK          (1 << ETH_GMCR_RST_MIB_SHIFT)
+
+/* Jumbo control register port mask register */
+#define ETH_JMBCTL_PORT_REG            0x4004
+
+/* Jumbo control mib good frame register */
+#define ETH_JMBCTL_MAXSIZE_REG         0x4008
+
+/* ETH port data */
+struct bcm_enetsw_port {
+       bool used;
+       const char *name;
+       /* Config */
+       bool bypass_link;
+       int force_speed;
+       bool force_duplex_full;
+       /* PHY */
+       int phy_id;
+};
+
+/* ETH data */
+struct bcm6368_eth_priv {
+       void __iomem *base;
+       /* DMA */
+       struct dma rx_dma;
+       struct dma tx_dma;
+       /* Ports */
+       uint8_t num_ports;
+       struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
+       int sw_port_link[ETH_MAX_PORT];
+       bool rgmii_override;
+       bool rgmii_timing;
+       /* PHY */
+       int phy_id;
+};
+
+static inline bool bcm_enet_port_is_rgmii(int portid)
+{
+       return portid >= ETH_RGMII_PORT0;
+}
+
+static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
+                            int phy_id, int reg)
+{
+       uint32_t val;
+
+       writel_be(0, priv->base + MII_SC_REG);
+
+       val = MII_SC_RD_MASK |
+             (phy_id << MII_SC_PHYID_SHIFT) |
+             (reg << MII_SC_REG_SHIFT);
+
+       if (ext)
+               val |= MII_SC_EXT_MASK;
+
+       writel_be(val, priv->base + MII_SC_REG);
+       udelay(50);
+
+       return readw_be(priv->base + MII_DAT_REG);
+}
+
+static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
+                             int phy_id, int reg, u16 data)
+{
+       uint32_t val;
+
+       writel_be(0, priv->base + MII_SC_REG);
+
+       val = MII_SC_WR_MASK |
+             (phy_id << MII_SC_PHYID_SHIFT) |
+             (reg << MII_SC_REG_SHIFT);
+
+       if (ext)
+               val |= MII_SC_EXT_MASK;
+
+       val |= data;
+
+       writel_be(val, priv->base + MII_SC_REG);
+       udelay(50);
+
+       return 0;
+}
+
+static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
+{
+       struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+       return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
+}
+
+static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+       struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+       return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
+}
+
+static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
+{
+       struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+       /* pad packets smaller than ETH_ZLEN */
+       if (length < ETH_ZLEN) {
+               memset(packet + length, 0, ETH_ZLEN - length);
+               length = ETH_ZLEN;
+       }
+
+       return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+static int bcm6368_eth_adjust_link(struct udevice *dev)
+{
+       struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+       unsigned int i;
+
+       for (i = 0; i < priv->num_ports; i++) {
+               struct bcm_enetsw_port *port;
+               int val, j, up, adv, lpa, speed, duplex, media;
+               int external_phy = bcm_enet_port_is_rgmii(i);
+               u8 override;
+
+               port = &priv->used_ports[i];
+               if (!port->used)
+                       continue;
+
+               if (port->bypass_link)
+                       continue;
+
+               /* dummy read to clear */
+               for (j = 0; j < 2; j++)
+                       val = bcm6368_mdio_read(priv, external_phy,
+                                               port->phy_id, MII_BMSR);
+
+               if (val == 0xffff)
+                       continue;
+
+               up = (val & BMSR_LSTATUS) ? 1 : 0;
+               if (!(up ^ priv->sw_port_link[i]))
+                       continue;
+
+               priv->sw_port_link[i] = up;
+
+               /* link changed */
+               if (!up) {
+                       dev_info(&priv->pdev->dev, "link DOWN on %s\n",
+                                port->name);
+                       writeb_be(ETH_PORTOV_ENABLE_MASK,
+                                 priv->base + ETH_PORTOV_REG(i));
+                       writeb_be(ETH_PTCTRL_RXDIS_MASK |
+                                 ETH_PTCTRL_TXDIS_MASK,
+                                 priv->base + ETH_PTCTRL_REG(i));
+                       continue;
+               }
+
+               adv = bcm6368_mdio_read(priv, external_phy,
+                                       port->phy_id, MII_ADVERTISE);
+
+               lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
+                                       MII_LPA);
+
+               /* figure out media and duplex from advertise and LPA values */
+               media = mii_nway_result(lpa & adv);
+               duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+
+               if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+                       speed = 100;
+               else
+                       speed = 10;
+
+               if (val & BMSR_ESTATEN) {
+                       adv = bcm6368_mdio_read(priv, external_phy,
+                                               port->phy_id, MII_CTRL1000);
+
+                       lpa = bcm6368_mdio_read(priv, external_phy,
+                                               port->phy_id, MII_STAT1000);
+
+                       if ((adv & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
+                           (lpa & (LPA_1000FULL | LPA_1000HALF))) {
+                               speed = 1000;
+                               duplex = (lpa & LPA_1000FULL);
+                       }
+               }
+
+               pr_alert("link UP on %s, %dMbps, %s-duplex\n",
+                        port->name, speed, duplex ? "full" : "half");
+
+               override = ETH_PORTOV_ENABLE_MASK |
+                          ETH_PORTOV_LINKUP_MASK;
+
+               if (speed == 1000)
+                       override |= ETH_PORTOV_1000_MASK;
+               else if (speed == 100)
+                       override |= ETH_PORTOV_100_MASK;
+               if (duplex)
+                       override |= ETH_PORTOV_FDX_MASK;
+
+               writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+               writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+       }
+
+       return 0;
+}
+
+static int bcm6368_eth_start(struct udevice *dev)
+{
+       struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+       uint8_t i;
+
+       /* prepare rx dma buffers */
+       for (i = 0; i < ETH_RX_DESC; i++) {
+               int ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
+                                             PKTSIZE_ALIGN);
+               if (ret < 0)
+                       break;
+       }
+
+       /* enable dma rx channel */
+       dma_enable(&priv->rx_dma);
+
+       /* enable dma tx channel */
+       dma_enable(&priv->tx_dma);
+
+       /* apply override config for bypass_link ports here. */
+       for (i = 0; i < priv->num_ports; i++) {
+               struct bcm_enetsw_port *port;
+               u8 override;
+
+               port = &priv->used_ports[i];
+               if (!port->used)
+                       continue;
+
+               if (!port->bypass_link)
+                       continue;
+
+               override = ETH_PORTOV_ENABLE_MASK |
+                          ETH_PORTOV_LINKUP_MASK;
+
+               switch (port->force_speed) {
+               case 1000:
+                       override |= ETH_PORTOV_1000_MASK;
+                       break;
+               case 100:
+                       override |= ETH_PORTOV_100_MASK;
+                       break;
+               case 10:
+                       break;
+               default:
+                       pr_warn("%s: invalid forced speed on port %s\n",
+                               __func__, port->name);
+                       break;
+               }
+
+               if (port->force_duplex_full)
+                       override |= ETH_PORTOV_FDX_MASK;
+
+               writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+               writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+       }
+
+       bcm6368_eth_adjust_link(dev);
+
+       return 0;
+}
+
+static void bcm6368_eth_stop(struct udevice *dev)
+{
+       struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+       /* disable dma rx channel */
+       dma_disable(&priv->rx_dma);
+
+       /* disable dma tx channel */
+       dma_disable(&priv->tx_dma);
+}
+
+static const struct eth_ops bcm6368_eth_ops = {
+       .free_pkt = bcm6368_eth_free_pkt,
+       .recv = bcm6368_eth_recv,
+       .send = bcm6368_eth_send,
+       .start = bcm6368_eth_start,
+       .stop = bcm6368_eth_stop,
+};
+
+static const struct udevice_id bcm6368_eth_ids[] = {
+       { .compatible = "brcm,bcm6368-enet", },
+       { /* sentinel */ }
+};
+
+static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv, int phy_id)
+{
+       uint8_t i;
+
+       for (i = 0; i < priv->num_ports; ++i) {
+               if (!priv->used_ports[i].used)
+                       continue;
+               if (priv->used_ports[i].phy_id == phy_id)
+                       return bcm_enet_port_is_rgmii(i);
+       }
+
+       return true;
+}
+
+static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
+                                int reg)
+{
+       struct bcm6368_eth_priv *priv = bus->priv;
+       bool ext = bcm6368_phy_is_external(priv, addr);
+
+       return bcm6368_mdio_read(priv, ext, addr, reg);
+}
+
+static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
+                                 int reg, u16 data)
+{
+       struct bcm6368_eth_priv *priv = bus->priv;
+       bool ext = bcm6368_phy_is_external(priv, addr);
+
+       return bcm6368_mdio_write(priv, ext, addr, reg, data);
+}
+
+static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
+{
+       struct mii_dev *bus;
+
+       bus = mdio_alloc();
+       if (!bus) {
+               pr_err("%s: failed to allocate MDIO bus\n", __func__);
+               return -ENOMEM;
+       }
+
+       bus->read = bcm6368_mii_mdio_read;
+       bus->write = bcm6368_mii_mdio_write;
+       bus->priv = priv;
+       snprintf(bus->name, sizeof(bus->name), "%s", name);
+
+       return mdio_register(bus);
+}
+
+static int bcm6368_eth_probe(struct udevice *dev)
+{
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+       int num_ports, ret, i;
+       uint32_t val;
+       ofnode node;
+
+       /* get base address */
+       priv->base = dev_remap_addr(dev);
+       if (!priv->base)
+               return -EINVAL;
+       pdata->iobase = (phys_addr_t) priv->base;
+
+       /* get number of ports */
+       num_ports = dev_read_u32_default(dev, "brcm,num-ports", ETH_MAX_PORT);
+       if (!num_ports || num_ports > ETH_MAX_PORT)
+               return -EINVAL;
+
+       /* get dma channels */
+       ret = dma_get_by_name(dev, "tx", &priv->tx_dma);
+       if (ret)
+               return -EINVAL;
+
+       ret = dma_get_by_name(dev, "rx", &priv->rx_dma);
+       if (ret)
+               return -EINVAL;
+
+       /* try to enable clocks */
+       for (i = 0; ; i++) {
+               struct clk clk;
+               int ret;
+
+               ret = clk_get_by_index(dev, i, &clk);
+               if (ret < 0)
+                       break;
+
+               ret = clk_enable(&clk);
+               if (ret < 0) {
+                       pr_err("%s: error enabling clock %d\n", __func__, i);
+                       return ret;
+               }
+
+               ret = clk_free(&clk);
+               if (ret < 0) {
+                       pr_err("%s: error freeing clock %d\n", __func__, i);
+                       return ret;
+               }
+       }
+
+       /* try to perform resets */
+       for (i = 0; ; i++) {
+               struct reset_ctl reset;
+               int ret;
+
+               ret = reset_get_by_index(dev, i, &reset);
+               if (ret < 0)
+                       break;
+
+               ret = reset_deassert(&reset);
+               if (ret < 0) {
+                       pr_err("%s: error deasserting reset %d\n", __func__, i);
+                       return ret;
+               }
+
+               ret = reset_free(&reset);
+               if (ret < 0) {
+                       pr_err("%s: error freeing reset %d\n", __func__, i);
+                       return ret;
+               }
+       }
+
+       /* set priv data */
+       priv->num_ports = num_ports;
+       if (dev_read_bool(dev, "brcm,rgmii-override"))
+               priv->rgmii_override = true;
+       if (dev_read_bool(dev, "brcm,rgmii-timing"))
+               priv->rgmii_timing = true;
+
+       /* get ports */
+       dev_for_each_subnode(node, dev) {
+               const char *comp;
+               const char *label;
+               unsigned int p;
+               int phy_id;
+               int speed;
+
+               comp = ofnode_read_string(node, "compatible");
+               if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
+                       continue;
+
+               p = ofnode_read_u32_default(node, "reg", ETH_MAX_PORT);
+               if (p >= num_ports)
+                       return -EINVAL;
+
+               label = ofnode_read_string(node, "label");
+               if (!label) {
+                       debug("%s: node %s has no label\n", __func__,
+                             ofnode_get_name(node));
+                       return -EINVAL;
+               }
+
+               phy_id = ofnode_read_u32_default(node, "brcm,phy-id", -1);
+
+               priv->used_ports[p].used = true;
+               priv->used_ports[p].name = label;
+               priv->used_ports[p].phy_id = phy_id;
+
+               if (ofnode_read_bool(node, "full-duplex"))
+                       priv->used_ports[p].force_duplex_full = true;
+               if (ofnode_read_bool(node, "bypass-link"))
+                       priv->used_ports[p].bypass_link = true;
+               speed = ofnode_read_u32_default(node, "speed", 0);
+               if (speed)
+                       priv->used_ports[p].force_speed = speed;
+       }
+
+       /* init mii bus */
+       ret = bcm6368_mdio_init(dev->name, priv);
+       if (ret)
+               return ret;
+
+       /* disable all ports */
+       for (i = 0; i < priv->num_ports; i++) {
+               writeb_be(ETH_PORTOV_ENABLE_MASK,
+                             priv->base + ETH_PORTOV_REG(i));
+               writeb_be(ETH_PTCTRL_RXDIS_MASK |
+                             ETH_PTCTRL_TXDIS_MASK,
+                             priv->base + ETH_PTCTRL_REG(i));
+
+               priv->sw_port_link[i] = 0;
+       }
+
+       /* enable external ports */
+       for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
+               u8 rgmii_ctrl;
+
+               if (!priv->used_ports[i].used)
+                       continue;
+
+               rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i));
+               rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN;
+               if (priv->rgmii_override)
+                       rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
+               if (priv->rgmii_timing)
+                       rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;
+               writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i));
+       }
+
+       /* reset mib */
+       val = readb_be(priv->base + ETH_GMCR_REG);
+       val |= ETH_GMCR_RST_MIB_MASK;
+       writeb_be(val, priv->base + ETH_GMCR_REG);
+       mdelay(1);
+       val &= ~ETH_GMCR_RST_MIB_MASK;
+       writeb_be(val, priv->base + ETH_GMCR_REG);
+       mdelay(1);
+
+       /* force CPU port state */
+       val = readb_be(priv->base + ETH_IMPOV_REG);
+       val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK;
+       writeb_be(val, priv->base + ETH_IMPOV_REG);
+
+       /* enable switch forward engine */
+       val = readb_be(priv->base + ETH_SWMODE_REG);
+       val |= ETH_SWMODE_FWD_EN_MASK;
+       writeb_be(val, priv->base + ETH_SWMODE_REG);
+
+       /* enable jumbo on all ports */
+       writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
+       writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(bcm6368_eth) = {
+       .name = "bcm6368_eth",
+       .id = UCLASS_ETH,
+       .of_match = bcm6368_eth_ids,
+       .ops = &bcm6368_eth_ops,
+       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+       .priv_auto_alloc_size = sizeof(struct bcm6368_eth_priv),
+       .probe = bcm6368_eth_probe,
+};
index e837eb7688cc0e70623971bcb9bec2c7572c2a8d..cda4caa8034dd2910c4edd18af33300f5f9316ee 100644 (file)
@@ -656,7 +656,8 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
 
        phy_probe(dev);
 
-       bus->phymap[addr] = dev;
+       if (addr >= 0 && addr < PHY_MAX_ADDR)
+               bus->phymap[addr] = dev;
 
        return dev;
 }
index 7e6fad305aebc1d6fe6e15d352cba8e7c40814b2..1dbe2b104b245add7085907c8e8fc203287e1d6a 100644 (file)
@@ -306,6 +306,7 @@ source "drivers/pinctrl/nxp/Kconfig"
 source "drivers/pinctrl/renesas/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
 source "drivers/pinctrl/exynos/Kconfig"
+source "drivers/pinctrl/mscc/Kconfig"
 source "drivers/pinctrl/mvebu/Kconfig"
 source "drivers/pinctrl/broadcom/Kconfig"
 
index 293bad3a950bc97fdacca0b63253030a9e12f595..66d36b99d1ec5da84bd44b3b07a9f2da9bc00572 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_PIC32)   += pinctrl_pic32.o
 obj-$(CONFIG_PINCTRL_EXYNOS)   += exynos/
 obj-$(CONFIG_PINCTRL_MESON)    += meson/
 obj-$(CONFIG_PINCTRL_MTK)      += mediatek/
+obj-$(CONFIG_PINCTRL_MSCC)     += mscc/
 obj-$(CONFIG_ARCH_MVEBU)       += mvebu/
 obj-$(CONFIG_PINCTRL_SINGLE)   += pinctrl-single.o
 obj-$(CONFIG_PINCTRL_STI)      += pinctrl-sti.o
diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig
new file mode 100644 (file)
index 0000000..cfc6c06
--- /dev/null
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+config PINCTRL_MSCC
+       bool
+
+config PINCTRL_MSCC_OCELOT
+       depends on SOC_OCELOT && PINCTRL_FULL && OF_CONTROL
+       select PINCTRL_MSCC
+       default y
+       bool "Microsemi ocelot family pin control driver"
+       help
+          Support pin multiplexing and pin configuration control on
+          Microsemi ocelot SoCs.
+
+config PINCTRL_MSCC_LUTON
+       depends on SOC_LUTON && PINCTRL_FULL && OF_CONTROL
+       select PINCTRL_MSCC
+       default y
+       bool "Microsemi luton family pin control driver"
+       help
+          Support pin multiplexing and pin configuration control on
+          Microsemi luton SoCs.
diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile
new file mode 100644 (file)
index 0000000..6910671
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+obj-y += mscc-common.o
+obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o
+obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o
diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c
new file mode 100644 (file)
index 0000000..d74b8a6
--- /dev/null
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Microsemi SoCs pinctrl driver
+ *
+ * Author: <alexandre.belloni@free-electrons.com>
+ * Author: <gregory.clement@bootlin.com>
+ * License: Dual MIT/GPL
+ * Copyright (c) 2017 Microsemi Corporation
+ */
+
+#include <asm/gpio.h>
+#include <asm/system.h>
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <linux/io.h>
+#include "mscc-common.h"
+
+#define MSCC_GPIO_OUT_SET      0x0
+#define MSCC_GPIO_OUT_CLR      0x4
+#define MSCC_GPIO_OUT          0x8
+#define MSCC_GPIO_IN           0xc
+#define MSCC_GPIO_OE           0x10
+#define MSCC_GPIO_INTR         0x14
+#define MSCC_GPIO_INTR_ENA     0x18
+#define MSCC_GPIO_INTR_IDENT   0x1c
+#define MSCC_GPIO_ALT0         0x20
+#define MSCC_GPIO_ALT1         0x24
+
+static int mscc_get_functions_count(struct udevice *dev)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev);
+
+       return info->num_func;
+}
+
+static const char *mscc_get_function_name(struct udevice *dev,
+                                         unsigned int function)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev);
+
+       return info->function_names[function];
+}
+
+static int mscc_pin_function_idx(unsigned int pin, unsigned int function,
+                                const struct mscc_pin_data *mscc_pins)
+{
+       struct mscc_pin_caps *p = mscc_pins[pin].drv_data;
+       int i;
+
+       for (i = 0; i < MSCC_FUNC_PER_PIN; i++) {
+               if (function == p->functions[i])
+                       return i;
+       }
+
+       return -1;
+}
+
+static int mscc_pinmux_set_mux(struct udevice *dev,
+                              unsigned int pin_selector, unsigned int selector)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev);
+       struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data;
+       int f;
+
+       f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins);
+       if (f < 0)
+               return -EINVAL;
+       /*
+        * f is encoded on two bits.
+        * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of
+        * ALT1
+        * This is racy because both registers can't be updated at the same time
+        * but it doesn't matter much for now.
+        */
+       if (f & BIT(0))
+               setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
+       else
+               clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
+
+       if (f & BIT(1))
+               setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
+       else
+               clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
+
+       return 0;
+}
+
+static int mscc_pctl_get_groups_count(struct udevice *dev)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev);
+
+       return info->num_pins;
+}
+
+static const char *mscc_pctl_get_group_name(struct udevice *dev,
+                                           unsigned int group)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev);
+
+       return info->mscc_pins[group].name;
+}
+
+static int mscc_create_group_func_map(struct udevice *dev,
+                                     struct mscc_pinctrl *info)
+{
+       u16 pins[info->num_pins];
+       int f, npins, i;
+
+       for (f = 0; f < info->num_func; f++) {
+               for (npins = 0, i = 0; i < info->num_pins; i++) {
+                       if (mscc_pin_function_idx(i, f, info->mscc_pins) >= 0)
+                               pins[npins++] = i;
+               }
+
+               info->func[f].ngroups = npins;
+               info->func[f].groups = devm_kzalloc(dev, npins *
+                                                   sizeof(char *), GFP_KERNEL);
+               if (!info->func[f].groups)
+                       return -ENOMEM;
+
+               for (i = 0; i < npins; i++)
+                       info->func[f].groups[i] = info->mscc_pins[pins[i]].name;
+       }
+
+       return 0;
+}
+
+static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info)
+{
+       int ret;
+
+       ret = mscc_create_group_func_map(dev, info);
+       if (ret) {
+               dev_err(dev, "Unable to create group func map.\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int mscc_gpio_get(struct udevice *dev, unsigned int offset)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev->parent);
+       unsigned int val;
+
+       val = readl(info->regs + MSCC_GPIO_IN);
+
+       return !!(val & BIT(offset));
+}
+
+static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev->parent);
+
+       if (value)
+               writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET);
+       else
+               writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR);
+
+       return 0;
+}
+
+static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev->parent);
+       unsigned int val;
+
+       val = readl(info->regs + MSCC_GPIO_OE);
+
+       return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev->parent);
+
+       clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
+
+       return 0;
+}
+
+static int mscc_gpio_direction_output(struct udevice *dev,
+                                     unsigned int offset, int value)
+{
+       struct mscc_pinctrl *info = dev_get_priv(dev->parent);
+
+       setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
+
+       return mscc_gpio_set(dev, offset, value);
+}
+
+const struct dm_gpio_ops mscc_gpio_ops = {
+       .set_value = mscc_gpio_set,
+       .get_value = mscc_gpio_get,
+       .get_function = mscc_gpio_get_direction,
+       .direction_input = mscc_gpio_direction_input,
+       .direction_output = mscc_gpio_direction_output,
+};
+
+const struct pinctrl_ops mscc_pinctrl_ops = {
+       .get_pins_count = mscc_pctl_get_groups_count,
+       .get_pin_name = mscc_pctl_get_group_name,
+       .get_functions_count = mscc_get_functions_count,
+       .get_function_name = mscc_get_function_name,
+       .pinmux_set = mscc_pinmux_set_mux,
+       .set_state = pinctrl_generic_set_state,
+};
+
+int mscc_pinctrl_probe(struct udevice *dev, int num_func,
+                      const struct mscc_pin_data *mscc_pins, int num_pins,
+                      char *const *function_names)
+{
+       struct mscc_pinctrl *priv = dev_get_priv(dev);
+       int ret;
+
+       priv->regs = dev_remap_addr(dev);
+       if (!priv->regs)
+               return -EINVAL;
+
+       priv->func = devm_kzalloc(dev, num_func * sizeof(struct mscc_pmx_func),
+                                 GFP_KERNEL);
+       priv->num_func = num_func;
+       priv->mscc_pins = mscc_pins;
+       priv->num_pins = num_pins;
+       priv->function_names = function_names;
+       ret = mscc_pinctrl_register(dev, priv);
+
+       return ret;
+}
diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h
new file mode 100644 (file)
index 0000000..b0001db
--- /dev/null
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Microsemi SoCs pinctrl driver
+ *
+ * Author: <alexandre.belloni@free-electrons.com>
+ * License: Dual MIT/GPL
+ * Copyright (c) 2017 Microsemi Corporation
+ */
+
+#define MSCC_FUNC_PER_PIN      4
+
+struct mscc_pin_caps {
+       unsigned int pin;
+       unsigned char functions[MSCC_FUNC_PER_PIN];
+};
+
+struct mscc_pin_data {
+       const char *name;
+       struct mscc_pin_caps *drv_data;
+};
+
+#define MSCC_P(p, f0, f1, f2)                                          \
+static struct mscc_pin_caps mscc_pin_##p = {                           \
+       .pin = p,                                                       \
+       .functions = {                                                  \
+                       FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2,     \
+       },                                                              \
+}
+
+struct mscc_pmx_func {
+       const char **groups;
+       unsigned int ngroups;
+};
+
+struct mscc_pinctrl {
+       struct udevice *dev;
+       struct pinctrl_dev *pctl;
+       void __iomem *regs;
+       struct mscc_pmx_func *func;
+       int num_func;
+       const struct mscc_pin_data *mscc_pins;
+       int num_pins;
+       char * const *function_names;
+};
+
+int mscc_pinctrl_probe(struct udevice *dev, int num_func,
+                      const struct mscc_pin_data *mscc_pins, int num_pins,
+                      char * const *function_names);
+const struct pinctrl_ops mscc_pinctrl_ops;
+
+const struct dm_gpio_ops mscc_gpio_ops;
diff --git a/drivers/pinctrl/mscc/pinctrl-luton.c b/drivers/pinctrl/mscc/pinctrl-luton.c
new file mode 100644 (file)
index 0000000..7166588
--- /dev/null
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Microsemi SoCs pinctrl driver
+ *
+ * Author: <gregory.clement@bootlin.com>
+ * License: Dual MIT/GPL
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <asm/system.h>
+#include "mscc-common.h"
+
+enum {
+       FUNC_NONE,
+       FUNC_GPIO,
+       FUNC_SIO,
+       FUNC_TACHO,
+       FUNC_TWI,
+       FUNC_PHY_LED,
+       FUNC_EXT_IRQ,
+       FUNC_SFP,
+       FUNC_SI,
+       FUNC_PWM,
+       FUNC_UART,
+       FUNC_MAX
+};
+
+static char * const luton_function_names[] = {
+       [FUNC_NONE]             = "none",
+       [FUNC_GPIO]             = "gpio",
+       [FUNC_SIO]              = "sio",
+       [FUNC_TACHO]            = "tacho",
+       [FUNC_TWI]              = "twi",
+       [FUNC_PHY_LED]          = "phy_led",
+       [FUNC_EXT_IRQ]          = "ext_irq",
+       [FUNC_SFP]              = "sfp",
+       [FUNC_SI]               = "si",
+       [FUNC_PWM]              = "pwm",
+       [FUNC_UART]             = "uart",
+};
+
+MSCC_P(0,  SIO,       NONE,      NONE);
+MSCC_P(1,  SIO,       NONE,      NONE);
+MSCC_P(2,  SIO,       NONE,      NONE);
+MSCC_P(3,  SIO,       NONE,      NONE);
+MSCC_P(4,  TACHO,     NONE,      NONE);
+MSCC_P(5,  TWI,       PHY_LED,   NONE);
+MSCC_P(6,  TWI,       PHY_LED,   NONE);
+MSCC_P(7,  NONE,      PHY_LED,   NONE);
+MSCC_P(8,  EXT_IRQ,   PHY_LED,   NONE);
+MSCC_P(9,  EXT_IRQ,   PHY_LED,   NONE);
+MSCC_P(10, SFP,       PHY_LED,   NONE);
+MSCC_P(11, SFP,       PHY_LED,   NONE);
+MSCC_P(12, SFP,       PHY_LED,   NONE);
+MSCC_P(13, SFP,       PHY_LED,   NONE);
+MSCC_P(14, SI,        PHY_LED,   NONE);
+MSCC_P(15, SI,        PHY_LED,   NONE);
+MSCC_P(16, SI,        PHY_LED,   NONE);
+MSCC_P(17, SFP,       PHY_LED,   NONE);
+MSCC_P(18, SFP,       PHY_LED,   NONE);
+MSCC_P(19, SFP,       PHY_LED,   NONE);
+MSCC_P(20, SFP,       PHY_LED,   NONE);
+MSCC_P(21, SFP,       PHY_LED,   NONE);
+MSCC_P(22, SFP,       PHY_LED,   NONE);
+MSCC_P(23, SFP,       PHY_LED,   NONE);
+MSCC_P(24, SFP,       PHY_LED,   NONE);
+MSCC_P(25, SFP,       PHY_LED,   NONE);
+MSCC_P(26, SFP,       PHY_LED,   NONE);
+MSCC_P(27, SFP,       PHY_LED,   NONE);
+MSCC_P(28, SFP,       PHY_LED,   NONE);
+MSCC_P(29, PWM,       NONE,      NONE);
+MSCC_P(30, UART,      NONE,      NONE);
+MSCC_P(31, UART,      NONE,      NONE);
+
+#define LUTON_PIN(n) {                                         \
+       .name = "GPIO_"#n,                                      \
+       .drv_data = &mscc_pin_##n                               \
+}
+
+static const struct mscc_pin_data luton_pins[] = {
+       LUTON_PIN(0),
+       LUTON_PIN(1),
+       LUTON_PIN(2),
+       LUTON_PIN(3),
+       LUTON_PIN(4),
+       LUTON_PIN(5),
+       LUTON_PIN(6),
+       LUTON_PIN(7),
+       LUTON_PIN(8),
+       LUTON_PIN(9),
+       LUTON_PIN(10),
+       LUTON_PIN(11),
+       LUTON_PIN(12),
+       LUTON_PIN(13),
+       LUTON_PIN(14),
+       LUTON_PIN(15),
+       LUTON_PIN(16),
+       LUTON_PIN(17),
+       LUTON_PIN(18),
+       LUTON_PIN(19),
+       LUTON_PIN(20),
+       LUTON_PIN(21),
+       LUTON_PIN(22),
+       LUTON_PIN(23),
+       LUTON_PIN(24),
+       LUTON_PIN(25),
+       LUTON_PIN(26),
+       LUTON_PIN(27),
+       LUTON_PIN(28),
+       LUTON_PIN(29),
+       LUTON_PIN(30),
+       LUTON_PIN(31),
+};
+
+static int luton_gpio_probe(struct udevice *dev)
+{
+       struct gpio_dev_priv *uc_priv;
+
+       uc_priv = dev_get_uclass_priv(dev);
+       uc_priv->bank_name = "luton-gpio";
+       uc_priv->gpio_count = ARRAY_SIZE(luton_pins);
+
+       return 0;
+}
+
+static struct driver luton_gpio_driver = {
+       .name   = "luton-gpio",
+       .id     = UCLASS_GPIO,
+       .probe  = luton_gpio_probe,
+       .ops    = &mscc_gpio_ops,
+};
+
+int luton_pinctrl_probe(struct udevice *dev)
+{
+       int ret;
+
+       ret = mscc_pinctrl_probe(dev, FUNC_MAX, luton_pins,
+                                ARRAY_SIZE(luton_pins), luton_function_names);
+
+       if (ret)
+               return ret;
+
+       ret = device_bind(dev, &luton_gpio_driver, "luton-gpio", NULL,
+                         dev_of_offset(dev), NULL);
+
+       return 0;
+}
+
+static const struct udevice_id luton_pinctrl_of_match[] = {
+       {.compatible = "mscc,luton-pinctrl"},
+       {},
+};
+
+U_BOOT_DRIVER(luton_pinctrl) = {
+       .name = "luton-pinctrl",
+       .id = UCLASS_PINCTRL,
+       .of_match = of_match_ptr(luton_pinctrl_of_match),
+       .probe = luton_pinctrl_probe,
+       .priv_auto_alloc_size = sizeof(struct mscc_pinctrl),
+       .ops = &mscc_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/mscc/pinctrl-ocelot.c b/drivers/pinctrl/mscc/pinctrl-ocelot.c
new file mode 100644 (file)
index 0000000..10f9b90
--- /dev/null
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Microsemi SoCs pinctrl driver
+ *
+ * Author: <alexandre.belloni@free-electrons.com>
+ * Author: <gregory.clement@bootlin.com>
+ * License: Dual MIT/GPL
+ * Copyright (c) 2017 Microsemi Corporation
+ */
+
+#include <asm/gpio.h>
+#include <asm/system.h>
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <linux/io.h>
+#include "mscc-common.h"
+
+enum {
+       FUNC_NONE,
+       FUNC_GPIO,
+       FUNC_IRQ0_IN,
+       FUNC_IRQ0_OUT,
+       FUNC_IRQ1_IN,
+       FUNC_IRQ1_OUT,
+       FUNC_MIIM1,
+       FUNC_PCI_WAKE,
+       FUNC_PTP0,
+       FUNC_PTP1,
+       FUNC_PTP2,
+       FUNC_PTP3,
+       FUNC_PWM,
+       FUNC_RECO_CLK0,
+       FUNC_RECO_CLK1,
+       FUNC_SFP0,
+       FUNC_SFP1,
+       FUNC_SFP2,
+       FUNC_SFP3,
+       FUNC_SFP4,
+       FUNC_SFP5,
+       FUNC_SG0,
+       FUNC_SI,
+       FUNC_TACHO,
+       FUNC_TWI,
+       FUNC_TWI_SCL_M,
+       FUNC_UART,
+       FUNC_UART2,
+       FUNC_MAX
+};
+
+static char * const ocelot_function_names[] = {
+       [FUNC_NONE]             = "none",
+       [FUNC_GPIO]             = "gpio",
+       [FUNC_IRQ0_IN]          = "irq0_in",
+       [FUNC_IRQ0_OUT]         = "irq0_out",
+       [FUNC_IRQ1_IN]          = "irq1_in",
+       [FUNC_IRQ1_OUT]         = "irq1_out",
+       [FUNC_MIIM1]            = "miim1",
+       [FUNC_PCI_WAKE]         = "pci_wake",
+       [FUNC_PTP0]             = "ptp0",
+       [FUNC_PTP1]             = "ptp1",
+       [FUNC_PTP2]             = "ptp2",
+       [FUNC_PTP3]             = "ptp3",
+       [FUNC_PWM]              = "pwm",
+       [FUNC_RECO_CLK0]        = "reco_clk0",
+       [FUNC_RECO_CLK1]        = "reco_clk1",
+       [FUNC_SFP0]             = "sfp0",
+       [FUNC_SFP1]             = "sfp1",
+       [FUNC_SFP2]             = "sfp2",
+       [FUNC_SFP3]             = "sfp3",
+       [FUNC_SFP4]             = "sfp4",
+       [FUNC_SFP5]             = "sfp5",
+       [FUNC_SG0]              = "sg0",
+       [FUNC_SI]               = "si",
+       [FUNC_TACHO]            = "tacho",
+       [FUNC_TWI]              = "twi",
+       [FUNC_TWI_SCL_M]        = "twi_scl_m",
+       [FUNC_UART]             = "uart",
+       [FUNC_UART2]            = "uart2",
+};
+
+MSCC_P(0,  SG0,       NONE,      NONE);
+MSCC_P(1,  SG0,       NONE,      NONE);
+MSCC_P(2,  SG0,       NONE,      NONE);
+MSCC_P(3,  SG0,       NONE,      NONE);
+MSCC_P(4,  IRQ0_IN,   IRQ0_OUT,  TWI);
+MSCC_P(5,  IRQ1_IN,   IRQ1_OUT,  PCI_WAKE);
+MSCC_P(6,  UART,      TWI_SCL_M, NONE);
+MSCC_P(7,  UART,      TWI_SCL_M, NONE);
+MSCC_P(8,  SI,        TWI_SCL_M, IRQ0_OUT);
+MSCC_P(9,  SI,        TWI_SCL_M, IRQ1_OUT);
+MSCC_P(10, PTP2,      TWI_SCL_M, SFP0);
+MSCC_P(11, PTP3,      TWI_SCL_M, SFP1);
+MSCC_P(12, UART2,     TWI_SCL_M, SFP2);
+MSCC_P(13, UART2,     TWI_SCL_M, SFP3);
+MSCC_P(14, MIIM1,     TWI_SCL_M, SFP4);
+MSCC_P(15, MIIM1,     TWI_SCL_M, SFP5);
+MSCC_P(16, TWI,       NONE,      SI);
+MSCC_P(17, TWI,       TWI_SCL_M, SI);
+MSCC_P(18, PTP0,      TWI_SCL_M, NONE);
+MSCC_P(19, PTP1,      TWI_SCL_M, NONE);
+MSCC_P(20, RECO_CLK0, TACHO,     NONE);
+MSCC_P(21, RECO_CLK1, PWM,       NONE);
+
+#define OCELOT_PIN(n) {                                                \
+       .name = "GPIO_"#n,                                      \
+       .drv_data = &mscc_pin_##n                               \
+}
+
+static const struct mscc_pin_data ocelot_pins[] = {
+       OCELOT_PIN(0),
+       OCELOT_PIN(1),
+       OCELOT_PIN(2),
+       OCELOT_PIN(3),
+       OCELOT_PIN(4),
+       OCELOT_PIN(5),
+       OCELOT_PIN(6),
+       OCELOT_PIN(7),
+       OCELOT_PIN(8),
+       OCELOT_PIN(9),
+       OCELOT_PIN(10),
+       OCELOT_PIN(11),
+       OCELOT_PIN(12),
+       OCELOT_PIN(13),
+       OCELOT_PIN(14),
+       OCELOT_PIN(15),
+       OCELOT_PIN(16),
+       OCELOT_PIN(17),
+       OCELOT_PIN(18),
+       OCELOT_PIN(19),
+       OCELOT_PIN(20),
+       OCELOT_PIN(21),
+};
+
+static int ocelot_gpio_probe(struct udevice *dev)
+{
+       struct gpio_dev_priv *uc_priv;
+
+       uc_priv = dev_get_uclass_priv(dev);
+       uc_priv->bank_name = "ocelot-gpio";
+       uc_priv->gpio_count = ARRAY_SIZE(ocelot_pins);
+
+       return 0;
+}
+
+static struct driver ocelot_gpio_driver = {
+       .name   = "ocelot-gpio",
+       .id     = UCLASS_GPIO,
+       .probe  = ocelot_gpio_probe,
+       .ops    = &mscc_gpio_ops,
+};
+
+int ocelot_pinctrl_probe(struct udevice *dev)
+{
+       int ret;
+
+       ret = mscc_pinctrl_probe(dev, FUNC_MAX, ocelot_pins,
+                                ARRAY_SIZE(ocelot_pins),
+                                ocelot_function_names);
+
+       if (ret)
+               return ret;
+
+       ret = device_bind(dev, &ocelot_gpio_driver, "ocelot-gpio", NULL,
+                         dev_of_offset(dev), NULL);
+
+       return ret;
+}
+
+static const struct udevice_id ocelot_pinctrl_of_match[] = {
+       {.compatible = "mscc,ocelot-pinctrl"},
+       {},
+};
+
+U_BOOT_DRIVER(ocelot_pinctrl) = {
+       .name = "ocelot-pinctrl",
+       .id = UCLASS_PINCTRL,
+       .of_match = of_match_ptr(ocelot_pinctrl_of_match),
+       .probe = ocelot_pinctrl_probe,
+       .priv_auto_alloc_size = sizeof(struct mscc_pinctrl),
+       .ops = &mscc_pinctrl_ops,
+};
index 6db0445067079dcb2bdc986d7a1b6cd49710da98..29c910c55f3540982c4d182510d16b8555bb4064 100644 (file)
@@ -117,9 +117,9 @@ static int pinconfig_post_bind(struct udevice *dev)
        int ret;
 
        dev_for_each_subnode(node, dev) {
-               if (pre_reloc_only &&
-                   !ofnode_pre_reloc(node))
+               if (pre_reloc_only ^ ofnode_pre_reloc(node))
                        continue;
+
                /*
                 * If this node has "compatible" property, this is not
                 * a pin configuration node, but a normal device. skip.
index 4511625ff25133330e4eeab96169c28b7113c671..39e46279d533e97370593f84493ff202f38e6447 100644 (file)
@@ -113,7 +113,7 @@ int regulator_set_enable(struct udevice *dev, bool enable)
 
        uc_pdata = dev_get_uclass_platdata(dev);
        if (!enable && uc_pdata->always_on)
-               return -EACCES;
+               return 0;
 
        return ops->set_enable(dev, enable);
 }
index 6252dd8c4b5469d81904378835bdc876894476ea..b7ff2960abfef26787c3bbb1b53dc5deb7647413 100644 (file)
@@ -343,6 +343,13 @@ config DEBUG_UART_SANDBOX
          start up driver model. The driver will be available until the real
          driver model serial is running.
 
+config DEBUG_UART_SIFIVE
+       bool "SiFive UART"
+       help
+         Select this to enable a debug UART using the serial_sifive driver. You
+         will need to provide parameters to make this work. The driver will
+         be available until the real driver-model serial is running.
+
 config DEBUG_UART_STM32
        bool "STMicroelectronics STM32"
        depends on STM32_SERIAL
@@ -679,6 +686,12 @@ config PXA_SERIAL
          If you have a machine based on a Marvell XScale PXA2xx CPU you
          can enable its onboard serial ports by enabling this option.
 
+config SIFIVE_SERIAL
+       bool "SiFive UART support"
+       depends on DM_SERIAL
+       help
+         This driver supports the SiFive UART. If unsure say N.
+
 config STI_ASC_SERIAL
        bool "STMicroelectronics on-chip UART"
        depends on DM_SERIAL && ARCH_STI
index 2f8d065a4c2261126923b39e38c6a9dd7e722f85..06ee30697deb0d5e486ba0f155a99327b7623ac5 100644 (file)
@@ -67,6 +67,7 @@ obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o
 obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
 obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
 obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
+obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c
new file mode 100644 (file)
index 0000000..341728a
--- /dev/null
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Anup Patel <anup@brainfault.org>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <linux/compiler.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_TXFIFO_FULL       0x80000000
+#define UART_RXFIFO_EMPTY      0x80000000
+#define UART_RXFIFO_DATA       0x000000ff
+#define UART_TXCTRL_TXEN       0x1
+#define UART_RXCTRL_RXEN       0x1
+
+struct uart_sifive {
+       u32 txfifo;
+       u32 rxfifo;
+       u32 txctrl;
+       u32 rxctrl;
+       u32 ie;
+       u32 ip;
+       u32 div;
+};
+
+struct sifive_uart_platdata {
+       unsigned int clock;
+       int saved_input_char;
+       struct uart_sifive *regs;
+};
+
+/* Set up the baud rate in gd struct */
+static void _sifive_serial_setbrg(struct uart_sifive *regs,
+                                 unsigned long clock, unsigned long baud)
+{
+       writel((u32)((clock / baud) - 1), &regs->div);
+}
+
+static void _sifive_serial_init(struct uart_sifive *regs)
+{
+       writel(UART_TXCTRL_TXEN, &regs->txctrl);
+       writel(UART_RXCTRL_RXEN, &regs->rxctrl);
+       writel(0, &regs->ie);
+}
+
+static int _sifive_serial_putc(struct uart_sifive *regs, const char c)
+{
+       if (readl(&regs->txfifo) & UART_TXFIFO_FULL)
+               return -EAGAIN;
+
+       writel(c, &regs->txfifo);
+
+       return 0;
+}
+
+static int _sifive_serial_getc(struct uart_sifive *regs)
+{
+       int ch = readl(&regs->rxfifo);
+
+       if (ch & UART_RXFIFO_EMPTY)
+               return -EAGAIN;
+       ch &= UART_RXFIFO_DATA;
+
+       return (!ch) ? -EAGAIN : ch;
+}
+
+static int sifive_serial_setbrg(struct udevice *dev, int baudrate)
+{
+       int err;
+       struct clk clk;
+       struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
+
+       err = clk_get_by_index(dev, 0, &clk);
+       if (!err) {
+               err = clk_get_rate(&clk);
+               if (!IS_ERR_VALUE(err))
+                       platdata->clock = err;
+       } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
+               debug("SiFive UART failed to get clock\n");
+               return err;
+       }
+
+       if (!platdata->clock)
+               platdata->clock = dev_read_u32_default(dev, "clock-frequency", 0);
+       if (!platdata->clock) {
+               debug("SiFive UART clock not defined\n");
+               return -EINVAL;
+       }
+
+       _sifive_serial_setbrg(platdata->regs, platdata->clock, baudrate);
+
+       return 0;
+}
+
+static int sifive_serial_probe(struct udevice *dev)
+{
+       struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
+
+       /* No need to reinitialize the UART after relocation */
+       if (gd->flags & GD_FLG_RELOC)
+               return 0;
+
+       platdata->saved_input_char = 0;
+       _sifive_serial_init(platdata->regs);
+
+       return 0;
+}
+
+static int sifive_serial_getc(struct udevice *dev)
+{
+       int c;
+       struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
+       struct uart_sifive *regs = platdata->regs;
+
+       if (platdata->saved_input_char > 0) {
+               c = platdata->saved_input_char;
+               platdata->saved_input_char = 0;
+               return c;
+       }
+
+       while ((c = _sifive_serial_getc(regs)) == -EAGAIN) ;
+
+       return c;
+}
+
+static int sifive_serial_putc(struct udevice *dev, const char ch)
+{
+       int rc;
+       struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
+
+       while ((rc = _sifive_serial_putc(platdata->regs, ch)) == -EAGAIN) ;
+
+       return rc;
+}
+
+static int sifive_serial_pending(struct udevice *dev, bool input)
+{
+       struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
+       struct uart_sifive *regs = platdata->regs;
+
+       if (input) {
+               if (platdata->saved_input_char > 0)
+                       return 1;
+               platdata->saved_input_char = _sifive_serial_getc(regs);
+               return (platdata->saved_input_char > 0) ? 1 : 0;
+       } else {
+               return !!(readl(&regs->txfifo) & UART_TXFIFO_FULL);
+       }
+}
+
+static int sifive_serial_ofdata_to_platdata(struct udevice *dev)
+{
+       struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
+
+       platdata->regs = (struct uart_sifive *)dev_read_addr(dev);
+       if (IS_ERR(platdata->regs))
+               return PTR_ERR(platdata->regs);
+
+       return 0;
+}
+
+static const struct dm_serial_ops sifive_serial_ops = {
+       .putc = sifive_serial_putc,
+       .getc = sifive_serial_getc,
+       .pending = sifive_serial_pending,
+       .setbrg = sifive_serial_setbrg,
+};
+
+static const struct udevice_id sifive_serial_ids[] = {
+       { .compatible = "sifive,uart0" },
+       { }
+};
+
+U_BOOT_DRIVER(serial_sifive) = {
+       .name   = "serial_sifive",
+       .id     = UCLASS_SERIAL,
+       .of_match = sifive_serial_ids,
+       .ofdata_to_platdata = sifive_serial_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct sifive_uart_platdata),
+       .probe = sifive_serial_probe,
+       .ops    = &sifive_serial_ops,
+};
+
+#ifdef CONFIG_DEBUG_UART_SIFIVE
+static inline void _debug_uart_init(void)
+{
+       struct uart_sifive *regs =
+                       (struct uart_sifive *)CONFIG_DEBUG_UART_BASE;
+
+       _sifive_serial_setbrg(regs, CONFIG_DEBUG_UART_CLOCK,
+                             CONFIG_BAUDRATE);
+       _sifive_serial_init(regs);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+       struct uart_sifive *regs =
+                       (struct uart_sifive *)CONFIG_DEBUG_UART_BASE;
+
+       while (_sifive_serial_putc(regs, ch) == -EAGAIN)
+               WATCHDOG_RESET();
+}
+
+DEBUG_UART_FUNCS
+
+#endif
index 5cca41448674aa497bd65228f2e82d25ad1122aa..02d93763d42d8003e485dfaa16ce3f4ea91e0e24 100644 (file)
@@ -369,7 +369,13 @@ static int poll_transfer(struct dw_spi_priv *priv)
        return 0;
 }
 
-static void external_cs_manage(struct udevice *dev, bool on)
+/*
+ * We define external_cs_manage function as 'weak' as some targets
+ * (like MSCC Ocelot) don't control the external CS pin using a GPIO
+ * controller. These SoCs use specific registers to control by
+ * software the SPI pins (and especially the CS).
+ */
+__weak void external_cs_manage(struct udevice *dev, bool on)
 {
 #if defined(CONFIG_DM_GPIO) && !defined(CONFIG_SPL_BUILD)
        struct dw_spi_priv *priv = dev_get_priv(dev->parent);
index b0e6f32f0bc469994734a18c6b708fe48864a4af..df37a798bdcb908730970d16bf26d0e810d5f330 100644 (file)
@@ -126,6 +126,13 @@ config OMAP_TIMER
        help
          Select this to enable an timer for Omap devices.
 
+config RISCV_TIMER
+       bool "RISC-V timer support"
+       depends on TIMER && RISCV
+       help
+         Select this to enable support for the timer as defined
+         by the RISC-V privileged architecture spec.
+
 config ROCKCHIP_TIMER
        bool "Rockchip timer support"
        depends on TIMER
index c4fbab2aaca3fad18199300e6a0325880455a956..d0bf218b114f430f09ccfc2d9bc30e795db3fa93 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER)       += cadence-ttc.o
 obj-$(CONFIG_DESIGNWARE_APB_TIMER)     += dw-apb-timer.o
 obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
 obj-$(CONFIG_OMAP_TIMER)       += omap-timer.o
+obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o
 obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)    += sandbox_timer.o
 obj-$(CONFIG_STI_TIMER)                += sti-timer.o
diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
new file mode 100644 (file)
index 0000000..9f9f070
--- /dev/null
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * RISC-V privileged architecture defined generic timer driver
+ *
+ * This driver relies on RISC-V platform codes to provide the essential API
+ * riscv_get_time() which is supposed to return the timer counter as defined
+ * by the RISC-V privileged architecture spec.
+ *
+ * This driver can be used in both M-mode and S-mode U-Boot.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/io.h>
+
+/**
+ * riscv_get_time() - get the timer counter
+ *
+ * Platform codes should provide this API in order to make this driver function.
+ *
+ * @time:      the 64-bit timer count  as defined by the RISC-V privileged
+ *             architecture spec.
+ * @return:    0 on success, -ve on error.
+ */
+extern int riscv_get_time(u64 *time);
+
+static int riscv_timer_get_count(struct udevice *dev, u64 *count)
+{
+       return riscv_get_time(count);
+}
+
+static int riscv_timer_probe(struct udevice *dev)
+{
+       struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+       /* clock frequency was passed from the cpu driver as driver data */
+       uc_priv->clock_rate = dev->driver_data;
+
+       return 0;
+}
+
+static const struct timer_ops riscv_timer_ops = {
+       .get_count = riscv_timer_get_count,
+};
+
+U_BOOT_DRIVER(riscv_timer) = {
+       .name = "riscv_timer",
+       .id = UCLASS_TIMER,
+       .probe = riscv_timer_probe,
+       .ops = &riscv_timer_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
index ead5d3d810b9a12a37076f1b341a1cf4af128408..22d55cfd73e70dd17a979d1dc8d508053bd4f29e 100644 (file)
@@ -39,6 +39,8 @@ enum altera_iface {
        fast_passive_parallel,
        /* fast passive parallel with security (FPPS) */
        fast_passive_parallel_security,
+       /* secure device manager (SDM) mailbox */
+       secure_device_manager_mailbox,
        /* insert all new types before this */
        max_altera_iface_type,
 };
@@ -54,6 +56,8 @@ enum altera_family {
        Altera_StratixII,
        /* StratixV Family */
        Altera_StratixV,
+       /* Stratix10 Family */
+       Intel_FPGA_Stratix10,
        /* SoCFPGA Family */
        Altera_SoCFPGA,
 
@@ -116,4 +120,8 @@ int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
 int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
 #endif
 
+#ifdef CONFIG_FPGA_STRATIX10
+int stratix10_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
+#endif
+
 #endif /* _ALTERA_H_ */
index 39ca2e0bf3f5ff57cb415b40e7b68aecef4bc97f..788f4af70dab9d61bd70bf89eb6814d05503caf2 100644 (file)
@@ -6,6 +6,10 @@
 #ifndef __CONFIG_BMIPS_COMMON_H
 #define __CONFIG_BMIPS_COMMON_H
 
+/* ETH */
+#define CONFIG_PHY_RESET_DELAY         20
+#define CONFIG_SYS_RX_ETH_BUFFER       6
+
 /* UART */
 #define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200, \
                                          230400, 500000, 1500000 }
@@ -16,7 +20,7 @@
 
 /* Memory usage */
 #define CONFIG_SYS_MAXARGS             24
-#define CONFIG_SYS_MALLOC_LEN          (1024 * 1024)
+#define CONFIG_SYS_MALLOC_LEN          (2 * 1024 * 1024)
 #define CONFIG_SYS_BOOTPARAMS_LEN      (128 * 1024)
 #define CONFIG_SYS_CBSIZE              512
 
diff --git a/include/configs/ci20.h b/include/configs/ci20.h
new file mode 100644 (file)
index 0000000..9a36213
--- /dev/null
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * CI20 configuration
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#ifndef __CONFIG_CI20_H__
+#define __CONFIG_CI20_H__
+
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+/* Ingenic JZ4780 clock configuration. */
+#define CONFIG_SYS_HZ                  1000
+#define CONFIG_SYS_MHZ                 1200
+#define CONFIG_SYS_MIPS_TIMER_FREQ     (CONFIG_SYS_MHZ * 1000000)
+
+/* Memory configuration */
+#define CONFIG_SYS_MONITOR_LEN         (512 * 1024)
+#define CONFIG_SYS_MALLOC_LEN          (64 * 1024 * 1024)
+#define CONFIG_SYS_BOOTPARAMS_LEN      (128 * 1024)
+
+#define CONFIG_SYS_SDRAM_BASE          0x80000000 /* cached (KSEG0) address */
+#define CONFIG_SYS_INIT_SP_OFFSET      0x400000
+#define CONFIG_SYS_LOAD_ADDR           0x81000000
+#define CONFIG_LOADADDR                        CONFIG_SYS_LOAD_ADDR
+#define CONFIG_SYS_MEMTEST_START       0x80000000
+#define CONFIG_SYS_MEMTEST_END         0x88000000
+
+#define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
+
+/* NS16550-ish UARTs */
+#define CONFIG_SYS_NS16550_CLK         48000000
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+
+/* Ethernet: davicom DM9000 */
+#define CONFIG_DRIVER_DM9000           1
+#define CONFIG_DM9000_BASE             0xb6000000
+#define DM9000_IO                      CONFIG_DM9000_BASE
+#define DM9000_DATA                    (CONFIG_DM9000_BASE + 2)
+
+/* Environment */
+#define CONFIG_SYS_MMC_ENV_DEV         0
+#define CONFIG_ENV_SIZE                        (32 << 10)
+#define CONFIG_ENV_OFFSET              ((14 + 512) << 10)
+#define CONFIG_ENV_OVERWRITE
+
+/* Command line configuration. */
+#define CONFIG_SYS_CBSIZE      1024            /* Console I/O buffer size */
+#define CONFIG_SYS_MAXARGS     32              /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE                        /* U-BOOT version */
+
+/* Miscellaneous configuration options */
+#define CONFIG_SYS_BOOTM_LEN           (64 << 20)
+
+/* SPL */
+#define CONFIG_SPL_STACK               0xf4008000 /* only max. 2KB spare! */
+
+#define CONFIG_SPL_TEXT_BASE           0xf4000a00
+#define CONFIG_SPL_MAX_SIZE            ((14 * 1024) - 0xa00)
+
+#define CONFIG_SPL_BSS_START_ADDR      0xf4004000
+#define CONFIG_SPL_BSS_MAX_SIZE                0x00002000 /* 512KB, arbitrary */
+
+#define CONFIG_SPL_START_S_PATH                "arch/mips/mach-jz47xx"
+
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR        0x1c    /* 14 KiB offset */
+
+#endif /* __CONFIG_CI20_H__ */
index 3157225f06776240a439ba9a818ca7341a07c5b8..4e98f19a403545496b6b90a9a7466c67422f9700 100644 (file)
 #define CONFIG_SPL_SPI_FLASH_SUPPORT
 #define CONFIG_SPL_SPI_LOAD
 #define CONFIG_SPL_SPI_SUPPORT
-#define CONFIG_SYS_SPI_U_BOOT_OFFS     0x20000
+#define CONFIG_SYS_SPI_U_BOOT_OFFS     0x30000
 #define CONFIG_SYS_U_BOOT_OFFS         CONFIG_SYS_SPI_U_BOOT_OFFS
 #endif
 
index 68da920e300d0bbeb833785c67f135f5f85a2d25..ba763501cf2eb0cdaa88efaf1ded7e22f0b147bd 100644 (file)
@@ -46,7 +46,7 @@
 /* DRAM */
 #define CONFIG_SYS_SDRAM_BASE          0x80000000
 
-/* This is neede for kernel booting */
+/* This is needed for kernel booting */
 #define FDT_HIGH                       "fdt_high=0xac000000\0"
 
 /* Extra environment variables */
index b9d65697521bb754b6ccb093b979cf56f49573a1..775374cf2888ea196fb25700b0af0c0cf7272aa5 100644 (file)
 
 #define CONFIG_REVISION_TAG            1
 
-/* GPIO banks */
-#define CONFIG_OMAP3_GPIO_2            /* GPIO32..63   is in GPIO bank 2 */
-#define CONFIG_OMAP3_GPIO_4            /* GPIO96..127  is in GPIO bank 4 */
-
 /* TPS65950 */
 #define PBIASLITEVMODE1                        (1 << 8)
 
diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h
new file mode 100644 (file)
index 0000000..df89cda
--- /dev/null
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __VCOREIII_H
+#define __VCOREIII_H
+
+#include <linux/sizes.h>
+
+/* Onboard devices */
+
+#define CONFIG_SYS_MALLOC_LEN          0x100000
+#define CONFIG_SYS_LOAD_ADDR           0x00100000
+#define CONFIG_SYS_INIT_SP_OFFSET       0x400000
+
+#define CPU_CLOCK_RATE                 500000000 /* Clock for the MIPS core */
+#ifdef CONFIG_SOC_LUTON
+#define CONFIG_SYS_MIPS_TIMER_FREQ     208333333
+#else
+#define CONFIG_SYS_MIPS_TIMER_FREQ     (CPU_CLOCK_RATE / 2)
+#endif
+#define CONFIG_SYS_NS16550_CLK         CONFIG_SYS_MIPS_TIMER_FREQ
+
+#if defined(CONFIG_ENV_IS_IN_SPI_FLASH) && !defined(CONFIG_ENV_OFFSET)
+#define CONFIG_ENV_OFFSET              (1024 * 1024)
+#define CONFIG_ENV_SIZE                        (256 * 1024)
+#define CONFIG_ENV_SECT_SIZE           (256 * 1024)
+
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
+#define CONFIG_ENV_OFFSET_REDUND      (CONFIG_ENV_OFFSET + CONFIG_ENV_SECT_SIZE)
+
+#define CONFIG_ENV_SPI_MAX_HZ          0 /* This force to read from DT */
+#define CONFIG_ENV_SPI_MODE            0 /* This force to read from DT */
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE          0x80000000
+#if defined(CONFIG_DDRTYPE_H5TQ1G63BFA) || defined(CONFIG_DDRTYPE_MT47H128M8HQ)
+#define CONFIG_SYS_SDRAM_SIZE          (128 * SZ_1M)
+#elif defined(CONFIG_DDRTYPE_MT41J128M16HA) || defined(CONFIG_DDRTYPE_MT41K128M16JT)
+#define CONFIG_SYS_SDRAM_SIZE          (256 * SZ_1M)
+#elif defined(CONFIG_DDRTYPE_H5TQ4G63MFR) || defined(CONFIG_DDRTYPE_MT41K256M16)
+#define CONFIG_SYS_SDRAM_SIZE          (512 * SZ_1M)
+#else
+#error Unknown DDR size - please add!
+#endif
+
+#define CONFIG_CONS_INDEX              1
+
+#define CONFIG_SYS_MEMTEST_START       CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - SZ_1M)
+
+#define CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_BOARD_EARLY_INIT_R
+#if defined(CONFIG_MTDIDS_DEFAULT) && defined(CONFIG_MTDPARTS_DEFAULT)
+#define VCOREIII_DEFAULT_MTD_ENV                   \
+       "mtdparts="CONFIG_MTDPARTS_DEFAULT"\0"      \
+       "mtdids="CONFIG_MTDIDS_DEFAULT"\0"
+#else
+#define VCOREIII_DEFAULT_MTD_ENV    /* Go away */
+#endif
+
+#define CONFIG_SYS_BOOTM_LEN      (16 << 20)      /* Increase max gunzip size */
+
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       VCOREIII_DEFAULT_MTD_ENV                                        \
+       "loadaddr=0x81000000\0"                                         \
+       "spi_image_off=0x00100000\0"                                    \
+       "console=ttyS0,115200\0"                                        \
+       "setup=setenv bootargs console=${console} ${mtdparts}"          \
+       "${bootargs_extra}\0"                                           \
+       "spiboot=run setup; sf probe; sf read ${loadaddr}"              \
+       "${spi_image_off} 0x600000; bootm ${loadaddr}\0"                \
+       "ubootfile=u-boot.bin\0"                                        \
+       "update=sf probe;mtdparts;dhcp ${loadaddr} ${ubootfile};"       \
+       "sf erase UBoot 0x100000;"                                      \
+       "sf write ${loadaddr} UBoot  ${filesize}\0"                     \
+       "bootcmd=run spiboot\0"                                         \
+       ""
+#endif                         /* __VCOREIII_H */
index 367c5f46a00f8499f93027653946c15bc75c4033..28dd48feb8f0a6c1ce8aceaa2d8d15b8d49c39aa 100644 (file)
@@ -14,6 +14,8 @@
  * @device_id:     Driver-defined device identifier
  * @family:        DMTF CPU Family identifier
  * @id:            DMTF CPU Processor identifier
+ * @timebase_freq: the current frequency at which the cpu timer timebase
+ *                registers are updated (in Hz)
  *
  * This can be accessed with dev_get_parent_platdata() for any UCLASS_CPU
  * device.
@@ -24,6 +26,7 @@ struct cpu_platdata {
        ulong device_id;
        u16 family;
        u32 id[2];
+       u32 timebase_freq;
 };
 
 /* CPU features - mostly just a placeholder for now */
index d5e13c5c2d34a43984a387b0ebd22cccbc0c8187..3f10448cef11ddd34484685e3edaccd53a197db0 100644 (file)
 #define BCM6318_CLK_AFE                29
 #define BCM6318_CLK_QPROC      30
 
+#define BCM6318_UCLK_ADSL      0
+#define BCM6318_UCLK_ARB       1
+#define BCM6318_UCLK_MIPS      2
+#define BCM6318_UCLK_PCIE      3
+#define BCM6318_UCLK_PERIPH    4
+#define BCM6318_UCLK_PHYMIPS   5
+#define BCM6318_UCLK_ROBOSW    6
+#define BCM6318_UCLK_SAR       7
+#define BCM6318_UCLK_SDR       8
+#define BCM6318_UCLK_USB       9
+
 #endif /* __DT_BINDINGS_CLOCK_BCM6318_H */
diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h
new file mode 100644 (file)
index 0000000..73214c5
--- /dev/null
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This header provides clock numbers for the ingenic,jz4780-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4780 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+
+#define JZ4780_CLK_EXCLK       0
+#define JZ4780_CLK_RTCLK       1
+#define JZ4780_CLK_APLL                2
+#define JZ4780_CLK_MPLL                3
+#define JZ4780_CLK_EPLL                4
+#define JZ4780_CLK_VPLL                5
+#define JZ4780_CLK_OTGPHY      6
+#define JZ4780_CLK_SCLKA       7
+#define JZ4780_CLK_CPUMUX      8
+#define JZ4780_CLK_CPU         9
+#define JZ4780_CLK_L2CACHE     10
+#define JZ4780_CLK_AHB0                11
+#define JZ4780_CLK_AHB2PMUX    12
+#define JZ4780_CLK_AHB2                13
+#define JZ4780_CLK_PCLK                14
+#define JZ4780_CLK_DDR         15
+#define JZ4780_CLK_VPU         16
+#define JZ4780_CLK_I2SPLL      17
+#define JZ4780_CLK_I2S         18
+#define JZ4780_CLK_LCD0PIXCLK  19
+#define JZ4780_CLK_LCD1PIXCLK  20
+#define JZ4780_CLK_MSCMUX      21
+#define JZ4780_CLK_MSC0                22
+#define JZ4780_CLK_MSC1                23
+#define JZ4780_CLK_MSC2                24
+#define JZ4780_CLK_UHC         25
+#define JZ4780_CLK_SSIPLL      26
+#define JZ4780_CLK_SSI         27
+#define JZ4780_CLK_CIMMCLK     28
+#define JZ4780_CLK_PCMPLL      29
+#define JZ4780_CLK_PCM         30
+#define JZ4780_CLK_GPU         31
+#define JZ4780_CLK_HDMI                32
+#define JZ4780_CLK_BCH         33
+#define JZ4780_CLK_NEMC                34
+#define JZ4780_CLK_OTG0                35
+#define JZ4780_CLK_SSI0                36
+#define JZ4780_CLK_SMB0                37
+#define JZ4780_CLK_SMB1                38
+#define JZ4780_CLK_SCC         39
+#define JZ4780_CLK_AIC         40
+#define JZ4780_CLK_TSSI0       41
+#define JZ4780_CLK_OWI         42
+#define JZ4780_CLK_KBC         43
+#define JZ4780_CLK_SADC                44
+#define JZ4780_CLK_UART0       45
+#define JZ4780_CLK_UART1       46
+#define JZ4780_CLK_UART2       47
+#define JZ4780_CLK_UART3       48
+#define JZ4780_CLK_SSI1                49
+#define JZ4780_CLK_SSI2                50
+#define JZ4780_CLK_PDMA                51
+#define JZ4780_CLK_GPS         52
+#define JZ4780_CLK_MAC         53
+#define JZ4780_CLK_SMB2                54
+#define JZ4780_CLK_CIM         55
+#define JZ4780_CLK_LCD         56
+#define JZ4780_CLK_TVE         57
+#define JZ4780_CLK_IPU         58
+#define JZ4780_CLK_DDR0                59
+#define JZ4780_CLK_DDR1                60
+#define JZ4780_CLK_SMB3                61
+#define JZ4780_CLK_TSSI1       62
+#define JZ4780_CLK_COMPRESS    63
+#define JZ4780_CLK_AIC1                64
+#define JZ4780_CLK_GPVLC       65
+#define JZ4780_CLK_OTG1                66
+#define JZ4780_CLK_UART4       67
+#define JZ4780_CLK_AHBMON      68
+#define JZ4780_CLK_SMB4                69
+#define JZ4780_CLK_DES         70
+#define JZ4780_CLK_X2D         71
+#define JZ4780_CLK_CORE1       72
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
diff --git a/include/dt-bindings/dma/bcm6318-dma.h b/include/dt-bindings/dma/bcm6318-dma.h
new file mode 100644 (file)
index 0000000..ad7c5ac
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6318_H
+#define __DT_BINDINGS_DMA_BCM6318_H
+
+#define BCM6318_DMA_ENETSW_RX  0
+#define BCM6318_DMA_ENETSW_TX  1
+
+#endif /* __DT_BINDINGS_DMA_BCM6318_H */
diff --git a/include/dt-bindings/dma/bcm63268-dma.h b/include/dt-bindings/dma/bcm63268-dma.h
new file mode 100644 (file)
index 0000000..7d02711
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM63268_H
+#define __DT_BINDINGS_DMA_BCM63268_H
+
+#define BCM63268_DMA_ENETSW_RX 0
+#define BCM63268_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM63268_H */
diff --git a/include/dt-bindings/dma/bcm6328-dma.h b/include/dt-bindings/dma/bcm6328-dma.h
new file mode 100644 (file)
index 0000000..7494df2
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6328_H
+#define __DT_BINDINGS_DMA_BCM6328_H
+
+#define BCM6328_DMA_ENETSW_RX  0
+#define BCM6328_DMA_ENETSW_TX  1
+
+#endif /* __DT_BINDINGS_DMA_BCM6328_H */
diff --git a/include/dt-bindings/dma/bcm6338-dma.h b/include/dt-bindings/dma/bcm6338-dma.h
new file mode 100644 (file)
index 0000000..f2e0b20
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6338_H
+#define __DT_BINDINGS_DMA_BCM6338_H
+
+#define BCM6338_DMA_ENET_RX    0
+#define BCM6338_DMA_ENET_TX    1
+
+#endif /* __DT_BINDINGS_DMA_BCM6338_H */
diff --git a/include/dt-bindings/dma/bcm6348-dma.h b/include/dt-bindings/dma/bcm6348-dma.h
new file mode 100644 (file)
index 0000000..36c2ffd
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6348_H
+#define __DT_BINDINGS_DMA_BCM6348_H
+
+#define BCM6348_DMA_ENET0_RX   0
+#define BCM6348_DMA_ENET0_TX   1
+#define BCM6348_DMA_ENET1_RX   2
+#define BCM6348_DMA_ENET1_TX   3
+
+#endif /* __DT_BINDINGS_DMA_BCM6348_H */
diff --git a/include/dt-bindings/dma/bcm6358-dma.h b/include/dt-bindings/dma/bcm6358-dma.h
new file mode 100644 (file)
index 0000000..3118b9d
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6358_H
+#define __DT_BINDINGS_DMA_BCM6358_H
+
+#define BCM6358_DMA_ENET0_RX   0
+#define BCM6358_DMA_ENET0_TX   1
+#define BCM6358_DMA_ENET1_RX   2
+#define BCM6358_DMA_ENET1_TX   3
+
+#endif /* __DT_BINDINGS_DMA_BCM6358_H */
diff --git a/include/dt-bindings/dma/bcm6362-dma.h b/include/dt-bindings/dma/bcm6362-dma.h
new file mode 100644 (file)
index 0000000..1e62236
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6362_H
+#define __DT_BINDINGS_DMA_BCM6362_H
+
+#define BCM6362_DMA_ENETSW_RX  0
+#define BCM6362_DMA_ENETSW_TX  1
+
+#endif /* __DT_BINDINGS_DMA_BCM6362_H */
diff --git a/include/dt-bindings/dma/bcm6368-dma.h b/include/dt-bindings/dma/bcm6368-dma.h
new file mode 100644 (file)
index 0000000..36c6caa
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6368_H
+#define __DT_BINDINGS_DMA_BCM6368_H
+
+#define BCM6368_DMA_ENETSW_RX  0
+#define BCM6368_DMA_ENETSW_TX  1
+
+#endif /* __DT_BINDINGS_DMA_BCM6368_H */
index 4848ca6e25a59f6b6602166d6f3d329ec9b2b4d6..583f7d0963c38212faad4a56e33b896619d59168 100755 (executable)
 set -e
 set -u
 
+PROG_NAME="${0##*/}"
+
+usage() {
+       echo "$PROG_NAME <path to u-boot.cfg> <path to whitelist file> <source dir>"
+       exit 1
+}
+
+[ $# -ge 3 ] || usage
+
 path="$1"
 whitelist="$2"
 srctree="$3"
index 13c85428cbaa2da05124a28db2621d902a742b8e..a4f154415db2057b2b9eb9b0fac6bdcfdf2ea200 100644 (file)
@@ -1,11 +1,10 @@
 config UT_OVERLAY
        bool "Enable Device Tree Overlays Unit Tests"
-       depends on OF_LIBFDT_OVERLAY
-       depends on UNIT_TEST
+       depends on UNIT_TEST && OF_CONTROL
+       default y
+       select OF_LIBFDT_OVERLAY
        help
          This enables the 'ut overlay' command which runs a series of unit
          tests on the fdt overlay code.
          If all is well then all tests pass although there will be a few
          messages printed along the way.
-         Be warned that it requires an out-of-tree dtc compiler with patches
-         to support the DT overlays, otherwise it will fail.