MSCC: add support for Luton SoCs

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

Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
This commit is contained in:
Gregory CLEMENT 2018-12-14 16:16:48 +01:00 committed by Daniel Schwierzeck
parent dd1033e4e0
commit 6bd8231a6d
11 changed files with 494 additions and 4 deletions

View file

@ -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

View file

@ -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

View file

@ -48,6 +48,10 @@ 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
#if CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO
/*
@ -75,6 +79,14 @@ void vcoreiii_tlb_init(void)
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);
/*
@ -85,6 +97,6 @@ int mach_cpu_init(void)
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;
}

View file

@ -19,9 +19,11 @@ static inline int vcoreiii_train_bytelane(void)
ret = hal_vcoreiii_train_bytelane(0);
#ifdef CONFIG_SOC_OCELOT
if (ret)
return ret;
ret = hal_vcoreiii_train_bytelane(1);
#endif
return ret;
}

View file

@ -10,6 +10,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

View file

@ -614,6 +614,98 @@ 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(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
@ -646,12 +738,12 @@ static inline void hal_vcoreiii_init_memctl(void)
/* 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);
@ -660,7 +752,12 @@ static inline void hal_vcoreiii_init_memctl(void)
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);
@ -670,6 +767,7 @@ static inline void hal_vcoreiii_init_memctl(void)
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 */
@ -680,6 +778,11 @@ static inline void hal_vcoreiii_init_memctl(void)
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)
@ -693,7 +796,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));
@ -704,5 +807,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 */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)