Merge branch '2022-10-06-assorted-platform-and-board-updates'

- Assorted platform updates for developerbox, armv8 platforms in
  general, TI K3 and AM65 platforms, nuvoton NPCM845 SoC and then clock
  driver, ftgpio010 support, and common/board_f cleanups.
This commit is contained in:
Tom Rini
2022-10-07 11:23:19 -04:00
40 changed files with 1707 additions and 77 deletions

View File

@@ -503,6 +503,10 @@ void dcache_enable(void)
mmu_setup();
}
/* Set up page tables only once (it is done also by mmu_setup()) */
if (!gd->arch.tlb_fillptr)
setup_all_pgtables();
set_sctlr(get_sctlr() | CR_C);
}

View File

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

View File

@@ -0,0 +1,170 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
#include <dt-bindings/clock/nuvoton,npcm845-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
interrupt-parent = <&gic>;
ranges;
gcr: system-controller@f0800000 {
compatible = "nuvoton,npcm845-gcr", "syscon";
reg = <0x0 0xf0800000 0x0 0x1000>;
};
gic: interrupt-controller@dfff9000 {
compatible = "arm,gic-400";
reg = <0x0 0xdfff9000 0x0 0x1000>,
<0x0 0xdfffa000 0x0 0x2000>,
<0x0 0xdfffc000 0x0 0x2000>,
<0x0 0xdfffe000 0x0 0x2000>;
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
#interrupt-cells = <3>;
interrupt-controller;
#address-cells = <0>;
ppi-partitions {
ppi_cluster0: interrupt-partition-0 {
affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
};
};
};
};
ahb {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
interrupt-parent = <&gic>;
ranges;
rstc: reset-controller@f0801000 {
compatible = "nuvoton,npcm845-reset";
reg = <0x0 0xf0801000 0x0 0x78>;
#reset-cells = <2>;
nuvoton,sysgcr = <&gcr>;
};
clk: clock-controller@f0801000 {
compatible = "nuvoton,npcm845-clk";
#clock-cells = <1>;
reg = <0x0 0xf0801000 0x0 0x1000>;
};
apb {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&gic>;
ranges = <0x0 0x0 0xf0000000 0x00300000>,
<0xfff00000 0x0 0xfff00000 0x00016000>;
timer0: timer@8000 {
compatible = "nuvoton,npcm845-timer";
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x8000 0x1C>;
clocks = <&clk NPCM8XX_CLK_REFCLK>;
clock-names = "refclk";
};
serial0: serial@0 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x0 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial1: serial@1000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x1000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial2: serial@2000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x2000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial3: serial@3000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x3000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial4: serial@4000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x4000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial5: serial@5000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x5000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial6: serial@6000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x6000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
watchdog0: watchdog@801c {
compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x801c 0x4>;
status = "disabled";
clocks = <&clk NPCM8XX_CLK_REFCLK>;
syscon = <&gcr>;
};
watchdog1: watchdog@901c {
compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x901c 0x4>;
status = "disabled";
clocks = <&clk NPCM8XX_CLK_REFCLK>;
syscon = <&gcr>;
};
watchdog2: watchdog@a01c {
compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xa01c 0x4>;
status = "disabled";
clocks = <&clk NPCM8XX_CLK_REFCLK>;
syscon = <&gcr>;
};
};
};
};

View File

@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
/dts-v1/;
#include "nuvoton-npcm845.dtsi"
/ {
model = "Nuvoton npcm845 Development Board (Device Tree)";
compatible = "nuvoton,npcm845-evb", "nuvoton,npcm845";
aliases {
serial0 = &serial0;
};
chosen {
stdout-path = &serial0;
};
memory {
reg = <0x0 0x0 0x0 0x40000000>;
};
};
&serial0 {
status = "okay";
};
&watchdog1 {
status = "okay";
};

View File

@@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
#include "nuvoton-common-npcm8xx.dtsi"
#include "nuvoton-npcm8xx-u-boot.dtsi"
/ {
#address-cells = <2>;
#size-cells = <2>;
cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x0>;
next-level-cache = <&l2>;
enable-method = "psci";
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x1>;
next-level-cache = <&l2>;
enable-method = "psci";
};
cpu2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x2>;
next-level-cache = <&l2>;
enable-method = "psci";
};
cpu3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x3>;
next-level-cache = <&l2>;
enable-method = "psci";
};
l2: l2-cache {
compatible = "cache";
};
};
arm-pmu {
compatible = "arm,cortex-a35-pmu";
interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
};
psci {
compatible = "arm,psci-1.0";
method = "smc";
};
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
};

View File

@@ -0,0 +1,136 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/reset/nuvoton,npcm8xx-reset.h>
/ {
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&gic>;
/* external reference clock */
clk_refclk: clk-refclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
clock-output-names = "refclk";
};
ahb {
rstc: reset-controller@f0801000 {
compatible = "nuvoton,npcm845-reset", "syscon",
"simple-mfd";
reg = <0x0 0xf0801000 0x0 0xC4>;
rstc1: reset-controller1 {
compatible = "syscon-reset";
#reset-cells = <1>;
regmap = <&rstc>;
offset = <NPCM8XX_RESET_IPSRST1>;
mask = <0xFFFFFFFF>;
};
rstc2: reset-controller2 {
compatible = "syscon-reset";
#reset-cells = <1>;
regmap = <&rstc>;
offset = <NPCM8XX_RESET_IPSRST2>;
mask = <0xFFFFFFFF>;
};
rstc3: reset-controller3 {
compatible = "syscon-reset";
#reset-cells = <1>;
regmap = <&rstc>;
offset = <NPCM8XX_RESET_IPSRST3>;
mask = <0xFFFFFFFF>;
};
rstc4: reset-controller4 {
compatible = "syscon-reset";
#reset-cells = <1>;
regmap = <&rstc>;
offset = <NPCM8XX_RESET_IPSRST4>;
mask = <0xFFFFFFFF>;
};
};
clk: clock-controller@f0801000 {
compatible = "nuvoton,npcm845-clk", "syscon";
#clock-cells = <1>;
clock-controller;
reg = <0x0 0xf0801000 0x0 0x1000>;
clock-names = "refclk";
clocks = <&clk_refclk>;
};
apb {
serial0: serial@0 {
compatible = "nuvoton,npcm845-uart";
reg = <0x0 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>, <&clk NPCM8XX_CLK_PLL2DIV2>;
clock-frequency = <24000000>;
status = "disabled";
};
gpio0: gpio0@10000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x10000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio0";
};
gpio1: gpio1@11000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x11000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio1";
};
gpio2: gpio2@12000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x12000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio2";
};
gpio3: gpio3@13000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x13000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio3";
};
gpio4: gpio4@14000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x14000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio4";
};
gpio5: gpio5@15000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x15000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio5";
};
gpio6: gpio6@16000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x16000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio6";
};
gpio7: gpio7@17000 {
compatible = "nuvoton,npcm-gpio";
reg = <0x17000 0xB0>;
#gpio-cells = <2>;
gpio-controller;
gpio-bank-name = "gpio7";
};
};
};
};

View File

