[PATCH v3 0/4] Add Nuvoton NPCM750 support

The patch series add basic supoorts for NPCM750, which is Nuvoton's 3th-generation BMC (Baseboard Management Controller). Add drivers to support Clock,Timer,Uart for NPCM7xx SoC.
the NPCM750 computing subsystem comprises a dual-core ARM a9 at 800MHz speed with L1/L2 caches
dts,dtsi and npcm7xx-reset.h have been submitted to kernel upstream.
the patch is base on top of current master and pass the CI test. https://github.com/u-boot/u-boot/pull/169
Jim Liu (4): arm: nuvoton: Add support for Nuvoton NPCM750 BMC clk: nuvoton: Add support for NPCM750 serial: npcm: Add support for Nuvoton NPCM SoCs timer: npcm: Add NPCM timer support
arch/arm/Kconfig | 8 + arch/arm/Makefile | 1 + arch/arm/dts/Makefile | 1 + arch/arm/dts/nuvoton-common-npcm7xx.dtsi | 1120 +++++++++++++++++ arch/arm/dts/nuvoton-npcm750-evb.dts | 405 ++++++ arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi | 157 +++ arch/arm/dts/nuvoton-npcm750.dtsi | 62 + arch/arm/include/asm/arch-npcm7xx/gcr.h | 65 + arch/arm/mach-npcm/Kconfig | 26 + arch/arm/mach-npcm/Makefile | 1 + arch/arm/mach-npcm/npcm7xx/Kconfig | 22 + arch/arm/mach-npcm/npcm7xx/Makefile | 1 + arch/arm/mach-npcm/npcm7xx/cpu.c | 66 + arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c | 29 + .../mach-npcm/npcm7xx/l2_cache_pl310_init.S | 71 ++ board/nuvoton/poleg_evb/Kconfig | 25 + board/nuvoton/poleg_evb/MAINTAINERS | 7 + board/nuvoton/poleg_evb/Makefile | 1 + board/nuvoton/poleg_evb/poleg_evb.c | 48 + configs/poleg_evb_defconfig | 40 + drivers/clk/Makefile | 1 + drivers/clk/nuvoton/Makefile | 2 + drivers/clk/nuvoton/clk_npcm.c | 299 +++++ drivers/clk/nuvoton/clk_npcm.h | 105 ++ drivers/clk/nuvoton/clk_npcm7xx.c | 95 ++ drivers/serial/Kconfig | 9 + drivers/serial/Makefile | 1 + drivers/serial/serial_npcm.c | 157 +++ drivers/timer/Kconfig | 9 + drivers/timer/Makefile | 1 + drivers/timer/npcm-timer.c | 115 ++ include/configs/poleg.h | 44 + .../dt-bindings/clock/nuvoton,npcm7xx-clock.h | 46 + .../dt-bindings/reset/nuvoton,npcm7xx-reset.h | 91 ++ 34 files changed, 3131 insertions(+) create mode 100644 arch/arm/dts/nuvoton-common-npcm7xx.dtsi create mode 100644 arch/arm/dts/nuvoton-npcm750-evb.dts create mode 100644 arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi create mode 100644 arch/arm/dts/nuvoton-npcm750.dtsi create mode 100644 arch/arm/include/asm/arch-npcm7xx/gcr.h create mode 100644 arch/arm/mach-npcm/Kconfig create mode 100644 arch/arm/mach-npcm/Makefile create mode 100644 arch/arm/mach-npcm/npcm7xx/Kconfig create mode 100644 arch/arm/mach-npcm/npcm7xx/Makefile create mode 100644 arch/arm/mach-npcm/npcm7xx/cpu.c create mode 100644 arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c create mode 100644 arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S create mode 100644 board/nuvoton/poleg_evb/Kconfig create mode 100644 board/nuvoton/poleg_evb/MAINTAINERS create mode 100644 board/nuvoton/poleg_evb/Makefile create mode 100644 board/nuvoton/poleg_evb/poleg_evb.c create mode 100644 configs/poleg_evb_defconfig create mode 100644 drivers/clk/nuvoton/Makefile create mode 100644 drivers/clk/nuvoton/clk_npcm.c create mode 100644 drivers/clk/nuvoton/clk_npcm.h create mode 100644 drivers/clk/nuvoton/clk_npcm7xx.c create mode 100644 drivers/serial/serial_npcm.c create mode 100644 drivers/timer/npcm-timer.c create mode 100644 include/configs/poleg.h create mode 100644 include/dt-bindings/clock/nuvoton,npcm7xx-clock.h create mode 100644 include/dt-bindings/reset/nuvoton,npcm7xx-reset.h

