As the Ocelots SoCs, this family of SoCs are found in the Microsemi
Switches solution.

Signed-off-by: Gregory CLEMENT <gregory.clem...@bootlin.com>
---
 arch/mips/mach-mscc/Kconfig                   |  13 +
 arch/mips/mach-mscc/Makefile                  |   1 +
 arch/mips/mach-mscc/cpu.c                     |  13 +
 arch/mips/mach-mscc/dram.c                    |   2 +
 arch/mips/mach-mscc/include/mach/common.h     |   4 +
 arch/mips/mach-mscc/include/mach/ddr.h        | 114 +++++++-
 .../mips/mach-mscc/include/mach/luton/luton.h |  37 +++
 .../include/mach/luton/luton_devcpu_gcb.h     |  14 +
 .../include/mach/luton/luton_icpu_cfg.h       | 245 ++++++++++++++++++
 arch/mips/mach-mscc/lowlevel_init.S           |   7 +
 arch/mips/mach-mscc/lowlevel_init_luton.S     |  62 +++++
 11 files changed, 508 insertions(+), 4 deletions(-)
 create mode 100644 arch/mips/mach-mscc/include/mach/luton/luton.h
 create mode 100644 arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h
 create mode 100644 arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h
 create mode 100644 arch/mips/mach-mscc/lowlevel_init_luton.S

diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig
index 7f1b270207..a8cace0e79 100644
--- a/arch/mips/mach-mscc/Kconfig
+++ b/arch/mips/mach-mscc/Kconfig
@@ -21,6 +21,12 @@ config SOC_OCELOT
        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"
 
@@ -41,6 +47,13 @@ config TARGET_OCELOT_PCB123
          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
diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile
index d14ec33838..6c60f26ca4 100644
--- a/arch/mips/mach-mscc/Makefile
+++ b/arch/mips/mach-mscc/Makefile
@@ -3,3 +3,4 @@
 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
index 0c8f7933cd..562b2cf5f9 100644
--- a/arch/mips/mach-mscc/cpu.c
+++ b/arch/mips/mach-mscc/cpu.c
@@ -31,12 +31,25 @@ void vcoreiii_tlb_init(void)
         */
        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
 }
 
 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), REG_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), REG_CFG(ICPU_SPI_MST_CFG));
+#else
        writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
               ICPU_SPI_MST_CFG_CLK_DIV(9), REG_CFG(ICPU_SPI_MST_CFG));
+#endif
        return 0;
 }
diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c
index b82961f773..5ee141ab77 100644
--- a/arch/mips/mach-mscc/dram.c
+++ b/arch/mips/mach-mscc/dram.c
@@ -23,7 +23,9 @@ int vcoreiii_ddr_init(void)
                hal_vcoreiii_wait_memctl();
                if (hal_vcoreiii_init_dqs() != 0 ||
                    hal_vcoreiii_train_bytelane(0) != 0
+#ifdef CONFIG_SOC_OCELOT
                    || hal_vcoreiii_train_bytelane(1) != 0
+#endif
                    )
                        hal_vcoreiii_ddr_failed();
        }
diff --git a/arch/mips/mach-mscc/include/mach/common.h 
b/arch/mips/mach-mscc/include/mach/common.h
index 41887097f9..4ba1f7974c 100644
--- a/arch/mips/mach-mscc/include/mach/common.h
+++ b/arch/mips/mach-mscc/include/mach/common.h
@@ -13,6 +13,10 @@
 #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
diff --git a/arch/mips/mach-mscc/include/mach/ddr.h 
b/arch/mips/mach-mscc/include/mach/ddr.h
index c089af8e33..51ea65b573 100644
--- a/arch/mips/mach-mscc/include/mach/ddr.h
+++ b/arch/mips/mach-mscc/include/mach/ddr.h
@@ -586,6 +586,99 @@ static inline int dram_check(void)
        }
        return 0;
 }
+#else                          /* Luton */
+
+static inline void sleep_100ns(u32 val)
+{
+}
+
+static inline void hal_vcoreiii_ddr_reset_assert(void)
+{
+       setbits_le32(REG_CFG(ICPU_MEMPHY_CFG), ICPU_MEMPHY_CFG_PHY_RST);
+       setbits_le32(REG_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(REG_CFG(ICPU_MEMPHY_CFG));
+
+       /* Do a fifo reset and start over */
+       writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+              REG_CFG(ICPU_MEMPHY_CFG));
+       writel(memphy_cfg & ~ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+              REG_CFG(ICPU_MEMPHY_CFG));
+       writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+              REG_CFG(ICPU_MEMPHY_CFG));
+}
+
+static inline void hal_vcoreiii_ddr_verified(void)
+{
+}
+
+static inline int look_for(u32 data)
+{
+       register u32 byte = ((volatile u8 *)MSCC_DDR_TO)[0];
+
+       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)
+{
+#define DDR ((volatile u32 *) MSCC_DDR_TO)
+       register u32 i;
+
+       for (i = 0; i < 8; i++) {
+               DDR[i] = ~i;
+               if (DDR[i] != ~i)
+                       return 1;
+       }
+
+       return 0;
+}
+#endif
+
 /*
  * NB: Called *early* to init memory controller - assumes inlining as
  * no stack is available!
@@ -617,12 +710,12 @@ static inline void hal_vcoreiii_init_memctl(void)
        /* Wait for ZCAL to clear */
        while (readl(REG_CFG(ICPU_MEMPHY_ZCAL)) & ICPU_MEMPHY_ZCAL_ZCAL_ENA)
                ;