@@ -0,0 +1,140 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* System Global Control Register definitions
* Copyright (c) 2022 Nuvoton Technology Corp.
*/
#ifndef _NPCM_GCR_H_
#define _NPCM_GCR_H_
#define NPCM_GCR_BA 0xF0800000
/* On-Chip ARBEL NPCM8XX VERSIONS */
#define ARBEL_Z1 0x00A35850
#define ARBEL_A1 0x04a35850
#define ARBEL_NPCM845 0x00000000
#define ARBEL_NPCM830 0x00300395
#define ARBEL_NPCM810 0x00000220
#define MFSEL4_ESPISEL BIT(8)
#define MFSEL1_LPCSEL BIT(26)
#define INTCR2_WDC BIT(21)
struct npcm_gcr {
unsigned int pdid;
unsigned int pwron;
unsigned int swstrps;
unsigned int rsvd1[2];
unsigned int miscpe;
unsigned int spldcnt;
unsigned int rsvd2[1];
unsigned int flockr2;
unsigned int flockr3;
unsigned int rsvd3[3];
unsigned int a35_mode;
unsigned int spswc;
unsigned int intcr;
unsigned int intsr;
unsigned int obscr1;
unsigned int obsdr1;
unsigned int rsvd4[1];
unsigned int hifcr;
unsigned int rsvd5[3];
unsigned int intcr2;
unsigned int rsvd6[1];
unsigned int srcnt;
unsigned int ressr;
unsigned int rlockr1;
unsigned int flockr1;
unsigned int dscnt;
unsigned int mdlr;
unsigned int scrpad_c;
unsigned int scrpad_b;
unsigned int rsvd7[4];
unsigned int daclvlr;
unsigned int intcr3;
unsigned int pcirctl;
unsigned int rsvd8[2];
unsigned int vsintr;
unsigned int rsvd9[1];
unsigned int sd2sur1;
unsigned int sd2sur2;
unsigned int sd2irv3;
unsigned int intcr4;
unsigned int obscr2;
unsigned int obsdr2;
unsigned int rsvd10[5];
unsigned int i2csegsel;
unsigned int i2csegctl;
unsigned int vsrcr;
unsigned int mlockr;
unsigned int rsvd11[8];
unsigned int etsr;
unsigned int dft1r;
unsigned int dft2r;
unsigned int dft3r;
unsigned int edffsr;
unsigned int rsvd12[1];
unsigned int intcrpce3;
unsigned int intcrpce2;
unsigned int intcrpce0;
unsigned int intcrpce1;
unsigned int dactest;
unsigned int scrpad;
unsigned int usb1phyctl;
unsigned int usb2phyctl;
unsigned int usb3phyctl;
unsigned int intsr2;
unsigned int intcrpce2b;
unsigned int intcrpce0b;
unsigned int intcrpce1b;
unsigned int intcrpce3b;
unsigned int rsvd13[4];
unsigned int intcrpce2c;
unsigned int intcrpce0c;
unsigned int intcrpce1c;
unsigned int intcrpce3c;
unsigned int rsvd14[40];
unsigned int sd2irv4;
unsigned int sd2irv5;
unsigned int sd2irv6;
unsigned int sd2irv7;
unsigned int sd2irv8;
unsigned int sd2irv9;
unsigned int sd2irv10;
unsigned int sd2irv11;
unsigned int rsvd15[8];
unsigned int mfsel1;
unsigned int mfsel2;
unsigned int mfsel3;
unsigned int mfsel4;
unsigned int mfsel5;
unsigned int mfsel6;
unsigned int mfsel7;
unsigned int rsvd16[1];
unsigned int mfsel_lk1;
unsigned int mfsel_lk2;
unsigned int mfsel_lk3;
unsigned int mfsel_lk4;
unsigned int mfsel_lk5;
unsigned int mfsel_lk6;
unsigned int mfsel_lk7;
unsigned int rsvd17[1];
unsigned int mfsel_set1;
unsigned int mfsel_set2;
unsigned int mfsel_set3;
unsigned int mfsel_set4;
unsigned int mfsel_set5;
unsigned int mfsel_set6;
unsigned int mfsel_set7;
unsigned int rsvd18[1];
unsigned int mfsel_clr1;
unsigned int mfsel_clr2;
unsigned int mfsel_clr3;
unsigned int mfsel_clr4;
unsigned int mfsel_clr5;
unsigned int mfsel_clr6;
unsigned int mfsel_clr7;
};
#endif

View File

@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef _NPCM_RST_H_
#define _NPCM_RST_H_
/* Watchdog Timer Controller Register */
#define WTCR0_REG 0xF000801C
#define WTCR_WTR BIT(0)
#define WTCR_WTRE BIT(1)
#define WTCR_WTE BIT(7)
/* Reset status bits */
#define PORST BIT(31)
#define CORST BIT(30)
#define WD0RST BIT(29)
#define SW1RST BIT(28)
#define SW2RST BIT(27)
#define SW3RST BIT(26)
#define SW4RST BIT(25)
#define WD1RST BIT(24)
#define WD2RST BIT(23)
#define RST_STS_MASK GENMASK(31, 23)
int npcm_get_reset_status(void);
#endif

View File