Add basic support for the Nuvoton NPCM750 EVB (Poleg).
Signed-off-by: Jim Liu JJLIU0@nuvoton.com --- Changes for V3: - remove unused define in poleg.h - add define to defconfig Changes for v2: - coding style cleanup - remove reset.c and use sysreset function - re-generate the defconfig - remove v1 dts/dtsi and use linux upstream dts/dtsi --- arch/arm/Kconfig | 8 + arch/arm/Makefile | 1 + arch/arm/dts/Makefile | 1 + arch/arm/dts/nuvoton-common-npcm7xx.dtsi | 1120 +++++++++++++++++ arch/arm/dts/nuvoton-npcm750-evb.dts | 405 ++++++ arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi | 157 +++ arch/arm/dts/nuvoton-npcm750.dtsi | 62 + arch/arm/include/asm/arch-npcm7xx/gcr.h | 65 + arch/arm/mach-npcm/Kconfig | 26 + arch/arm/mach-npcm/Makefile | 1 + arch/arm/mach-npcm/npcm7xx/Kconfig | 22 + arch/arm/mach-npcm/npcm7xx/Makefile | 1 + arch/arm/mach-npcm/npcm7xx/cpu.c | 66 + arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c | 29 + .../mach-npcm/npcm7xx/l2_cache_pl310_init.S | 71 ++ board/nuvoton/poleg_evb/Kconfig | 25 + board/nuvoton/poleg_evb/MAINTAINERS | 7 + board/nuvoton/poleg_evb/Makefile | 1 + board/nuvoton/poleg_evb/poleg_evb.c | 48 + configs/poleg_evb_defconfig | 40 + include/configs/poleg.h | 44 + .../dt-bindings/reset/nuvoton,npcm7xx-reset.h | 91 ++ 22 files changed, 2291 insertions(+) create mode 100644 arch/arm/dts/nuvoton-common-npcm7xx.dtsi create mode 100644 arch/arm/dts/nuvoton-npcm750-evb.dts create mode 100644 arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi create mode 100644 arch/arm/dts/nuvoton-npcm750.dtsi create mode 100644 arch/arm/include/asm/arch-npcm7xx/gcr.h create mode 100644 arch/arm/mach-npcm/Kconfig create mode 100644 arch/arm/mach-npcm/Makefile create mode 100644 arch/arm/mach-npcm/npcm7xx/Kconfig create mode 100644 arch/arm/mach-npcm/npcm7xx/Makefile create mode 100644 arch/arm/mach-npcm/npcm7xx/cpu.c create mode 100644 arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c create mode 100644 arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S create mode 100644 board/nuvoton/poleg_evb/Kconfig create mode 100644 board/nuvoton/poleg_evb/MAINTAINERS create mode 100644 board/nuvoton/poleg_evb/Makefile create mode 100644 board/nuvoton/poleg_evb/poleg_evb.c create mode 100644 configs/poleg_evb_defconfig create mode 100644 include/configs/poleg.h create mode 100644 include/dt-bindings/reset/nuvoton,npcm7xx-reset.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index efe33a58e1..f4cc5df93b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -977,6 +977,12 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_NPCM + bool "Support Nuvoton SoCs" + select DM + select OF_CONTROL + imply CMD_DM + config ARCH_APPLE bool "Apple SoCs" select ARM64 @@ -2256,6 +2262,8 @@ source "arch/arm/mach-imx/Kconfig"
source "arch/arm/mach-nexell/Kconfig"
+source "arch/arm/mach-npcm/Kconfig" + source "board/armltd/total_compute/Kconfig"
source "board/bosch/shc/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ad757e982e..85c23bcf77 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -72,6 +72,7 @@ machine-$(CONFIG_ARCH_MEDIATEK) += mediatek machine-$(CONFIG_ARCH_MESON) += meson machine-$(CONFIG_ARCH_MVEBU) += mvebu machine-$(CONFIG_ARCH_NEXELL) += nexell +machine-$(CONFIG_ARCH_NPCM) += npcm machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2 machine-$(CONFIG_ARCH_ORION5X) += orion5x machine-$(CONFIG_ARCH_OWL) += owl diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index df7b4addf9..70869c6136 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1173,6 +1173,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8516-pumpkin.dtb \ mt8518-ap1-emmc.dtb
+dtb-$(CONFIG_ARCH_NPCM7xx) += nuvoton-npcm750-evb.dtb dtb-$(CONFIG_XEN) += xenguest-arm64.dtb
dtb-$(CONFIG_ARCH_OCTEONTX) += octeontx.dtb diff --git a/arch/arm/dts/nuvoton-common-npcm7xx.dtsi b/arch/arm/dts/nuvoton-common-npcm7xx.dtsi new file mode 100644 index 0000000000..02ee4d78e2 --- /dev/null +++ b/arch/arm/dts/nuvoton-common-npcm7xx.dtsi @@ -0,0 +1,1120 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h> +#include <dt-bindings/reset/nuvoton,npcm7xx-reset.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + + /* external reference clock */ + clk_refclk: clk_refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "refclk"; + }; + + /* external reference clock for cpu. float in normal operation */ + clk_sysbypck: clk_sysbypck { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <800000000>; + clock-output-names = "sysbypck"; + }; + + /* external reference clock for MC. float in normal operation */ + clk_mcbypck: clk_mcbypck { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <800000000>; + clock-output-names = "mcbypck"; + }; + + /* external clock signal rg1refck, supplied by the phy */ + clk_rg1refck: clk_rg1refck { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + clock-output-names = "clk_rg1refck"; + }; + + /* external clock signal rg2refck, supplied by the phy */ + clk_rg2refck: clk_rg2refck { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + clock-output-names = "clk_rg2refck"; + }; + + clk_xin: clk_xin { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "clk_xin"; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges = <0x0 0xf0000000 0x00900000>; + + scu: scu@3fe000 { + compatible = "arm,cortex-a9-scu"; + reg = <0x3fe000 0x1000>; + }; + + l2: cache-controller@3fc000 { + compatible = "arm,pl310-cache"; + reg = <0x3fc000 0x1000>; + interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; + cache-unified; + cache-level = <2>; + clocks = <&clk NPCM7XX_CLK_AXI>; + arm,shared-override; + }; + + gic: interrupt-controller@3ff000 { + compatible = "arm,cortex-a9-gic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x3ff000 0x1000>, + <0x3fe100 0x100>; + }; + + gcr: gcr@800000 { + compatible = "nuvoton,npcm750-gcr", "syscon", "simple-mfd"; + reg = <0x800000 0x1000>; + }; + + rst: rst@801000 { + compatible = "nuvoton,npcm750-rst", "syscon", "simple-mfd"; + reg = <0x801000 0x6C>; + }; + }; + + ahb { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges; + + rstc: rstc@f0801000 { + compatible = "nuvoton,npcm750-reset"; + reg = <0xf0801000 0x70>; + #reset-cells = <2>; + }; + + clk: clock-controller@f0801000 { + compatible = "nuvoton,npcm750-clk", "syscon"; + #clock-cells = <1>; + clock-controller; + reg = <0xf0801000 0x1000>; + clock-names = "refclk", "sysbypck", "mcbypck"; + clocks = <&clk_refclk>, <&clk_sysbypck>, <&clk_mcbypck>; + }; + + gmac0: eth@f0802000 { + device_type = "network"; + compatible = "nuvoton,npcm-dwmac"; + reg = <0xf0802000 0x2000>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + ethernet = <0>; + clocks = <&clk_rg1refck>, <&clk NPCM7XX_CLK_AHB>; + clock-names = "stmmaceth", "clk_gmac"; + pinctrl-names = "default"; + pinctrl-0 = <&rg1_pins + &rg1mdio_pins>; + status = "disabled"; + }; + + ehci1: usb@f0806000 { + compatible = "nuvoton,npcm750-ehci"; + reg = <0xf0806000 0x1000>; + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + fiu0: spi@fb000000 { + compatible = "nuvoton,npcm750-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfb000000 0x1000>; + reg-names = "control", "memory"; + clocks = <&clk NPCM7XX_CLK_SPI0>; + clock-names = "clk_spi0"; + status = "disabled"; + }; + + fiu3: spi@c0000000 { + compatible = "nuvoton,npcm750-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc0000000 0x1000>; + reg-names = "control", "memory"; + clocks = <&clk NPCM7XX_CLK_SPI3>; + clock-names = "clk_spi3"; + pinctrl-names = "default"; + pinctrl-0 = <&spi3_pins>; + status = "disabled"; + }; + + fiux: spi@fb001000 { + compatible = "nuvoton,npcm750-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfb001000 0x1000>; + reg-names = "control", "memory"; + clocks = <&clk NPCM7XX_CLK_SPIX>; + clock-names = "clk_spix"; + status = "disabled"; + }; + + apb { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges = <0x0 0xf0000000 0x00300000>; + + lpc_kcs: lpc_kcs@7000 { + compatible = "nuvoton,npcm750-lpc-kcs", "simple-mfd", "syscon"; + reg = <0x7000 0x40>; + reg-io-width = <1>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x7000 0x40>; + + kcs1: kcs1@0 { + compatible = "nuvoton,npcm750-kcs-bmc"; + reg = <0x0 0x40>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <1>; + status = "disabled"; + }; + + kcs2: kcs2@0 { + compatible = "nuvoton,npcm750-kcs-bmc"; + reg = <0x0 0x40>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <2>; + status = "disabled"; + }; + + kcs3: kcs3@0 { + compatible = "nuvoton,npcm750-kcs-bmc"; + reg = <0x0 0x40>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <3>; + status = "disabled"; + }; + }; + + spi0: spi@200000 { + compatible = "nuvoton,npcm750-pspi"; + reg = <0x200000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pspi1_pins>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_APB5>; + clock-names = "clk_apb5"; + resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI1>; + status = "disabled"; + }; + + spi1: spi@201000 { + compatible = "nuvoton,npcm750-pspi"; + reg = <0x201000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pspi2_pins>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_APB5>; + clock-names = "clk_apb5"; + resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI2>; + status = "disabled"; + }; + + timer0: timer@8000 { + compatible = "nuvoton,npcm750-timer"; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x8000 0x1C>; + clocks = <&clk NPCM7XX_CLK_TIMER>; + }; + + watchdog0: watchdog@801C { + compatible = "nuvoton,npcm750-wdt"; + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x801C 0x4>; + status = "disabled"; + clocks = <&clk NPCM7XX_CLK_TIMER>; + }; + + watchdog1: watchdog@901C { + compatible = "nuvoton,npcm750-wdt"; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x901C 0x4>; + status = "disabled"; + clocks = <&clk NPCM7XX_CLK_TIMER>; + }; + + watchdog2: watchdog@a01C { + compatible = "nuvoton,npcm750-wdt"; + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xa01C 0x4>; + status = "disabled"; + clocks = <&clk NPCM7XX_CLK_TIMER>; + }; + + serial0: serial@1000 { + compatible = "nuvoton,npcm750-uart"; + reg = <0x1000 0x1000>; + clocks = <&clk NPCM7XX_CLK_UART>, <&clk NPCM7XX_CLK_PLL2DIV2>; + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + status = "disabled"; + }; + + serial1: serial@2000 { + compatible = "nuvoton,npcm750-uart"; + reg = <0x2000 0x1000>; + clocks = <&clk NPCM7XX_CLK_UART>, <&clk NPCM7XX_CLK_PLL2DIV2>; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + status = "disabled"; + }; + + serial2: serial@3000 { + compatible = "nuvoton,npcm750-uart"; + reg = <0x3000 0x1000>; + clocks = <&clk NPCM7XX_CLK_UART>, <&clk NPCM7XX_CLK_PLL2DIV2>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + status = "disabled"; + }; + + serial3: serial@4000 { + compatible = "nuvoton,npcm750-uart"; + reg = <0x4000 0x1000>; + clocks = <&clk NPCM7XX_CLK_UART>, <&clk NPCM7XX_CLK_PLL2DIV2>; + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + status = "disabled"; + }; + + rng: rng@b000 { + compatible = "nuvoton,npcm750-rng"; + reg = <0xb000 0x8>; + status = "disabled"; + }; + + adc: adc@c000 { + compatible = "nuvoton,npcm750-adc"; + reg = <0xc000 0x8>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_ADC>; + resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; + status = "disabled"; + }; + + pwm_fan: pwm-fan-controller@103000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,npcm750-pwm-fan"; + reg = <0x103000 0x2000>, <0x180000 0x8000>; + reg-names = "pwm", "fan"; + clocks = <&clk NPCM7XX_CLK_APB3>, + <&clk NPCM7XX_CLK_APB4>; + clock-names = "pwm","fan"; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins &pwm1_pins + &pwm2_pins &pwm3_pins + &pwm4_pins &pwm5_pins + &pwm6_pins &pwm7_pins + &fanin0_pins &fanin1_pins + &fanin2_pins &fanin3_pins + &fanin4_pins &fanin5_pins + &fanin6_pins &fanin7_pins + &fanin8_pins &fanin9_pins + &fanin10_pins &fanin11_pins + &fanin12_pins &fanin13_pins + &fanin14_pins &fanin15_pins>; + status = "disabled"; + }; + + i2c0: i2c@80000 { + reg = <0x80000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb0_pins>; + status = "disabled"; + }; + + i2c1: i2c@81000 { + reg = <0x81000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb1_pins>; + status = "disabled"; + }; + + i2c2: i2c@82000 { + reg = <0x82000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb2_pins>; + status = "disabled"; + }; + + i2c3: i2c@83000 { + reg = <0x83000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb3_pins>; + status = "disabled"; + }; + + i2c4: i2c@84000 { + reg = <0x84000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb4_pins>; + status = "disabled"; + }; + + i2c5: i2c@85000 { + reg = <0x85000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb5_pins>; + status = "disabled"; + }; + + i2c6: i2c@86000 { + reg = <0x86000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb6_pins>; + status = "disabled"; + }; + + i2c7: i2c@87000 { + reg = <0x87000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb7_pins>; + status = "disabled"; + }; + + i2c8: i2c@88000 { + reg = <0x88000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb8_pins>; + status = "disabled"; + }; + + i2c9: i2c@89000 { + reg = <0x89000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb9_pins>; + status = "disabled"; + }; + + i2c10: i2c@8a000 { + reg = <0x8a000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb10_pins>; + status = "disabled"; + }; + + i2c11: i2c@8b000 { + reg = <0x8b000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb11_pins>; + status = "disabled"; + }; + + i2c12: i2c@8c000 { + reg = <0x8c000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb12_pins>; + status = "disabled"; + }; + + i2c13: i2c@8d000 { + reg = <0x8d000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb13_pins>; + status = "disabled"; + }; + + i2c14: i2c@8e000 { + reg = <0x8e000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb14_pins>; + status = "disabled"; + }; + + i2c15: i2c@8f000 { + reg = <0x8f000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb15_pins>; + status = "disabled"; + }; + }; + }; + + pinctrl: pinctrl@f0800000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nuvoton,npcm750-pinctrl", "syscon", "simple-mfd"; + ranges = <0 0xf0010000 0x8000>; + gpio0: gpio@f0010000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x0 0x80>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 0 32>; + }; + gpio1: gpio@f0011000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1000 0x80>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 32 32>; + }; + gpio2: gpio@f0012000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2000 0x80>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 64 32>; + }; + gpio3: gpio@f0013000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x3000 0x80>; + interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 96 32>; + }; + gpio4: gpio@f0014000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x4000 0x80>; + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 128 32>; + }; + gpio5: gpio@f0015000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x5000 0x80>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 160 32>; + }; + gpio6: gpio@f0016000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x6000 0x80>; + interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 192 32>; + }; + gpio7: gpio@f0017000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x7000 0x80>; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 224 32>; + }; + + iox1_pins: iox1-pins { + groups = "iox1"; + function = "iox1"; + }; + iox2_pins: iox2-pins { + groups = "iox2"; + function = "iox2"; + }; + smb1d_pins: smb1d-pins { + groups = "smb1d"; + function = "smb1d"; + }; + smb2d_pins: smb2d-pins { + groups = "smb2d"; + function = "smb2d"; + }; + lkgpo1_pins: lkgpo1-pins { + groups = "lkgpo1"; + function = "lkgpo1"; + }; + lkgpo2_pins: lkgpo2-pins { + groups = "lkgpo2"; + function = "lkgpo2"; + }; + ioxh_pins: ioxh-pins { + groups = "ioxh"; + function = "ioxh"; + }; + gspi_pins: gspi-pins { + groups = "gspi"; + function = "gspi"; + }; + smb5b_pins: smb5b-pins { + groups = "smb5b"; + function = "smb5b"; + }; + smb5c_pins: smb5c-pins { + groups = "smb5c"; + function = "smb5c"; + }; + lkgpo0_pins: lkgpo0-pins { + groups = "lkgpo0"; + function = "lkgpo0"; + }; + pspi2_pins: pspi2-pins { + groups = "pspi2"; + function = "pspi2"; + }; + smb4den_pins: smb4den-pins { + groups = "smb4den"; + function = "smb4den"; + }; + smb4b_pins: smb4b-pins { + groups = "smb4b"; + function = "smb4b"; + }; + smb4c_pins: smb4c-pins { + groups = "smb4c"; + function = "smb4c"; + }; + smb15_pins: smb15-pins { + groups = "smb15"; + function = "smb15"; + }; + smb4d_pins: smb4d-pins { + groups = "smb4d"; + function = "smb4d"; + }; + smb14_pins: smb14-pins { + groups = "smb14"; + function = "smb14"; + }; + smb5_pins: smb5-pins { + groups = "smb5"; + function = "smb5"; + }; + smb4_pins: smb4-pins { + groups = "smb4"; + function = "smb4"; + }; + smb3_pins: smb3-pins { + groups = "smb3"; + function = "smb3"; + }; + spi0cs1_pins: spi0cs1-pins { + groups = "spi0cs1"; + function = "spi0cs1"; + }; + spi0cs2_pins: spi0cs2-pins { + groups = "spi0cs2"; + function = "spi0cs2"; + }; + spi0cs3_pins: spi0cs3-pins { + groups = "spi0cs3"; + function = "spi0cs3"; + }; + smb3c_pins: smb3c-pins { + groups = "smb3c"; + function = "smb3c"; + }; + smb3b_pins: smb3b-pins { + groups = "smb3b"; + function = "smb3b"; + }; + bmcuart0a_pins: bmcuart0a-pins { + groups = "bmcuart0a"; + function = "bmcuart0a"; + }; + uart1_pins: uart1-pins { + groups = "uart1"; + function = "uart1"; + }; + jtag2_pins: jtag2-pins { + groups = "jtag2"; + function = "jtag2"; + }; + bmcuart1_pins: bmcuart1-pins { + groups = "bmcuart1"; + function = "bmcuart1"; + }; + uart2_pins: uart2-pins { + groups = "uart2"; + function = "uart2"; + }; + bmcuart0b_pins: bmcuart0b-pins { + groups = "bmcuart0b"; + function = "bmcuart0b"; + }; + r1err_pins: r1err-pins { + groups = "r1err"; + function = "r1err"; + }; + r1md_pins: r1md-pins { + groups = "r1md"; + function = "r1md"; + }; + smb3d_pins: smb3d-pins { + groups = "smb3d"; + function = "smb3d"; + }; + fanin0_pins: fanin0-pins { + groups = "fanin0"; + function = "fanin0"; + }; + fanin1_pins: fanin1-pins { + groups = "fanin1"; + function = "fanin1"; + }; + fanin2_pins: fanin2-pins { + groups = "fanin2"; + function = "fanin2"; + }; + fanin3_pins: fanin3-pins { + groups = "fanin3"; + function = "fanin3"; + }; + fanin4_pins: fanin4-pins { + groups = "fanin4"; + function = "fanin4"; + }; + fanin5_pins: fanin5-pins { + groups = "fanin5"; + function = "fanin5"; + }; + fanin6_pins: fanin6-pins { + groups = "fanin6"; + function = "fanin6"; + }; + fanin7_pins: fanin7-pins { + groups = "fanin7"; + function = "fanin7"; + }; + fanin8_pins: fanin8-pins { + groups = "fanin8"; + function = "fanin8"; + }; + fanin9_pins: fanin9-pins { + groups = "fanin9"; + function = "fanin9"; + }; + fanin10_pins: fanin10-pins { + groups = "fanin10"; + function = "fanin10"; + }; + fanin11_pins: fanin11-pins { + groups = "fanin11"; + function = "fanin11"; + }; + fanin12_pins: fanin12-pins { + groups = "fanin12"; + function = "fanin12"; + }; + fanin13_pins: fanin13-pins { + groups = "fanin13"; + function = "fanin13"; + }; + fanin14_pins: fanin14-pins { + groups = "fanin14"; + function = "fanin14"; + }; + fanin15_pins: fanin15-pins { + groups = "fanin15"; + function = "fanin15"; + }; + pwm0_pins: pwm0-pins { + groups = "pwm0"; + function = "pwm0"; + }; + pwm1_pins: pwm1-pins { + groups = "pwm1"; + function = "pwm1"; + }; + pwm2_pins: pwm2-pins { + groups = "pwm2"; + function = "pwm2"; + }; + pwm3_pins: pwm3-pins { + groups = "pwm3"; + function = "pwm3"; + }; + r2_pins: r2-pins { + groups = "r2"; + function = "r2"; + }; + r2err_pins: r2err-pins { + groups = "r2err"; + function = "r2err"; + }; + r2md_pins: r2md-pins { + groups = "r2md"; + function = "r2md"; + }; + ga20kbc_pins: ga20kbc-pins { + groups = "ga20kbc"; + function = "ga20kbc"; + }; + smb5d_pins: smb5d-pins { + groups = "smb5d"; + function = "smb5d"; + }; + lpc_pins: lpc-pins { + groups = "lpc"; + function = "lpc"; + }; + espi_pins: espi-pins { + groups = "espi"; + function = "espi"; + }; + rg1_pins: rg1-pins { + groups = "rg1"; + function = "rg1"; + }; + rg1mdio_pins: rg1mdio-pins { + groups = "rg1mdio"; + function = "rg1mdio"; + }; + rg2_pins: rg2-pins { + groups = "rg2"; + function = "rg2"; + }; + ddr_pins: ddr-pins { + groups = "ddr"; + function = "ddr"; + }; + smb0_pins: smb0-pins { + groups = "smb0"; + function = "smb0"; + }; + smb1_pins: smb1-pins { + groups = "smb1"; + function = "smb1"; + }; + smb2_pins: smb2-pins { + groups = "smb2"; + function = "smb2"; + }; + smb2c_pins: smb2c-pins { + groups = "smb2c"; + function = "smb2c"; + }; + smb2b_pins: smb2b-pins { + groups = "smb2b"; + function = "smb2b"; + }; + smb1c_pins: smb1c-pins { + groups = "smb1c"; + function = "smb1c"; + }; + smb1b_pins: smb1b-pins { + groups = "smb1b"; + function = "smb1b"; + }; + smb8_pins: smb8-pins { + groups = "smb8"; + function = "smb8"; + }; + smb9_pins: smb9-pins { + groups = "smb9"; + function = "smb9"; + }; + smb10_pins: smb10-pins { + groups = "smb10"; + function = "smb10"; + }; + smb11_pins: smb11-pins { + groups = "smb11"; + function = "smb11"; + }; + sd1_pins: sd1-pins { + groups = "sd1"; + function = "sd1"; + }; + sd1pwr_pins: sd1pwr-pins { + groups = "sd1pwr"; + function = "sd1pwr"; + }; + pwm4_pins: pwm4-pins { + groups = "pwm4"; + function = "pwm4"; + }; + pwm5_pins: pwm5-pins { + groups = "pwm5"; + function = "pwm5"; + }; + pwm6_pins: pwm6-pins { + groups = "pwm6"; + function = "pwm6"; + }; + pwm7_pins: pwm7-pins { + groups = "pwm7"; + function = "pwm7"; + }; + mmc8_pins: mmc8-pins { + groups = "mmc8"; + function = "mmc8"; + }; + mmc_pins: mmc-pins { + groups = "mmc"; + function = "mmc"; + }; + mmcwp_pins: mmcwp-pins { + groups = "mmcwp"; + function = "mmcwp"; + }; + mmccd_pins: mmccd-pins { + groups = "mmccd"; + function = "mmccd"; + }; + mmcrst_pins: mmcrst-pins { + groups = "mmcrst"; + function = "mmcrst"; + }; + clkout_pins: clkout-pins { + groups = "clkout"; + function = "clkout"; + }; + serirq_pins: serirq-pins { + groups = "serirq"; + function = "serirq"; + }; + lpcclk_pins: lpcclk-pins { + groups = "lpcclk"; + function = "lpcclk"; + }; + scipme_pins: scipme-pins { + groups = "scipme"; + function = "scipme"; + }; + sci_pins: sci-pins { + groups = "sci"; + function = "sci"; + }; + smb6_pins: smb6-pins { + groups = "smb6"; + function = "smb6"; + }; + smb7_pins: smb7-pins { + groups = "smb7"; + function = "smb7"; + }; + pspi1_pins: pspi1-pins { + groups = "pspi1"; + function = "pspi1"; + }; + faninx_pins: faninx-pins { + groups = "faninx"; + function = "faninx"; + }; + r1_pins: r1-pins { + groups = "r1"; + function = "r1"; + }; + spi3_pins: spi3-pins { + groups = "spi3"; + function = "spi3"; + }; + spi3cs1_pins: spi3cs1-pins { + groups = "spi3cs1"; + function = "spi3cs1"; + }; + spi3quad_pins: spi3quad-pins { + groups = "spi3quad"; + function = "spi3quad"; + }; + spi3cs2_pins: spi3cs2-pins { + groups = "spi3cs2"; + function = "spi3cs2"; + }; + spi3cs3_pins: spi3cs3-pins { + groups = "spi3cs3"; + function = "spi3cs3"; + }; + nprd_smi_pins: nprd-smi-pins { + groups = "nprd_smi"; + function = "nprd_smi"; + }; + smb0b_pins: smb0b-pins { + groups = "smb0b"; + function = "smb0b"; + }; + smb0c_pins: smb0c-pins { + groups = "smb0c"; + function = "smb0c"; + }; + smb0den_pins: smb0den-pins { + groups = "smb0den"; + function = "smb0den"; + }; + smb0d_pins: smb0d-pins { + groups = "smb0d"; + function = "smb0d"; + }; + ddc_pins: ddc-pins { + groups = "ddc"; + function = "ddc"; + }; + rg2mdio_pins: rg2mdio-pins { + groups = "rg2mdio"; + function = "rg2mdio"; + }; + wdog1_pins: wdog1-pins { + groups = "wdog1"; + function = "wdog1"; + }; + wdog2_pins: wdog2-pins { + groups = "wdog2"; + function = "wdog2"; + }; + smb12_pins: smb12-pins { + groups = "smb12"; + function = "smb12"; + }; + smb13_pins: smb13-pins { + groups = "smb13"; + function = "smb13"; + }; + spix_pins: spix-pins { + groups = "spix"; + function = "spix"; + }; + spixcs1_pins: spixcs1-pins { + groups = "spixcs1"; + function = "spixcs1"; + }; + clkreq_pins: clkreq-pins { + groups = "clkreq"; + function = "clkreq"; + }; + hgpio0_pins: hgpio0-pins { + groups = "hgpio0"; + function = "hgpio0"; + }; + hgpio1_pins: hgpio1-pins { + groups = "hgpio1"; + function = "hgpio1"; + }; + hgpio2_pins: hgpio2-pins { + groups = "hgpio2"; + function = "hgpio2"; + }; + hgpio3_pins: hgpio3-pins { + groups = "hgpio3"; + function = "hgpio3"; + }; + hgpio4_pins: hgpio4-pins { + groups = "hgpio4"; + function = "hgpio4"; + }; + hgpio5_pins: hgpio5-pins { + groups = "hgpio5"; + function = "hgpio5"; + }; + hgpio6_pins: hgpio6-pins { + groups = "hgpio6"; + function = "hgpio6"; + }; + hgpio7_pins: hgpio7-pins { + groups = "hgpio7"; + function = "hgpio7"; + }; + }; +}; diff --git a/arch/arm/dts/nuvoton-npcm750-evb.dts b/arch/arm/dts/nuvoton-npcm750-evb.dts new file mode 100644 index 0000000000..3e4abe6610 --- /dev/null +++ b/arch/arm/dts/nuvoton-npcm750-evb.dts @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology tomer.maimon@nuvoton.com +// Copyright 2018 Google, Inc. + +/dts-v1/; +#include "nuvoton-npcm750.dtsi" +#include "dt-bindings/gpio/gpio.h" +#include "nuvoton-npcm750-pincfg-evb.dtsi" + +/ { + model = "Nuvoton npcm750 Development Board (Device Tree)"; + compatible = "nuvoton,npcm750-evb", "nuvoton,npcm750"; + + aliases { + ethernet2 = &gmac0; + ethernet3 = &gmac1; + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + i2c14 = &i2c14; + i2c15 = &i2c15; + spi0 = &spi0; + spi1 = &spi1; + fiu0 = &fiu0; + fiu1 = &fiu3; + fiu2 = &fiux; + }; + + chosen { + stdout-path = &serial0; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x20000000>; + }; +}; + +&gmac0 { + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&gmac1 { + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&fiu0 { + status = "okay"; + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; + partitions@80000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + bbuboot1@0 { + label = "bb-uboot-1"; + reg = <0x0000000 0x80000>; + read-only; + }; + bbuboot2@80000 { + label = "bb-uboot-2"; + reg = <0x0080000 0x80000>; + read-only; + }; + envparam@100000 { + label = "env-param"; + reg = <0x0100000 0x40000>; + read-only; + }; + spare@140000 { + label = "spare"; + reg = <0x0140000 0xC0000>; + }; + kernel@200000 { + label = "kernel"; + reg = <0x0200000 0x400000>; + }; + rootfs@600000 { + label = "rootfs"; + reg = <0x0600000 0x700000>; + }; + spare1@d00000 { + label = "spare1"; + reg = <0x0D00000 0x200000>; + }; + spare2@f00000 { + label = "spare2"; + reg = <0x0F00000 0x200000>; + }; + spare3@1100000 { + label = "spare3"; + reg = <0x1100000 0x200000>; + }; + spare4@1300000 { + label = "spare4"; + reg = <0x1300000 0x0>; + }; + }; + }; +}; + +&fiu3 { + pinctrl-0 = <&spi3_pins>, <&spi3quad_pins>; + status = "okay"; + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; + partitions@A0000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + system1@0 { + label = "spi3-system1"; + reg = <0x0 0x0>; + }; + }; + }; +}; + +&fiux { + spix-mode; +}; + +&watchdog1 { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&serial0 { + status = "okay"; + clock-frequency = <24000000>; +}; + +&serial1 { + status = "okay"; +}; + +&serial2 { + status = "okay"; +}; + +&serial3 { + status = "okay"; +}; + +&adc { + status = "okay"; +}; + +&lpc_kcs { + kcs1: kcs1@0 { + status = "okay"; + }; + + kcs2: kcs2@0 { + status = "okay"; + }; + + kcs3: kcs3@0 { + status = "okay"; + }; +}; + +/* lm75 on SVB */ +&i2c0 { + clock-frequency = <100000>; + status = "okay"; + lm75@48 { + compatible = "lm75"; + reg = <0x48>; + status = "okay"; + }; +}; + +/* lm75 on EB */ +&i2c1 { + clock-frequency = <100000>; + status = "okay"; + lm75@48 { + compatible = "lm75"; + reg = <0x48>; + status = "okay"; + }; +}; + +/* tmp100 on EB */ +&i2c2 { + clock-frequency = <100000>; + status = "okay"; + tmp100@48 { + compatible = "tmp100"; + reg = <0x48>; + status = "okay"; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c5 { + clock-frequency = <100000>; + status = "okay"; +}; + +/* tmp100 on SVB */ +&i2c6 { + clock-frequency = <100000>; + status = "okay"; + tmp100@48 { + compatible = "tmp100"; + reg = <0x48>; + status = "okay"; + }; +}; + +&i2c7 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c8 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c9 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c10 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c11 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c14 { + clock-frequency = <100000>; + status = "okay"; +}; + +&pwm_fan { + status = "okay"; + fan@0 { + reg = <0x00>; + fan-tach-ch = /bits/ 8 <0x00 0x01>; + cooling-levels = <127 255>; + }; + fan@1 { + reg = <0x01>; + fan-tach-ch = /bits/ 8 <0x02 0x03>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@2 { + reg = <0x02>; + fan-tach-ch = /bits/ 8 <0x04 0x05>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@3 { + reg = <0x03>; + fan-tach-ch = /bits/ 8 <0x06 0x07>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@4 { + reg = <0x04>; + fan-tach-ch = /bits/ 8 <0x08 0x09>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@5 { + reg = <0x05>; + fan-tach-ch = /bits/ 8 <0x0A 0x0B>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@6 { + reg = <0x06>; + fan-tach-ch = /bits/ 8 <0x0C 0x0D>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@7 { + reg = <0x07>; + fan-tach-ch = /bits/ 8 <0x0E 0x0F>; + cooling-levels = /bits/ 8 <127 255>; + }; +}; + +&spi0 { + cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; + status = "okay"; + Flash@0 { + compatible = "winbond,w25q128", + "jedec,spi-nor"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <5000000>; + partition@0 { + label = "spi0_spare1"; + reg = <0x0000000 0x800000>; + }; + partition@1 { + label = "spi0_spare2"; + reg = <0x800000 0x0>; + }; + }; +}; + +&spi1 { + cs-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + status = "okay"; + Flash@0 { + compatible = "winbond,w25q128fw", + "jedec,spi-nor"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <5000000>; + partition@0 { + label = "spi1_spare1"; + reg = <0x0000000 0x800000>; + }; + partition@1 { + label = "spi1_spare2"; + reg = <0x800000 0x0>; + }; + }; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = < &iox1_pins + &pin8_input + &pin9_output_high + &pin10_input + &pin11_output_high + &pin16_input + &pin24_output_high + &pin25_output_low + &pin32_output_high + &jtag2_pins + &pin61_output_high + &pin62_output_high + &pin63_output_high + &lpc_pins + &pin160_input + &pin162_input + &pin168_input + &pin169_input + &pin170_input + &pin187_output_high + &pin190_input + &pin191_output_high + &pin192_output_high + &pin197_output_low + &ddc_pins + &pin218_input + &pin219_output_low + &pin220_output_low + &pin221_output_high + &pin222_input + &pin223_output_low + &spix_pins + &pin228_output_low + &pin231_output_high + &pin255_input>; +}; + diff --git a/arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi b/arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi new file mode 100644 index 0000000000..3b3806274a --- /dev/null +++ b/arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology + +/ { + pinctrl: pinctrl@f0800000 { + pin8_input: pin8-input { + pins = "GPIO8/LKGPO1"; + bias-disable; + input-enable; + }; + pin9_output_high: pin9-output-high { + pins = "GPIO9/LKGPO2"; + bias-disable; + output-high; + }; + pin10_input: pin10-input { + pins = "GPIO10/IOXHLD"; + bias-disable; + input-enable; + }; + pin11_output_high: pin11-output-high { + pins = "GPIO11/IOXHCK"; + bias-disable; + output-high; + }; + pin16_input: pin16-input { + pins = "GPIO16/LKGPO0"; + bias-disable; + input-enable; + }; + pin24_output_high: pin24-output-high { + pins = "GPIO24/IOXHDO"; + bias-disable; + output-high; + }; + pin25_output_low: pin25-output-low { + pins = "GPIO25/IOXHDI"; + bias-disable; + output-low; + }; + pin32_output_high: pin32-output-high { + pins = "GPIO32/nSPI0CS1"; + bias-disable; + output-high; + }; + pin61_output_high: pin61-output-high { + pins = "GPO61/nDTR1_BOUT1/STRAP6"; + bias-disable; + output-high; + }; + pin62_output_high: pin62-output-high { + pins = "GPO62/nRTST1/STRAP5"; + bias-disable; + output-high; + }; + pin63_output_high: pin63-output-high { + pins = "GPO63/TXD1/STRAP4"; + bias-disable; + output-high; + }; + pin160_input: pin160-input { + pins = "GPIO160/CLKOUT/RNGOSCOUT"; + bias-disable; + input-enable; + }; + pin162_input: pin162-input { + pins = "GPIO162/SERIRQ"; + bias-disable; + input-enable; + }; + pin168_input: pin168-input { + pins = "GPIO168/nCLKRUN/nESPIALERT"; + bias-disable; + input-enable; + }; + pin169_input: pin169-input { + pins = "GPIO169/nSCIPME"; + bias-disable; + input-enable; + }; + pin170_input: pin170-input { + pins = "GPIO170/nSMI"; + bias-disable; + input-enable; + }; + pin187_output_high: pin187-output-high { + pins = "GPIO187/nSPI3CS1"; + bias-disable; + output-high; + }; + pin190_input: pin190-input { + pins = "GPIO190/nPRD_SMI"; + bias-disable; + input-enable; + }; + pin191_output_high: pin191-output-high { + pins = "GPIO191"; + bias-disable; + output-high; + }; + pin192_output_high: pin192-output-high { + pins = "GPIO192"; + bias-disable; + output-high; + }; + pin197_output_low: pin197-output-low { + pins = "GPIO197/SMB0DEN"; + bias-disable; + output-low; + }; + pin218_input: pin218-input { + pins = "GPIO218/nWDO1"; + bias-disable; + input-enable; + }; + pin219_output_low: pin219-output-low { + pins = "GPIO219/nWDO2"; + bias-disable; + output-low; + }; + pin220_output_low: pin220-output-low { + pins = "GPIO220/SMB12SCL"; + bias-disable; + output-low; + }; + pin221_output_high: pin221-output-high { + pins = "GPIO221/SMB12SDA"; + bias-disable; + output-high; + }; + pin222_input: pin222-input { + pins = "GPIO222/SMB13SCL"; + bias-disable; + input-enable; + }; + pin223_output_low: pin223-output-low { + pins = "GPIO223/SMB13SDA"; + bias-disable; + output-low; + }; + pin228_output_low: pin228-output-low { + pins = "GPIO228/nSPIXCS1"; + bias-disable; + output-low; + }; + pin231_output_high: pin231-output-high { + pins = "GPIO230/SPIXD3"; + bias-disable; + output-high; + }; + pin255_input: pin255-input { + pins = "GPI255/DACOSEL"; + bias-disable; + input-enable; + }; + }; +}; diff --git a/arch/arm/dts/nuvoton-npcm750.dtsi b/arch/arm/dts/nuvoton-npcm750.dtsi new file mode 100644 index 0000000000..13eee0fe56 --- /dev/null +++ b/arch/arm/dts/nuvoton-npcm750.dtsi @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology tomer.maimon@nuvoton.com +// Copyright 2018 Google, Inc. + +#include "nuvoton-common-npcm7xx.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "nuvoton,npcm750-smp"; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + clocks = <&clk NPCM7XX_CLK_CPU>; + clock-names = "clk_cpu"; + reg = <0>; + next-level-cache = <&l2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + clocks = <&clk NPCM7XX_CLK_CPU>; + clock-names = "clk_cpu"; + reg = <1>; + next-level-cache = <&l2>; + }; + }; + + soc { + timer@3fe600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x3fe600 0x20>; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | + IRQ_TYPE_LEVEL_HIGH)>; + clocks = <&clk NPCM7XX_CLK_AHB>; + }; + }; + + ahb { + gmac1: eth@f0804000 { + device_type = "network"; + compatible = "snps,dwmac"; + reg = <0xf0804000 0x2000>; + interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + ethernet = <1>; + clocks = <&clk_rg2refck>, <&clk NPCM7XX_CLK_AHB>; + clock-names = "stmmaceth", "clk_gmac"; + pinctrl-names = "default"; + pinctrl-0 = <&rg2_pins + &rg2mdio_pins>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/include/asm/arch-npcm7xx/gcr.h b/arch/arm/include/asm/arch-npcm7xx/gcr.h new file mode 100644 index 0000000000..762a0b6d6b --- /dev/null +++ b/arch/arm/include/asm/arch-npcm7xx/gcr.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __NPCM750_GCR_H_ +#define __NPCM750_GCR_H_ + +/* On-Chip POLEG NPCM750 VERSIONS */ +#define POLEG_Z1 0x00A92750 +#define POLEG_A1 0x04A92750 +#define POLEG_NPCM750 0x00000000 +#define POLEG_NPCM730 0x00300395 +#define POLEG_NPCM710 0x00200380 + +#define PWRON_SECEN 7 /* STRAP8 */ +#define NPCM_GCR_BA 0xF0800000 + +struct npcm_gcr { + unsigned int pdid; + unsigned int pwron; + unsigned char res1[0x4]; + unsigned int mfsel1; + unsigned int mfsel2; + unsigned int miscpe; + unsigned char res2[0x20]; + unsigned int spswc; + unsigned int intcr; + unsigned int intsr; + unsigned char res3[0xc]; + unsigned int hifcr; + unsigned int sd1irv1; + unsigned int sd1irv2; + unsigned char res4[0x4]; + unsigned int intcr2; + unsigned int mfsel3; + unsigned int srcnt; + unsigned int ressr; + unsigned int rlockr1; + unsigned int flockr1; + unsigned int dscnt; + unsigned int mdlr; + unsigned char res5[0x18]; + unsigned int davclvlr; + unsigned int intcr3; + unsigned char res6[0xc]; + unsigned int vsintr; + unsigned int mfsel4; + unsigned int sd2irv1; + unsigned int sd2irv2; + unsigned char res7[0x8]; + unsigned int cpbpntr; + unsigned char res8[0x8]; + unsigned int cpctl; + unsigned int cp2bst; + unsigned int b2cpnt; + unsigned int cppctl; + unsigned int i2csegsel; + unsigned int i2csegctl; + unsigned int vsrcr; + unsigned int mlockr; + unsigned char res9[0x4c]; + unsigned int scrpad; + unsigned int usb1phyctl; + unsigned int usb2phyctl; +}; + +#endif diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig new file mode 100644 index 0000000000..cf5043d6b8 --- /dev/null +++ b/arch/arm/mach-npcm/Kconfig @@ -0,0 +1,26 @@ +if ARCH_NPCM + +config SYS_ARCH + default "arm" + +config SYS_TEXT_BASE + default 0x8000 + +choice + prompt "Nuvoton SoC select" + default ARCH_NPCM7xx + +config ARCH_NPCM7xx + bool "Support Nuvoton NPCM7xx SoC" + select CPU_V7A + select OF_CONTROL + select DM + help + General support for NPCM7xx BMC (Poleg). + Nuvoton NPCM7xx BMC is based on the Cortex A9. + +endchoice + +source "arch/arm/mach-npcm/npcm7xx/Kconfig" + +endif diff --git a/arch/arm/mach-npcm/Makefile b/arch/arm/mach-npcm/Makefile new file mode 100644 index 0000000000..8a1572b4f0 --- /dev/null +++ b/arch/arm/mach-npcm/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_NPCM7xx) += npcm7xx/ diff --git a/arch/arm/mach-npcm/npcm7xx/Kconfig b/arch/arm/mach-npcm/npcm7xx/Kconfig new file mode 100644 index 0000000000..237e7ba7e5 --- /dev/null +++ b/arch/arm/mach-npcm/npcm7xx/Kconfig @@ -0,0 +1,22 @@ +if ARCH_NPCM7xx + +config SYS_CPU + default "armv7" + +config SYS_SOC + default "npcm7xx" + +config TARGET_POLEG + bool "NPCM POLEG board" + help + poleg EVB is Nuvoton evaluation board for NPCM750 SoC, + supports general functions of Basebase Management + Controller(BMC). + +config SYS_MEM_TOP_HIDE + hex "Reserved TOP memory" + default 0x03000000 + +source "board/nuvoton/poleg_evb/Kconfig" + +endif diff --git a/arch/arm/mach-npcm/npcm7xx/Makefile b/arch/arm/mach-npcm/npcm7xx/Makefile new file mode 100644 index 0000000000..49f9877bd6 --- /dev/null +++ b/arch/arm/mach-npcm/npcm7xx/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_TARGET_POLEG) += cpu.o l2_cache_pl310_init.o l2_cache_pl310.o diff --git a/arch/arm/mach-npcm/npcm7xx/cpu.c b/arch/arm/mach-npcm/npcm7xx/cpu.c new file mode 100644 index 0000000000..dd74bb9e08 --- /dev/null +++ b/arch/arm/mach-npcm/npcm7xx/cpu.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include <common.h> +#include <cpu_func.h> +#include <asm/armv7.h> +#include <asm/io.h> +#include <asm/arch/gcr.h> + +int print_cpuinfo(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + unsigned int id, mdlr; + + mdlr = readl(&gcr->mdlr); + + printf("CPU: "); + + switch (mdlr) { + case POLEG_NPCM750: + printf("NPCM750 "); + break; + case POLEG_NPCM730: + printf("NPCM730 "); + break; + case POLEG_NPCM710: + printf("NPCM710 "); + break; + default: + printf("NPCM7XX "); + break; + } + + id = readl(&gcr->pdid); + switch (id) { + case POLEG_Z1: + printf("Z1 is no supported! @ "); + break; + case POLEG_A1: + printf("A1 @ "); + break; + default: + printf("Unknown\n"); + break; + } + + return 0; +} + +void s_init(void) +{ + /* Invalidate L2 cache in lowlevel_init */ + v7_outer_cache_inval_all(); +} + +void enable_caches(void) +{ + dcache_enable(); +} + +void disable_caches(void) +{ + dcache_disable(); +} diff --git a/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c new file mode 100644 index 0000000000..cba2e342dc --- /dev/null +++ b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/pl310.h> + +void l2_pl310_init(void); + +void set_pl310_ctrl(u32 enable) +{ + struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE; + + writel(enable, &pl310->pl310_ctrl); +} + +void v7_outer_cache_enable(void) +{ + l2_pl310_init(); + + set_pl310_ctrl(1); +} + +void v7_outer_cache_disable(void) +{ + set_pl310_ctrl(0); +} diff --git a/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S new file mode 100644 index 0000000000..8ec4e374a5 --- /dev/null +++ b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +.align 5 + +#include <linux/linkage.h> + +#ifndef CONFIG_SYS_L2CACHE_OFF + +ENTRY(l2_pl310_init) + +@------------------------------------------------------------------ +@ L2CC (PL310) Initialization +@------------------------------------------------------------------ + @ In this example PL310 PA = VA. The memory was marked as Device memory + @ in previous stages when defining CORE0 private address space + LDR r0, =0xF03FC000 @ A9_BASE_ADDR + + @ Disable L2 Cache controller just in case it is already on + LDR r1, =0x0 + STR r1, [r0,#0x100] + + @ Set aux cntrl + @ Way size = 32KB + @ Way = 16 + LDR r1, =0x02050000 + ORR r1, r1, #(1 << 29) @ Instruction prefetch enable + ORR r1, r1, #(1 << 28) @ Data prefetch enable + ORR r1, r1, #(1 << 22) @ cache replacement policy + STR r1, [r0,#0x104] @ auxilary control reg at offset 0x104 + + @ Set tag RAM latency + @ 1 cycle RAM write access latency + @ 1 cycle RAM read access latency + @ 1 cycle RAM setup latency + LDR r1, =0x00000000 + STR r1, [r0,#0x108] @ tag ram control reg at offset 0x108 + + @ Set Data RAM latency + @ 1 cycle RAM write access latency + @ 2 cycles RAM read access latency + @ 1 cycle RAM setup latency + LDR r1, =0x00000000 + STR r1, [r0,#0x10C] @ data ram control reg at offset 0x108 + + @Cache maintenance - invalidate 16 ways (0xffff) - base offset 0x77C + LDR r1, =0xFFFF + STR r1, [r0,#0x77C] @ invalidate by way register at offset 0x77C +poll_invalidate: + LDR r1, [r0,#0x77C] @ invalidate by way register at offset 0x77C + TST r1, #1 + BNE poll_invalidate + + @ Ensure L2 remains disabled for the time being + LDR r1, =0x0 + STR r1, [r0,#0x100] + + MRC p15, 4, r0, c15, c0, 0 @ Read periph base address + @ SCU offset from base of private peripheral space = 0x000 + + LDR r1, [r0, #0x0] @ Read the SCU Control Register + ORR r1, r1, #0x1 @ Set bit 0 (The Enable bit) + STR r1, [r0, #0x0] @ Write back modifed value + + BX lr + +ENDPROC(l2_pl310_init) + +#endif diff --git a/board/nuvoton/poleg_evb/Kconfig b/board/nuvoton/poleg_evb/Kconfig new file mode 100644 index 0000000000..d3f4c1dd81 --- /dev/null +++ b/board/nuvoton/poleg_evb/Kconfig @@ -0,0 +1,25 @@ +if TARGET_POLEG + +config SYS_BOARD + default "poleg_evb" + +config SYS_VENDOR + default "nuvoton" + +config SYS_CONFIG_NAME + default "poleg" + +choice + prompt "Target board select" + default TARGET_POLEG_EVB + +config TARGET_POLEG_EVB + bool "Poleg EVB" + help + poleg EVB is Nuvoton evaluation board for NPCM750 SoC, + supports general functions of Basebase Management + Controller(BMC). + +endchoice + +endif diff --git a/board/nuvoton/poleg_evb/MAINTAINERS b/board/nuvoton/poleg_evb/MAINTAINERS new file mode 100644 index 0000000000..8797295c41 --- /dev/null +++ b/board/nuvoton/poleg_evb/MAINTAINERS @@ -0,0 +1,7 @@ +Poleg EVB +M: Stanley Chu yschu@nuvoton.com +M: Jim Liu JJLIU0@nuvoton.com +S: Maintained +F: board/nuvoton/poleg_evb/ +F: include/configs/poleg.h +F: configs/poleg_evb_defconfig diff --git a/board/nuvoton/poleg_evb/Makefile b/board/nuvoton/poleg_evb/Makefile new file mode 100644 index 0000000000..377433d60a --- /dev/null +++ b/board/nuvoton/poleg_evb/Makefile @@ -0,0 +1 @@ +obj-y := poleg_evb.o diff --git a/board/nuvoton/poleg_evb/poleg_evb.c b/board/nuvoton/poleg_evb/poleg_evb.c new file mode 100644 index 0000000000..aef142a881 --- /dev/null +++ b/board/nuvoton/poleg_evb/poleg_evb.c @@ -0,0 +1,48 @@ +// 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) +{ + return 0; +} + +int dram_init(void) +{ + struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA; + + int ramsize = (readl(&gcr->intcr3) >> 8) & 0x7; + + switch (ramsize) { + case 0: + gd->ram_size = 0x08000000; /* 128 MB. */ + break; + case 1: + gd->ram_size = 0x10000000; /* 256 MB. */ + break; + case 2: + gd->ram_size = 0x20000000; /* 512 MB. */ + break; + case 3: + gd->ram_size = 0x40000000; /* 1024 MB. */ + break; + case 4: + gd->ram_size = 0x80000000; /* 2048 MB. */ + break; + + default: + break; + } + + return 0; +} diff --git a/configs/poleg_evb_defconfig b/configs/poleg_evb_defconfig new file mode 100644 index 0000000000..f7bdefcf93 --- /dev/null +++ b/configs/poleg_evb_defconfig @@ -0,0 +1,40 @@ +CONFIG_ARM=y +CONFIG_ARCH_CPU_INIT=y +CONFIG_ARCH_NPCM=y +CONFIG_SYS_TEXT_BASE=0x8200 +CONFIG_SYS_MALLOC_LEN=0x240000 +CONFIG_SYS_MALLOC_F_LEN=0x1000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_ENV_SIZE=0x40000 +CONFIG_ENV_OFFSET=0x100000 +CONFIG_ENV_SECT_SIZE=0x4000 +CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="nuvoton-npcm750-evb" +CONFIG_ARCH_NPCM7xx=y +CONFIG_TARGET_POLEG=y +CONFIG_SYS_LOAD_ADDR=0x10000000 +CONFIG_ENV_ADDR=0x80100000 +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run common_bootargs; run romboot" +CONFIG_SYS_PROMPT="U-Boot>" +CONFIG_CMD_GPIO=y +CONFIG_CMD_SPI=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_UUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_CLK=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_DM_SERIAL=y +CONFIG_NPCM_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_WATCHDOG=y +CONFIG_TIMER=y +CONFIG_NPCM_TIMER=y diff --git a/include/configs/poleg.h b/include/configs/poleg.h new file mode 100644 index 0000000000..c21b063c05 --- /dev/null +++ b/include/configs/poleg.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#ifndef __CONFIG_POLEG_H +#define __CONFIG_POLEG_H + +#ifndef CONFIG_SYS_L2CACHE_OFF +#define CONFIG_SYS_L2_PL310 1 +#define CONFIG_SYS_PL310_BASE 0xF03FC000 /* L2 - Cache Regs Base (4k Space)*/ +#endif + +#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_BOOTMAPSZ (0x30 << 20) +#define CONFIG_SYS_SDRAM_BASE 0x0 +#define CONFIG_SYS_INIT_SP_ADDR (0x00008000 - GENERATED_GBL_DATA_SIZE) + +/* Default environemnt variables */ +#define CONFIG_SERVERIP 192.168.0.1 +#define CONFIG_IPADDR 192.168.0.2 +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_EXTRA_ENV_SETTINGS "uimage_flash_addr=80200000\0" \ + "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" \ + "ethact=eth${eth_num}\0" \ + "romboot=echo Booting from flash; echo +++ uimage at 0x${uimage_flash_addr}; " \ + "echo Using bootargs: ${bootargs};bootm ${uimage_flash_addr}\0" \ + "autostart=yes\0" \ + "eth_num=0\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" \ + "common_bootargs=setenv bootargs earlycon=${earlycon} root=/dev/ram " \ + "console=${console} mem=${mem} ramdisk_size=48000 basemac=${ethaddr}\0" \ + "sd_prog=fatload mmc 0 10000000 image-bmc; cp.b 10000000 80000000 ${filesize}\0" \ + "sd_run=fatload mmc 0 10000000 image-bmc; bootm 10200000\0" \ + "\0" + +#endif diff --git a/include/dt-bindings/reset/nuvoton,npcm7xx-reset.h b/include/dt-bindings/reset/nuvoton,npcm7xx-reset.h new file mode 100644 index 0000000000..757f5e34c8 --- /dev/null +++ b/include/dt-bindings/reset/nuvoton,npcm7xx-reset.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (c) 2020 Nuvoton Technology corporation. + +#ifndef _DT_BINDINGS_NPCM7XX_RESET_H +#define _DT_BINDINGS_NPCM7XX_RESET_H + +#define NPCM7XX_RESET_IPSRST1 0x20 +#define NPCM7XX_RESET_IPSRST2 0x24 +#define NPCM7XX_RESET_IPSRST3 0x34 + +/* Reset lines on IP1 reset module (NPCM7XX_RESET_IPSRST1) */ +#define NPCM7XX_RESET_FIU3 1 +#define NPCM7XX_RESET_UDC1 5 +#define NPCM7XX_RESET_EMC1 6 +#define NPCM7XX_RESET_UART_2_3 7 +#define NPCM7XX_RESET_UDC2 8 +#define NPCM7XX_RESET_PECI 9 +#define NPCM7XX_RESET_AES 10 +#define NPCM7XX_RESET_UART_0_1 11 +#define NPCM7XX_RESET_MC 12 +#define NPCM7XX_RESET_SMB2 13 +#define NPCM7XX_RESET_SMB3 14 +#define NPCM7XX_RESET_SMB4 15 +#define NPCM7XX_RESET_SMB5 16 +#define NPCM7XX_RESET_PWM_M0 18 +#define NPCM7XX_RESET_TIMER_0_4 19 +#define NPCM7XX_RESET_TIMER_5_9 20 +#define NPCM7XX_RESET_EMC2 21 +#define NPCM7XX_RESET_UDC4 22 +#define NPCM7XX_RESET_UDC5 23 +#define NPCM7XX_RESET_UDC6 24 +#define NPCM7XX_RESET_UDC3 25 +#define NPCM7XX_RESET_ADC 27 +#define NPCM7XX_RESET_SMB6 28 +#define NPCM7XX_RESET_SMB7 29 +#define NPCM7XX_RESET_SMB0 30 +#define NPCM7XX_RESET_SMB1 31 + +/* Reset lines on IP2 reset module (NPCM7XX_RESET_IPSRST2) */ +#define NPCM7XX_RESET_MFT0 0 +#define NPCM7XX_RESET_MFT1 1 +#define NPCM7XX_RESET_MFT2 2 +#define NPCM7XX_RESET_MFT3 3 +#define NPCM7XX_RESET_MFT4 4 +#define NPCM7XX_RESET_MFT5 5 +#define NPCM7XX_RESET_MFT6 6 +#define NPCM7XX_RESET_MFT7 7 +#define NPCM7XX_RESET_MMC 8 +#define NPCM7XX_RESET_SDHC 9 +#define NPCM7XX_RESET_GFX_SYS 10 +#define NPCM7XX_RESET_AHB_PCIBRG 11 +#define NPCM7XX_RESET_VDMA 12 +#define NPCM7XX_RESET_ECE 13 +#define NPCM7XX_RESET_VCD 14 +#define NPCM7XX_RESET_OTP 16 +#define NPCM7XX_RESET_SIOX1 18 +#define NPCM7XX_RESET_SIOX2 19 +#define NPCM7XX_RESET_3DES 21 +#define NPCM7XX_RESET_PSPI1 22 +#define NPCM7XX_RESET_PSPI2 23 +#define NPCM7XX_RESET_GMAC2 25 +#define NPCM7XX_RESET_USB_HOST 26 +#define NPCM7XX_RESET_GMAC1 28 +#define NPCM7XX_RESET_CP 31 + +/* Reset lines on IP3 reset module (NPCM7XX_RESET_IPSRST3) */ +#define NPCM7XX_RESET_PWM_M1 0 +#define NPCM7XX_RESET_SMB12 1 +#define NPCM7XX_RESET_SPIX 2 +#define NPCM7XX_RESET_SMB13 3 +#define NPCM7XX_RESET_UDC0 4 +#define NPCM7XX_RESET_UDC7 5 +#define NPCM7XX_RESET_UDC8 6 +#define NPCM7XX_RESET_UDC9 7 +#define NPCM7XX_RESET_PCI_MAILBOX 9 +#define NPCM7XX_RESET_SMB14 12 +#define NPCM7XX_RESET_SHA 13 +#define NPCM7XX_RESET_SEC_ECC 14 +#define NPCM7XX_RESET_PCIE_RC 15 +#define NPCM7XX_RESET_TIMER_10_14 16 +#define NPCM7XX_RESET_RNG 17 +#define NPCM7XX_RESET_SMB15 18 +#define NPCM7XX_RESET_SMB8 19 +#define NPCM7XX_RESET_SMB9 20 +#define NPCM7XX_RESET_SMB10 21 +#define NPCM7XX_RESET_SMB11 22 +#define NPCM7XX_RESET_ESPI 23 +#define NPCM7XX_RESET_USB_PHY_1 24 +#define NPCM7XX_RESET_USB_PHY_2 25 + +#endif

