mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-16 23:07:00 +00:00
Merge branch '2022-05-05-platform-updates'
- Nuvoton NPCM750 board support and some related drivers - MediaTek pinctrl updates - Bugfixes for sandbox, ls10xxx, and 64bit TI platforms
This commit is contained in:
commit
ae242b2ea6
48 changed files with 3562 additions and 72 deletions
4
Kconfig
4
Kconfig
|
@ -257,9 +257,7 @@ config SYS_MALLOC_F_LEN
|
|||
default 0x4000 if SANDBOX || RISCV || ARCH_APPLE || ROCKCHIP_RK3368 || \
|
||||
ROCKCHIP_RK3399
|
||||
default 0x8000 if RCAR_GEN3
|
||||
default 0x10000 if ARCH_IMX8 || (ARCH_IMX8M && !IMX8MQ) || \
|
||||
ARCH_LS1012A || ARCH_LS1021A || ARCH_LS1043A || \
|
||||
ARCH_LS1046A
|
||||
default 0x10000 if ARCH_IMX8 || (ARCH_IMX8M && !IMX8MQ)
|
||||
default 0x2000
|
||||
help
|
||||
Before relocation, memory is very limited on many platforms. Still,
|
||||
|
|
|
@ -1004,6 +1004,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
|
||||
|
@ -2279,6 +2285,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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1184,6 +1184,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
|
||||
|
|
1120
arch/arm/dts/nuvoton-common-npcm7xx.dtsi
Normal file
1120
arch/arm/dts/nuvoton-common-npcm7xx.dtsi
Normal file
File diff suppressed because it is too large
Load diff
405
arch/arm/dts/nuvoton-npcm750-evb.dts
Normal file
405
arch/arm/dts/nuvoton-npcm750-evb.dts
Normal file
|
@ -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>;
|
||||
};
|
||||
|
157
arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi
Normal file
157
arch/arm/dts/nuvoton-npcm750-pincfg-evb.dtsi
Normal file
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
62
arch/arm/dts/nuvoton-npcm750.dtsi
Normal file
62
arch/arm/dts/nuvoton-npcm750.dtsi
Normal file
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
65
arch/arm/include/asm/arch-npcm7xx/gcr.h
Normal file
65
arch/arm/include/asm/arch-npcm7xx/gcr.h
Normal file
|
@ -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
|
26
arch/arm/mach-npcm/Kconfig
Normal file
26
arch/arm/mach-npcm/Kconfig
Normal file
|
@ -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
|
1
arch/arm/mach-npcm/Makefile
Normal file
1
arch/arm/mach-npcm/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_ARCH_NPCM7xx) += npcm7xx/
|
22
arch/arm/mach-npcm/npcm7xx/Kconfig
Normal file
22
arch/arm/mach-npcm/npcm7xx/Kconfig
Normal file
|
@ -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
|
1
arch/arm/mach-npcm/npcm7xx/Makefile
Normal file
1
arch/arm/mach-npcm/npcm7xx/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_TARGET_POLEG) += cpu.o l2_cache_pl310_init.o l2_cache_pl310.o
|
66
arch/arm/mach-npcm/npcm7xx/cpu.c
Normal file
66
arch/arm/mach-npcm/npcm7xx/cpu.c
Normal file
|
@ -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();
|
||||
}
|
29
arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c
Normal file
29
arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c
Normal file
|
@ -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);
|
||||
}
|
71
arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S
Normal file
71
arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S
Normal file
|
@ -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
|
|
@ -291,6 +291,31 @@ void invalidate_dcache_range(unsigned long start, unsigned long stop)
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* setup_auto_tree() - Set up a basic device tree to allow sandbox to work
|
||||
*
|
||||
* This is used when no device tree is provided. It creates a simple tree with
|
||||
* just a /binman node.
|
||||
*
|
||||
* @blob: Place to put the created device tree
|
||||
* Returns: 0 on success, -ve FDT error code on failure
|
||||
*/
|
||||
static int setup_auto_tree(void *blob)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fdt_create_empty_tree(blob, 256);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Create a /binman node in case CONFIG_BINMAN is enabled */
|
||||
err = fdt_add_subnode(blob, 0, "binman");
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *board_fdt_blob_setup(int *ret)
|
||||
{
|
||||
struct sandbox_state *state = state_get_current();
|
||||
|
@ -303,7 +328,7 @@ void *board_fdt_blob_setup(int *ret)
|
|||
blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
|
||||
*ret = 0;
|
||||
if (!state->fdt_fname) {
|
||||
err = fdt_create_empty_tree(blob, 256);
|
||||
err = setup_auto_tree(blob);
|
||||
if (!err)
|
||||
goto done;
|
||||
printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
|
||||
|
|
25
board/nuvoton/poleg_evb/Kconfig
Normal file
25
board/nuvoton/poleg_evb/Kconfig
Normal file
|
@ -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
|
7
board/nuvoton/poleg_evb/MAINTAINERS
Normal file
7
board/nuvoton/poleg_evb/MAINTAINERS
Normal file
|
@ -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
|
1
board/nuvoton/poleg_evb/Makefile
Normal file
1
board/nuvoton/poleg_evb/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
obj-y := poleg_evb.o
|
48
board/nuvoton/poleg_evb/poleg_evb.c
Normal file
48
board/nuvoton/poleg_evb/poleg_evb.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
DEVELOPER BOX
|
||||
M: Masami Hiramatsu <masami.hiramatsu@linaro.org>
|
||||
M: Jassi Brar <jaswinder.singh@linaro.org>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/synquacer-*
|
||||
|
|
40
configs/poleg_evb_defconfig
Normal file
40
configs/poleg_evb_defconfig
Normal file
|
@ -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
|
|
@ -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/
|
||||
|
|
2
drivers/clk/nuvoton/Makefile
Normal file
2
drivers/clk/nuvoton/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_ARCH_NPCM) += clk_npcm.o
|
||||
obj-$(CONFIG_ARCH_NPCM7xx) += clk_npcm7xx.o
|
299
drivers/clk/nuvoton/clk_npcm.c
Normal file
299
drivers/clk/nuvoton/clk_npcm.c
Normal file
|
@ -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,
|
||||
};
|
105
drivers/clk/nuvoton/clk_npcm.h
Normal file
105
drivers/clk/nuvoton/clk_npcm.h
Normal file
|
@ -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
|
95
drivers/clk/nuvoton/clk_npcm7xx.c
Normal file
95
drivers/clk/nuvoton/clk_npcm7xx.c
Normal file
|
@ -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,
|
||||
};
|
|
@ -279,6 +279,13 @@ config MXS_GPIO
|
|||
help
|
||||
Support GPIO controllers on i.MX23 and i.MX28 platforms
|
||||
|
||||
config NPCM_GPIO
|
||||
bool "Nuvoton NPCM GPIO driver"
|
||||
depends on DM_GPIO
|
||||
help
|
||||
Support GPIO controllers on Nuvovon NPCM SoCs.
|
||||
NPCM7xx/NPCM8xx contain 8 GPIO banks, each bank contains 32 pins.
|
||||
|
||||
config OMAP_GPIO
|
||||
bool "TI OMAP GPIO driver"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
|
|
|
@ -28,6 +28,7 @@ obj-$(CONFIG_MARVELL_GPIO) += mvgpio.o
|
|||
obj-$(CONFIG_MCP230XX_GPIO) += mcp230xx_gpio.o
|
||||
obj-$(CONFIG_MXC_GPIO) += mxc_gpio.o
|
||||
obj-$(CONFIG_MXS_GPIO) += mxs_gpio.o
|
||||
obj-$(CONFIG_NPCM_GPIO) += npcm_gpio.o
|
||||
obj-$(CONFIG_PCA953X) += pca953x.o
|
||||
obj-$(CONFIG_PCA9698) += pca9698.o
|
||||
obj-$(CONFIG_ROCKCHIP_GPIO) += rk_gpio.o
|
||||
|
|
123
drivers/gpio/npcm_gpio.c
Normal file
123
drivers/gpio/npcm_gpio.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2022 Nuvoton Technology Corp.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define NPCM_GPIOS_PER_BANK 32
|
||||
|
||||
/* Register offsets */
|
||||
#define GPIO_DIN 0x4 /* RO - Data In */
|
||||
#define GPIO_DOUT 0xC /* RW - Data Out */
|
||||
#define GPIO_OE 0x10 /* RW - Output Enable */
|
||||
#define GPIO_IEM 0x58 /* RW - Input Enable Mask */
|
||||
#define GPIO_OES 0x70 /* WO - Output Enable Register Set */
|
||||
#define GPIO_OEC 0x74 /* WO - Output Enable Register Clear */
|
||||
|
||||
struct npcm_gpio_priv {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static int npcm_gpio_direction_input(struct udevice *dev, unsigned int offset)
|
||||
{
|
||||
struct npcm_gpio_priv *priv = dev_get_priv(dev);
|
||||
|
||||
writel(BIT(offset), priv->base + GPIO_OEC);
|
||||
setbits_le32(priv->base + GPIO_IEM, BIT(offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int npcm_gpio_direction_output(struct udevice *dev, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct npcm_gpio_priv *priv = dev_get_priv(dev);
|
||||
|
||||
clrbits_le32(priv->base + GPIO_IEM, BIT(offset));
|
||||
writel(BIT(offset), priv->base + GPIO_OES);
|
||||
|
||||
if (value)
|
||||
setbits_le32(priv->base + GPIO_DOUT, BIT(offset));
|
||||
else
|
||||
clrbits_le32(priv->base + GPIO_DOUT, BIT(offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int npcm_gpio_get_value(struct udevice *dev, unsigned int offset)
|
||||
{
|
||||
struct npcm_gpio_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (readl(priv->base + GPIO_IEM) & BIT(offset))
|
||||
return !!(readl(priv->base + GPIO_DIN) & BIT(offset));
|
||||
|
||||
if (readl(priv->base + GPIO_OE) & BIT(offset))
|
||||
return !!(readl(priv->base + GPIO_DOUT) & BIT(offset));
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int npcm_gpio_set_value(struct udevice *dev, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct npcm_gpio_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (value)
|
||||
setbits_le32(priv->base + GPIO_DOUT, BIT(offset));
|
||||
else
|
||||
clrbits_le32(priv->base + GPIO_DOUT, BIT(offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int npcm_gpio_get_function(struct udevice *dev, unsigned int offset)
|
||||
{
|
||||
struct npcm_gpio_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (readl(priv->base + GPIO_IEM) & BIT(offset))
|
||||
return GPIOF_INPUT;
|
||||
|
||||
if (readl(priv->base + GPIO_OE) & BIT(offset))
|
||||
return GPIOF_OUTPUT;
|
||||
|
||||
return GPIOF_FUNC;
|
||||
}
|
||||
|
||||
static const struct dm_gpio_ops npcm_gpio_ops = {
|
||||
.direction_input = npcm_gpio_direction_input,
|
||||
.direction_output = npcm_gpio_direction_output,
|
||||
.get_value = npcm_gpio_get_value,
|
||||
.set_value = npcm_gpio_set_value,
|
||||
.get_function = npcm_gpio_get_function,
|
||||
};
|
||||
|
||||
static int npcm_gpio_probe(struct udevice *dev)
|
||||
{
|
||||
struct npcm_gpio_priv *priv = dev_get_priv(dev);
|
||||
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
uc_priv->gpio_count = NPCM_GPIOS_PER_BANK;
|
||||
uc_priv->bank_name = dev->name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id npcm_gpio_match[] = {
|
||||
{ .compatible = "nuvoton,npcm845-gpio" },
|
||||
{ .compatible = "nuvoton,npcm750-gpio" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(npcm_gpio) = {
|
||||
.name = "npcm_gpio",
|
||||
.id = UCLASS_GPIO,
|
||||
.of_match = npcm_gpio_match,
|
||||
.probe = npcm_gpio_probe,
|
||||
.priv_auto = sizeof(struct npcm_gpio_priv),
|
||||
.ops = &npcm_gpio_ops,
|
||||
};
|
|
@ -45,18 +45,18 @@ static const struct mtk_drive_desc mtk_drive[] = {
|
|||
|
||||
static const char *mtk_pinctrl_dummy_name = "_dummy";
|
||||
|
||||
static void mtk_w32(struct udevice *dev, u32 reg, u32 val)
|
||||
static void mtk_w32(struct udevice *dev, u8 i, u32 reg, u32 val)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
__raw_writel(val, priv->base + reg);
|
||||
__raw_writel(val, priv->base[i] + reg);
|
||||
}
|
||||
|
||||
static u32 mtk_r32(struct udevice *dev, u32 reg)
|
||||
static u32 mtk_r32(struct udevice *dev, u8 i, u32 reg)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return __raw_readl(priv->base + reg);
|
||||
return __raw_readl(priv->base[i] + reg);
|
||||
}
|
||||
|
||||
static inline int get_count_order(unsigned int count)
|
||||
|
@ -70,21 +70,28 @@ static inline int get_count_order(unsigned int count)
|
|||
}
|
||||
|
||||
void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
return mtk_i_rmw(dev, 0, reg, mask, set);
|
||||
}
|
||||
|
||||
void mtk_i_rmw(struct udevice *dev, u8 i, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = mtk_r32(dev, reg);
|
||||
val = mtk_r32(dev, i, reg);
|
||||
val &= ~mask;
|
||||
val |= set;
|
||||
mtk_w32(dev, reg, val);
|
||||
mtk_w32(dev, i, reg, val);
|
||||
}
|
||||
|
||||
static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
|
||||
const struct mtk_pin_reg_calc *rc,
|
||||
struct mtk_pin_field *pfd)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct mtk_pin_field_calc *c, *e;
|
||||
u32 bits;
|
||||
u32 base_calc = priv->soc->base_calc;
|
||||
|
||||
c = rc->range;
|
||||
e = c + rc->nranges;
|
||||
|
@ -111,6 +118,11 @@ static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
|
|||
pfd->bitpos = bits % c->sz_reg;
|
||||
pfd->mask = (1 << c->x_bits) - 1;
|
||||
|
||||
if (base_calc)
|
||||
pfd->index = c->i_base;
|
||||
else
|
||||
pfd->index = 0;
|
||||
|
||||
/* pfd->next is used for indicating that bit wrapping-around happens
|
||||
* which requires the manipulation for bit 0 starting in the next
|
||||
* register to form the complete field read/write.
|
||||
|
@ -150,10 +162,10 @@ static void mtk_hw_write_cross_field(struct udevice *dev,
|
|||
|
||||
mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
|
||||
|
||||
mtk_rmw(dev, pf->offset, pf->mask << pf->bitpos,
|
||||
mtk_i_rmw(dev, pf->index, pf->offset, pf->mask << pf->bitpos,
|
||||
(value & pf->mask) << pf->bitpos);
|
||||
|
||||
mtk_rmw(dev, pf->offset + pf->next, BIT(nbits_h) - 1,
|
||||
mtk_i_rmw(dev, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
|
||||
(value & pf->mask) >> nbits_l);
|
||||
}
|
||||
|
||||
|
@ -164,8 +176,8 @@ static void mtk_hw_read_cross_field(struct udevice *dev,
|
|||
|
||||
mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
|
||||
|
||||
l = (mtk_r32(dev, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
|
||||
h = (mtk_r32(dev, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
|
||||
l = (mtk_r32(dev, pf->index, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
|
||||
h = (mtk_r32(dev, pf->index, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
|
||||
|
||||
*value = (h << nbits_l) | l;
|
||||
}
|
||||
|
@ -181,7 +193,7 @@ static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
|
|||
return err;
|
||||
|
||||
if (!pf.next)
|
||||
mtk_rmw(dev, pf.offset, pf.mask << pf.bitpos,
|
||||
mtk_i_rmw(dev, pf.index, pf.offset, pf.mask << pf.bitpos,
|
||||
(value & pf.mask) << pf.bitpos);
|
||||
else
|
||||
mtk_hw_write_cross_field(dev, &pf, value);
|
||||
|
@ -200,13 +212,32 @@ static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
|
|||
return err;
|
||||
|
||||
if (!pf.next)
|
||||
*value = (mtk_r32(dev, pf.offset) >> pf.bitpos) & pf.mask;
|
||||
*value = (mtk_r32(dev, pf.index, pf.offset) >> pf.bitpos) & pf.mask;
|
||||
else
|
||||
mtk_hw_read_cross_field(dev, &pf, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
static int mtk_get_pin_io_type(struct udevice *dev, int pin,
|
||||
struct mtk_io_type_desc *io_type)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
u8 io_n = priv->soc->pins[pin].io_n;
|
||||
|
||||
if (io_n >= priv->soc->ntype)
|
||||
return -EINVAL;
|
||||
|
||||
io_type->name = priv->soc->io_type[io_n].name;
|
||||
io_type->bias_set = priv->soc->io_type[io_n].bias_set;
|
||||
io_type->drive_set = priv->soc->io_type[io_n].drive_set;
|
||||
io_type->input_enable = priv->soc->io_type[io_n].input_enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mtk_get_groups_count(struct udevice *dev)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
@ -236,7 +267,6 @@ static int mtk_get_pin_muxing(struct udevice *dev, unsigned int selector,
|
|||
char *buf, int size)
|
||||
{
|
||||
int val, err;
|
||||
|
||||
err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -308,13 +338,31 @@ static const struct pinconf_param mtk_conf_params[] = {
|
|||
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
|
||||
};
|
||||
|
||||
|
||||
int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
||||
int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val)
|
||||
{
|
||||
int err, disable, pullup;
|
||||
return mtk_pinconf_bias_set_pu_pd(dev, pin, disable, pullup, val);
|
||||
}
|
||||
|
||||
disable = (arg == PIN_CONFIG_BIAS_DISABLE);
|
||||
pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
|
||||
int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* try pupd_r1_r0 if pullen_pullsel return error */
|
||||
err = mtk_pinconf_bias_set_pullen_pullsel(dev, pin, disable, pullup,
|
||||
val);
|
||||
if (err)
|
||||
return mtk_pinconf_bias_set_pupd_r1_r0(dev, pin, disable,
|
||||
pullup, val);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_set_pu_pd(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (disable) {
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, 0);
|
||||
|
@ -323,7 +371,6 @@ int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
|||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
} else {
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, pullup);
|
||||
if (err)
|
||||
|
@ -336,14 +383,10 @@ int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
||||
int mtk_pinconf_bias_set_pullen_pullsel(struct udevice *dev, u32 pin,
|
||||
bool disable, bool pullup, u32 val)
|
||||
{
|
||||
int err, disable, pullup, r0, r1;
|
||||
|
||||
disable = (arg == PIN_CONFIG_BIAS_DISABLE);
|
||||
pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
|
||||
r0 = !!(val & 1);
|
||||
r1 = !!(val & 2);
|
||||
int err;
|
||||
|
||||
if (disable) {
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 0);
|
||||
|
@ -359,16 +402,62 @@ int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* Also set PUPD/R0/R1 if the pin has them */
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PUPD, !pullup);
|
||||
if (err != -EINVAL) {
|
||||
mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R0, r0);
|
||||
mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R1, r1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_set_pupd_r1_r0(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val)
|
||||
{
|
||||
int err, r0, r1;
|
||||
|
||||
r0 = !!(val & 1);
|
||||
r1 = !!(val & 2);
|
||||
|
||||
if (disable) {
|
||||
pullup = 0;
|
||||
r0 = 0;
|
||||
r1 = 0;
|
||||
}
|
||||
|
||||
/* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PUPD, !pullup);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Also set PUPD/R0/R1 if the pin has them */
|
||||
mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R0, r0);
|
||||
mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R1, r1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_set(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
||||
{
|
||||
int err;
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct mtk_io_type_desc io_type;
|
||||
int rev = priv->soc->rev;
|
||||
bool disable, pullup;
|
||||
|
||||
disable = (arg == PIN_CONFIG_BIAS_DISABLE);
|
||||
pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
|
||||
|
||||
if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
|
||||
if (io_type.bias_set)
|
||||
err = io_type.bias_set(dev, pin, disable, pullup,
|
||||
val);
|
||||
else
|
||||
err = -EINVAL;
|
||||
|
||||
} else if (rev == MTK_PINCTRL_V0) {
|
||||
err = mtk_pinconf_bias_set_v0(dev, pin, disable, pullup, val);
|
||||
} else {
|
||||
err = mtk_pinconf_bias_set_v1(dev, pin, disable, pullup, val);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg)
|
||||
{
|
||||
int err;
|
||||
|
@ -379,6 +468,23 @@ int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg)
|
|||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinconf_input_enable(struct udevice *dev, u32 pin, u32 arg)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct mtk_io_type_desc io_type;
|
||||
|
||||
int rev = priv->soc->rev;
|
||||
|
||||
if (!mtk_get_pin_io_type(dev, pin, &io_type))
|
||||
if (io_type.input_enable)
|
||||
return io_type.input_enable(dev, pin, arg);
|
||||
if (rev == MTK_PINCTRL_V1)
|
||||
return mtk_pinconf_input_enable_v1(dev, pin, arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -410,7 +516,6 @@ int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, u32 arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
@ -429,21 +534,37 @@ int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
|
||||
{
|
||||
int err;
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct mtk_io_type_desc io_type;
|
||||
int rev = priv->soc->rev;
|
||||
|
||||
if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
|
||||
if (io_type.drive_set)
|
||||
err = io_type.drive_set(dev, pin, arg);
|
||||
else
|
||||
err = -EINVAL;
|
||||
} else if (rev == MTK_PINCTRL_V0) {
|
||||
err = mtk_pinconf_drive_set_v0(dev, pin, arg);
|
||||
} else {
|
||||
err = mtk_pinconf_drive_set_v1(dev, pin, arg);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
|
||||
unsigned int param, unsigned int arg)
|
||||
{
|
||||
int err = 0;
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
int rev = priv->soc->rev;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (rev == MTK_PINCTRL_V0)
|
||||
err = mtk_pinconf_bias_set_v0(dev, pin, param, arg);
|
||||
else
|
||||
err = mtk_pinconf_bias_set_v1(dev, pin, param, arg);
|
||||
err = mtk_pinconf_bias_set(dev, pin, param, arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
|
@ -456,8 +577,7 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
|
|||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
if (rev == MTK_PINCTRL_V1)
|
||||
err = mtk_pinconf_input_enable_v1(dev, pin, param);
|
||||
err = mtk_pinconf_input_enable(dev, pin, param);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
|
@ -486,10 +606,7 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
|
|||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
if (rev == MTK_PINCTRL_V0)
|
||||
err = mtk_pinconf_drive_set_v0(dev, pin, arg);
|
||||
else
|
||||
err = mtk_pinconf_drive_set_v1(dev, pin, arg);
|
||||
err = mtk_pinconf_drive_set(dev, pin, arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
|
@ -656,13 +773,23 @@ int mtk_pinctrl_common_probe(struct udevice *dev,
|
|||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
int ret = 0;
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (!priv->base)
|
||||
return -EINVAL;
|
||||
u32 i = 0;
|
||||
fdt_addr_t addr;
|
||||
u32 base_calc = soc->base_calc;
|
||||
u32 nbase_names = soc->nbase_names;
|
||||
|
||||
priv->soc = soc;
|
||||
|
||||
if (!base_calc)
|
||||
nbase_names = 1;
|
||||
|
||||
for (i = 0; i < nbase_names; i++) {
|
||||
addr = devfdt_get_addr_index(dev, i);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
priv->base[i] = (void __iomem *)addr;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_GPIO) || \
|
||||
(defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
|
||||
ret = mtk_gpiochip_register(dev);
|
||||
|
|
|
@ -8,12 +8,19 @@
|
|||
|
||||
#define MTK_PINCTRL_V0 0x0
|
||||
#define MTK_PINCTRL_V1 0x1
|
||||
#define BASE_CALC_NONE 0
|
||||
#define MAX_BASE_CALC 10
|
||||
|
||||
#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
|
||||
#define MTK_PIN(_number, _name, _drv_n) { \
|
||||
|
||||
#define MTK_PIN(_number, _name, _drv_n) \
|
||||
MTK_TYPED_PIN(_number, _name, _drv_n, IO_TYPE_DEFAULT)
|
||||
|
||||
#define MTK_TYPED_PIN(_number, _name, _drv_n, _io_n) { \
|
||||
.number = _number, \
|
||||
.name = _name, \
|
||||
.drv_n = _drv_n, \
|
||||
.io_n = _io_n, \
|
||||
}
|
||||
|
||||
#define PINCTRL_PIN_GROUP(name, id) \
|
||||
|
@ -24,10 +31,11 @@
|
|||
id##_funcs, \
|
||||
}
|
||||
|
||||
#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
|
||||
_x_bits, _sz_reg, _fixed) { \
|
||||
#define PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, \
|
||||
_s_bit, _x_bits, _sz_reg, _fixed) { \
|
||||
.s_pin = _s_pin, \
|
||||
.e_pin = _e_pin, \
|
||||
.i_base = _i_base, \
|
||||
.s_addr = _s_addr, \
|
||||
.x_addrs = _x_addrs, \
|
||||
.s_bit = _s_bit, \
|
||||
|
@ -36,6 +44,11 @@
|
|||
.fixed = _fixed, \
|
||||
}
|
||||
|
||||
#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
|
||||
_x_bits, _sz_reg, _fixed) \
|
||||
PIN_FIELD_BASE_CALC(_s_pin, _e_pin, BASE_CALC_NONE, _s_addr, \
|
||||
_x_addrs, _s_bit, _x_bits, _sz_reg, _fixed)
|
||||
|
||||
/* List these attributes which could be modified for the pin */
|
||||
enum {
|
||||
PINCTRL_PIN_REG_MODE,
|
||||
|
@ -67,9 +80,22 @@ enum {
|
|||
DRV_GRP4,
|
||||
};
|
||||
|
||||
/* Group the pins by the io type */
|
||||
enum {
|
||||
IO_TYPE_DEFAULT,
|
||||
IO_TYPE_GRP0,
|
||||
IO_TYPE_GRP1,
|
||||
IO_TYPE_GRP2,
|
||||
IO_TYPE_GRP3,
|
||||
IO_TYPE_GRP4,
|
||||
IO_TYPE_GRP5,
|
||||
IO_TYPE_GRP6,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_pin_field - the structure that holds the information of the field
|
||||
* used to describe the attribute for the pin
|
||||
* @index: the index pointing to the entry in base address list
|
||||
* @offset: the register offset relative to the base address
|
||||
* @mask: the mask used to filter out the field from the register
|
||||
* @bitpos: the start bit relative to the register
|
||||
|
@ -77,6 +103,7 @@ enum {
|
|||
next register
|
||||
*/
|
||||
struct mtk_pin_field {
|
||||
u8 index;
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u8 bitpos;
|
||||
|
@ -88,6 +115,7 @@ struct mtk_pin_field {
|
|||
* the guide used to look up the relevant field
|
||||
* @s_pin: the start pin within the range
|
||||
* @e_pin: the end pin within the range
|
||||
* @i_base: the index pointing to the entry in base address list
|
||||
* @s_addr: the start address for the range
|
||||
* @x_addrs: the address distance between two consecutive registers
|
||||
* within the range
|
||||
|
@ -101,6 +129,7 @@ struct mtk_pin_field {
|
|||
struct mtk_pin_field_calc {
|
||||
u16 s_pin;
|
||||
u16 e_pin;
|
||||
u8 i_base;
|
||||
u32 s_addr;
|
||||
u8 x_addrs;
|
||||
u8 s_bit;
|
||||
|
@ -127,11 +156,13 @@ struct mtk_pin_reg_calc {
|
|||
* @number: unique pin number from the global pin number space
|
||||
* @name: name for this pin
|
||||
* @drv_n: the index with the driving group
|
||||
* @io_n: the index with the io type
|
||||
*/
|
||||
struct mtk_pin_desc {
|
||||
unsigned int number;
|
||||
const char *name;
|
||||
u8 drv_n;
|
||||
u8 io_n;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -160,6 +191,21 @@ struct mtk_function_desc {
|
|||
int num_group_names;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_io_type_desc - io class descriptor for specific pins
|
||||
* @name: name of the io class
|
||||
*/
|
||||
struct mtk_io_type_desc {
|
||||
const char *name;
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
/* Specific pinconfig operations */
|
||||
int (*bias_set)(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val);
|
||||
int (*drive_set)(struct udevice *dev, u32 pin, u32 arg);
|
||||
int (*input_enable)(struct udevice *dev, u32 pin, u32 arg);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* struct mtk_pin_soc - the structure that holds SoC-specific data */
|
||||
struct mtk_pinctrl_soc {
|
||||
const char *name;
|
||||
|
@ -170,8 +216,13 @@ struct mtk_pinctrl_soc {
|
|||
int ngrps;
|
||||
const struct mtk_function_desc *funcs;
|
||||
int nfuncs;
|
||||
const struct mtk_io_type_desc *io_type;
|
||||
u8 ntype;
|
||||
int gpio_mode;
|
||||
const char * const *base_names;
|
||||
unsigned int nbase_names;
|
||||
int rev;
|
||||
int base_calc;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -181,7 +232,7 @@ struct mtk_pinctrl_soc {
|
|||
* @soc: SoC specific data
|
||||
*/
|
||||
struct mtk_pinctrl_priv {
|
||||
void __iomem *base;
|
||||
void __iomem *base[MAX_BASE_CALC];
|
||||
struct mtk_pinctrl_soc *soc;
|
||||
};
|
||||
|
||||
|
@ -189,7 +240,26 @@ extern const struct pinctrl_ops mtk_pinctrl_ops;
|
|||
|
||||
/* A common read-modify-write helper for MediaTek chips */
|
||||
void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set);
|
||||
void mtk_i_rmw(struct udevice *dev, u8 i, u32 reg, u32 mask, u32 set);
|
||||
int mtk_pinctrl_common_probe(struct udevice *dev,
|
||||
struct mtk_pinctrl_soc *soc);
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
|
||||
int mtk_pinconf_bias_set_pu_pd(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val);
|
||||
int mtk_pinconf_bias_set_pullen_pullsel(struct udevice *dev, u32 pin,
|
||||
bool disable, bool pullup, u32 val);
|
||||
int mtk_pinconf_bias_set_pupd_r1_r0(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val);
|
||||
int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val);
|
||||
int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val);
|
||||
int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg);
|
||||
int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, u32 arg);
|
||||
int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __PINCTRL_MEDIATEK_H__ */
|
||||
|
|
|
@ -1016,6 +1016,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
|
||||
|
|
|
@ -66,6 +66,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
|
||||
|
|
157
drivers/serial/serial_npcm.c
Normal file
157
drivers/serial/serial_npcm.c
Normal file
|
@ -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,
|
||||
};
|
|
@ -172,6 +172,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
|
||||
|
|
|
@ -14,6 +14,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
|
||||
|
|
115
drivers/timer/npcm-timer.c
Normal file
115
drivers/timer/npcm-timer.c
Normal file
|
@ -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,
|
||||
};
|
|
@ -24,8 +24,7 @@
|
|||
|
||||
#define CONFIG_SPL_MAX_SIZE CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE
|
||||
#if defined(CONFIG_TARGET_AM642_A53_EVM)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \
|
||||
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE - 4)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
|
||||
#else
|
||||
/*
|
||||
* Maximum size in memory allocated to the SPL BSS. Keep it as tight as
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
/* SPL Loader Configuration */
|
||||
#ifdef CONFIG_TARGET_AM654_A53_EVM
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \
|
||||
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
|
||||
#else
|
||||
/*
|
||||
* Maximum size in memory allocated to the SPL BSS. Keep it as tight as
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
|
||||
/* SPL Loader Configuration */
|
||||
#if defined(CONFIG_TARGET_J721E_A72_EVM) || defined(CONFIG_TARGET_J7200_A72_EVM)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \
|
||||
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
|
||||
#define CONFIG_SYS_UBOOT_BASE 0x50280000
|
||||
/* Image load address in RAM for DFU boot*/
|
||||
#else
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
|
||||
/* SPL Loader Configuration */
|
||||
#if defined(CONFIG_TARGET_J721S2_A72_EVM) || defined(CONFIG_TARGET_J7200_A72_EVM)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \
|
||||
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
|
||||
#define CONFIG_SYS_UBOOT_BASE 0x50280000
|
||||
/* Image load address in RAM for DFU boot*/
|
||||
#else
|
||||
|
|
44
include/configs/poleg.h
Normal file
44
include/configs/poleg.h
Normal file
|
@ -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
|
46
include/dt-bindings/clock/nuvoton,npcm7xx-clock.h
Normal file
46
include/dt-bindings/clock/nuvoton,npcm7xx-clock.h
Normal file
|
@ -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
|
||||
|
91
include/dt-bindings/reset/nuvoton,npcm7xx-reset.h
Normal file
91
include/dt-bindings/reset/nuvoton,npcm7xx-reset.h
Normal file
|
@ -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
|
|
@ -9,6 +9,18 @@ def test_help(u_boot_console):
|
|||
|
||||
u_boot_console.run_command('help')
|
||||
|
||||
@pytest.mark.boardspec('sandbox')
|
||||
def test_help_no_devicetree(u_boot_console):
|
||||
try:
|
||||
cons = u_boot_console
|
||||
cons.restart_uboot_with_flags([], use_dtb=False)
|
||||
cons.run_command('help')
|
||||
output = cons.get_spawn_output().replace('\r', '')
|
||||
assert 'print command description/usage' in output
|
||||
finally:
|
||||
# Restart afterward to get the normal device tree back
|
||||
u_boot_console.restart_uboot()
|
||||
|
||||
@pytest.mark.boardspec('sandbox_vpl')
|
||||
def test_vpl_help(u_boot_console):
|
||||
try:
|
||||
|
|
|
@ -27,6 +27,7 @@ class ConsoleSandbox(ConsoleBase):
|
|||
|
||||
super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024)
|
||||
self.sandbox_flags = []
|
||||
self.use_dtb = True
|
||||
|
||||
def get_spawn(self):
|
||||
"""Connect to a fresh U-Boot instance.
|
||||
|
@ -53,16 +54,13 @@ class ConsoleSandbox(ConsoleBase):
|
|||
cmd = []
|
||||
if self.config.gdbserver:
|
||||
cmd += ['gdbserver', self.config.gdbserver]
|
||||
cmd += [
|
||||
self.config.build_dir + fname,
|
||||
'-v',
|
||||
'-d',
|
||||
self.config.dtb
|
||||
]
|
||||
cmd += [self.config.build_dir + fname, '-v']
|
||||
if self.use_dtb:
|
||||
cmd += ['-d', self.config.dtb]
|
||||
cmd += self.sandbox_flags
|
||||
return Spawn(cmd, cwd=self.config.source_dir)
|
||||
|
||||
def restart_uboot_with_flags(self, flags, expect_reset=False):
|
||||
def restart_uboot_with_flags(self, flags, expect_reset=False, use_dtb=True):
|
||||
"""Run U-Boot with the given command-line flags
|
||||
|
||||
Args:
|
||||
|
@ -70,6 +68,7 @@ class ConsoleSandbox(ConsoleBase):
|
|||
expect_reset: Boolean indication whether this boot is expected
|
||||
to be reset while the 1st boot process after main boot before
|
||||
prompt. False by default.
|
||||
use_dtb: True to use a device tree file, False to run without one
|
||||
|
||||
Returns:
|
||||
A u_boot_spawn.Spawn object that is attached to U-Boot.
|
||||
|
@ -77,9 +76,11 @@ class ConsoleSandbox(ConsoleBase):
|
|||
|
||||
try:
|
||||
self.sandbox_flags = flags
|
||||
self.use_dtb = use_dtb
|
||||
return self.restart_uboot(expect_reset)
|
||||
finally:
|
||||
self.sandbox_flags = []
|
||||
self.use_dtb = True
|
||||
|
||||
def kill(self, sig):
|
||||
"""Send a specific Unix signal to the sandbox process.
|
||||
|
|
Loading…
Add table
Reference in a new issue