-
+#ifdef CONFIG_SOC_OCELOT
        /* Check no ZCAL_ERR */
        if (readl(REG_CFG(ICPU_MEMPHY_ZCAL_STAT))
            & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR)
                hal_vcoreiii_ddr_failed();
-
+#endif
        /* Drive CL, CK, ODT */
        setbits_le32(REG_CFG(ICPU_MEMPHY_CFG), ICPU_MEMPHY_CFG_PHY_ODT_OE |
                     ICPU_MEMPHY_CFG_PHY_CK_OE | ICPU_MEMPHY_CFG_PHY_CL_OE);
@@ -631,8 +724,12 @@ static inline void hal_vcoreiii_init_memctl(void)
        writel(MSCC_MEMPARM_MEMCFG, REG_CFG(ICPU_MEMCTRL_CFG));
        writel(MSCC_MEMPARM_PERIOD, REG_CFG(ICPU_MEMCTRL_REF_PERIOD));
 
-
+#ifdef CONFIG_SOC_OCELOT
        writel(MSCC_MEMPARM_TIMING0, REG_CFG(ICPU_MEMCTRL_TIMING0));
+#else /* Luton */
+       clrbits_le32(REG_CFG(ICPU_MEMCTRL_TIMING0), ((1 << 20) - 1));
+       setbits_le32(REG_CFG(ICPU_MEMCTRL_TIMING0), MSCC_MEMPARM_TIMING0);
+#endif
 
        writel(MSCC_MEMPARM_TIMING1, REG_CFG(ICPU_MEMCTRL_TIMING1));
        writel(MSCC_MEMPARM_TIMING2, REG_CFG(ICPU_MEMCTRL_TIMING2));
@@ -642,6 +739,7 @@ static inline void hal_vcoreiii_init_memctl(void)
        writel(MSCC_MEMPARM_MR2, REG_CFG(ICPU_MEMCTRL_MR2_VAL));
        writel(MSCC_MEMPARM_MR3, REG_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 */
@@ -652,6 +750,11 @@ static inline void hal_vcoreiii_init_memctl(void)
        hal_vcoreiii_ddr_reset_release();
 
        writel(readl(REG_CFG(ICPU_GPR(7))) + 1, REG_CFG(ICPU_GPR(7)));
+#else                          /* Luton */
+       /* Termination setup - disable ODT */
+       writel(0, REG_CFG(ICPU_MEMCTRL_TERMRES_CTRL));
+
+#endif
 }
 
 static inline void hal_vcoreiii_wait_memctl(void)
@@ -665,7 +768,7 @@ static inline void hal_vcoreiii_wait_memctl(void)
 
        /* Settle...? */
        sleep_100ns(10000);
-
+#ifdef CONFIG_SOC_OCELOT
        /* Establish data contents in DDR RAM for training */
 
        __raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO));
@@ -676,5 +779,8 @@ static inline void hal_vcoreiii_wait_memctl(void)
        __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
index 0000000000..b6e1090a2f
--- /dev/null
+++ b/arch/mips/mach-mscc/include/mach/luton/luton.h
@@ -0,0 +1,37 @@
+/* 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
+#ifndef MSCC_IO_OFFSET1
+#define MSCC_IO_OFFSET1(offset) (MSCC_IO_ORIGIN1_OFFSET + offset)
+#endif
+#ifndef MSCC_IO_OFFSET2
+#define MSCC_IO_OFFSET2(offset) (MSCC_IO_ORIGIN2_OFFSET + offset)
+#endif
+#define BASE_CFG        0x70000000
+#define BASE_UART       0x70100000
+#define BASE_DEVCPU_GCB 0x60070000
+#define BASE_MACRO      0x600a0000
+
+#define REG_OFFSET(t, o) ((volatile unsigned long *)(t + (o)))
+#define REG_CFG(x) REG_OFFSET(BASE_CFG, x)
+#define REG_GCB(x) REG_OFFSET(BASE_DEVCPU_GCB, x)
+#define REG_MACRO(x) REG_OFFSET(BASE_MACRO, x)
+
+#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
index 0000000000..8c0b612325
--- /dev/null
+++ b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h
@@ -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
index 0000000000..9233f037bb
--- /dev/null
+++ b/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h
@@ -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/lowlevel_init.S 
b/arch/mips/mach-mscc/lowlevel_init.S
index e6dc9427e1..a2776fa54e 100644
--- a/arch/mips/mach-mscc/lowlevel_init.S
+++ b/arch/mips/mach-mscc/lowlevel_init.S
@@ -8,6 +8,9 @@
 
     .set noreorder
     .extern     vcoreiii_tlb_init
+#ifdef CONFIG_SOC_LUTON
+    .extern     pll_init
+#endif
 
 LEAF(lowlevel_init)
        /*
@@ -18,6 +21,10 @@ LEAF(lowlevel_init)
 
        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
index 0000000000..6b298a99da
--- /dev/null
+++ b/arch/mips/mach-mscc/lowlevel_init_luton.S
@@ -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)
-- 
2.19.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to