On Tue, Apr 19, 2022 at 01:32:19PM +0800, Jim Liu wrote:
Add basic support for the Nuvoton NPCM750 EVB (Poleg).
Signed-off-by: Jim Liu JJLIU0@nuvoton.com
Applied to u-boot/master, thanks!

Add clock controller driver for NPCM750
Signed-off-by: Jim Liu JJLIU0@nuvoton.com Signed-off-by: Stanley Chu yschu@nuvoton.com --- Changes for v3: - no changes since v2 Changes for v2: - combine NPCM750 and NPCM845 clk driver. --- drivers/clk/Makefile | 1 + drivers/clk/nuvoton/Makefile | 2 + drivers/clk/nuvoton/clk_npcm.c | 299 ++++++++++++++++++ drivers/clk/nuvoton/clk_npcm.h | 105 ++++++ drivers/clk/nuvoton/clk_npcm7xx.c | 95 ++++++ .../dt-bindings/clock/nuvoton,npcm7xx-clock.h | 46 +++ 6 files changed, 548 insertions(+) create mode 100644 drivers/clk/nuvoton/Makefile create mode 100644 drivers/clk/nuvoton/clk_npcm.c create mode 100644 drivers/clk/nuvoton/clk_npcm.h create mode 100644 drivers/clk/nuvoton/clk_npcm7xx.c create mode 100644 include/dt-bindings/clock/nuvoton,npcm7xx-clock.h
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index bb4eee5d99..f5b553172c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ +obj-$(CONFIG_ARCH_NPCM) += nuvoton/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_SOCFPGA) += altera/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ diff --git a/drivers/clk/nuvoton/Makefile b/drivers/clk/nuvoton/Makefile new file mode 100644 index 0000000000..c63d9c16f1 --- /dev/null +++ b/drivers/clk/nuvoton/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_ARCH_NPCM) += clk_npcm.o +obj-$(CONFIG_ARCH_NPCM7xx) += clk_npcm7xx.o diff --git a/drivers/clk/nuvoton/clk_npcm.c b/drivers/clk/nuvoton/clk_npcm.c new file mode 100644 index 0000000000..8d71f2a24b --- /dev/null +++ b/drivers/clk/nuvoton/clk_npcm.c @@ -0,0 +1,299 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Nuvoton Technology Corp. + * + * Formula for calculating clock rate: + * Fout = ((Fin / PRE_DIV) / div) / POST_DIV + */ + +#include <div64.h> +#include <dm.h> +#include <asm/io.h> +#include <linux/bitfield.h> +#include <linux/log2.h> +#include "clk_npcm.h" + +static int clkid_to_clksel(struct npcm_clk_select *selector, int id) +{ + int i; + + for (i = 0; i < selector->num_parents; i++) { + if (selector->parents[i].id == id) + return selector->parents[i].clksel; + } + + return -EINVAL; +} + +static int clksel_to_clkid(struct npcm_clk_select *selector, int clksel) +{ + int i; + + for (i = 0; i < selector->num_parents; i++) { + if (selector->parents[i].clksel == clksel) + return selector->parents[i].id; + } + + return -EINVAL; +} + +static struct npcm_clk_pll *npcm_clk_pll_get(struct npcm_clk_data *clk_data, int id) +{ + struct npcm_clk_pll *pll = clk_data->clk_plls; + int i; + + for (i = 0; i < clk_data->num_plls; i++) { + if (pll->id == id) + return pll; + pll++; + } + + return NULL; +} + +static struct npcm_clk_select *npcm_clk_selector_get(struct npcm_clk_data *clk_data, + int id) +{ + struct npcm_clk_select *selector = clk_data->clk_selectors; + int i; + + for (i = 0; i < clk_data->num_selectors; i++) { + if (selector->id == id) + return selector; + selector++; + } + + return NULL; +} + +static struct npcm_clk_div *npcm_clk_divider_get(struct npcm_clk_data *clk_data, + int id) +{ + struct npcm_clk_div *divider = clk_data->clk_dividers; + int i; + + for (i = 0; i < clk_data->num_dividers; i++) { + if (divider->id == id) + return divider; + divider++; + } + + return NULL; +} + +static ulong npcm_clk_get_fin(struct clk *clk) +{ + struct npcm_clk_priv *priv = dev_get_priv(clk->dev); + struct npcm_clk_select *selector; + struct clk parent; + ulong parent_rate; + u32 val, clksel; + int ret; + + selector = npcm_clk_selector_get(priv->clk_data, clk->id); + if (!selector) + return 0; + + if (selector->flags & FIXED_PARENT) { + clksel = 0; + } else { + val = readl(priv->base + selector->reg); + clksel = (val & selector->mask) >> (ffs(selector->mask) - 1); + } + parent.id = clksel_to_clkid(selector, clksel); + + ret = clk_request(clk->dev, &parent); + if (ret) + return 0; + + parent_rate = clk_get_rate(&parent); + + debug("fin of clk%lu = %lu\n", clk->id, parent_rate); + return parent_rate; +} + +static u32 npcm_clk_get_div(struct clk *clk) +{ + struct npcm_clk_priv *priv = dev_get_priv(clk->dev); + struct npcm_clk_div *divider; + u32 val, div; + + divider = npcm_clk_divider_get(priv->clk_data, clk->id); + if (!divider) + return 0; + + val = readl(priv->base + divider->reg); + div = (val & divider->mask) >> (ffs(divider->mask) - 1); + if (divider->flags & DIV_TYPE1) + div = div + 1; + else + div = 1 << div; + + if (divider->flags & PRE_DIV2) + div = div << 1; + + return div; +} + +static u32 npcm_clk_set_div(struct clk *clk, u32 div) +{ + struct npcm_clk_priv *priv = dev_get_priv(clk->dev); + struct npcm_clk_div *divider; + u32 val, clkdiv; + + divider = npcm_clk_divider_get(priv->clk_data, clk->id); + if (!divider) + return -EINVAL; + + if (divider->flags & PRE_DIV2) + div = div >> 1; + + if (divider->flags & DIV_TYPE1) + clkdiv = div - 1; + else + clkdiv = ilog2(div); + + val = readl(priv->base + divider->reg); + val &= ~divider->mask; + val |= (clkdiv << (ffs(divider->mask) - 1)) & divider->mask; + writel(val, priv->base + divider->reg); + + return 0; +} + +static ulong npcm_clk_get_fout(struct clk *clk) +{ + ulong parent_rate; + u32 div; + + parent_rate = npcm_clk_get_fin(clk); + if (!parent_rate) + return -EINVAL; + + div = npcm_clk_get_div(clk); + if (!div) + return -EINVAL; + + debug("fout of clk%lu = (%lu / %u)\n", clk->id, parent_rate, div); + return (parent_rate / div); +} + +static ulong npcm_clk_get_pll_fout(struct clk *clk) +{ + struct npcm_clk_priv *priv = dev_get_priv(clk->dev); + struct npcm_clk_pll *pll; + struct clk parent; + ulong parent_rate; + ulong fbdv, indv, otdv1, otdv2; + u32 val; + u64 ret; + + pll = npcm_clk_pll_get(priv->clk_data, clk->id); + if (!pll) + return -ENODEV; + + parent.id = pll->parent_id; + ret = clk_request(clk->dev, &parent); + if (ret) + return ret; + + parent_rate = clk_get_rate(&parent); + + val = readl(priv->base + pll->reg); + indv = FIELD_GET(PLLCON_INDV, val); + fbdv = FIELD_GET(PLLCON_FBDV, val); + otdv1 = FIELD_GET(PLLCON_OTDV1, val); + otdv2 = FIELD_GET(PLLCON_OTDV2, val); + + ret = (u64)parent_rate * fbdv; + do_div(ret, indv * otdv1 * otdv2); + if (pll->flags & POST_DIV2) + do_div(ret, 2); + + debug("fout of pll(id %lu) = %llu\n", clk->id, ret); + return ret; +} + +static ulong npcm_clk_get_rate(struct clk *clk) +{ + struct npcm_clk_priv *priv = dev_get_priv(clk->dev); + struct npcm_clk_data *clk_data = priv->clk_data; + struct clk refclk; + int ret; + + debug("%s: id %lu\n", __func__, clk->id); + if (clk->id == clk_data->refclk_id) { + ret = clk_get_by_name(clk->dev, "refclk", &refclk); + if (!ret) + return clk_get_rate(&refclk); + else + return ret; + } + + if (clk->id >= clk_data->pll0_id && + clk->id < clk_data->pll0_id + clk_data->num_plls) + return npcm_clk_get_pll_fout(clk); + else + return npcm_clk_get_fout(clk); +} + +static ulong npcm_clk_set_rate(struct clk *clk, ulong rate) +{ + ulong parent_rate; + u32 div; + int ret; + + debug("%s: id %lu, rate %lu\n", __func__, clk->id, rate); + parent_rate = npcm_clk_get_fin(clk); + if (!parent_rate) + return -EINVAL; + + div = DIV_ROUND_UP(parent_rate, rate); + ret = npcm_clk_set_div(clk, div); + if (ret) + return ret; + + debug("%s: rate %lu, new rate (%lu / %u)\n", __func__, rate, parent_rate, div); + return (parent_rate / div); +} + +static int npcm_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct npcm_clk_priv *priv = dev_get_priv(clk->dev); + struct npcm_clk_select *selector; + int clksel; + u32 val; + + debug("%s: id %lu, parent %lu\n", __func__, clk->id, parent->id); + selector = npcm_clk_selector_get(priv->clk_data, clk->id); + if (!selector) + return -EINVAL; + + clksel = clkid_to_clksel(selector, parent->id); + if (clksel < 0) + return -EINVAL; + + val = readl(priv->base + selector->reg); + val &= ~selector->mask; + val |= clksel << (ffs(selector->mask) - 1); + writel(val, priv->base + selector->reg); + + return 0; +} + +static int npcm_clk_request(struct clk *clk) +{ + struct npcm_clk_priv *priv = dev_get_priv(clk->dev); + + if (clk->id >= priv->num_clks) + return -EINVAL; + + return 0; +} + +const struct clk_ops npcm_clk_ops = { + .get_rate = npcm_clk_get_rate, + .set_rate = npcm_clk_set_rate, + .set_parent = npcm_clk_set_parent, + .request = npcm_clk_request, +}; diff --git a/drivers/clk/nuvoton/clk_npcm.h b/drivers/clk/nuvoton/clk_npcm.h new file mode 100644 index 0000000000..06b60dc8b8 --- /dev/null +++ b/drivers/clk/nuvoton/clk_npcm.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _CLK_NPCM_H_ +#define _CLK_NPCM_H_ + +#include <clk-uclass.h> + +/* Register offsets */ +#define CLKSEL 0x04 /* clock source selection */ +#define CLKDIV1 0x08 /* clock divider 1 */ +#define CLKDIV2 0x2C /* clock divider 2 */ +#define CLKDIV3 0x58 /* clock divider 3 */ +#define PLLCON0 0x0C /* pll0 control */ +#define PLLCON1 0x10 /* pll1 control */ +#define PLLCON2 0x54 /* pll2 control */ + +/* CLKSEL bit filed */ +#define NPCM7XX_CPUCKSEL GENMASK(1, 0) +#define NPCM8XX_CPUCKSEL GENMASK(2, 0) +#define SDCKSEL GENMASK(7, 6) +#define UARTCKSEL GENMASK(9, 8) +#define TIMCKSEL GENMASK(15, 14) + +/* CLKDIV1 bit filed */ +#define SPI3CKDIV GENMASK(10, 6) +#define MMCCKDIV GENMASK(15, 11) +#define UARTDIV1 GENMASK(20, 16) +#define TIMCKDIV GENMASK(25, 21) +#define CLK4DIV GENMASK(27, 26) + +/* CLKDIV2 bit filed */ +#define APB5CKDIV GENMASK(23, 22) +#define APB2CKDIV GENMASK(27, 26) + +/* CLKDIV3 bit filed */ +#define SPIXCKDIV GENMASK(5, 1) +#define SPI0CKDIV GENMASK(10, 6) +#define UARTDIV2 GENMASK(15, 11) +#define SPI1CKDIV GENMASK(23, 16) + +/* PLLCON bit filed */ +#define PLLCON_INDV GENMASK(5, 0) +#define PLLCON_OTDV1 GENMASK(10, 8) +#define PLLCON_OTDV2 GENMASK(15, 13) +#define PLLCON_FBDV GENMASK(27, 16) + +/* Flags */ +#define DIV_TYPE1 BIT(0) /* div = clkdiv + 1 */ +#define DIV_TYPE2 BIT(1) /* div = 1 << clkdiv */ +#define PRE_DIV2 BIT(2) /* Pre divisor = 2 */ +#define POST_DIV2 BIT(3) /* Post divisor = 2 */ +#define FIXED_PARENT BIT(4) /* clock source is fixed */ + +/* Parameters of PLL configuration */ +struct npcm_clk_pll { + const int id; + const int parent_id; + u32 reg; + u32 flags; +}; + +/* Parent clock id to clksel mapping */ +struct parent_data { + int id; + int clksel; +}; + +/* Parameters of parent selection */ +struct npcm_clk_select { + const int id; + const struct parent_data *parents; + u32 reg; + u32 mask; + u8 num_parents; + u32 flags; +}; + +/* Parameters of clock divider */ +struct npcm_clk_div { + const int id; + u32 reg; + u32 mask; + u32 flags; +}; + +struct npcm_clk_data { + struct npcm_clk_pll *clk_plls; + int num_plls; + struct npcm_clk_select *clk_selectors; + int num_selectors; + struct npcm_clk_div *clk_dividers; + int num_dividers; + int refclk_id; + int pll0_id; +}; + +struct npcm_clk_priv { + void __iomem *base; + struct npcm_clk_data *clk_data; + int num_clks; +}; + +extern const struct clk_ops npcm_clk_ops; + +#endif diff --git a/drivers/clk/nuvoton/clk_npcm7xx.c b/drivers/clk/nuvoton/clk_npcm7xx.c new file mode 100644 index 0000000000..a12aaa2f4c --- /dev/null +++ b/drivers/clk/nuvoton/clk_npcm7xx.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include <dm.h> +#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h> +#include "clk_npcm.h" + +/* Parent clock map */ +static const struct parent_data pll_parents[] = { + {NPCM7XX_CLK_PLL0, 0}, + {NPCM7XX_CLK_PLL1, 1}, + {NPCM7XX_CLK_REFCLK, 2}, + {NPCM7XX_CLK_PLL2DIV2, 3} +}; + +static const struct parent_data cpuck_parents[] = { + {NPCM7XX_CLK_PLL0, 0}, + {NPCM7XX_CLK_PLL1, 1}, + {NPCM7XX_CLK_REFCLK, 2}, +}; + +static const struct parent_data apb_parent[] = {{NPCM7XX_CLK_AHB, 0}}; + +static struct npcm_clk_pll npcm7xx_clk_plls[] = { + {NPCM7XX_CLK_PLL0, NPCM7XX_CLK_REFCLK, PLLCON0, 0}, + {NPCM7XX_CLK_PLL1, NPCM7XX_CLK_REFCLK, PLLCON1, 0}, + {NPCM7XX_CLK_PLL2, NPCM7XX_CLK_REFCLK, PLLCON2, 0}, + {NPCM7XX_CLK_PLL2DIV2, NPCM7XX_CLK_REFCLK, PLLCON2, POST_DIV2} +}; + +static struct npcm_clk_select npcm7xx_clk_selectors[] = { + {NPCM7XX_CLK_AHB, cpuck_parents, CLKSEL, NPCM7XX_CPUCKSEL, 3, 0}, + {NPCM7XX_CLK_APB2, apb_parent, 0, 0, 1, FIXED_PARENT}, + {NPCM7XX_CLK_APB5, apb_parent, 0, 0, 1, FIXED_PARENT}, + {NPCM7XX_CLK_SPI0, apb_parent, 0, 0, 1, FIXED_PARENT}, + {NPCM7XX_CLK_SPI3, apb_parent, 0, 0, 1, FIXED_PARENT}, + {NPCM7XX_CLK_SPIX, apb_parent, 0, 0, 1, FIXED_PARENT}, + {NPCM7XX_CLK_UART, pll_parents, CLKSEL, UARTCKSEL, 4, 0}, + {NPCM7XX_CLK_TIMER, pll_parents, CLKSEL, TIMCKSEL, 4, 0}, + {NPCM7XX_CLK_SDHC, pll_parents, CLKSEL, SDCKSEL, 4, 0} +}; + +static struct npcm_clk_div npcm7xx_clk_dividers[] = { + {NPCM7XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2}, + {NPCM7XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2}, + {NPCM7XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2}, + {NPCM7XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1}, + {NPCM7XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1}, + {NPCM7XX_CLK_SPIX, CLKDIV3, SPIXCKDIV, DIV_TYPE1}, + {NPCM7XX_CLK_UART, CLKDIV1, UARTDIV1, DIV_TYPE1}, + {NPCM7XX_CLK_TIMER, CLKDIV1, TIMCKDIV, DIV_TYPE2}, + {NPCM7XX_CLK_SDHC, CLKDIV1, MMCCKDIV, DIV_TYPE1} +}; + +static struct npcm_clk_data npcm7xx_clk_data = { + .clk_plls = npcm7xx_clk_plls, + .num_plls = ARRAY_SIZE(npcm7xx_clk_plls), + .clk_selectors = npcm7xx_clk_selectors, + .num_selectors = ARRAY_SIZE(npcm7xx_clk_selectors), + .clk_dividers = npcm7xx_clk_dividers, + .num_dividers = ARRAY_SIZE(npcm7xx_clk_dividers), + .refclk_id = NPCM7XX_CLK_REFCLK, + .pll0_id = NPCM7XX_CLK_PLL0, +}; + +static int npcm7xx_clk_probe(struct udevice *dev) +{ + struct npcm_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -EINVAL; + + priv->clk_data = &npcm7xx_clk_data; + priv->num_clks = NPCM7XX_NUM_CLOCKS; + + return 0; +} + +static const struct udevice_id npcm7xx_clk_ids[] = { + { .compatible = "nuvoton,npcm750-clk" }, + { } +}; + +U_BOOT_DRIVER(clk_npcm) = { + .name = "clk_npcm", + .id = UCLASS_CLK, + .of_match = npcm7xx_clk_ids, + .ops = &npcm_clk_ops, + .priv_auto = sizeof(struct npcm_clk_priv), + .probe = npcm7xx_clk_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h b/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h new file mode 100644 index 0000000000..65e6bc4eee --- /dev/null +++ b/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Nuvoton NPCM7xx Clock Generator binding + * clock binding number for all clocks supportted by nuvoton,npcm7xx-clk + * + * Copyright (C) 2018 Nuvoton Technologies tali.perry@nuvoton.com + * + */ + +#ifndef __DT_BINDINGS_CLOCK_NPCM7XX_H +#define __DT_BINDINGS_CLOCK_NPCM7XX_H + +#define NPCM7XX_CLK_CPU 0 +#define NPCM7XX_CLK_GFX_PIXEL 1 +#define NPCM7XX_CLK_MC 2 +#define NPCM7XX_CLK_ADC 3 +#define NPCM7XX_CLK_AHB 4 +#define NPCM7XX_CLK_TIMER 5 +#define NPCM7XX_CLK_UART 6 +#define NPCM7XX_CLK_MMC 7 +#define NPCM7XX_CLK_SPI3 8 +#define NPCM7XX_CLK_PCI 9 +#define NPCM7XX_CLK_AXI 10 +#define NPCM7XX_CLK_APB4 11 +#define NPCM7XX_CLK_APB3 12 +#define NPCM7XX_CLK_APB2 13 +#define NPCM7XX_CLK_APB1 14 +#define NPCM7XX_CLK_APB5 15 +#define NPCM7XX_CLK_CLKOUT 16 +#define NPCM7XX_CLK_GFX 17 +#define NPCM7XX_CLK_SU 18 +#define NPCM7XX_CLK_SU48 19 +#define NPCM7XX_CLK_SDHC 20 +#define NPCM7XX_CLK_SPI0 21 +#define NPCM7XX_CLK_SPIX 22 +#define NPCM7XX_CLK_REFCLK 23 +#define NPCM7XX_CLK_SYSBYPCK 24 +#define NPCM7XX_CLK_MCBYPCK 25 +#define NPCM7XX_CLK_PLL0 26 +#define NPCM7XX_CLK_PLL1 27 +#define NPCM7XX_CLK_PLL2 28 +#define NPCM7XX_CLK_PLL2DIV2 29 +#define NPCM7XX_NUM_CLOCKS (NPCM7XX_CLK_PLL2DIV2 + 1) + +#endif +