@@ -9,9 +9,21 @@
#include <common.h>
#include <init.h>
#include <asm/global_data.h>
#include <asm/mach-types.h>
DECLARE_GLOBAL_DATA_PTR;
int arch_setup_bdinfo(void)
{
#ifdef CONFIG_MACH_TYPE
struct bd_info *bd = gd->bd;
bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
#endif
return 0;
}
void arch_print_bdinfo(void)
{
struct bd_info *bd = gd->bd;

View File

@@ -19,8 +19,16 @@ config ARCH_NPCM7xx
General support for NPCM7xx BMC (Poleg).
Nuvoton NPCM7xx BMC is based on the Cortex A9.
config ARCH_NPCM8XX
bool "Support Nuvoton NPCM8xx SoC"
select ARM64
help
General support for NPCM8xx BMC (Arbel).
Nuvoton NPCM8xx BMC is based on the Cortex A35.
endchoice
source "arch/arm/mach-npcm/npcm7xx/Kconfig"
source "arch/arm/mach-npcm/npcm8xx/Kconfig"
endif

View File

@@ -1 +1,2 @@
obj-$(CONFIG_ARCH_NPCM7xx) += npcm7xx/
obj-$(CONFIG_ARCH_NPCM8XX) += npcm8xx/

View File

@@ -0,0 +1,18 @@
if ARCH_NPCM8XX
config SYS_CPU
default "armv8"
config SYS_SOC
default "npcm8xx"
config TARGET_ARBEL_EVB
bool "Arbel Evaluation Board"
help
ARBEL_EVB is Nuvoton evaluation board for NPCM845 SoC,
supports general functions of Basebase Management Controller
(BMC).
source "board/nuvoton/arbel_evb/Kconfig"
endif

View File

@@ -0,0 +1 @@
obj-y += cpu.o reset.o

View File

@@ -0,0 +1,135 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2022 Nuvoton Technology Corp.
*/
#include <common.h>
#include <dm.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/arch/gcr.h>
#include <asm/armv8/mmu.h>
#define SYSCNT_CTRL_BASE_ADDR 0xF07FC000
#define SC_CNTCR_ENABLE BIT(0)
#define SC_CNTCR_HDBG BIT(1)
#define SC_CNTCR_FREQ0 BIT(8)
#define SC_CNTCR_FREQ1 BIT(9)
/* System Counter register map */
struct sctr_regs {
u32 cntcr;
u32 cntsr;
u32 cntcv1;
u32 cntcv2;
u32 resv1[4];
u32 cntfid0;
u32 cntfid1;
u32 cntfid2;
u32 resv2[1001];
u32 counterid[1];
};
DECLARE_GLOBAL_DATA_PTR;
int print_cpuinfo(void)
{
struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
unsigned int val;
unsigned long mpidr_val;
asm volatile("mrs %0, mpidr_el1" : "=r" (mpidr_val));
val = readl(&gcr->mdlr);
printf("CPU-%lu: ", mpidr_val & 0x3);
switch (val) {
case ARBEL_NPCM845:
printf("NPCM845 ");
break;
case ARBEL_NPCM830:
printf("NPCM830 ");
break;
case ARBEL_NPCM810:
printf("NPCM810 ");
break;
default:
printf("NPCM8XX ");
break;
}
val = readl(&gcr->pdid);
switch (val) {
case ARBEL_Z1:
printf("Z1 @ ");
break;
case ARBEL_A1:
printf("A1 @ ");
break;
default:
printf("Unknown\n");
break;
}
return 0;
}
int arch_cpu_init(void)
{
if (!IS_ENABLED(CONFIG_SYS_DCACHE_OFF)) {
/* Enable cache to speed up system running */
if (get_sctlr() & CR_M)
return 0;
icache_enable();
__asm_invalidate_dcache_all();
__asm_invalidate_tlb_all();
set_sctlr(get_sctlr() | CR_C);
}
return 0;
}
static struct mm_region npcm_mem_map[1 + CONFIG_NR_DRAM_BANKS + 1] = {
{
/* DRAM */
.phys = 0x0UL,
.virt = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
},
{
.phys = 0x80000000UL,
.virt = 0x80000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
{
/* List terminator */
0,
}
};
struct mm_region *mem_map = npcm_mem_map;
int timer_init(void)
{
struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR;
u32 cntfrq_el0;
/* Enable system counter */
__asm__ __volatile__("mrs %0, CNTFRQ_EL0\n\t" : "=r" (cntfrq_el0) : : "memory");
writel(cntfrq_el0, &sctr->cntfid0);
clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1,
SC_CNTCR_ENABLE | SC_CNTCR_HDBG);
gd->arch.tbl = 0;
gd->arch.tbu = 0;
return 0;
}

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2022 Nuvoton Technology Corp.
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/gcr.h>
#include <asm/arch/rst.h>
void reset_cpu(void)
{
/* Generate a watchdog0 reset */
writel(WTCR_WTR | WTCR_WTRE | WTCR_WTE, WTCR0_REG);
while (1)
;
}
void reset_misc(void)
{
struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
clrbits_le32(&gcr->intcr2, INTCR2_WDC);
}
int npcm_get_reset_status(void)
{
struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
u32 val;
val = readl(&gcr->ressr);
if (!val)
val = readl(&gcr->intcr2);
return val & RST_STS_MASK;
}

View File

@@ -92,12 +92,6 @@ struct arch_global_data {
#include <asm-generic/global_data.h>
#if 1
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r2")
#else /* We could use plain global data, but the resulting code is bigger */
#define XTRN_DECLARE_GLOBAL_DATA_PTR extern
#define DECLARE_GLOBAL_DATA_PTR XTRN_DECLARE_GLOBAL_DATA_PTR \
gd_t *gd
#endif
#endif /* __ASM_GBL_DATA_H */

View File

@@ -13,6 +13,7 @@
#include <common.h>
#include <init.h>
#include <asm/global_data.h>
#include <asm/mp.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -30,3 +31,19 @@ int arch_reserve_stacks(void)
return 0;
}
int arch_setup_dest_addr(void)
{
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
/*
* We need to make sure the location we intend to put secondary core
* boot code is reserved and not used by any part of u-boot
*/
if (gd->relocaddr > determine_mp_bootpg(NULL)) {
gd->relocaddr = determine_mp_bootpg(NULL);
debug("Reserving MP boot page to %08lx\n", gd->relocaddr);
}
#endif
return 0;
}

View File

@@ -0,0 +1,18 @@
if TARGET_ARBEL_EVB
config SYS_BOARD
default "arbel_evb"
config SYS_VENDOR
default "nuvoton"
config SYS_CONFIG_NAME
default "arbel"
config SYS_MEM_TOP_HIDE
hex "Reserved TOP memory"
default 0xB000000
help
Reserve memory for ECC/GFX/VCD/ECE.
endif

View File

@@ -0,0 +1,7 @@
Arbel EVB
M: Stanley Chu <yschu@nuvoton.com>
M: Jim Liu <JJLIU0@nuvoton.com>
S: Maintained
F: board/nuvoton/arbel_evb/
F: include/configs/arbel.h
F: configs/arbel_evb_defconfig

View File

@@ -0,0 +1 @@
obj-y += arbel_evb.o

View File

@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2022 Nuvoton Technology Corp.
*/
#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include <asm/arch/gcr.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;
/*
* Get dram size from bootblock.
* The value is stored in scrpad_02 register.
*/
gd->ram_size = readl(&gcr->scrpad_b);
return 0;
}

View File

