arm: mmp: add initial support for PXA1908 SoC

Add initial support for Marvell PXA1908. The SoC has 4 Cortex-A53 cores,
a GC7000UL GPU and a variety of peripheral controllers.

Signed-off-by: Duje Mihanović <duje.mihanovic@skole.hr>
Reviewed-by: Stefan Roese <sr@denx.de>
This commit is contained in:
Duje Mihanović
2025-01-24 16:47:49 +01:00
committed by Stefan Roese
parent 2d84e1519c
commit 08b27fce29
9 changed files with 265 additions and 0 deletions

View File

@@ -386,6 +386,14 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-marvell.git
F: drivers/pci/pci-aardvark.c
F: drivers/pci/pci_mvebu.c
ARM MARVELL PXA1908
M: Duje Mihanović <duje.mihanovic@skole.hr>
S: Maintained
T: git git://git.dujemihanovic.xyz/u-boot.git
F: arch/arm/dts/pxa1908*
F: arch/arm/mach-mmp/
F: include/configs/pxa1908.h
ARM MARVELL SERIAL DRIVERS
M: Pali Rohár <pali@kernel.org>
M: Stefan Roese <sr@denx.de>

View File

@@ -842,6 +842,15 @@ config ARCH_MEDIATEK
Support for the MediaTek SoCs family developed by MediaTek Inc.
Please refer to doc/README.mediatek for more information.
config ARCH_MMP
bool "Marvell MMP"
select ARM64
select DM
select DM_SERIAL
select OF_CONTROL
select SAVE_PREV_BL_FDT_ADDR
select SAVE_PREV_BL_INITRAMFS_START_ADDR
config ARCH_LPC32XX
bool "NXP LPC32xx platform"
select CPU_ARM926EJS
@@ -2310,6 +2319,8 @@ source "arch/arm/mach-meson/Kconfig"
source "arch/arm/mach-mediatek/Kconfig"
source "arch/arm/mach-mmp/Kconfig"
source "arch/arm/mach-qemu/Kconfig"
source "arch/arm/mach-rockchip/Kconfig"

View File

@@ -69,6 +69,7 @@ machine-$(CONFIG_ARCH_KIRKWOOD) += kirkwood
machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
machine-$(CONFIG_ARCH_MEDIATEK) += mediatek
machine-$(CONFIG_ARCH_MESON) += meson
machine-$(CONFIG_ARCH_MMP) += mmp
machine-$(CONFIG_ARCH_MVEBU) += mvebu
machine-$(CONFIG_ARCH_NEXELL) += nexell
machine-$(CONFIG_ARCH_NPCM) += npcm

106
arch/arm/dts/pxa1908.dtsi Normal file
View File

@@ -0,0 +1,106 @@
// SPDX-License-Identifier: GPL-2.0-only
/dts-v1/;
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
model = "Marvell Armada PXA1908";
compatible = "marvell,pxa1908";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0 0>;
enable-method = "psci";
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0 1>;
enable-method = "psci";
};
cpu2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0 2>;
enable-method = "psci";
};
cpu3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0 3>;
enable-method = "psci";
};
};
psci {
compatible = "arm,psci-0.2";
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)>;
};
soc {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
gic: interrupt-controller@d1df9000 {
compatible = "arm,gic-400";
reg = <0 0xd1df9000 0 0x1000>,
<0 0xd1dfa000 0 0x2000>,
/* The subsequent registers are guesses. */
<0 0xd1dfc000 0 0x2000>,
<0 0xd1dfe000 0 0x2000>;
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
interrupt-controller;
#interrupt-cells = <3>;
};
apb@d4000000 {
compatible = "simple-bus";
reg = <0 0xd4000000 0 0x200000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 0xd4000000 0x200000>;
uart0: serial@17000 {
compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0x17000 0x1000>;
clock-frequency = <14745600>;
reg-shift = <2>;
};
uart1: serial@18000 {
compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0x18000 0x1000>;
clock-frequency = <14745600>;
reg-shift = <2>;
};
uart2: serial@36000 {
compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0x36000 0x1000>;
clock-frequency = <117000000>;
reg-shift = <2>;
};
};
};
};

View File

@@ -0,0 +1,6 @@
if ARCH_MMP
config LNX_KRNL_IMG_TEXT_OFFSET_BASE
default TEXT_BASE
endif

View File

@@ -0,0 +1 @@
obj-y += board.o mmu.o

84
arch/arm/mach-mmp/board.c Normal file
View File

@@ -0,0 +1,84 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2024
* Duje Mihanović <duje.mihanovic@skole.hr>
*/
#include <errno.h>
#include <init.h>
#include <fdt_support.h>
#include <asm/io.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
/* Timer constants */
#define APBC_COUNTER_CLK_SEL 0xd4015064
#define COUNTER_BASE 0xd4101000
#define COUNTER_EN BIT(0)
#define COUNTER_HALT_ON_DEBUG BIT(1)
int timer_init(void)
{
u32 tmp = readl(APBC_COUNTER_CLK_SEL);
if ((tmp >> 16) != 0x319)
return -1;
/* Set timer frequency to 26MHz */
writel(tmp | 1, APBC_COUNTER_CLK_SEL);
writel(COUNTER_EN | COUNTER_HALT_ON_DEBUG, COUNTER_BASE);
gd->arch.timer_rate_hz = 26000000;
return 0;
}
int board_init(void)
{
return 0;
}
int dram_init(void)
{
if (fdtdec_setup_mem_size_base() != 0)
puts("fdtdec_setup_mem_size_base() has failed\n");
return 0;
}
#ifndef CONFIG_SYSRESET
void reset_cpu(void)
{
}
#endif
/* Stolen from arch/arm/mach-snapdragon/board.c */
int board_fdt_blob_setup(void **fdtp)
{
struct fdt_header *fdt;
bool internal_valid, external_valid;
int ret = 0;
fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
external_valid = fdt && !fdt_check_header(fdt);
internal_valid = !fdt_check_header(*fdtp);
/*
* There is no point returning an error here, U-Boot can't do anything useful in this situation.
* Bail out while we can still print a useful error message.
*/
if (!internal_valid && !external_valid)
panic("Internal FDT is invalid and no external FDT was provided! (fdt=%#llx)\n",
(phys_addr_t)fdt);
if (internal_valid) {
debug("Using built in FDT\n");
ret = -EEXIST;
} else {
debug("Using external FDT\n");
/* So we can use it before returning */
*fdtp = fdt;
}
return ret;
}

30
arch/arm/mach-mmp/mmu.c Normal file
View File

@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2024
* Duje Mihanović <duje.mihanovic@skole.hr>
*/
#include <asm/armv8/mmu.h>
#include <linux/sizes.h>
static struct mm_region pxa1908_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 2UL * SZ_1G,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
},
{
.virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 2UL * SZ_1G,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_INNER_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
{
0,
}
};
struct mm_region *mem_map = pxa1908_mem_map;

18
include/configs/pxa1908.h Normal file
View File

@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2024
* Duje Mihanović <duje.mihanovic@skole.hr>
*/
#ifndef __PXA1908_H
#define __PXA1908_H
#define CFG_SYS_SDRAM_BASE 0x1000000
#define CFG_SYS_INIT_RAM_ADDR 0x10000000
#define CFG_SYS_INIT_RAM_SIZE 0x4000
#define CFG_SYS_NS16550_IER 0x40
#define CFG_SYS_BAUDRATE_TABLE { 115200, 230400, 460800, 921600 }
#define CFG_EXTRA_ENV_SETTINGS \
"bootcmd=bootm $prevbl_initrd_start_addr\0"
#endif