On 4/19/22 1:32 AM, Jim Liu wrote:
Add clock controller driver for NPCM750
Signed-off-by: Jim Liu JJLIU0@nuvoton.com Signed-off-by: Stanley Chu yschu@nuvoton.com
Changes for v3: - no changes since v2 Changes for v2: - combine NPCM750 and NPCM845 clk driver.
drivers/clk/Makefile | 1 + drivers/clk/nuvoton/Makefile | 2 + drivers/clk/nuvoton/clk_npcm.c | 299 ++++++++++++++++++ drivers/clk/nuvoton/clk_npcm.h | 105 ++++++ drivers/clk/nuvoton/clk_npcm7xx.c | 95 ++++++ .../dt-bindings/clock/nuvoton,npcm7xx-clock.h | 46 +++ 6 files changed, 548 insertions(+) create mode 100644 drivers/clk/nuvoton/Makefile create mode 100644 drivers/clk/nuvoton/clk_npcm.c create mode 100644 drivers/clk/nuvoton/clk_npcm.h create mode 100644 drivers/clk/nuvoton/clk_npcm7xx.c create mode 100644 include/dt-bindings/clock/nuvoton,npcm7xx-clock.h
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index bb4eee5d99..f5b553172c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ +obj-$(CONFIG_ARCH_NPCM) += nuvoton/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_SOCFPGA) += altera/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ diff --git a/drivers/clk/nuvoton/Makefile b/drivers/clk/nuvoton/Makefile new file mode 100644 index 0000000000..c63d9c16f1 --- /dev/null +++ b/drivers/clk/nuvoton/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_ARCH_NPCM) += clk_npcm.o +obj-$(CONFIG_ARCH_NPCM7xx) += clk_npcm7xx.o diff --git a/drivers/clk/nuvoton/clk_npcm.c b/drivers/clk/nuvoton/clk_npcm.c new file mode 100644 index 0000000000..8d71f2a24b --- /dev/null +++ b/drivers/clk/nuvoton/clk_npcm.c @@ -0,0 +1,299 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2022 Nuvoton Technology Corp.
- Formula for calculating clock rate:
- Fout = ((Fin / PRE_DIV) / div) / POST_DIV
- */
+#include <div64.h> +#include <dm.h> +#include <asm/io.h> +#include <linux/bitfield.h> +#include <linux/log2.h> +#include "clk_npcm.h"
+static int clkid_to_clksel(struct npcm_clk_select *selector, int id) +{
- int i;
- for (i = 0; i < selector->num_parents; i++) {
if (selector->parents[i].id == id)
return selector->parents[i].clksel;
- }
- return -EINVAL;
+}
+static int clksel_to_clkid(struct npcm_clk_select *selector, int clksel) +{
- int i;
- for (i = 0; i < selector->num_parents; i++) {
if (selector->parents[i].clksel == clksel)
return selector->parents[i].id;
- }
- return -EINVAL;
+}
+static struct npcm_clk_pll *npcm_clk_pll_get(struct npcm_clk_data *clk_data, int id) +{
- struct npcm_clk_pll *pll = clk_data->clk_plls;
- int i;
- for (i = 0; i < clk_data->num_plls; i++) {
if (pll->id == id)
return pll;
pll++;
- }
- return NULL;
+}
+static struct npcm_clk_select *npcm_clk_selector_get(struct npcm_clk_data *clk_data,
int id)
+{
- struct npcm_clk_select *selector = clk_data->clk_selectors;
- int i;
- for (i = 0; i < clk_data->num_selectors; i++) {
if (selector->id == id)
return selector;
selector++;
- }
- return NULL;
+}
+static struct npcm_clk_div *npcm_clk_divider_get(struct npcm_clk_data *clk_data,
int id)
+{
- struct npcm_clk_div *divider = clk_data->clk_dividers;
- int i;
- for (i = 0; i < clk_data->num_dividers; i++) {
if (divider->id == id)
return divider;
divider++;
- }
- return NULL;
+}
+static ulong npcm_clk_get_fin(struct clk *clk) +{
- struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
- struct npcm_clk_select *selector;
- struct clk parent;
- ulong parent_rate;
- u32 val, clksel;
- int ret;
- selector = npcm_clk_selector_get(priv->clk_data, clk->id);
- if (!selector)
return 0;
- if (selector->flags & FIXED_PARENT) {
clksel = 0;
- } else {
val = readl(priv->base + selector->reg);
clksel = (val & selector->mask) >> (ffs(selector->mask) - 1);
- }
- parent.id = clksel_to_clkid(selector, clksel);
- ret = clk_request(clk->dev, &parent);
- if (ret)
return 0;
- parent_rate = clk_get_rate(&parent);
- debug("fin of clk%lu = %lu\n", clk->id, parent_rate);
- return parent_rate;
+}
+static u32 npcm_clk_get_div(struct clk *clk) +{
- struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
- struct npcm_clk_div *divider;
- u32 val, div;
- divider = npcm_clk_divider_get(priv->clk_data, clk->id);
- if (!divider)
return 0;
- val = readl(priv->base + divider->reg);
- div = (val & divider->mask) >> (ffs(divider->mask) - 1);
- if (divider->flags & DIV_TYPE1)
div = div + 1;
- else
div = 1 << div;
- if (divider->flags & PRE_DIV2)
div = div << 1;
- return div;
+}
+static u32 npcm_clk_set_div(struct clk *clk, u32 div) +{
- struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
- struct npcm_clk_div *divider;
- u32 val, clkdiv;
- divider = npcm_clk_divider_get(priv->clk_data, clk->id);
- if (!divider)
return -EINVAL;
- if (divider->flags & PRE_DIV2)
div = div >> 1;
- if (divider->flags & DIV_TYPE1)
clkdiv = div - 1;
- else
clkdiv = ilog2(div);
- val = readl(priv->base + divider->reg);
- val &= ~divider->mask;
- val |= (clkdiv << (ffs(divider->mask) - 1)) & divider->mask;
- writel(val, priv->base + divider->reg);
- return 0;
+}
+static ulong npcm_clk_get_fout(struct clk *clk) +{
- ulong parent_rate;
- u32 div;
- parent_rate = npcm_clk_get_fin(clk);
- if (!parent_rate)
return -EINVAL;
- div = npcm_clk_get_div(clk);
- if (!div)
return -EINVAL;
- debug("fout of clk%lu = (%lu / %u)\n", clk->id, parent_rate, div);
- return (parent_rate / div);
+}
+static ulong npcm_clk_get_pll_fout(struct clk *clk) +{
- struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
- struct npcm_clk_pll *pll;
- struct clk parent;
- ulong parent_rate;
- ulong fbdv, indv, otdv1, otdv2;
- u32 val;
- u64 ret;
- pll = npcm_clk_pll_get(priv->clk_data, clk->id);
- if (!pll)
return -ENODEV;
- parent.id = pll->parent_id;
- ret = clk_request(clk->dev, &parent);
- if (ret)
return ret;
- parent_rate = clk_get_rate(&parent);
- val = readl(priv->base + pll->reg);
- indv = FIELD_GET(PLLCON_INDV, val);
- fbdv = FIELD_GET(PLLCON_FBDV, val);
- otdv1 = FIELD_GET(PLLCON_OTDV1, val);
- otdv2 = FIELD_GET(PLLCON_OTDV2, val);
- ret = (u64)parent_rate * fbdv;
- do_div(ret, indv * otdv1 * otdv2);
- if (pll->flags & POST_DIV2)
do_div(ret, 2);
- debug("fout of pll(id %lu) = %llu\n", clk->id, ret);
- return ret;
+}
+static ulong npcm_clk_get_rate(struct clk *clk) +{
- struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
- struct npcm_clk_data *clk_data = priv->clk_data;
- struct clk refclk;
- int ret;
- debug("%s: id %lu\n", __func__, clk->id);
- if (clk->id == clk_data->refclk_id) {
ret = clk_get_by_name(clk->dev, "refclk", &refclk);
if (!ret)
return clk_get_rate(&refclk);
else
return ret;
- }
- if (clk->id >= clk_data->pll0_id &&
clk->id < clk_data->pll0_id + clk_data->num_plls)
return npcm_clk_get_pll_fout(clk);
- else
return npcm_clk_get_fout(clk);
+}
+static ulong npcm_clk_set_rate(struct clk *clk, ulong rate) +{
- ulong parent_rate;
- u32 div;
- int ret;
- debug("%s: id %lu, rate %lu\n", __func__, clk->id, rate);
- parent_rate = npcm_clk_get_fin(clk);
- if (!parent_rate)
return -EINVAL;
- div = DIV_ROUND_UP(parent_rate, rate);
- ret = npcm_clk_set_div(clk, div);
- if (ret)
return ret;
- debug("%s: rate %lu, new rate (%lu / %u)\n", __func__, rate, parent_rate, div);
- return (parent_rate / div);
+}
+static int npcm_clk_set_parent(struct clk *clk, struct clk *parent) +{
- struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
- struct npcm_clk_select *selector;
- int clksel;
- u32 val;
- debug("%s: id %lu, parent %lu\n", __func__, clk->id, parent->id);
- selector = npcm_clk_selector_get(priv->clk_data, clk->id);
- if (!selector)
return -EINVAL;
- clksel = clkid_to_clksel(selector, parent->id);
- if (clksel < 0)
return -EINVAL;
- val = readl(priv->base + selector->reg);
- val &= ~selector->mask;
- val |= clksel << (ffs(selector->mask) - 1);
- writel(val, priv->base + selector->reg);
- return 0;
+}
+static int npcm_clk_request(struct clk *clk) +{
- struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
- if (clk->id >= priv->num_clks)
return -EINVAL;
- return 0;
+}
+const struct clk_ops npcm_clk_ops = {
- .get_rate = npcm_clk_get_rate,
- .set_rate = npcm_clk_set_rate,
- .set_parent = npcm_clk_set_parent,
- .request = npcm_clk_request,
+}; diff --git a/drivers/clk/nuvoton/clk_npcm.h b/drivers/clk/nuvoton/clk_npcm.h new file mode 100644 index 0000000000..06b60dc8b8 --- /dev/null +++ b/drivers/clk/nuvoton/clk_npcm.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef _CLK_NPCM_H_ +#define _CLK_NPCM_H_
+#include <clk-uclass.h>
+/* Register offsets */ +#define CLKSEL 0x04 /* clock source selection */ +#define CLKDIV1 0x08 /* clock divider 1 */ +#define CLKDIV2 0x2C /* clock divider 2 */ +#define CLKDIV3 0x58 /* clock divider 3 */ +#define PLLCON0 0x0C /* pll0 control */ +#define PLLCON1 0x10 /* pll1 control */ +#define PLLCON2 0x54 /* pll2 control */
+/* CLKSEL bit filed */ +#define NPCM7XX_CPUCKSEL GENMASK(1, 0) +#define NPCM8XX_CPUCKSEL GENMASK(2, 0) +#define SDCKSEL GENMASK(7, 6) +#define UARTCKSEL GENMASK(9, 8) +#define TIMCKSEL GENMASK(15, 14)
+/* CLKDIV1 bit filed */ +#define SPI3CKDIV GENMASK(10, 6) +#define MMCCKDIV GENMASK(15, 11) +#define UARTDIV1 GENMASK(20, 16) +#define TIMCKDIV GENMASK(25, 21) +#define CLK4DIV GENMASK(27, 26)
+/* CLKDIV2 bit filed */ +#define APB5CKDIV GENMASK(23, 22) +#define APB2CKDIV GENMASK(27, 26)
+/* CLKDIV3 bit filed */ +#define SPIXCKDIV GENMASK(5, 1) +#define SPI0CKDIV GENMASK(10, 6) +#define UARTDIV2 GENMASK(15, 11) +#define SPI1CKDIV GENMASK(23, 16)
+/* PLLCON bit filed */ +#define PLLCON_INDV GENMASK(5, 0) +#define PLLCON_OTDV1 GENMASK(10, 8) +#define PLLCON_OTDV2 GENMASK(15, 13) +#define PLLCON_FBDV GENMASK(27, 16)
+/* Flags */ +#define DIV_TYPE1 BIT(0) /* div = clkdiv + 1 */ +#define DIV_TYPE2 BIT(1) /* div = 1 << clkdiv */ +#define PRE_DIV2 BIT(2) /* Pre divisor = 2 */ +#define POST_DIV2 BIT(3) /* Post divisor = 2 */ +#define FIXED_PARENT BIT(4) /* clock source is fixed */
+/* Parameters of PLL configuration */ +struct npcm_clk_pll {
- const int id;
- const int parent_id;
- u32 reg;
- u32 flags;
+};
+/* Parent clock id to clksel mapping */ +struct parent_data {
- int id;
- int clksel;
+};
+/* Parameters of parent selection */ +struct npcm_clk_select {
- const int id;
- const struct parent_data *parents;
- u32 reg;
- u32 mask;
- u8 num_parents;
- u32 flags;
+};
+/* Parameters of clock divider */ +struct npcm_clk_div {
- const int id;
- u32 reg;
- u32 mask;
- u32 flags;
+};
+struct npcm_clk_data {
- struct npcm_clk_pll *clk_plls;
- int num_plls;
- struct npcm_clk_select *clk_selectors;
- int num_selectors;
- struct npcm_clk_div *clk_dividers;
- int num_dividers;
- int refclk_id;
- int pll0_id;
+};
+struct npcm_clk_priv {
- void __iomem *base;
- struct npcm_clk_data *clk_data;
- int num_clks;
+};
+extern const struct clk_ops npcm_clk_ops;
+#endif diff --git a/drivers/clk/nuvoton/clk_npcm7xx.c b/drivers/clk/nuvoton/clk_npcm7xx.c new file mode 100644 index 0000000000..a12aaa2f4c --- /dev/null +++ b/drivers/clk/nuvoton/clk_npcm7xx.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2021 Nuvoton Technology Corp.
- */
+#include <dm.h> +#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h> +#include "clk_npcm.h"
+/* Parent clock map */ +static const struct parent_data pll_parents[] = {
- {NPCM7XX_CLK_PLL0, 0},
- {NPCM7XX_CLK_PLL1, 1},
- {NPCM7XX_CLK_REFCLK, 2},
- {NPCM7XX_CLK_PLL2DIV2, 3}
+};
+static const struct parent_data cpuck_parents[] = {
- {NPCM7XX_CLK_PLL0, 0},
- {NPCM7XX_CLK_PLL1, 1},
- {NPCM7XX_CLK_REFCLK, 2},
+};
+static const struct parent_data apb_parent[] = {{NPCM7XX_CLK_AHB, 0}};
+static struct npcm_clk_pll npcm7xx_clk_plls[] = {
- {NPCM7XX_CLK_PLL0, NPCM7XX_CLK_REFCLK, PLLCON0, 0},
- {NPCM7XX_CLK_PLL1, NPCM7XX_CLK_REFCLK, PLLCON1, 0},
- {NPCM7XX_CLK_PLL2, NPCM7XX_CLK_REFCLK, PLLCON2, 0},
- {NPCM7XX_CLK_PLL2DIV2, NPCM7XX_CLK_REFCLK, PLLCON2, POST_DIV2}
+};
+static struct npcm_clk_select npcm7xx_clk_selectors[] = {
- {NPCM7XX_CLK_AHB, cpuck_parents, CLKSEL, NPCM7XX_CPUCKSEL, 3, 0},
- {NPCM7XX_CLK_APB2, apb_parent, 0, 0, 1, FIXED_PARENT},
- {NPCM7XX_CLK_APB5, apb_parent, 0, 0, 1, FIXED_PARENT},
- {NPCM7XX_CLK_SPI0, apb_parent, 0, 0, 1, FIXED_PARENT},
- {NPCM7XX_CLK_SPI3, apb_parent, 0, 0, 1, FIXED_PARENT},
- {NPCM7XX_CLK_SPIX, apb_parent, 0, 0, 1, FIXED_PARENT},
- {NPCM7XX_CLK_UART, pll_parents, CLKSEL, UARTCKSEL, 4, 0},
- {NPCM7XX_CLK_TIMER, pll_parents, CLKSEL, TIMCKSEL, 4, 0},
- {NPCM7XX_CLK_SDHC, pll_parents, CLKSEL, SDCKSEL, 4, 0}
+};
+static struct npcm_clk_div npcm7xx_clk_dividers[] = {
- {NPCM7XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2},
- {NPCM7XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2},
- {NPCM7XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2},
- {NPCM7XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1},
- {NPCM7XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1},
- {NPCM7XX_CLK_SPIX, CLKDIV3, SPIXCKDIV, DIV_TYPE1},
- {NPCM7XX_CLK_UART, CLKDIV1, UARTDIV1, DIV_TYPE1},
- {NPCM7XX_CLK_TIMER, CLKDIV1, TIMCKDIV, DIV_TYPE2},
- {NPCM7XX_CLK_SDHC, CLKDIV1, MMCCKDIV, DIV_TYPE1}
+};
+static struct npcm_clk_data npcm7xx_clk_data = {
- .clk_plls = npcm7xx_clk_plls,
- .num_plls = ARRAY_SIZE(npcm7xx_clk_plls),
- .clk_selectors = npcm7xx_clk_selectors,
- .num_selectors = ARRAY_SIZE(npcm7xx_clk_selectors),
- .clk_dividers = npcm7xx_clk_dividers,
- .num_dividers = ARRAY_SIZE(npcm7xx_clk_dividers),
- .refclk_id = NPCM7XX_CLK_REFCLK,
- .pll0_id = NPCM7XX_CLK_PLL0,
+};
+static int npcm7xx_clk_probe(struct udevice *dev) +{
- struct npcm_clk_priv *priv = dev_get_priv(dev);
- priv->base = dev_read_addr_ptr(dev);
- if (!priv->base)
return -EINVAL;
- priv->clk_data = &npcm7xx_clk_data;
- priv->num_clks = NPCM7XX_NUM_CLOCKS;
- return 0;
+}
+static const struct udevice_id npcm7xx_clk_ids[] = {
- { .compatible = "nuvoton,npcm750-clk" },
- { }
+};
+U_BOOT_DRIVER(clk_npcm) = {
- .name = "clk_npcm",
- .id = UCLASS_CLK,
- .of_match = npcm7xx_clk_ids,
- .ops = &npcm_clk_ops,
- .priv_auto = sizeof(struct npcm_clk_priv),
- .probe = npcm7xx_clk_probe,
- .flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h b/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h new file mode 100644 index 0000000000..65e6bc4eee --- /dev/null +++ b/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- Nuvoton NPCM7xx Clock Generator binding
- clock binding number for all clocks supportted by nuvoton,npcm7xx-clk
- Copyright (C) 2018 Nuvoton Technologies tali.perry@nuvoton.com
- */
+#ifndef __DT_BINDINGS_CLOCK_NPCM7XX_H +#define __DT_BINDINGS_CLOCK_NPCM7XX_H
+#define NPCM7XX_CLK_CPU 0 +#define NPCM7XX_CLK_GFX_PIXEL 1 +#define NPCM7XX_CLK_MC 2 +#define NPCM7XX_CLK_ADC 3 +#define NPCM7XX_CLK_AHB 4 +#define NPCM7XX_CLK_TIMER 5 +#define NPCM7XX_CLK_UART 6 +#define NPCM7XX_CLK_MMC 7 +#define NPCM7XX_CLK_SPI3 8 +#define NPCM7XX_CLK_PCI 9 +#define NPCM7XX_CLK_AXI 10 +#define NPCM7XX_CLK_APB4 11 +#define NPCM7XX_CLK_APB3 12 +#define NPCM7XX_CLK_APB2 13 +#define NPCM7XX_CLK_APB1 14 +#define NPCM7XX_CLK_APB5 15 +#define NPCM7XX_CLK_CLKOUT 16 +#define NPCM7XX_CLK_GFX 17 +#define NPCM7XX_CLK_SU 18 +#define NPCM7XX_CLK_SU48 19 +#define NPCM7XX_CLK_SDHC 20 +#define NPCM7XX_CLK_SPI0 21 +#define NPCM7XX_CLK_SPIX 22 +#define NPCM7XX_CLK_REFCLK 23 +#define NPCM7XX_CLK_SYSBYPCK 24 +#define NPCM7XX_CLK_MCBYPCK 25 +#define NPCM7XX_CLK_PLL0 26 +#define NPCM7XX_CLK_PLL1 27 +#define NPCM7XX_CLK_PLL2 28 +#define NPCM7XX_CLK_PLL2DIV2 29 +#define NPCM7XX_NUM_CLOCKS (NPCM7XX_CLK_PLL2DIV2 + 1)
+#endif
Reviewed-by: Sean Anderson seanga2@gmail.com

On Tue, Apr 19, 2022 at 01:32:20PM +0800, Jim Liu wrote:
Add clock controller driver for NPCM750
Signed-off-by: Jim Liu JJLIU0@nuvoton.com Signed-off-by: Stanley Chu yschu@nuvoton.com Reviewed-by: Sean Anderson seanga2@gmail.com
Applied to u-boot/master, thanks!

Add Nuvoton BMC NPCM7xx/NPCM8xx uart driver
Signed-off-by: Jim Liu JJLIU0@nuvoton.com Signed-off-by: Stanley Chu yschu@nuvoton.com --- Changes for v3: - no changes since v2 Changes for v2: - coding style cleanup - Add support for setting parent clock --- drivers/serial/Kconfig | 9 ++ drivers/serial/Makefile | 1 + drivers/serial/serial_npcm.c | 157 +++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 drivers/serial/serial_npcm.c
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index dc514c95d3..5434389835 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -995,6 +995,15 @@ config MPC8XX_CONS depends on MPC8xx default y
+config NPCM_SERIAL + bool "Nuvoton NPCM UART driver" + depends on DM_SERIAL + help + Select this to enable UART support for Nuvoton BMCs + (NPCM7xx and NPCM8xx). + The driver enables the onboard serial port with 8-N-1 + configuration. + config XEN_SERIAL bool "XEN serial support" depends on XEN diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index b68b5e7b2b..033e060a44 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_MSM_GENI_SERIAL) += serial_msm_geni.o obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o +obj-$(CONFIG_NPCM_SERIAL) += serial_npcm.o obj-$(CONFIG_OCTEON_SERIAL_BOOTCMD) += serial_octeon_bootcmd.o obj-$(CONFIG_OCTEON_SERIAL_PCIE_CONSOLE) += serial_octeon_pcie_console.o obj-$(CONFIG_OWL_SERIAL) += serial_owl.o diff --git a/drivers/serial/serial_npcm.c b/drivers/serial/serial_npcm.c new file mode 100644 index 0000000000..76ac7cb80d --- /dev/null +++ b/drivers/serial/serial_npcm.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <serial.h> + +struct npcm_uart { + union { + u32 rbr; /* Receive Buffer Register */ + u32 thr; /* Transmit Holding Register */ + u32 dll; /* Divisor Latch (Low Byte) Register */ + }; + union { + u32 ier; /* Interrupt Enable Register */ + u32 dlm; /* Divisor Latch (Low Byte) Register */ + }; + union { + u32 iir; /* Interrupt Identification Register */ + u32 fcr; /* FIFO Control Register */ + }; + u32 lcr; /* Line Control Register */ + u32 mcr; /* Modem Control Register */ + u32 lsr; /* Line Status Control Register */ + u32 msr; /* Modem Status Register */ + u32 tor; /* Timeout Register */ +}; + +#define LCR_WLS_8BITS 3 /* 8-bit word length select */ +#define FCR_TFR BIT(2) /* TxFIFO reset */ +#define FCR_RFR BIT(1) /* RxFIFO reset */ +#define FCR_FME BIT(0) /* FIFO mode enable */ +#define LSR_THRE BIT(5) /* Status of TxFIFO empty */ +#define LSR_RFDR BIT(0) /* Status of RxFIFO data ready */ +#define LCR_DLAB BIT(7) /* Divisor latch access bit */ + +struct npcm_serial_plat { + struct npcm_uart *reg; + u32 uart_clk; /* frequency of uart clock source */ +}; + +static int npcm_serial_pending(struct udevice *dev, bool input) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + + if (input) + return readb(&uart->lsr) & LSR_RFDR ? 1 : 0; + else + return readb(&uart->lsr) & LSR_THRE ? 0 : 1; +} + +static int npcm_serial_putc(struct udevice *dev, const char ch) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + + if (!(readb(&uart->lsr) & LSR_THRE)) + return -EAGAIN; + + writeb(ch, &uart->thr); + + return 0; +} + +static int npcm_serial_getc(struct udevice *dev) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + + if (!(readb(&uart->lsr) & LSR_RFDR)) + return -EAGAIN; + + return readb(&uart->rbr); +} + +static int npcm_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + u16 divisor; + + /* BaudOut = UART Clock / (16 * [Divisor + 2]) */ + divisor = DIV_ROUND_CLOSEST(plat->uart_clk, 16 * baudrate + 2) - 2; + + setbits_8(&uart->lcr, LCR_DLAB); + writeb(divisor & 0xff, &uart->dll); + writeb(divisor >> 8, &uart->dlm); + clrbits_8(&uart->lcr, LCR_DLAB); + + return 0; +} + +static int npcm_serial_probe(struct udevice *dev) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + struct clk clk, parent; + u32 freq; + int ret; + + plat->reg = dev_read_addr_ptr(dev); + freq = dev_read_u32_default(dev, "clock-frequency", 0); + + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_get_by_index(dev, 1, &parent); + if (!ret) { + ret = clk_set_parent(&clk, &parent); + if (ret) + return ret; + } + + ret = clk_set_rate(&clk, freq); + if (ret < 0) + return ret; + plat->uart_clk = ret; + + /* Disable all interrupt */ + writeb(0, &uart->ier); + + /* Set 8 bit, 1 stop, no parity */ + writeb(LCR_WLS_8BITS, &uart->lcr); + + /* Reset RX/TX FIFO */ + writeb(FCR_FME | FCR_RFR | FCR_TFR, &uart->fcr); + + return 0; +} + +static const struct dm_serial_ops npcm_serial_ops = { + .getc = npcm_serial_getc, + .setbrg = npcm_serial_setbrg, + .putc = npcm_serial_putc, + .pending = npcm_serial_pending, +}; + +static const struct udevice_id npcm_serial_ids[] = { + { .compatible = "nuvoton,npcm750-uart" }, + { .compatible = "nuvoton,npcm845-uart" }, + { } +}; + +U_BOOT_DRIVER(serial_npcm) = { + .name = "serial_npcm", + .id = UCLASS_SERIAL, + .of_match = npcm_serial_ids, + .plat_auto = sizeof(struct npcm_serial_plat), + .probe = npcm_serial_probe, + .ops = &npcm_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +};