@@ -89,8 +89,6 @@ struct draminfo {
struct draminfo_entry entry[3];
};
struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
DECLARE_GLOBAL_DATA_PTR;
#define LOAD_OFFSET 0x100
@@ -137,42 +135,18 @@ int ft_board_setup(void *blob, struct bd_info *bd)
int dram_init(void)
{
struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
struct draminfo_entry *ent = synquacer_draminfo->entry;
struct mm_region *mr;
int i, ri;
if (synquacer_draminfo->nr_regions < 1) {
log_err("Failed to get correct DRAM information\n");
return -1;
}
/*
* U-Boot RAM size must be under the first DRAM region so that it doesn't
* access secure memory which is at the end of the first DRAM region.
*/
gd->ram_size = ent[0].size;
/* Update memory region maps */
for (i = 0; i < synquacer_draminfo->nr_regions; i++) {
if (i >= MAX_DDR_REGIONS)
break;
ri = DDR_REGION_INDEX(i);
mem_map[ri].phys = ent[i].base;
mem_map[ri].size = ent[i].size;
if (i == 0)
continue;
mr = &mem_map[DDR_REGION_INDEX(0)];
mem_map[ri].virt = mr->virt + mr->size;
mem_map[ri].attrs = mr->attrs;
}
gd->ram_base = ent[0].base;
return 0;
}
int dram_init_banksize(void)
{
struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
struct draminfo_entry *ent = synquacer_draminfo->entry;
int i;
@@ -187,6 +161,43 @@ int dram_init_banksize(void)
return 0;
}
void build_mem_map(void)
{
struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
struct draminfo_entry *ent = synquacer_draminfo->entry;
struct mm_region *mr;
int i, ri;
if (synquacer_draminfo->nr_regions < 1) {
log_err("Failed to get correct DRAM information\n");
return;
}
/* Update memory region maps */
for (i = 0; i < synquacer_draminfo->nr_regions; i++) {
if (i >= MAX_DDR_REGIONS)
break;
ri = DDR_REGION_INDEX(i);
mem_map[ri].phys = ent[i].base;
mem_map[ri].size = ent[i].size;
mem_map[ri].virt = mem_map[ri].phys;
if (i == 0)
continue;
mr = &mem_map[DDR_REGION_INDEX(0)];
mem_map[ri].attrs = mr->attrs;
}
}
void enable_caches(void)
{
build_mem_map();
icache_enable();
dcache_enable();
}
int print_cpuinfo(void)
{
printf("CPU: SC2A11:Cortex-A53 MPCore 24cores\n");

View File

@@ -36,9 +36,7 @@
#include <post.h>
#include <relocate.h>
#include <serial.h>
#ifdef CONFIG_SPL
#include <spl.h>
#endif
#include <status_led.h>
#include <sysreset.h>
#include <timer.h>
@@ -46,12 +44,6 @@
#include <video.h>
#include <watchdog.h>
#include <asm/cache.h>
#ifdef CONFIG_MACH_TYPE
#include <asm/mach-types.h>
#endif
#if defined(CONFIG_MP) && defined(CONFIG_PPC)
#include <asm/mp.h>
#endif
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/sections.h>
@@ -59,18 +51,7 @@
#include <linux/errno.h>
#include <linux/log2.h>
/*
* Pointer to initial global data area
*
* Here we initialize it if needed.
*/
#ifdef XTRN_DECLARE_GLOBAL_DATA_PTR
#undef XTRN_DECLARE_GLOBAL_DATA_PTR
#define XTRN_DECLARE_GLOBAL_DATA_PTR /* empty = allocate here */
DECLARE_GLOBAL_DATA_PTR = (gd_t *)(CONFIG_SYS_INIT_GD_ADDR);
#else
DECLARE_GLOBAL_DATA_PTR;
#endif
/*
* TODO(sjg@chromium.org): IMO this code should be
@@ -357,6 +338,11 @@ __weak phys_size_t board_get_usable_ram_top(phys_size_t total_size)
return gd->ram_top;
}
__weak int arch_setup_dest_addr(void)
{
return 0;
}
static int setup_dest_addr(void)
{
debug("Monitor len: %08lX\n", gd->mon_len);
@@ -384,17 +370,8 @@ static int setup_dest_addr(void)
gd->ram_top = board_get_usable_ram_top(gd->mon_len);
gd->relocaddr = gd->ram_top;
debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
/*
* We need to make sure the location we intend to put secondary core
* boot code is reserved and not used by any part of u-boot
*/
if (gd->relocaddr > determine_mp_bootpg(NULL)) {
gd->relocaddr = determine_mp_bootpg(NULL);
debug("Reserving MP boot page to %08lx\n", gd->relocaddr);
}
#endif
return 0;
return arch_setup_dest_addr();
}
#ifdef CONFIG_PRAM
@@ -635,10 +612,6 @@ int setup_bdinfo(void)
bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */
}
#ifdef CONFIG_MACH_TYPE
bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
#endif
return arch_setup_bdinfo();
}

View File

@@ -0,0 +1,66 @@
CONFIG_ARM=y
CONFIG_ARCH_NPCM=y
CONFIG_SYS_MALLOC_LEN=0x240000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x40000
CONFIG_ENV_OFFSET=0x1C0000
CONFIG_ENV_SECT_SIZE=0x1000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="nuvoton-npcm845-evb"
CONFIG_SYS_PROMPT="U-Boot>"
# CONFIG_PSCI_RESET is not set
CONFIG_ARCH_NPCM8XX=y
CONFIG_TARGET_ARBEL_EVB=y
CONFIG_SYS_LOAD_ADDR=0x10000000
CONFIG_ENV_ADDR=0x801C0000
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="run common_bootargs; run romboot"
CONFIG_HUSH_PARSER=y
CONFIG_SYS_MAXARGS=32
CONFIG_SYS_BOOTM_LEN=0x1400000
CONFIG_CMD_GPIO=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_UUID=y
CONFIG_CMD_FAT=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
CONFIG_NPCM_GPIO=y
# CONFIG_INPUT is not set
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHY_BROADCOM=y
CONFIG_PHY_GIGE=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_RGMII=y
CONFIG_MII=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_PINCTRL_NPCM8XX=y
CONFIG_DM_RESET=y
CONFIG_RESET_SYSCON=y
CONFIG_DM_SERIAL=y
CONFIG_NPCM_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_NPCM_FIU_SPI=y
CONFIG_TIMER=y
CONFIG_NPCM_TIMER=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_GENERIC=y
CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS=1
CONFIG_USB_STORAGE=y
# CONFIG_EFI_LOADER is not set

View File

@@ -36,6 +36,11 @@ On most architectures the global data pointer is stored in a register.
The sandbox, x86_64, and Xtensa are notable exceptions.
Current implementation uses a register for the GD pointer because this results
in smaller code. However, using plain global data for the GD pointer would be
possible too (and simpler, as it does not require the reservation of a specific
register for it), but the resulting code is bigger.
Clang for ARM does not support assigning a global register. When using Clang
gd is defined as an inline function using assembly code. This adds a few bytes
to the code size.

View File

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

View File

