
Add basic support for the Nuvoton NPCM845 BMC.
Signed-off-by: Stanley Chu yschu@nuvoton.com --- arch/arm/Kconfig | 9 + arch/arm/Makefile | 1 + arch/arm/include/asm/arch-npcm8xx/clock.h | 164 ++++++++++++ arch/arm/include/asm/arch-npcm8xx/espi.h | 23 ++ arch/arm/include/asm/arch-npcm8xx/gcr.h | 313 ++++++++++++++++++++++ arch/arm/include/asm/arch-npcm8xx/gpio.h | 11 + arch/arm/include/asm/arch-npcm8xx/rst.h | 32 +++ arch/arm/mach-nuvoton/Kconfig | 24 ++ arch/arm/mach-nuvoton/Makefile | 1 + arch/arm/mach-nuvoton/npcm8xx/Kconfig | 18 ++ arch/arm/mach-nuvoton/npcm8xx/Makefile | 1 + arch/arm/mach-nuvoton/npcm8xx/cpu.c | 170 ++++++++++++ arch/arm/mach-nuvoton/npcm8xx/reset.c | 51 ++++ board/nuvoton/arbel/Kconfig | 18 ++ board/nuvoton/arbel/Makefile | 1 + board/nuvoton/arbel/arbel.c | 33 +++ include/configs/arbel.h | 54 ++++ 17 files changed, 924 insertions(+) create mode 100644 arch/arm/include/asm/arch-npcm8xx/clock.h create mode 100644 arch/arm/include/asm/arch-npcm8xx/espi.h create mode 100644 arch/arm/include/asm/arch-npcm8xx/gcr.h create mode 100644 arch/arm/include/asm/arch-npcm8xx/gpio.h create mode 100644 arch/arm/include/asm/arch-npcm8xx/rst.h create mode 100644 arch/arm/mach-nuvoton/Kconfig create mode 100644 arch/arm/mach-nuvoton/Makefile create mode 100644 arch/arm/mach-nuvoton/npcm8xx/Kconfig create mode 100644 arch/arm/mach-nuvoton/npcm8xx/Makefile create mode 100644 arch/arm/mach-nuvoton/npcm8xx/cpu.c create mode 100644 arch/arm/mach-nuvoton/npcm8xx/reset.c create mode 100644 board/nuvoton/arbel/Kconfig create mode 100644 board/nuvoton/arbel/Makefile create mode 100644 board/nuvoton/arbel/arbel.c create mode 100644 include/configs/arbel.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f7f03837fe..80ec42f6be 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1952,6 +1952,13 @@ config TARGET_XENGUEST_ARM64 select LINUX_KERNEL_IMAGE_HEADER select XEN_SERIAL select SSCANF + +config ARCH_NPCM + bool "Support Nuvoton SoCs" + select DM + select OF_CONTROL + imply CMD_DM + endchoice
config SUPPORT_PASSING_ATAGS @@ -2150,6 +2157,8 @@ source "arch/arm/mach-imx/Kconfig"
source "arch/arm/mach-nexell/Kconfig"
+source "arch/arm/mach-nuvoton/Kconfig" + source "board/armltd/total_compute/Kconfig"
source "board/bosch/shc/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ad757e982e..29a0250ab6 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -92,6 +92,7 @@ machine-$(CONFIG_ARCH_VERSAL) += versal machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_ARCH_ZYNQMP) += zynqmp machine-$(CONFIG_ARCH_ZYNQMP_R5) += zynqmp-r5 +machine-$(CONFIG_ARCH_NPCM) += nuvoton
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
diff --git a/arch/arm/include/asm/arch-npcm8xx/clock.h b/arch/arm/include/asm/arch-npcm8xx/clock.h new file mode 100644 index 0000000000..088b536b7b --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/clock.h @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#ifndef _NPCM_CLOCK_H_ +#define _NPCM_CLOCK_H_ + +#define NPCM_CLK_BA 0xF0801000 +enum { + APB1 = 1, + APB2 = 2, + APB3 = 3, + APB4 = 4, + APB5 = 5, + SPI0 = 10, + SPI1 = 11, + SPI3 = 13, + SPIX = 14, +}; + +/* Clock Select Register (CLKSEL) */ +#define CLKSEL_RCPCKSEL 27 +#define CLKSEL_RGSEL 25 +#define CLKSEL_GFXMSEL 21 +#define CLKSEL_CLKOUTSEL 18 +#define CLKSEL_PCICKSEL 16 +#define CLKSEL_ADCCKSEL 14 +#define CLKSEL_MCCKSEL 12 +#define CLKSEL_SUCKSEL 10 +#define CLKSEL_UARTCKSEL 8 +#define CLKSEL_SDCKSEL 6 +#define CLKSEL_PIXCKSEL 4 +#define CLKSEL_CPUCKSEL 0 + +/* Clock Divider Control Register 1 (CLKDIV1) */ +#define CLKDIV1_ADCCKDIV 28 +#define CLKDIV1_CLK4DIV 26 +#define CLKDIV1_PRE_ADCCKDIV 21 +#define CLKDIV1_UARTDIV 16 +#define CLKDIV1_MMCCKDIV 11 +#define CLKDIV1_SPI3CKDIV 6 +#define CLKDIV1_PCICKDIV 2 + +/* Clock Divider Control Register 2 (CLKDIV2) */ +#define CLKDIV2_APB4CKDIV 30 +#define CLKDIV2_APB3CKDIV 28 +#define CLKDIV2_APB2CKDIV 26 +#define CLKDIV2_APB1CKDIV 24 +#define CLKDIV2_APB5CKDIV 22 +#define CLKDIV2_CLKOUTDIV 16 +#define CLKDIV2_GFXCKDIV 13 +#define CLKDIV2_SUCKDIV 8 +#define CLKDIV2_SU48CKDIV 4 + +/* PLL Control Register 2 (PLLCON2) */ +#define PLLCON_LOKI 31 +#define PLLCON_LOKS 30 +#define PLLCON_FBDV 16 +#define PLLCON_OTDV2 13 +#define PLLCON_PWDEN 12 +#define PLLCON_OTDV1 8 +#define PLLCON_INDV 0 + +/* CPUCKSEL (CPU/AMBA/MC Clock Source Select Bit) */ +#define CLKSEL_CPUCKSEL_PLL0 0x00 /* 0 0: PLL0 clock*/ +#define CLKSEL_CPUCKSEL_PLL1 0x01 /* 0 1: PLL1 clock */ +#define CLKSEL_CPUCKSEL_CLKREF 0x02 /* 1 0: CLKREF input (25 MHZ, default) */ +#define CLKSEL_CPUCKSEL_SYSBPCK 0x03 /* 1 1: Bypass clock from pin SYSBPCK */ + +/* UARTCKSEL (Core and Host UART Clock Source Select Bit). */ +#define CLKSEL_UARTCKSEL_PLL0 0x00 /* 0 0: PLL0 clock. */ +#define CLKSEL_UARTCKSEL_PLL1 0x01 /* 0 1: PLL1 clock. */ +#define CLKSEL_UARTCKSEL_CLKREF 0x02 /* 1 0: CLKREF clock (25 MHZ, default). */ +#define CLKSEL_UARTCKSEL_PLL2 0x03 /* 1 1: PLL2 clock divided by 2. */ + +/* SDCKSEL (SDHC Clock Source Select Bit). */ +#define CLKSEL_SDCKSEL_PLL0 0x00 /* 0 0: PLL0 clock. */ +#define CLKSEL_SDCKSEL_PLL1 0x01 /* 0 1: PLL1 clock. */ +#define CLKSEL_SDCKSEL_CLKREF 0x02 /* 1 0: CLKREF clock (25 MHZ, default). */ +#define CLKSEL_SDCKSEL_PLL2 0x03 /* 1 1: PLL2 clock divided by 2. */ + +/* IP Software Reset Register 1 (IPSRST1), offset 0x20 */ +#define IPSRST1_USBDEV1 5 +#define IPSRST1_USBDEV2 8 +#define IPSRST1_USBDEV3 25 +#define IPSRST1_USBDEV4 22 +#define IPSRST1_USBDEV5 23 +#define IPSRST1_USBDEV6 24 +#define IPSRST1_GMAC4 21 +#define IPSRST1_GMAC3 6 + +/* IP Software Reset Register 2 (IPSRST2), offset 0x24 */ +#define IPSRST2_GMAC1 28 +#define IPSRST2_GMAC2 25 +#define IPSRST2_USBHOST1 26 +#define IPSRST2_SDHC 9 +#define IPSRST2_MMC 8 + +/* IP Software Reset Register 3 (IPSRST3), offset 0x34 */ +#define IPSRST3_USBPHY1 24 +#define IPSRST3_USBPHY2 25 +#define IPSRST3_USBHUB 8 +#define IPSRST3_USBDEV9 7 +#define IPSRST3_USBDEV8 6 +#define IPSRST3_USBDEV7 5 +#define IPSRST3_USBDEV0 4 + +/* IP Software Reset Register 4 (IPSRST4), offset 0x74 */ +#define IPSRST4_USBHOST2 31 +#define IPSRST4_USBPHY3 25 + +#define EXT_CLOCK_FREQUENCY_KHZ 25 * 1000 * 1UL +#define EXT_CLOCK_FREQUENCY_MHZ 25 + +struct clk_ctl { + unsigned int clken1; + unsigned int clksel; + unsigned int clkdiv1; + unsigned int pllcon0; + unsigned int pllcon1; + unsigned int swrstr; + unsigned char res1[0x8]; + unsigned int ipsrst1; + unsigned int ipsrst2; + unsigned int clken2; + unsigned int clkdiv2; + unsigned int clken3; + unsigned int ipsrst3; + unsigned int wd0rcr; + unsigned int wd1rcr; + unsigned int wd2rcr; + unsigned int swrstc1; + unsigned int swrstc2; + unsigned int swrstc3; + unsigned int tiprstc; + unsigned int pllcon2; + unsigned int clkdiv3; + unsigned int corstc; + unsigned int pllcong; + unsigned int ahbckfi; + unsigned int seccnt; + unsigned int cntr25m; + unsigned int clken4; + unsigned int ipsrst4; + unsigned int busto; + unsigned int clkdiv4; + unsigned int wd0rcrb; + unsigned int wd1rcrb; + unsigned int wd2rcrb; + unsigned int swrstc1b; + unsigned int swrstc2b; + unsigned int swrstc3b; + unsigned int tiprstcb; + unsigned int corstcb; + unsigned int ipsrstdis1; + unsigned int ipsrstdis2; + unsigned int ipsrstdis3; + unsigned int ipsrstdis4; + unsigned char res2[0x10]; + unsigned int thrtl_cnt; +}; + +#endif diff --git a/arch/arm/include/asm/arch-npcm8xx/espi.h b/arch/arm/include/asm/arch-npcm8xx/espi.h new file mode 100644 index 0000000000..d4de012b02 --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/espi.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _NPCM_ESPI_H_ +#define _NPCM_ESPI_H_ + +#define NPCM_ESPI_BA 0xF009F000 +/* Register offsets */ +#define ESPICFG 0x04 +#define ESPIHINDP 0x80 + +/* Channel Supported */ +#define ESPICFG_CHNSUPP_MASK 0x0F +#define ESPICFG_CHNSUPP_SHFT 24 + +/* I/O Mode Supported */ +#define ESPICFG_IOMODE_SHIFT 8 +#define ESPI_IO_MODE_SINGLE_DUAL_QUAD 3 + +/* Maximum Frequency Supported */ +#define ESPICFG_MAXFREQ_SHIFT 10 +#define ESPI_MAX_33_MHZ 2 + +#endif diff --git a/arch/arm/include/asm/arch-npcm8xx/gcr.h b/arch/arm/include/asm/arch-npcm8xx/gcr.h new file mode 100644 index 0000000000..14a4b2dbfb --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/gcr.h @@ -0,0 +1,313 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#ifndef _NPCM_GCR_H_ +#define _NPCM_GCR_H_ + +#define NPCM_GCR_BA 0xF0800000 +/* On-Chip ARBEL NPCM8XX VERSIONS */ + +#define ARBEL_Z1 0x00A35850 +#define ARBEL_A1 0x04a35850 +#define ARBEL_NPCM845 0x00000000 +#define ARBEL_NPCM830 0x00300395 +#define ARBEL_NPCM810 0x00000220 + +/* Function Lock Register 2 (FLOCKR2) */ +#define FLOCKR2_MMCRST 12 +#define FLOCKR2_MMCRSTLK 13 +#define FLOCKR2_G35DA2P 18 + +/* Power-On Setting Register (PWRON) */ +#define PWRON_BSPA 4 /* STRAP5 */ +#define PWRON_SECEN 7 /* STRAP8 */ + +/* Multiple Function Pin Select Register 1 (MFSEL1) */ +#define MFSEL1_SIRQSE 31 +#define MFSEL1_IOX1SEL 30 +#define MFSEL1_HSI2BSEL 29 +#define MFSEL1_HSI1BSEL 28 +#define MFSEL1_DVH1SEL 27 +#define MFSEL1_LPCSEL 26 +#define MFSEL1_PECIB 25 +#define MFSEL1_GSPISEL 24 +#define MFSEL1_SMISEL 22 +#define MFSEL1_CLKOSEL 21 +#define MFSEL1_DVOSEL 18 +#define MFSEL1_KBCICSEL 17 +#define MFSEL1_R2MDSEL 16 +#define MFSEL1_R2ERRSEL 15 +#define MFSEL1_RMII2SEL 14 +#define MFSEL1_R1MDSEL 13 +#define MFSEL1_R1ERRSEL 12 +#define MFSEL1_HSI2ASEL 11 +#define MFSEL1_HSI1ASEL 10 +#define MFSEL1_BSPSEL 9 +#define MFSEL1_SMB2SEL 8 +#define MFSEL1_SMB1SEL 7 +#define MFSEL1_SMB0SEL 6 +#define MFSEL1_HSI2CSEL 5 +#define MFSEL1_HSI1CSEL 4 +#define MFSEL1_S0CS1SEL 3 +#define MFSEL1_SMB5SEL 2 +#define MFSEL1_SMB4SEL 1 +#define MFSEL1_SMB3SEL 0 + +/* Multiple Function Pin Select Register 3 (MFSEL3) */ +#define MFSEL3_DVODEDLY 27 +#define MFSEL3_DDRDVOSEL 26 +#define MFSEL3_MMCCDSEL 25 +#define MFSEL3_BU1SEL 24 +#define MFSEL3_I3C5SEL 22 +#define MFSEL3_WDO2SEL 20 +#define MFSEL3_WDO1SEL 19 +#define MFSEL3_IOXHSEL 18 +#define MFSEL3_PCIEPUSE 17 +#define MFSEL3_CLKRUNSEL 16 +#define MFSEL3_IOX2SEL 14 +#define MFSEL3_PSPISEL 13 +#define MFSEL3_MMC8SEL 11 +#define MFSEL3_MMCSEL 10 +#define MFSEL3_RMII1SEL 9 +#define MFSEL3_SMB15SEL 8 +#define MFSEL3_SMB14SEL 7 +#define MFSEL3_SMB13SEL 6 +#define MFSEL3_SMB12SEL 5 +#define MFSEL3_SPI1SEL 4 +#define MFSEL3_FIN1916SELB 3 +#define MFSEL3_SMB7SEL 2 +#define MFSEL3_SMB6SEL 1 +#define MFSEL3_SCISEL 0 + +/* Multiple Function Pin Select Register 4 (MFSEL4) */ +#define MFSEL4_SMB11DDC 29 +#define MFSEL4_SXCS1SEL 28 +#define MFSEL4_SPXSEL 27 +#define MFSEL4_RG2SEL 24 +#define MFSEL4_RG2MSEL 23 +#define MFSEL4_BU2SELB 22 +#define MFSEL4_SG1MSEL 21 +#define MFSEL4_SP3QSEL 20 +#define MFSEL4_S3CS3SEL 19 +#define MFSEL4_S3CS2SEL 18 +#define MFSEL4_S3CS1SEL 17 +#define MFSEL4_SP3SEL 16 +#define MFSEL4_SP0QSEL 15 +#define MFSEL4_SMB11SEL 14 +#define MFSEL4_SMB10SEL 13 +#define MFSEL4_SMB9SEL 12 +#define MFSEL4_SMB8SEL 11 +#define MFSEL4_DBGTRSEL 10 +#define MFSEL4_CKRQSEL 9 +#define MFSEL4_ESPISEL 8 +#define MFSEL4_MMCRSEL 6 +#define MFSEL4_SD1PSEL 5 +#define MFSEL4_ROSEL 4 +#define MFSEL4_ESPIPMESEL 2 +#define MFSEL4_BSPASEL 1 +#define MFSEL4_JTAG2SEL 0 + +/* Multiple Function Pin Select Register 5 (MFSEL5) */ +#define MFSEL5_R3OENSEL 14 +#define MFSEL5_RMII3SEL 11 +#define MFSEL5_R2OENSEL 10 +#define MFSEL5_R1OENSEL 9 +#define MFSEL5_NSPI1CS3SEL 5 +#define MFSEL5_NSPI1CS2SEL 4 +#define MFSEL5_SPI1D23SEL 3 +#define MFSEL5_NSPI1CS1SEL 0 + +/* Multiple Function Pin Select Register 6 (MFSEL6) */ +#define MFSEL6_GPIO1836SEL 19 +#define MFSEL6_FM1SEL 17 + +/* Multiple Function Pin Select Register 7 (MFSEL7) */ +#define MFSEL7_SMB15SELB 27 +#define MFSEL7_GPIO1889SEL 25 + +/* USB PHY1 Control Register (USB1PHYCTL) */ +#define USB1PHYCTL_RS 28 +/* USB PHY2 Control Register (USB2PHYCTL) */ +#define USB2PHYCTL_RS 28 +/* USB PHY2 Control Register (USB3PHYCTL) */ +#define USB3PHYCTL_RS 28 + +/* Integration Control Register (INTCR) */ +#define INTCR_DUDKSMOD 30 +#define INTCR_DDC3I 29 +#define INTCR_KVMSI 28 +#define INTCR_DEHS 27 +#define INTCR_GGPCT2_0 24 +#define INTCR_SGC2 23 +#define INTCR_DSNS_TRIG 21 +#define INTCR_DAC_SNS 20 +#define INTCR_SGC1 19 +#define INTCR_LDDRB 18 +#define INTCR_GIRST 17 +#define INTCR_DUDKSEN 16 +#define INTCR_DACOFF 15 +#define INTCR_DACSEL 14 +#define INTCR_GFXINT 12 +#define INTCR_DACOSOVR 10 +#define INTCR_GFXIFDIS 8 +#define INTCR_H2RQDIS 9 +#define INTCR_H2DISPOFF 8 +#define INTCR_GFXINT2 7 +#define INTCR_VGAIOEN 6 +#define INTCR_PSPIFEN 4 +#define INTCR_HIFEN 3 +#define INTCR_SMBFEN 2 +#define INTCR_MFTFEN 1 +#define INTCR_KCSRST_MODE 0 + +/* Integration Control Register (INTCR2) */ +#define INTCR2_WDC 21 + +/* Integration Control Register (INTCR3) */ +#define INTCR3_USBLPBK2 31 /* USB loop-backed HOST 1/2 */ +#define INTCR3_USBLPBK 24 /* USB loop-backed mode on/off */ +#define INTCR3_USBPHY3SW 14 /* 2 bits */ +#define INTCR3_USBPHY2SW 12 /* 2 bits */ +#define INTCR3_USBPPS 6 +#define INTCR3_UHUB_RWUD 5 + +/* Integration Control Register (INTCR4) */ +#define INTCR4_GMMAP1 24 +#define INTCR4_GMMAP0 16 +#define INTCR4_R3EN 14 +#define INTCR4_R2EN 13 +#define INTCR4_R1EN 12 +#define INTCR4_RGMIIREF 6 + +/* I2C Segment Pin Select Register (I2CSEGSEL) */ +#define I2CSEGSEL_S0DECFG 3 +#define I2CSEGSEL_S4DECFG 17 + +/* I2C Segment Control Register (I2CSEGCTL) */ +#define I2CSEGCTL_S0DEN 20 +#define I2CSEGCTL_S0DWE 21 +#define I2CSEGCTL_S4DEN 24 +#define I2CSEGCTL_S4DWE 25 +#define I2CSEGCTL_INIT_VAL 0x9333F000 + +struct npcm_gcr { + unsigned int pdid; + unsigned int pwron; + unsigned int swstrps; + unsigned int rsvd1[2]; + unsigned int miscpe; + unsigned int spldcnt; + unsigned int rsvd2[1]; + unsigned int flockr2; + unsigned int flockr3; + unsigned int rsvd3[3]; + unsigned int a35_mode; + unsigned int spswc; + unsigned int intcr; + unsigned int intsr; + unsigned int obscr1; + unsigned int obsdr1; + unsigned int rsvd4[1]; + unsigned int hifcr; + unsigned int rsvd5[3]; + unsigned int intcr2; + unsigned int rsvd6[1]; + unsigned int srcnt; + unsigned int ressr; + unsigned int rlockr1; + unsigned int flockr1; + unsigned int dscnt; + unsigned int mdlr; + unsigned int scrpad_c; + /* scrpad_b: holds the active dram size (value set by bootblock) */ + unsigned int scrpad_b; + unsigned int rsvd7[4]; + unsigned int daclvlr; + unsigned int intcr3; + unsigned int pcirctl; + unsigned int rsvd8[2]; + unsigned int vsintr; + unsigned int rsvd9[1]; + unsigned int sd2sur1; + unsigned int sd2sur2; + unsigned int sd2irv3; + unsigned int intcr4; + unsigned int obscr2; + unsigned int obsdr2; + unsigned int rsvd10[5]; + unsigned int i2csegsel; + unsigned int i2csegctl; + unsigned int vsrcr; + unsigned int mlockr; + unsigned int rsvd11[8]; + unsigned int etsr; + unsigned int dft1r; + unsigned int dft2r; + unsigned int dft3r; + unsigned int edffsr; + unsigned int rsvd12[1]; + unsigned int intcrpce3; + unsigned int intcrpce2; + unsigned int intcrpce0; + unsigned int intcrpce1; + unsigned int dactest; + unsigned int scrpad; + unsigned int usb1phyctl; + unsigned int usb2phyctl; + unsigned int usb3phyctl; + unsigned int intsr2; + unsigned int intcrpce2b; + unsigned int intcrpce0b; + unsigned int intcrpce1b; + unsigned int intcrpce3b; + unsigned int rsvd13[4]; + unsigned int intcrpce2c; + unsigned int intcrpce0c; + unsigned int intcrpce1c; + unsigned int intcrpce3c; + unsigned int rsvd14[40]; + unsigned int sd2irv4; + unsigned int sd2irv5; + unsigned int sd2irv6; + unsigned int sd2irv7; + unsigned int sd2irv8; + unsigned int sd2irv9; + unsigned int sd2irv10; + unsigned int sd2irv11; + unsigned int rsvd15[8]; + unsigned int mfsel1; + unsigned int mfsel2; + unsigned int mfsel3; + unsigned int mfsel4; + unsigned int mfsel5; + unsigned int mfsel6; + unsigned int mfsel7; + unsigned int rsvd16[1]; + unsigned int mfsel_lk1; + unsigned int mfsel_lk2; + unsigned int mfsel_lk3; + unsigned int mfsel_lk4; + unsigned int mfsel_lk5; + unsigned int mfsel_lk6; + unsigned int mfsel_lk7; + unsigned int rsvd17[1]; + unsigned int mfsel_set1; + unsigned int mfsel_set2; + unsigned int mfsel_set3; + unsigned int mfsel_set4; + unsigned int mfsel_set5; + unsigned int mfsel_set6; + unsigned int mfsel_set7; + unsigned int rsvd18[1]; + unsigned int mfsel_clr1; + unsigned int mfsel_clr2; + unsigned int mfsel_clr3; + unsigned int mfsel_clr4; + unsigned int mfsel_clr5; + unsigned int mfsel_clr6; + unsigned int mfsel_clr7; + }; + +#endif diff --git a/arch/arm/include/asm/arch-npcm8xx/gpio.h b/arch/arm/include/asm/arch-npcm8xx/gpio.h new file mode 100644 index 0000000000..234a1d3de9 --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/gpio.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#ifndef _NPCM_GPIO_H_ +#define _NPCM_GPIO_H_ + +#define NPCM_GPIO_BA 0xF0010000 + +#endif diff --git a/arch/arm/include/asm/arch-npcm8xx/rst.h b/arch/arm/include/asm/arch-npcm8xx/rst.h new file mode 100644 index 0000000000..ffaff50fe2 --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/rst.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _NPCM_RST_H_ +#define _NPCM_RST_H_ + +enum reset_type { + PORST_TYPE = 0x01, + CORST_TYPE = 0x02, + WD0RST_TYPE = 0x03, + SWR1ST_TYPE = 0x04, + SWR2ST_TYPE = 0x05, + SWR3ST_TYPE = 0x06, + SWR4ST_TYPE = 0x07, + WD1RST_TYPE = 0x08, + WD2RST_TYPE = 0x09, + UNKNOWN_TYPE = 0x10, +}; + +#define PORST 0x80000000 +#define CORST 0x40000000 +#define WD0RST 0x20000000 +#define SWR1ST 0x10000000 +#define SWR2ST 0x08000000 +#define SWR3ST 0x04000000 +#define SWR4ST 0x02000000 +#define WD1RST 0x01000000 +#define WD2RST 0x00800000 +#define RESSR_MASK 0xff800000 + +enum reset_type npcm8xx_reset_reason(void); + +#endif diff --git a/arch/arm/mach-nuvoton/Kconfig b/arch/arm/mach-nuvoton/Kconfig new file mode 100644 index 0000000000..e014dd4b79 --- /dev/null +++ b/arch/arm/mach-nuvoton/Kconfig @@ -0,0 +1,24 @@ +if ARCH_NPCM + +config SYS_ARCH + default "arm" + +config SYS_TEXT_BASE + default 0x8000 + +choice + prompt "Nuvoton SoC select" + default ARCH_NPCM8XX + +config ARCH_NPCM8XX + bool "Support Nuvoton NPCM8xx SoC" + select ARM64 + help + General support for NPCM8xx BMC (Arbel). + Nuvoton NPCM8xx BMC is based on the Cortex A35. + +endchoice + +source "arch/arm/mach-nuvoton/npcm8xx/Kconfig" + +endif diff --git a/arch/arm/mach-nuvoton/Makefile b/arch/arm/mach-nuvoton/Makefile new file mode 100644 index 0000000000..e75689a1a0 --- /dev/null +++ b/arch/arm/mach-nuvoton/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_NPCM8XX) += npcm8xx/ diff --git a/arch/arm/mach-nuvoton/npcm8xx/Kconfig b/arch/arm/mach-nuvoton/npcm8xx/Kconfig new file mode 100644 index 0000000000..478a046ad5 --- /dev/null +++ b/arch/arm/mach-nuvoton/npcm8xx/Kconfig @@ -0,0 +1,18 @@ +if ARCH_NPCM8XX + +config SYS_CPU + default "armv8" + +config SYS_SOC + default "npcm8xx" + +config TARGET_ARBEL_EVB + bool "Arbel-EVB" + help + ARBEL_EVB is Nuvoton evaluation board for NPCM845 SoC, + supports general functions of Basebase Management Controller + (BMC). + +source "board/nuvoton/arbel/Kconfig" + +endif diff --git a/arch/arm/mach-nuvoton/npcm8xx/Makefile b/arch/arm/mach-nuvoton/npcm8xx/Makefile new file mode 100644 index 0000000000..c62a4aa20a --- /dev/null +++ b/arch/arm/mach-nuvoton/npcm8xx/Makefile @@ -0,0 +1 @@ +obj-y += reset.o cpu.o diff --git a/arch/arm/mach-nuvoton/npcm8xx/cpu.c b/arch/arm/mach-nuvoton/npcm8xx/cpu.c new file mode 100644 index 0000000000..8a7315d535 --- /dev/null +++ b/arch/arm/mach-nuvoton/npcm8xx/cpu.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include <common.h> +#include <dm.h> +#include <cpu_func.h> +#include <asm/io.h> +#include <asm/arch/gcr.h> +#include <asm/arch/espi.h> +#include <asm/armv8/mmu.h> +#include <asm/system.h> +#include <asm/global_data.h> + +/* System Counter */ +struct sctr_regs { + u32 cntcr; + u32 cntsr; + u32 cntcv1; + u32 cntcv2; + u32 resv1[4]; + u32 cntfid0; + u32 cntfid1; + u32 cntfid2; + u32 resv2[1001]; + u32 counterid[1]; +}; + +#define SC_CNTCR_ENABLE BIT(0) +#define SC_CNTCR_HDBG BIT(1) +#define SC_CNTCR_FREQ0 BIT(8) +#define SC_CNTCR_FREQ1 BIT(9) + +#define SYSCNT_CTRL_BASE_ADDR 0xF07FC000 + +DECLARE_GLOBAL_DATA_PTR; + +int print_cpuinfo(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + unsigned int id = 0; + unsigned long mpidr_val = 0; + unsigned int mdlr = 0; + + asm volatile("mrs %0, mpidr_el1" : "=r" (mpidr_val)); + + mdlr = readl(&gcr->mdlr); + + printf("CPU-%d: ", (unsigned int)(mpidr_val & 0x3)); + + switch (mdlr) { + case ARBEL_NPCM845: + printf("NPCM845 "); + break; + case ARBEL_NPCM830: + printf("NPCM830 "); + break; + case ARBEL_NPCM810: + printf("NPCM810 "); + break; + default: + printf("NPCM8XX "); + break; + } + + id = readl(&gcr->pdid); + switch (id) { + case ARBEL_Z1: + printf("Z1 @ "); + break; + case ARBEL_A1: + printf("A1 @ "); + break; + default: + printf("Unknown\n"); + break; + } + + return 0; +} + +static void npcm_sysintf_init(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + u32 espi_ch_supp, val; + + espi_ch_supp = ofnode_conf_read_int("espi-channel-support", 0); + + if (espi_ch_supp) { + /* Use eSPI function and initialize ESPICFG */ + u32 hindp = 0x00011110 | espi_ch_supp; + + writel((readl(&gcr->mfsel4) | (1 << MFSEL4_ESPISEL)), &gcr->mfsel4); + writel(hindp, NPCM_ESPI_BA + ESPIHINDP); + val = readl(NPCM_ESPI_BA + ESPICFG); + val |= ESPI_IO_MODE_SINGLE_DUAL_QUAD << ESPICFG_IOMODE_SHIFT; + val |= ESPI_MAX_33_MHZ << ESPICFG_MAXFREQ_SHIFT; + val |= ((espi_ch_supp & ESPICFG_CHNSUPP_MASK) << ESPICFG_CHNSUPP_SHFT); + writel(val, NPCM_ESPI_BA + ESPICFG); + } else { + /* Use LPC function */ + writel((readl(&gcr->mfsel1) | (1 << MFSEL1_LPCSEL)), &gcr->mfsel1); + } +} + +int arch_cpu_init(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + + if (!IS_ENABLED(CONFIG_SYS_DCACHE_OFF)) { + /* enable cache to speed up system running */ + if (get_sctlr() & CR_M) + return 0; + + icache_enable(); + __asm_invalidate_dcache_all(); + __asm_invalidate_tlb_all(); + set_sctlr(get_sctlr() | CR_C); + } + + /* Power voltage select setup */ + setbits_le32(&gcr->vsrcr, BIT(30)); + + npcm_sysintf_init(); + + return 0; +} + +static struct mm_region npcm_mem_map[1 + CONFIG_NR_DRAM_BANKS + 1] = { + { + /* DRAM */ + .phys = 0x0UL, + .virt = 0x0UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, + { + .phys = 0x80000000UL, + .virt = 0x80000000UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, + { + /* List terminator */ + 0, + } +}; + +struct mm_region *mem_map = npcm_mem_map; + +int timer_init(void) +{ + struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR; + unsigned int cntfrq_el0; + + __asm__ __volatile__("mrs %0, CNTFRQ_EL0\n\t" : "=r" (cntfrq_el0) : : "memory"); + writel(cntfrq_el0, &sctr->cntfid0); + + clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1, + SC_CNTCR_ENABLE | SC_CNTCR_HDBG); + + gd->arch.tbl = 0; + gd->arch.tbu = 0; + + return 0; +} diff --git a/arch/arm/mach-nuvoton/npcm8xx/reset.c b/arch/arm/mach-nuvoton/npcm8xx/reset.c new file mode 100644 index 0000000000..7fbed7ba76 --- /dev/null +++ b/arch/arm/mach-nuvoton/npcm8xx/reset.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/rst.h> +#include <asm/arch/gcr.h> + +void reset_cpu(void) +{ + /* Watcdog reset - WTCR register set WTE-BIT7 WTRE-BIT1 WTR-BIT0 */ + writel(0x83, 0xf000801c); + + while (1) + ; +} + +void reset_misc(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + + /* clear WDC */ + writel(readl(&gcr->intcr2) & ~(1 << INTCR2_WDC), &gcr->intcr2); +} + +enum reset_type npcm8xx_reset_reason(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + enum reset_type type = UNKNOWN_TYPE; + u32 value = readl(&gcr->ressr); + + if (value == 0) + value = ~readl(&gcr->intcr2); + + value &= RESSR_MASK; + + if (value & CORST) + type = CORST; + if (value & WD0RST) + type = WD0RST; + if (value & WD1RST) + type = WD1RST; + if (value & WD2RST) + type = WD2RST; + if (value & PORST) + type = PORST; + + return type; +} diff --git a/board/nuvoton/arbel/Kconfig b/board/nuvoton/arbel/Kconfig new file mode 100644 index 0000000000..4a03ea1abf --- /dev/null +++ b/board/nuvoton/arbel/Kconfig @@ -0,0 +1,18 @@ +if TARGET_ARBEL_EVB + +config SYS_BOARD + default "arbel" + +config SYS_VENDOR + default "nuvoton" + +config SYS_CONFIG_NAME + default "arbel" + +config SYS_MEM_TOP_HIDE + hex "Reserved TOP memory" + default 0xB000000 + help + Reserve memory for ECC/GFX/VCD/ECE. + +endif diff --git a/board/nuvoton/arbel/Makefile b/board/nuvoton/arbel/Makefile new file mode 100644 index 0000000000..f9ad1dea34 --- /dev/null +++ b/board/nuvoton/arbel/Makefile @@ -0,0 +1 @@ +obj-y += arbel.o diff --git a/board/nuvoton/arbel/arbel.c b/board/nuvoton/arbel/arbel.c new file mode 100644 index 0000000000..86cef98c5f --- /dev/null +++ b/board/nuvoton/arbel/arbel.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <asm/arch/gcr.h> +#include <asm/mach-types.h> + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + gd->bd->bi_arch_number = MACH_TYPE_NPCMX50; + gd->bd->bi_boot_params = (CONFIG_SYS_SDRAM_BASE + 0x100UL); + + return 0; +} + +int dram_init(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + + /* + * get dram active size value from bootblock. + * Value sent using scrpad_02 register. + */ + gd->ram_size = readl(&gcr->scrpad_b); + + return 0; +} diff --git a/include/configs/arbel.h b/include/configs/arbel.h new file mode 100644 index 0000000000..2cb658c3e6 --- /dev/null +++ b/include/configs/arbel.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#ifndef __CONFIG_ARBEL_H +#define __CONFIG_ARBEL_H + +#define CONFIG_GICV2 +#define GICD_BASE (0xDFFF9000) +#define GICC_BASE (0xDFFFA000) + +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1 +#define CONFIG_USB_OHCI_NEW +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_SYS_MAXARGS 32 +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_BOOTM_LEN (20 << 20) +#define CONFIG_SYS_BOOTMAPSZ (20 << 20) +#define CONFIG_SYS_SDRAM_BASE 0x0 +#define CONFIG_SYS_INIT_SP_ADDR (0x00008000 - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_MONITOR_LEN (256 << 10) +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_HZ 1000 +#define CONFIG_BITBANGMII_MULTI + +/* Default environemnt variables */ +#define CONFIG_BOOTCOMMAND "run common_bootargs; run romboot" +#define CONFIG_EXTRA_ENV_SETTINGS "uimage_flash_addr=80200000\0" \ + "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" \ + "ethact=gmac1\0" \ + "autostart=no\0" \ + "ethaddr=00:00:F7:A0:00:FC\0" \ + "eth1addr=00:00:F7:A0:00:FD\0" \ + "eth2addr=00:00:F7:A0:00:FE\0" \ + "eth3addr=00:00:F7:A0:00:FF\0" \ + "gatewayip=192.168.0.17\0" \ + "serverip=192.168.0.17\0" \ + "ipaddr=192.168.0.15\0" \ + "romboot=echo Booting Kernel from flash at 0x${uimage_flash_addr}; " \ + "echo Using bootargs: ${bootargs};bootm ${uimage_flash_addr}\0" \ + "earlycon=uart8250,mmio32,0xf0000000\0" \ + "console=ttyS0,115200n8\0" \ + "common_bootargs=setenv bootargs earlycon=${earlycon} root=/dev/ram " \ + "console=${console} ramdisk_size=48000\0" \ + "\0" + +#endif