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:
Tom Rini 2022-05-05 14:42:02 -04:00
commit ae242b2ea6
48 changed files with 3562 additions and 72 deletions

View File

@ -257,9 +257,7 @@ config SYS_MALLOC_F_LEN
default 0x4000 if SANDBOX || RISCV || ARCH_APPLE || ROCKCHIP_RK3368 || \ default 0x4000 if SANDBOX || RISCV || ARCH_APPLE || ROCKCHIP_RK3368 || \
ROCKCHIP_RK3399 ROCKCHIP_RK3399
default 0x8000 if RCAR_GEN3 default 0x8000 if RCAR_GEN3
default 0x10000 if ARCH_IMX8 || (ARCH_IMX8M && !IMX8MQ) || \ default 0x10000 if ARCH_IMX8 || (ARCH_IMX8M && !IMX8MQ)
ARCH_LS1012A || ARCH_LS1021A || ARCH_LS1043A || \
ARCH_LS1046A
default 0x2000 default 0x2000
help help
Before relocation, memory is very limited on many platforms. Still, Before relocation, memory is very limited on many platforms. Still,

View File

@ -1004,6 +1004,12 @@ config ARCH_NEXELL
select DM select DM
select GPIO_EXTRA_HEADER select GPIO_EXTRA_HEADER
config ARCH_NPCM
bool "Support Nuvoton SoCs"
select DM
select OF_CONTROL
imply CMD_DM
config ARCH_APPLE config ARCH_APPLE
bool "Apple SoCs" bool "Apple SoCs"
select ARM64 select ARM64
@ -2279,6 +2285,8 @@ source "arch/arm/mach-imx/Kconfig"
source "arch/arm/mach-nexell/Kconfig" source "arch/arm/mach-nexell/Kconfig"
source "arch/arm/mach-npcm/Kconfig"
source "board/armltd/total_compute/Kconfig" source "board/armltd/total_compute/Kconfig"
source "board/bosch/shc/Kconfig" source "board/bosch/shc/Kconfig"

View File

@ -72,6 +72,7 @@ machine-$(CONFIG_ARCH_MEDIATEK) += mediatek
machine-$(CONFIG_ARCH_MESON) += meson machine-$(CONFIG_ARCH_MESON) += meson
machine-$(CONFIG_ARCH_MVEBU) += mvebu machine-$(CONFIG_ARCH_MVEBU) += mvebu
machine-$(CONFIG_ARCH_NEXELL) += nexell machine-$(CONFIG_ARCH_NEXELL) += nexell
machine-$(CONFIG_ARCH_NPCM) += npcm
machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2 machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2
machine-$(CONFIG_ARCH_ORION5X) += orion5x machine-$(CONFIG_ARCH_ORION5X) += orion5x
machine-$(CONFIG_ARCH_OWL) += owl machine-$(CONFIG_ARCH_OWL) += owl

View File

@ -1184,6 +1184,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
mt8516-pumpkin.dtb \ mt8516-pumpkin.dtb \
mt8518-ap1-emmc.dtb mt8518-ap1-emmc.dtb
dtb-$(CONFIG_ARCH_NPCM7xx) += nuvoton-npcm750-evb.dtb
dtb-$(CONFIG_XEN) += xenguest-arm64.dtb dtb-$(CONFIG_XEN) += xenguest-arm64.dtb
dtb-$(CONFIG_ARCH_OCTEONTX) += octeontx.dtb dtb-$(CONFIG_ARCH_OCTEONTX) += octeontx.dtb

File diff suppressed because it is too large Load Diff

View 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>;
};

View 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;
};
};
};

View 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";
};
};
};

View 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

View 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

View File

@ -0,0 +1 @@
obj-$(CONFIG_ARCH_NPCM7xx) += npcm7xx/

View 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

View File

@ -0,0 +1 @@
obj-$(CONFIG_TARGET_POLEG) += cpu.o l2_cache_pl310_init.o l2_cache_pl310.o

View 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();
}

