From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gregory CLEMENT Date: Tue, 9 Oct 2018 13:58:35 +0200 Subject: [U-Boot] [PATCH v2 4/7] MSCC: add support for Luton SoCs In-Reply-To: <20181009115838.21795-1-gregory.clement@bootlin.com> References: <20181009115838.21795-1-gregory.clement@bootlin.com> Message-ID: <20181009115838.21795-5-gregory.clement@bootlin.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de As the Ocelots SoCs, this family of SoCs are found in the Microsemi Switches solution. Signed-off-by: Gregory CLEMENT --- 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 #include #include +#elif defined(CONFIG_SOC_LUTON) +#include +#include +#include #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 +#include + +/* + * 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 +#include + +#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