@@ -0,0 +1,98 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2022 Nuvoton Technology Corp.
*/
#include <dm.h>
#include <dt-bindings/clock/nuvoton,npcm845-clk.h>
#include "clk_npcm.h"
/* Parent clock map */
static const struct parent_data pll_parents[] = {
{NPCM8XX_CLK_PLL0, 0},
{NPCM8XX_CLK_PLL1, 1},
{NPCM8XX_CLK_REFCLK, 2},
{NPCM8XX_CLK_PLL2DIV2, 3}
};
static const struct parent_data cpuck_parents[] = {
{NPCM8XX_CLK_PLL0, 0},
{NPCM8XX_CLK_PLL1, 1},
{NPCM8XX_CLK_REFCLK, 2},
{NPCM8XX_CLK_PLL2, 7}
};
static const struct parent_data apb_parent[] = {{NPCM8XX_CLK_AHB, 0}};
static struct npcm_clk_pll npcm8xx_clk_plls[] = {
{NPCM8XX_CLK_PLL0, NPCM8XX_CLK_REFCLK, PLLCON0, 0},
{NPCM8XX_CLK_PLL1, NPCM8XX_CLK_REFCLK, PLLCON1, 0},
{NPCM8XX_CLK_PLL2, NPCM8XX_CLK_REFCLK, PLLCON2, 0},
{NPCM8XX_CLK_PLL2DIV2, NPCM8XX_CLK_REFCLK, PLLCON2, POST_DIV2}
};
static struct npcm_clk_select npcm8xx_clk_selectors[] = {
{NPCM8XX_CLK_AHB, cpuck_parents, CLKSEL, NPCM8XX_CPUCKSEL, 4, 0},
{NPCM8XX_CLK_APB2, apb_parent, 0, 0, 1, FIXED_PARENT},
{NPCM8XX_CLK_APB5, apb_parent, 0, 0, 1, FIXED_PARENT},
{NPCM8XX_CLK_SPI0, apb_parent, 0, 0, 1, FIXED_PARENT},
{NPCM8XX_CLK_SPI1, apb_parent, 0, 0, 1, FIXED_PARENT},
{NPCM8XX_CLK_SPI3, apb_parent, 0, 0, 1, FIXED_PARENT},
{NPCM8XX_CLK_SPIX, apb_parent, 0, 0, 1, FIXED_PARENT},
{NPCM8XX_CLK_UART, pll_parents, CLKSEL, UARTCKSEL, 4, 0},
{NPCM8XX_CLK_UART2, pll_parents, CLKSEL, UARTCKSEL, 4, 0},
{NPCM8XX_CLK_SDHC, pll_parents, CLKSEL, SDCKSEL, 4, 0}
};
static struct npcm_clk_div npcm8xx_clk_dividers[] = {
{NPCM8XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2},
{NPCM8XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2},
{NPCM8XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2},
{NPCM8XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1},
{NPCM8XX_CLK_SPI1, CLKDIV3, SPI1CKDIV, DIV_TYPE1},
{NPCM8XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1},
{NPCM8XX_CLK_SPIX, CLKDIV3, SPIXCKDIV, DIV_TYPE1},
{NPCM8XX_CLK_UART, CLKDIV1, UARTDIV1, DIV_TYPE1},
{NPCM8XX_CLK_UART2, CLKDIV3, UARTDIV2, DIV_TYPE1},
{NPCM8XX_CLK_SDHC, CLKDIV1, MMCCKDIV, DIV_TYPE1}
};
static struct npcm_clk_data npcm8xx_clk_data = {
.clk_plls = npcm8xx_clk_plls,
.num_plls = ARRAY_SIZE(npcm8xx_clk_plls),
.clk_selectors = npcm8xx_clk_selectors,
.num_selectors = ARRAY_SIZE(npcm8xx_clk_selectors),
.clk_dividers = npcm8xx_clk_dividers,
.num_dividers = ARRAY_SIZE(npcm8xx_clk_dividers),
.refclk_id = NPCM8XX_CLK_REFCLK,
.pll0_id = NPCM8XX_CLK_PLL0,
};
static int npcm8xx_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 = &npcm8xx_clk_data;
priv->num_clks = NPCM8XX_NUM_CLOCKS;
return 0;
}
static const struct udevice_id npcm8xx_clk_ids[] = {
{ .compatible = "nuvoton,npcm845-clk" },
{ }
};
U_BOOT_DRIVER(clk_npcm) = {
.name = "clk_npcm",
.id = UCLASS_CLK,
.of_match = npcm8xx_clk_ids,
.ops = &npcm_clk_ops,
.priv_auto = sizeof(struct npcm_clk_priv),
.probe = npcm8xx_clk_probe,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -14,6 +14,7 @@
#include <malloc.h>
#include <linux/bitops.h>
#include <linux/dma-mapping.h>
#include <linux/sizes.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/devres.h>

View File

@@ -605,4 +605,10 @@ config TURRIS_OMNIA_MCU
help
Support for GPIOs on MCU connected to Turris Omnia via i2c.
config FTGPIO010
bool "Faraday Technology FTGPIO010 driver"
depends on DM_GPIO
help
Support for GPIOs on Faraday Technology's FTGPIO010 controller.
endif

View File

@@ -75,3 +75,4 @@ obj-$(CONFIG_SL28CPLD_GPIO) += sl28cpld-gpio.o
obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN) += zynqmp_gpio_modepin.o
obj-$(CONFIG_SLG7XL45106_I2C_GPO) += gpio_slg7xl45106.o
obj-$(CONFIG_$(SPL_TPL_)TURRIS_OMNIA_MCU) += turris_omnia_mcu.o
obj-$(CONFIG_FTGPIO010) += ftgpio010.o

111
drivers/gpio/ftgpio010.c Normal file
View File

@@ -0,0 +1,111 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Faraday Technology's FTGPIO010 controller.
*/
#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include <asm/gpio.h>
struct ftgpio010_regs {
u32 out;
u32 in;
u32 direction; // 1 - output
u32 reserved;
u32 set;
u32 clear;
};
struct ftgpio010_plat {
struct ftgpio010_regs __iomem *regs;
};
static int ftgpio010_direction_input(struct udevice *dev, unsigned int pin)
{
struct ftgpio010_plat *plat = dev_get_plat(dev);
struct ftgpio010_regs *const regs = plat->regs;
clrbits_le32(&regs->direction, 1 << pin);
return 0;
}
static int ftgpio010_direction_output(struct udevice *dev, unsigned int pin,
int val)
{
struct ftgpio010_plat *plat = dev_get_plat(dev);
struct ftgpio010_regs *const regs = plat->regs;
/* change the data first, then the direction. to avoid glitch */
out_le32(val ? &regs->set : &regs->clear, 1 << pin);
setbits_le32(&regs->direction, 1 << pin);
return 0;
}
static int ftgpio010_get_value(struct udevice *dev, unsigned int pin)
{
struct ftgpio010_plat *plat = dev_get_plat(dev);
struct ftgpio010_regs *const regs = plat->regs;
return in_le32(&regs->in) >> pin & 1;
}
static int ftgpio010_set_value(struct udevice *dev, unsigned int pin, int val)
{
struct ftgpio010_plat *plat = dev_get_plat(dev);
struct ftgpio010_regs *const regs = plat->regs;
out_le32(val ? &regs->set : &regs->clear, 1 << pin);
return 0;
}
static int ftgpio010_get_function(struct udevice *dev, unsigned int pin)
{
struct ftgpio010_plat *plat = dev_get_plat(dev);
struct ftgpio010_regs *const regs = plat->regs;
if (in_le32(&regs->direction) >> pin & 1)
return GPIOF_OUTPUT;
return GPIOF_INPUT;
}
static int ftgpio010_probe(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->gpio_count = ofnode_read_u32_default(dev_ofnode(dev),
"nr-gpios", 32);
return 0;
}
static int ftgpio010_of_to_plat(struct udevice *dev)
{
struct ftgpio010_plat *plat = dev_get_plat(dev);
plat->regs = dev_read_addr_ptr(dev);
return 0;
}
static const struct dm_gpio_ops ftgpio010_ops = {
.direction_input = ftgpio010_direction_input,
.direction_output = ftgpio010_direction_output,
.get_value = ftgpio010_get_value,
.set_value = ftgpio010_set_value,
.get_function = ftgpio010_get_function,
};
static const struct udevice_id ftgpio010_ids[] = {
{ .compatible = "faraday,ftgpio010" },
{ }
};
U_BOOT_DRIVER(ftgpio010) = {
.name = "ftgpio010",
.id = UCLASS_GPIO,
.of_match = ftgpio010_ids,
.ops = &ftgpio010_ops,
.of_to_plat = ftgpio010_of_to_plat,
.plat_auto = sizeof(struct ftgpio010_plat),
.probe = ftgpio010_probe,
};

View File