View 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);
}

View 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

View File

@ -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) void *board_fdt_blob_setup(int *ret)
{ {
struct sandbox_state *state = state_get_current(); 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); blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
*ret = 0; *ret = 0;
if (!state->fdt_fname) { if (!state->fdt_fname) {
err = fdt_create_empty_tree(blob, 256); err = setup_auto_tree(blob);
if (!err) if (!err)
goto done; goto done;
printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); printf("Unable to create empty FDT: %s\n", fdt_strerror(err));

View 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

View 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

View File

@ -0,0 +1 @@
obj-y := poleg_evb.o

View 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;
}

View File

@ -1,5 +1,4 @@
DEVELOPER BOX DEVELOPER BOX
M: Masami Hiramatsu <masami.hiramatsu@linaro.org>
M: Jassi Brar <jaswinder.singh@linaro.org> M: Jassi Brar <jaswinder.singh@linaro.org>
S: Maintained S: Maintained
F: arch/arm/dts/synquacer-* F: arch/arm/dts/synquacer-*

View 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

View File

@ -20,6 +20,7 @@ obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_ARCH_MESON) += meson/ obj-$(CONFIG_ARCH_MESON) += meson/
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_NPCM) += nuvoton/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_SOCFPGA) += altera/ obj-$(CONFIG_ARCH_SOCFPGA) += altera/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/

View File

@ -0,0 +1,2 @@
obj-$(CONFIG_ARCH_NPCM) += clk_npcm.o
obj-$(CONFIG_ARCH_NPCM7xx) += clk_npcm7xx.o

View 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,
};

View 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

View 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,
};

View File

@ -279,6 +279,13 @@ config MXS_GPIO
help help
Support GPIO controllers on i.MX23 and i.MX28 platforms 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 config OMAP_GPIO
bool "TI OMAP GPIO driver" bool "TI OMAP GPIO driver"
depends on ARCH_OMAP2PLUS depends on ARCH_OMAP2PLUS

View File

@ -28,6 +28,7 @@ obj-$(CONFIG_MARVELL_GPIO) += mvgpio.o
obj-$(CONFIG_MCP230XX_GPIO) += mcp230xx_gpio.o obj-$(CONFIG_MCP230XX_GPIO) += mcp230xx_gpio.o
obj-$(CONFIG_MXC_GPIO) += mxc_gpio.o obj-$(CONFIG_MXC_GPIO) += mxc_gpio.o
obj-$(CONFIG_MXS_GPIO) += mxs_gpio.o obj-$(CONFIG_MXS_GPIO) += mxs_gpio.o
obj-$(CONFIG_NPCM_GPIO) += npcm_gpio.o
obj-$(CONFIG_PCA953X) += pca953x.o obj-$(CONFIG_PCA953X) += pca953x.o
obj-$(CONFIG_PCA9698) += pca9698.o obj-$(CONFIG_PCA9698) += pca9698.o
obj-$(CONFIG_ROCKCHIP_GPIO) += rk_gpio.o obj-$(CONFIG_ROCKCHIP_GPIO) += rk_gpio.o

123
drivers/gpio/npcm_gpio.c Normal file
View 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,
};

View File