On Tue, Apr 19, 2022 at 01:32:21PM +0800, Jim Liu wrote:
Add Nuvoton BMC NPCM7xx/NPCM8xx uart driver
Signed-off-by: Jim Liu JJLIU0@nuvoton.com Signed-off-by: Stanley Chu yschu@nuvoton.com
Applied to u-boot/master, thanks!

Add Nuvoton BMC NPCM7xx/NPCM8xx timer driver.
Signed-off-by: Jim Liu JJLIU0@nuvoton.com Signed-off-by: Stanley Chu yschu@nuvoton.com --- Changes for v3: - no changes since v2 Changes for v2: - coding style cleanup --- drivers/timer/Kconfig | 9 +++ drivers/timer/Makefile | 1 + drivers/timer/npcm-timer.c | 115 +++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 drivers/timer/npcm-timer.c
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 8fad59b81a..4d538a6892 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -151,6 +151,15 @@ config NOMADIK_MTU_TIMER The MTU provides 4 decrementing free-running timers. At the moment, only the first timer is used by the driver.
+config NPCM_TIMER + bool "Nuvoton NPCM timer support" + depends on TIMER + help + Select this to enable a timer on Nuvoton NPCM SoCs. + NPCM timer module has 5 down-counting timers, only the first timer + is used to implement timer ops. No support for early timer and + boot timer. + config OMAP_TIMER bool "Omap timer support" depends on TIMER diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index 58da6c1e84..6d7558cc56 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o obj-$(CONFIG_NOMADIK_MTU_TIMER) += nomadik-mtu-timer.o +obj-$(CONFIG_NPCM_TIMER) += npcm-timer.o obj-$(CONFIG_OMAP_TIMER) += omap-timer.o obj-$(CONFIG_RENESAS_OSTM_TIMER) += ostm_timer.o obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o diff --git a/drivers/timer/npcm-timer.c b/drivers/timer/npcm-timer.c new file mode 100644 index 0000000000..4562a6f231 --- /dev/null +++ b/drivers/timer/npcm-timer.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Nuvoton Technology Corp. + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <timer.h> +#include <asm/io.h> + +#define NPCM_TIMER_CLOCK_RATE 1000000UL /* 1MHz timer */ +#define NPCM_TIMER_INPUT_RATE 25000000UL /* Rate of input clock */ +#define NPCM_TIMER_TDR_MASK GENMASK(23, 0) +#define NPCM_TIMER_MAX_VAL NPCM_TIMER_TDR_MASK /* max counter value */ + +/* Register offsets */ +#define TCR0 0x0 /* Timer Control and Status Register */ +#define TICR0 0x8 /* Timer Initial Count Register */ +#define TDR0 0x10 /* Timer Data Register */ + +/* TCR fields */ +#define TCR_MODE_PERIODIC BIT(27) +#define TCR_EN BIT(30) +#define TCR_PRESCALE (NPCM_TIMER_INPUT_RATE / NPCM_TIMER_CLOCK_RATE - 1) + +enum input_clock_type { + INPUT_CLOCK_FIXED, /* input clock rate is fixed */ + INPUT_CLOCK_NON_FIXED +}; + +/** + * struct npcm_timer_priv - private data for npcm timer driver + * npcm timer is a 24-bits down-counting timer. + * + * @last_count: last hw counter value + * @counter: the value to be returned for get_count ops + */ +struct npcm_timer_priv { + void __iomem *base; + u32 last_count; + u64 counter; +}; + +static u64 npcm_timer_get_count(struct udevice *dev) +{ + struct npcm_timer_priv *priv = dev_get_priv(dev); + u32 val; + + /* The timer is counting down */ + val = readl(priv->base + TDR0) & NPCM_TIMER_TDR_MASK; + if (val <= priv->last_count) + priv->counter += priv->last_count - val; + else + priv->counter += priv->last_count + (NPCM_TIMER_MAX_VAL + 1 - val); + priv->last_count = val; + + return priv->counter; +} + +static int npcm_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct npcm_timer_priv *priv = dev_get_priv(dev); + enum input_clock_type type = dev_get_driver_data(dev); + struct clk clk; + int ret; + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -EINVAL; + uc_priv->clock_rate = NPCM_TIMER_CLOCK_RATE; + + if (type == INPUT_CLOCK_NON_FIXED) { + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_set_rate(&clk, NPCM_TIMER_INPUT_RATE); + if (ret < 0) + return ret; + } + + /* + * Configure timer and start + * periodic mode + * timer clock rate = input clock / prescale + */ + writel(0, priv->base + TCR0); + writel(NPCM_TIMER_MAX_VAL, priv->base + TICR0); + writel(TCR_EN | TCR_MODE_PERIODIC | TCR_PRESCALE, + priv->base + TCR0); + + return 0; +} + +static const struct timer_ops npcm_timer_ops = { + .get_count = npcm_timer_get_count, +}; + +static const struct udevice_id npcm_timer_ids[] = { + { .compatible = "nuvoton,npcm845-timer", .data = INPUT_CLOCK_FIXED}, + { .compatible = "nuvoton,npcm750-timer", .data = INPUT_CLOCK_NON_FIXED}, + {} +}; + +U_BOOT_DRIVER(npcm_timer) = { + .name = "npcm_timer", + .id = UCLASS_TIMER, + .of_match = npcm_timer_ids, + .priv_auto = sizeof(struct npcm_timer_priv), + .probe = npcm_timer_probe, + .ops = &npcm_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +};

On Tue, Apr 19, 2022 at 01:32:22PM +0800, Jim Liu wrote:
Add Nuvoton BMC NPCM7xx/NPCM8xx timer driver.
Signed-off-by: Jim Liu JJLIU0@nuvoton.com Signed-off-by: Stanley Chu yschu@nuvoton.com
Applied to u-boot/master, thanks!
participants (3)
-
Jim Liu
-
Sean Anderson
-
Tom Rini