@@ -21,6 +21,7 @@
#include <net.h>
#include <phy.h>
#include <power-domain.h>
#include <soc.h>
#include <linux/bitops.h>
#include <linux/soc/ti/ti-udma.h>
@@ -127,6 +128,8 @@ struct am65_cpsw_priv {
bool has_phy;
ofnode phy_node;
u32 phy_addr;
bool mdio_manual_mode;
};
#ifdef PKTSIZE_ALIGN
@@ -541,6 +544,20 @@ static const struct eth_ops am65_cpsw_ops = {
.read_rom_hwaddr = am65_cpsw_read_rom_hwaddr,
};
static const struct soc_attr k3_mdio_soc_data[] = {
{ .family = "AM62X", .revision = "SR1.0" },
{ .family = "AM64X", .revision = "SR1.0" },
{ .family = "AM64X", .revision = "SR2.0" },
{ .family = "AM65X", .revision = "SR1.0" },
{ .family = "AM65X", .revision = "SR2.0" },
{ .family = "J7200", .revision = "SR1.0" },
{ .family = "J7200", .revision = "SR2.0" },
{ .family = "J721E", .revision = "SR1.0" },
{ .family = "J721E", .revision = "SR1.1" },
{ .family = "J721S2", .revision = "SR1.0" },
{ /* sentinel */ },
};
static int am65_cpsw_mdio_init(struct udevice *dev)
{
struct am65_cpsw_priv *priv = dev_get_priv(dev);
@@ -552,7 +569,8 @@ static int am65_cpsw_mdio_init(struct udevice *dev)
cpsw_common->bus = cpsw_mdio_init(dev->name,
cpsw_common->mdio_base,
cpsw_common->bus_freq,
clk_get_rate(&cpsw_common->fclk));
clk_get_rate(&cpsw_common->fclk),
priv->mdio_manual_mode);
if (!cpsw_common->bus)
return -EFAULT;
@@ -657,6 +675,10 @@ static int am65_cpsw_port_probe(struct udevice *dev)
sprintf(portname, "%s%s", dev->parent->name, dev->name);
device_set_name(dev, portname);
priv->mdio_manual_mode = false;
if (soc_device_match(k3_mdio_soc_data))
priv->mdio_manual_mode = true;
ret = am65_cpsw_ofdata_parse_phy(dev);
if (ret)
goto out;

View File

@@ -922,7 +922,8 @@ int _cpsw_register(struct cpsw_priv *priv)
idx = idx + 1;
}
priv->bus = cpsw_mdio_init(priv->dev->name, data->mdio_base, 0, 0);
priv->bus = cpsw_mdio_init(priv->dev->name, data->mdio_base, 0, 0,
false);
if (!priv->bus)
return -EFAULT;

View File

@@ -23,6 +23,11 @@ struct cpsw_mdio_regs {
#define CONTROL_FAULT_ENABLE BIT(18)
#define CONTROL_DIV_MASK GENMASK(15, 0)
#define MDIO_MAN_MDCLK_O BIT(2)
#define MDIO_MAN_OE BIT(1)
#define MDIO_MAN_PIN BIT(0)
#define MDIO_MANUALMODE BIT(31)
u32 alive;
u32 link;
u32 linkintraw;
@@ -32,7 +37,9 @@ struct cpsw_mdio_regs {
u32 userintmasked;
u32 userintmaskset;
u32 userintmaskclr;
u32 __reserved_1[20];
u32 manualif;
u32 poll;
u32 __reserved_1[18];
struct {
u32 access;
@@ -51,6 +58,13 @@ struct cpsw_mdio_regs {
#define PHY_REG_MASK 0x1f
#define PHY_ID_MASK 0x1f
#define MDIO_BITRANGE 0x8000
#define C22_READ_PATTERN 0x6
#define C22_WRITE_PATTERN 0x5
#define C22_BITRANGE 0x8
#define PHY_BITRANGE 0x10
#define PHY_DATA_BITRANGE 0x8000
/*
* This timeout definition is a worst-case ultra defensive measure against
* unexpected controller lock ups. Ideally, we should never ever hit this
@@ -58,12 +72,239 @@ struct cpsw_mdio_regs {
*/
#define CPSW_MDIO_TIMEOUT 100 /* msecs */
enum cpsw_mdio_manual {
MDIO_PIN = 0,
MDIO_OE,
MDIO_MDCLK,
};
struct cpsw_mdio {
struct cpsw_mdio_regs *regs;
struct mii_dev *bus;
int div;
};
static void cpsw_mdio_disable(struct cpsw_mdio *mdio)
{
u32 reg;
/* Disable MDIO state machine */
reg = readl(&mdio->regs->control);
reg &= ~CONTROL_ENABLE;
writel(reg, &mdio->regs->control);
}
static void cpsw_mdio_enable_manual_mode(struct cpsw_mdio *mdio)
{
u32 reg;
/* set manual mode */
reg = readl(&mdio->regs->poll);
reg |= MDIO_MANUALMODE;
writel(reg, &mdio->regs->poll);
}
static void cpsw_mdio_sw_set_bit(struct cpsw_mdio *mdio,
enum cpsw_mdio_manual bit)
{
u32 reg;
reg = readl(&mdio->regs->manualif);
switch (bit) {
case MDIO_OE:
reg |= MDIO_MAN_OE;
writel(reg, &mdio->regs->manualif);
break;
case MDIO_PIN:
reg |= MDIO_MAN_PIN;
writel(reg, &mdio->regs->manualif);
break;
case MDIO_MDCLK:
reg |= MDIO_MAN_MDCLK_O;
writel(reg, &mdio->regs->manualif);
break;
default:
break;
};
}
static void cpsw_mdio_sw_clr_bit(struct cpsw_mdio *mdio,
enum cpsw_mdio_manual bit)
{
u32 reg;
reg = readl(&mdio->regs->manualif);
switch (bit) {
case MDIO_OE:
reg &= ~MDIO_MAN_OE;
writel(reg, &mdio->regs->manualif);
break;
case MDIO_PIN:
reg &= ~MDIO_MAN_PIN;
writel(reg, &mdio->regs->manualif);
break;
case MDIO_MDCLK:
reg = readl(&mdio->regs->manualif);
reg &= ~MDIO_MAN_MDCLK_O;
writel(reg, &mdio->regs->manualif);
break;
default:
break;
};
}
static int cpsw_mdio_test_man_bit(struct cpsw_mdio *mdio,
enum cpsw_mdio_manual bit)
{
u32 reg;
reg = readl(&mdio->regs->manualif);
return test_bit(bit, &reg);
}
static void cpsw_mdio_toggle_man_bit(struct cpsw_mdio *mdio,
enum cpsw_mdio_manual bit)
{
cpsw_mdio_sw_clr_bit(mdio, bit);
cpsw_mdio_sw_set_bit(mdio, bit);
}
static void cpsw_mdio_man_send_pattern(struct cpsw_mdio *mdio,
u32 bitrange, u32 val)
{
u32 i;
for (i = bitrange; i; i = i >> 1) {
if (i & val)
cpsw_mdio_sw_set_bit(mdio, MDIO_PIN);
else
cpsw_mdio_sw_clr_bit(mdio, MDIO_PIN);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
}
}
static void cpsw_mdio_sw_preamble(struct cpsw_mdio *mdio)
{
u32 i;
cpsw_mdio_sw_clr_bit(mdio, MDIO_OE);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_set_bit(mdio, MDIO_MDCLK);
for (i = 0; i < 32; i++) {
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
}
}
static int cpsw_mdio_sw_read(struct mii_dev *bus, int phy_id,
int dev_addr, int phy_reg)
{
struct cpsw_mdio *mdio = bus->priv;
u32 reg, i;
u8 ack;
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
cpsw_mdio_disable(mdio);
cpsw_mdio_enable_manual_mode(mdio);
cpsw_mdio_sw_preamble(mdio);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_set_bit(mdio, MDIO_OE);
/* Issue clause 22 MII read function {0,1,1,0} */
cpsw_mdio_man_send_pattern(mdio, C22_BITRANGE, C22_READ_PATTERN);
/* Send the device number MSB first */
cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_id);
/* Send the register number MSB first */
cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_reg);
/* Send turn around cycles */
cpsw_mdio_sw_clr_bit(mdio, MDIO_OE);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
ack = cpsw_mdio_test_man_bit(mdio, MDIO_PIN);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
reg = 0;
if (ack == 0) {
for (i = MDIO_BITRANGE; i; i = i >> 1) {
if (cpsw_mdio_test_man_bit(mdio, MDIO_PIN))
reg |= i;
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
}
} else {
for (i = MDIO_BITRANGE; i; i = i >> 1)
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
reg = 0xFFFF;
}
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_set_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_set_bit(mdio, MDIO_MDCLK);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
return reg;
}
static int cpsw_mdio_sw_write(struct mii_dev *bus, int phy_id,
int dev_addr, int phy_reg, u16 phy_data)
{
struct cpsw_mdio *mdio = bus->priv;
if ((phy_reg & ~PHY_REG_MASK) || (phy_id & ~PHY_ID_MASK))
return -EINVAL;
cpsw_mdio_disable(mdio);
cpsw_mdio_enable_manual_mode(mdio);
cpsw_mdio_sw_preamble(mdio);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_set_bit(mdio, MDIO_OE);
/* Issue clause 22 MII write function {0,1,0,1} */
cpsw_mdio_man_send_pattern(mdio, C22_BITRANGE, C22_WRITE_PATTERN);
/* Send the device number MSB first */
cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_id);
/* Send the register number MSB first */
cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_reg);
/* set turn-around cycles */
cpsw_mdio_sw_set_bit(mdio, MDIO_PIN);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_clr_bit(mdio, MDIO_PIN);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
/* Send Register data MSB first */
cpsw_mdio_man_send_pattern(mdio, PHY_DATA_BITRANGE, phy_data);
cpsw_mdio_sw_clr_bit(mdio, MDIO_OE);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
return 0;
}
/* wait until hardware is ready for another user access */
static int cpsw_mdio_wait_for_user_access(struct cpsw_mdio *mdio)
{
@@ -130,7 +371,7 @@ u32 cpsw_mdio_get_alive(struct mii_dev *bus)
}
struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
u32 bus_freq, int fck_freq)
u32 bus_freq, int fck_freq, bool manual_mode)
{
struct cpsw_mdio *cpsw_mdio;
int ret;
@@ -172,8 +413,14 @@ struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
*/
mdelay(1);
cpsw_mdio->bus->read = cpsw_mdio_read;
cpsw_mdio->bus->write = cpsw_mdio_write;
if (manual_mode) {
cpsw_mdio->bus->read = cpsw_mdio_sw_read;
cpsw_mdio->bus->write = cpsw_mdio_sw_write;
} else {
cpsw_mdio->bus->read = cpsw_mdio_read;
cpsw_mdio->bus->write = cpsw_mdio_write;
}
cpsw_mdio->bus->priv = cpsw_mdio;
snprintf(cpsw_mdio->bus->name, sizeof(cpsw_mdio->bus->name), name);

View File

@@ -11,7 +11,7 @@
struct cpsw_mdio;
struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
u32 bus_freq, int fck_freq);
u32 bus_freq, int fck_freq, bool manual_mode);
void cpsw_mdio_free(struct mii_dev *bus);
u32 cpsw_mdio_get_alive(struct mii_dev *bus);

