[PATCH v1 1/9] arm: nuvoton: Add support for Nuvoton NPCM845 BMC

Sean Anderson seanga2 at gmail.com
Wed Dec 15 19:32:11 CET 2021


On 12/14/21 9:57 PM, Stanley Chu wrote:
> Add basic support for the Nuvoton NPCM845 BMC.
> 
> Signed-off-by: Stanley Chu <yschu at 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

Please add this (and all the other includes) in the patches adding the
drivers which use them. This makes it much easier to review.

Additionally, if these defines are not used elsewhere, they can be
included at the beginning of the clock driver itself.

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

Don't redefine these. Just use include/dt-bindings/clock/npcm845-clock.h

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

Please use GENMASK for this. For example,

	#define CLKSEL_CPUCKSEL GENMASK(1, 0)

This allows you to do things like

u32 clksel = readl(&regs->clksel);

	switch (FIELD_GET(CLKSEL_CPUCKSEL, clksel)) {

	}

later on, instead of having magic masks everywhere.

> +
> +/* 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 */

If you have multiple logical devices in one group of registers, you
should look into organizing your bindings like

	syscon at 0xf0801000 {
		compatible = "simple-mfd";
		reg = <0x0 0xf0801000 0x0 0x70>;

		clks: clock-controller {
			compatible = "nuvoton,npcm845-clock";
			#clock-cells = <1>;
			clocks = <&some_oscillator>;
			clock-names = "extclk";
			u-boot,dm-pre-reloc;
		};

		rsts: reset-controller {
			compatible = "nuvoton,npcm845-reset";
			#reset-cells = <1>;
		}
	}

> +#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

Just define it in HZ and divide it as needed. The compiler will optimize
it. But see also my comments on your other patch.

> +
> +struct clk_ctl {

Please name this npcm_clk_ctl or similar.

> +	unsigned int  clken1;

Please use u32/u64 as the case may be.

--Sean

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



More information about the U-Boot mailing list