@ -45,18 +45,18 @@ static const struct mtk_drive_desc mtk_drive[] = {
static const char *mtk_pinctrl_dummy_name = "_dummy"; 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); 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); 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) 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) 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; u32 val;
val = mtk_r32(dev, reg); val = mtk_r32(dev, i, reg);
val &= ~mask; val &= ~mask;
val |= set; 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, static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
const struct mtk_pin_reg_calc *rc, const struct mtk_pin_reg_calc *rc,
struct mtk_pin_field *pfd) struct mtk_pin_field *pfd)
{ {
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
const struct mtk_pin_field_calc *c, *e; const struct mtk_pin_field_calc *c, *e;
u32 bits; u32 bits;
u32 base_calc = priv->soc->base_calc;
c = rc->range; c = rc->range;
e = c + rc->nranges; 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->bitpos = bits % c->sz_reg;
pfd->mask = (1 << c->x_bits) - 1; 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 /* pfd->next is used for indicating that bit wrapping-around happens
* which requires the manipulation for bit 0 starting in the next * which requires the manipulation for bit 0 starting in the next
* register to form the complete field read/write. * 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_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); (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); (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); mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
l = (mtk_r32(dev, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1); l = (mtk_r32(dev, pf->index, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
h = (mtk_r32(dev, pf->offset + pf->next)) & (BIT(nbits_h) - 1); h = (mtk_r32(dev, pf->index, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
*value = (h << nbits_l) | l; *value = (h << nbits_l) | l;
} }
@ -181,7 +193,7 @@ static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
return err; return err;
if (!pf.next) 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); (value & pf.mask) << pf.bitpos);
else else
mtk_hw_write_cross_field(dev, &pf, value); 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; return err;
if (!pf.next) 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 else
mtk_hw_read_cross_field(dev, &pf, value); mtk_hw_read_cross_field(dev, &pf, value);
return 0; 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) static int mtk_get_groups_count(struct udevice *dev)
{ {
struct mtk_pinctrl_priv *priv = dev_get_priv(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) char *buf, int size)
{ {
int val, err; int val, err;
err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val); err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val);
if (err) if (err)
return err; return err;
@ -308,13 +338,31 @@ static const struct pinconf_param mtk_conf_params[] = {
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
}; };
int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, bool disable,
int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg, u32 val) 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); int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, bool disable,
pullup = (arg == PIN_CONFIG_BIAS_PULL_UP); 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) { if (disable) {
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, 0); 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); err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, 0);
if (err) if (err)
return err; return err;
} else { } else {
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, pullup); err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, pullup);
if (err) if (err)
@ -336,14 +383,10 @@ int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg, u32 val)
return 0; 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; int err;
disable = (arg == PIN_CONFIG_BIAS_DISABLE);
pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
r0 = !!(val & 1);
r1 = !!(val & 2);
if (disable) { if (disable) {
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 0); 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; return err;
} }
/* Also set PUPD/R0/R1 if the pin has them */ return 0;
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); int mtk_pinconf_bias_set_pupd_r1_r0(struct udevice *dev, u32 pin, bool disable,
mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R1, r1); 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; 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 mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg)
{ {
int err; 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); err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
if (err) if (err)
return 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; return 0;
} }
@ -410,7 +516,6 @@ int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, u32 arg)
return 0; return 0;
} }
int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg) int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg)
{ {
struct mtk_pinctrl_priv *priv = dev_get_priv(dev); 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; 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, static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
unsigned int param, unsigned int arg) unsigned int param, unsigned int arg)
{ {
int err = 0; int err = 0;
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
int rev = priv->soc->rev;
switch (param) { switch (param) {
case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
if (rev == MTK_PINCTRL_V0) err = mtk_pinconf_bias_set(dev, pin, param, arg);
err = mtk_pinconf_bias_set_v0(dev, pin, param, arg);
else
err = mtk_pinconf_bias_set_v1(dev, pin, param, arg);
if (err) if (err)
goto err; goto err;
break; break;
@ -456,8 +577,7 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
goto err; goto err;
break; break;
case PIN_CONFIG_INPUT_ENABLE: case PIN_CONFIG_INPUT_ENABLE:
if (rev == MTK_PINCTRL_V1) err = mtk_pinconf_input_enable(dev, pin, param);
err = mtk_pinconf_input_enable_v1(dev, pin, param);
if (err) if (err)
goto err; goto err;
break; break;
@ -486,10 +606,7 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
goto err; goto err;
break; break;
case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_DRIVE_STRENGTH:
if (rev == MTK_PINCTRL_V0) err = mtk_pinconf_drive_set(dev, pin, arg);
err = mtk_pinconf_drive_set_v0(dev, pin, arg);
else
err = mtk_pinconf_drive_set_v1(dev, pin, arg);
if (err) if (err)
goto err; goto err;
break; break;
@ -656,13 +773,23 @@ int mtk_pinctrl_common_probe(struct udevice *dev,
{ {
struct mtk_pinctrl_priv *priv = dev_get_priv(dev); struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
int ret = 0; int ret = 0;
u32 i = 0;
priv->base = dev_read_addr_ptr(dev); fdt_addr_t addr;
if (!priv->base) u32 base_calc = soc->base_calc;
return -EINVAL; u32 nbase_names = soc->nbase_names;
priv->soc = soc; 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) || \ #if CONFIG_IS_ENABLED(DM_GPIO) || \
(defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO)) (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
ret = mtk_gpiochip_register(dev); ret = mtk_gpiochip_register(dev);

View File

@ -8,12 +8,19 @@
#define MTK_PINCTRL_V0 0x0 #define MTK_PINCTRL_V0 0x0
#define MTK_PINCTRL_V1 0x1 #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_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, \ .number = _number, \
.name = _name, \ .name = _name, \
.drv_n = _drv_n, \ .drv_n = _drv_n, \
.io_n = _io_n, \
} }
#define PINCTRL_PIN_GROUP(name, id) \ #define PINCTRL_PIN_GROUP(name, id) \
@ -24,10 +31,11 @@
id##_funcs, \ id##_funcs, \
} }
#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \ #define PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, \
_x_bits, _sz_reg, _fixed) { \ _s_bit, _x_bits, _sz_reg, _fixed) { \
.s_pin = _s_pin, \ .s_pin = _s_pin, \
.e_pin = _e_pin, \ .e_pin = _e_pin, \
.i_base = _i_base, \
.s_addr = _s_addr, \ .s_addr = _s_addr, \
.x_addrs = _x_addrs, \ .x_addrs = _x_addrs, \
.s_bit = _s_bit, \ .s_bit = _s_bit, \
@ -36,6 +44,11 @@
.fixed = _fixed, \ .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 */ /* List these attributes which could be modified for the pin */
enum { enum {
PINCTRL_PIN_REG_MODE, PINCTRL_PIN_REG_MODE,
@ -67,9 +80,22 @@ enum {
DRV_GRP4, 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 * struct mtk_pin_field - the structure that holds the information of the field
* used to describe the attribute for the pin * 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 * @offset: the register offset relative to the base address
* @mask: the mask used to filter out the field from the register * @mask: the mask used to filter out the field from the register
* @bitpos: the start bit relative to the register * @bitpos: the start bit relative to the register
@ -77,6 +103,7 @@ enum {
next register next register
*/ */
struct mtk_pin_field { struct mtk_pin_field {
u8 index;
u32 offset; u32 offset;
u32 mask; u32 mask;
u8 bitpos; u8 bitpos;
@ -88,6 +115,7 @@ struct mtk_pin_field {
* the guide used to look up the relevant field * the guide used to look up the relevant field
* @s_pin: the start pin within the range * @s_pin: the start pin within the range
* @e_pin: the end 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 * @s_addr: the start address for the range
* @x_addrs: the address distance between two consecutive registers * @x_addrs: the address distance between two consecutive registers
* within the range * within the range
@ -101,6 +129,7 @@ struct mtk_pin_field {
struct mtk_pin_field_calc { struct mtk_pin_field_calc {
u16 s_pin; u16 s_pin;
u16 e_pin; u16 e_pin;
u8 i_base;
u32 s_addr; u32 s_addr;
u8 x_addrs; u8 x_addrs;
u8 s_bit; u8 s_bit;
@ -127,11 +156,13 @@ struct mtk_pin_reg_calc {
* @number: unique pin number from the global pin number space * @number: unique pin number from the global pin number space
* @name: name for this pin * @name: name for this pin
* @drv_n: the index with the driving group * @drv_n: the index with the driving group
* @io_n: the index with the io type
*/ */
struct mtk_pin_desc { struct mtk_pin_desc {
unsigned int number; unsigned int number;
const char *name; const char *name;
u8 drv_n; u8 drv_n;
u8 io_n;
}; };
/** /**
@ -160,6 +191,21 @@ struct mtk_function_desc {
int num_group_names; 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_pin_soc - the structure that holds SoC-specific data */
struct mtk_pinctrl_soc { struct mtk_pinctrl_soc {
const char *name; const char *name;
@ -170,8 +216,13 @@ struct mtk_pinctrl_soc {
int ngrps; int ngrps;
const struct mtk_function_desc *funcs; const struct mtk_function_desc *funcs;
int nfuncs; int nfuncs;
const struct mtk_io_type_desc *io_type;
u8 ntype;
int gpio_mode; int gpio_mode;
const char * const *base_names;
unsigned int nbase_names;
int rev; int rev;
int base_calc;
}; };
/** /**
@ -181,7 +232,7 @@ struct mtk_pinctrl_soc {
* @soc: SoC specific data * @soc: SoC specific data
*/ */
struct mtk_pinctrl_priv { struct mtk_pinctrl_priv {
void __iomem *base; void __iomem *base[MAX_BASE_CALC];
struct mtk_pinctrl_soc *soc; 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 */ /* A common read-modify-write helper for MediaTek chips */
void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set); 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, int mtk_pinctrl_common_probe(struct udevice *dev,
struct mtk_pinctrl_soc *soc); 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__ */ #endif /* __PINCTRL_MEDIATEK_H__ */

View File

@ -1016,6 +1016,15 @@ config MPC8XX_CONS
depends on MPC8xx depends on MPC8xx
default y 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 config XEN_SERIAL
bool "XEN serial support" bool "XEN serial support"
depends on XEN depends on XEN

View File

@ -66,6 +66,7 @@ obj-$(CONFIG_MSM_GENI_SERIAL) += serial_msm_geni.o
obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o
obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o
obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.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_BOOTCMD) += serial_octeon_bootcmd.o
obj-$(CONFIG_OCTEON_SERIAL_PCIE_CONSOLE) += serial_octeon_pcie_console.o obj-$(CONFIG_OCTEON_SERIAL_PCIE_CONSOLE) += serial_octeon_pcie_console.o
obj-$(CONFIG_OWL_SERIAL) += serial_owl.o obj-$(CONFIG_OWL_SERIAL) += serial_owl.o

View 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,
};

View File

@ -172,6 +172,15 @@ config NOMADIK_MTU_TIMER
The MTU provides 4 decrementing free-running timers. The MTU provides 4 decrementing free-running timers.
At the moment, only the first timer is used by the driver. 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 config OMAP_TIMER
bool "Omap timer support" bool "Omap timer support"
depends on TIMER depends on TIMER

View File

@ -14,6 +14,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o
obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o
obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
obj-$(CONFIG_NOMADIK_MTU_TIMER) += nomadik-mtu-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_OMAP_TIMER) += omap-timer.o
obj-$(CONFIG_RENESAS_OSTM_TIMER) += ostm_timer.o obj-$(CONFIG_RENESAS_OSTM_TIMER) += ostm_timer.o
obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o

115
drivers/timer/npcm-timer.c Normal file
View 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,
};

View File

@ -24,8 +24,7 @@
#define CONFIG_SPL_MAX_SIZE CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE #define CONFIG_SPL_MAX_SIZE CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE
#if defined(CONFIG_TARGET_AM642_A53_EVM) #if defined(CONFIG_TARGET_AM642_A53_EVM)
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE - 4)
#else #else
/* /*
* Maximum size in memory allocated to the SPL BSS. Keep it as tight as * Maximum size in memory allocated to the SPL BSS. Keep it as tight as

View File

@ -19,8 +19,7 @@
/* SPL Loader Configuration */ /* SPL Loader Configuration */
#ifdef CONFIG_TARGET_AM654_A53_EVM #ifdef CONFIG_TARGET_AM654_A53_EVM
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
#else #else
/* /*
* Maximum size in memory allocated to the SPL BSS. Keep it as tight as * Maximum size in memory allocated to the SPL BSS. Keep it as tight as

View File

@ -20,8 +20,7 @@
/* SPL Loader Configuration */ /* SPL Loader Configuration */
#if defined(CONFIG_TARGET_J721E_A72_EVM) || defined(CONFIG_TARGET_J7200_A72_EVM) #if defined(CONFIG_TARGET_J721E_A72_EVM) || defined(CONFIG_TARGET_J7200_A72_EVM)
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
#define CONFIG_SYS_UBOOT_BASE 0x50280000 #define CONFIG_SYS_UBOOT_BASE 0x50280000
/* Image load address in RAM for DFU boot*/ /* Image load address in RAM for DFU boot*/
#else #else

View File

@ -21,8 +21,7 @@
/* SPL Loader Configuration */ /* SPL Loader Configuration */
#if defined(CONFIG_TARGET_J721S2_A72_EVM) || defined(CONFIG_TARGET_J7200_A72_EVM) #if defined(CONFIG_TARGET_J721S2_A72_EVM) || defined(CONFIG_TARGET_J7200_A72_EVM)
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + SZ_4M)
CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
#define CONFIG_SYS_UBOOT_BASE 0x50280000 #define CONFIG_SYS_UBOOT_BASE 0x50280000
/* Image load address in RAM for DFU boot*/ /* Image load address in RAM for DFU boot*/
#else #else

44
include/configs/poleg.h Normal file
View 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

View 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

View 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

View File

@ -9,6 +9,18 @@ def test_help(u_boot_console):
u_boot_console.run_command('help') 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') @pytest.mark.boardspec('sandbox_vpl')
def test_vpl_help(u_boot_console): def test_vpl_help(u_boot_console):
try: try:

View File

@ -27,6 +27,7 @@ class ConsoleSandbox(ConsoleBase):
super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024) super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024)
self.sandbox_flags = [] self.sandbox_flags = []
self.use_dtb = True
def get_spawn(self): def get_spawn(self):
"""Connect to a fresh U-Boot instance. """Connect to a fresh U-Boot instance.
@ -53,16 +54,13 @@ class ConsoleSandbox(ConsoleBase):
cmd = [] cmd = []
if self.config.gdbserver: if self.config.gdbserver:
cmd += ['gdbserver', self.config.gdbserver] cmd += ['gdbserver', self.config.gdbserver]
cmd += [ cmd += [self.config.build_dir + fname, '-v']
self.config.build_dir + fname, if self.use_dtb:
'-v', cmd += ['-d', self.config.dtb]
'-d',
self.config.dtb
]
cmd += self.sandbox_flags cmd += self.sandbox_flags
return Spawn(cmd, cwd=self.config.source_dir) 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 """Run U-Boot with the given command-line flags
Args: Args:
@ -70,6 +68,7 @@ class ConsoleSandbox(ConsoleBase):
expect_reset: Boolean indication whether this boot is expected expect_reset: Boolean indication whether this boot is expected
to be reset while the 1st boot process after main boot before to be reset while the 1st boot process after main boot before
prompt. False by default. prompt. False by default.
use_dtb: True to use a device tree file, False to run without one
Returns: Returns:
A u_boot_spawn.Spawn object that is attached to U-Boot. A u_boot_spawn.Spawn object that is attached to U-Boot.
@ -77,9 +76,11 @@ class ConsoleSandbox(ConsoleBase):
try: try:
self.sandbox_flags = flags self.sandbox_flags = flags
self.use_dtb = use_dtb
return self.restart_uboot(expect_reset) return self.restart_uboot(expect_reset)
finally: finally:
self.sandbox_flags = [] self.sandbox_flags = []
self.use_dtb = True
def kill(self, sig): def kill(self, sig):
"""Send a specific Unix signal to the sandbox process. """Send a specific Unix signal to the sandbox process.