View File

@@ -571,7 +571,8 @@ static int ks2_eth_probe(struct udevice *dev)
mdio_bus = cpsw_mdio_init("ethernet-mdio",
priv->mdio_base,
EMAC_MDIO_CLOCK_FREQ,
EMAC_MDIO_BUS_FREQ);
EMAC_MDIO_BUS_FREQ,
false);
if (!mdio_bus) {
pr_err("MDIO alloc failed\n");
return -ENOMEM;

35
include/configs/arbel.h Normal file
View File

@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Nuvoton Technology Corp.
*/
#ifndef __CONFIG_ARBEL_H
#define __CONFIG_ARBEL_H
#define CONFIG_SYS_SDRAM_BASE 0x0
#define CONFIG_SYS_BOOTMAPSZ (20 << 20)
#define CONFIG_SYS_INIT_RAM_ADDR CONFIG_SYS_SDRAM_BASE
#define CONFIG_SYS_INIT_RAM_SIZE 0x8000
/* Default environemnt variables */
#define CONFIG_EXTRA_ENV_SETTINGS "uimage_flash_addr=80200000\0" \
"stdin=serial\0" \
"stdout=serial\0" \
"stderr=serial\0" \
"ethact=gmac1\0" \
"autostart=no\0" \
"ethaddr=00:00:F7:A0:00:FC\0" \
"eth1addr=00:00:F7:A0:00:FD\0" \
"eth2addr=00:00:F7:A0:00:FE\0" \
"eth3addr=00:00:F7:A0:00:FF\0" \
"serverip=192.168.0.1\0" \
"ipaddr=192.168.0.2\0" \
"romboot=echo Booting Kernel from flash at 0x${uimage_flash_addr}; " \
"echo Using bootargs: ${bootargs};bootm ${uimage_flash_addr}\0" \
"earlycon=uart8250,mmio32,0xf0000000\0" \
"console=ttyS0,115200n8\0" \
"common_bootargs=setenv bootargs earlycon=${earlycon} root=/dev/ram " \
"console=${console} ramdisk_size=48000\0" \
"\0"
#endif

View File

@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2022 Nuvoton Technology Corp.
*
* Device Tree binding constants for NPCM8XX clock controller.
*/
#ifndef __DT_BINDINGS_CLOCK_NPCM8XX_H
#define __DT_BINDINGS_CLOCK_NPCM8XX_H
#define NPCM8XX_CLK_CPU 0
#define NPCM8XX_CLK_GFX_PIXEL 1
#define NPCM8XX_CLK_MC 2
#define NPCM8XX_CLK_ADC 3
#define NPCM8XX_CLK_AHB 4
#define NPCM8XX_CLK_TIMER 5
#define NPCM8XX_CLK_UART 6
#define NPCM8XX_CLK_UART2 7
#define NPCM8XX_CLK_MMC 8
#define NPCM8XX_CLK_SPI3 9
#define NPCM8XX_CLK_PCI 10
#define NPCM8XX_CLK_AXI 11
#define NPCM8XX_CLK_APB4 12
#define NPCM8XX_CLK_APB3 13
#define NPCM8XX_CLK_APB2 14
#define NPCM8XX_CLK_APB1 15
#define NPCM8XX_CLK_APB5 16
#define NPCM8XX_CLK_CLKOUT 17
#define NPCM8XX_CLK_GFX 18
#define NPCM8XX_CLK_SU 19
#define NPCM8XX_CLK_SU48 20
#define NPCM8XX_CLK_SDHC 21
#define NPCM8XX_CLK_SPI0 22
#define NPCM8XX_CLK_SPI1 23
#define NPCM8XX_CLK_SPIX 24
#define NPCM8XX_CLK_RG 25
#define NPCM8XX_CLK_RCP 26
#define NPCM8XX_CLK_PRE_ADC 27
#define NPCM8XX_CLK_ATB 28
#define NPCM8XX_CLK_PRE_CLK 29
#define NPCM8XX_CLK_TH 30
#define NPCM8XX_CLK_REFCLK 31
#define NPCM8XX_CLK_SYSBYPCK 32
#define NPCM8XX_CLK_MCBYPCK 33
#define NPCM8XX_CLK_PLL0 34
#define NPCM8XX_CLK_PLL1 35
#define NPCM8XX_CLK_PLL2 36
#define NPCM8XX_CLK_PLL2DIV2 37
#define NPCM8XX_NUM_CLOCKS (NPCM8XX_CLK_PLL2DIV2 + 1)
#endif

View File

@@ -0,0 +1,124 @@
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (c) 2020 Nuvoton Technology corporation.
#ifndef _DT_BINDINGS_NPCM8XX_RESET_H
#define _DT_BINDINGS_NPCM8XX_RESET_H
#define NPCM8XX_RESET_IPSRST1 0x20
#define NPCM8XX_RESET_IPSRST2 0x24
#define NPCM8XX_RESET_IPSRST3 0x34
#define NPCM8XX_RESET_IPSRST4 0x74
/* Reset lines on IP1 reset module (NPCM8XX_RESET_IPSRST1) */
#define NPCM8XX_RESET_GDMA0 3
#define NPCM8XX_RESET_UDC1 5
#define NPCM8XX_RESET_GMAC3 6
#define NPCM8XX_RESET_UART_2_3 7
#define NPCM8XX_RESET_UDC2 8
#define NPCM8XX_RESET_PECI 9
#define NPCM8XX_RESET_AES 10
#define NPCM8XX_RESET_UART_0_1 11
#define NPCM8XX_RESET_MC 12
#define NPCM8XX_RESET_SMB2 13
#define NPCM8XX_RESET_SMB3 14
#define NPCM8XX_RESET_SMB4 15
#define NPCM8XX_RESET_SMB5 16
#define NPCM8XX_RESET_PWM_M0 18
#define NPCM8XX_RESET_TIMER_0_4 19
#define NPCM8XX_RESET_TIMER_5_9 20
#define NPCM8XX_RESET_GMAC4 21
#define NPCM8XX_RESET_UDC4 22
#define NPCM8XX_RESET_UDC5 23
#define NPCM8XX_RESET_UDC6 24
#define NPCM8XX_RESET_UDC3 25
#define NPCM8XX_RESET_ADC 27
#define NPCM8XX_RESET_SMB6 28
#define NPCM8XX_RESET_SMB7 29
#define NPCM8XX_RESET_SMB0 30
#define NPCM8XX_RESET_SMB1 31
/* Reset lines on IP2 reset module (NPCM8XX_RESET_IPSRST2) */
#define NPCM8XX_RESET_MFT0 0
#define NPCM8XX_RESET_MFT1 1
#define NPCM8XX_RESET_MFT2 2
#define NPCM8XX_RESET_MFT3 3
#define NPCM8XX_RESET_MFT4 4
#define NPCM8XX_RESET_MFT5 5
#define NPCM8XX_RESET_MFT6 6
#define NPCM8XX_RESET_MFT7 7
#define NPCM8XX_RESET_MMC 8
#define NPCM8XX_RESET_GFX_SYS 10
#define NPCM8XX_RESET_AHB_PCIBRG 11
#define NPCM8XX_RESET_VDMA 12
#define NPCM8XX_RESET_ECE 13
#define NPCM8XX_RESET_VCD 14
#define NPCM8XX_RESET_VIRUART1 16
#define NPCM8XX_RESET_VIRUART2 17
#define NPCM8XX_RESET_SIOX1 18
#define NPCM8XX_RESET_SIOX2 19
#define NPCM8XX_RESET_BT 20
#define NPCM8XX_RESET_3DES 21
#define NPCM8XX_RESET_PSPI2 23
#define NPCM8XX_RESET_GMAC2 25
#define NPCM8XX_RESET_USBH1 26
#define NPCM8XX_RESET_GMAC1 28
#define NPCM8XX_RESET_CP1 31
/* Reset lines on IP3 reset module (NPCM8XX_RESET_IPSRST3) */
#define NPCM8XX_RESET_PWM_M1 0
#define NPCM8XX_RESET_SMB12 1
#define NPCM8XX_RESET_SPIX 2
#define NPCM8XX_RESET_SMB13 3
#define NPCM8XX_RESET_UDC0 4
#define NPCM8XX_RESET_UDC7 5
#define NPCM8XX_RESET_UDC8 6
#define NPCM8XX_RESET_UDC9 7
#define NPCM8XX_RESET_USBHUB 8
#define NPCM8XX_RESET_PCI_MAILBOX 9
#define NPCM8XX_RESET_GDMA1 10
#define NPCM8XX_RESET_GDMA2 11
#define NPCM8XX_RESET_SMB14 12
#define NPCM8XX_RESET_SHA 13
#define NPCM8XX_RESET_SEC_ECC 14
#define NPCM8XX_RESET_PCIE_RC 15
#define NPCM8XX_RESET_TIMER_10_14 16
#define NPCM8XX_RESET_RNG 17
#define NPCM8XX_RESET_SMB15 18
#define NPCM8XX_RESET_SMB8 19
#define NPCM8XX_RESET_SMB9 20
#define NPCM8XX_RESET_SMB10 21
#define NPCM8XX_RESET_SMB11 22
#define NPCM8XX_RESET_ESPI 23
#define NPCM8XX_RESET_USBPHY1 24
#define NPCM8XX_RESET_USBPHY2 25
/* Reset lines on IP4 reset module (NPCM8XX_RESET_IPSRST4) */
#define NPCM8XX_RESET_SMB16 0
#define NPCM8XX_RESET_SMB17 1
#define NPCM8XX_RESET_SMB18 2
#define NPCM8XX_RESET_SMB19 3
#define NPCM8XX_RESET_SMB20 4
#define NPCM8XX_RESET_SMB21 5
#define NPCM8XX_RESET_SMB22 6
#define NPCM8XX_RESET_SMB23 7
#define NPCM8XX_RESET_I3C0 8
#define NPCM8XX_RESET_I3C1 9
#define NPCM8XX_RESET_I3C2 10
#define NPCM8XX_RESET_I3C3 11
#define NPCM8XX_RESET_I3C4 12
#define NPCM8XX_RESET_I3C5 13
#define NPCM8XX_RESET_UART4 16
#define NPCM8XX_RESET_UART5 17
#define NPCM8XX_RESET_UART6 18
#define NPCM8XX_RESET_PCIMBX2 19
#define NPCM8XX_RESET_SMB24 22
#define NPCM8XX_RESET_SMB25 23
#define NPCM8XX_RESET_SMB26 24
#define NPCM8XX_RESET_USBPHY3 25
#define NPCM8XX_RESET_PCIRCPHY 27
#define NPCM8XX_RESET_PWM_M2 28
#define NPCM8XX_RESET_JTM1 29
#define NPCM8XX_RESET_JTM2 30
#define NPCM8XX_RESET_USBH2 31
#endif

View File

@@ -103,6 +103,19 @@ phys_size_t get_effective_memsize(void);
int testdram(void);
/**
* arch_setup_dest_addr() - Fix up initial reloc address
*
* This is called in generic board init sequence in common/board_f.c at the end
* of the setup_dest_addr() initcall. Each architecture could provide this
* function to make adjustments to the initial reloc address.
*
* If an implementation is not provided, it will just be a nop stub.
*
* Return: 0 if OK
*/
int arch_setup_dest_addr(void);
/**
* arch_reserve_stacks() - Reserve all necessary stacks
*