arm: mvebu: Support for 98DX25xx/98DX35xx SoC
Add support for the Allecat5/Alleycat5X SoC. These are L3 switches with an integrated CPU (referred to as the CnM block in Marvell's documentation). These have dual ARMv8.2 CPUs (Cortex-A55). This support has been ported from Marvell's SDK which is based on a much older version of U-Boot. Signed-off-by: Chris Packham <judge.packham@gmail.com>
This commit is contained in:
parent
c249938214
commit
7d7bb99e22
277
arch/arm/dts/ac5-98dx25xx.dtsi
Normal file
277
arch/arm/dts/ac5-98dx25xx.dtsi
Normal file
@ -0,0 +1,277 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Device Tree For AC5.
|
||||
*
|
||||
* Copyright (C) 2021 Marvell
|
||||
* Copyright (C) 2022 Allied Telesis Labs
|
||||
*/
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/ {
|
||||
model = "Marvell AC5 SoC";
|
||||
compatible = "marvell,ac5";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu-map {
|
||||
cluster0 {
|
||||
core0 {
|
||||
cpu = <&cpu0>;
|
||||
};
|
||||
core1 {
|
||||
cpu = <&cpu1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&l2>;
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x0 0x100>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&l2>;
|
||||
};
|
||||
|
||||
l2: l2-cache {
|
||||
compatible = "cache";
|
||||
};
|
||||
};
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-0.2";
|
||||
method = "smc";
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_PPI 8 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,armv8-pmuv3";
|
||||
interrupts = <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
dma-ranges;
|
||||
|
||||
internal-regs@7f000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
/* 16M internal register @ 0x7f00_0000 */
|
||||
ranges = <0x0 0x0 0x7f000000 0x1000000>;
|
||||
dma-coherent;
|
||||
|
||||
uart0: serial@12000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x12000 0x100>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-io-width = <1>;
|
||||
clocks = <&cnm_clock>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uart1: serial@12100 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x12100 0x100>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <1>;
|
||||
clocks = <&cnm_clock>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart2: serial@12200 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x12200 0x100>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <1>;
|
||||
clocks = <&cnm_clock>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart3: serial@12300 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x12300 0x100>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <1>;
|
||||
clocks = <&cnm_clock>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mdio: mdio@22004 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0x22004 0x4>;
|
||||
clocks = <&cnm_clock>;
|
||||
};
|
||||
|
||||
i2c0: i2c@11000 {
|
||||
compatible = "marvell,mv78230-i2c";
|
||||
reg = <0x11000 0x20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
clocks = <&cnm_clock>;
|
||||
clock-names = "core";
|
||||
interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency=<100000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c1: i2c@11100 {
|
||||
compatible = "marvell,mv78230-i2c";
|
||||
reg = <0x11100 0x20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
clocks = <&cnm_clock>;
|
||||
clock-names = "core";
|
||||
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency=<100000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpio0: gpio@18100 {
|
||||
compatible = "marvell,orion-gpio";
|
||||
reg = <0x18100 0x40>;
|
||||
ngpios = <32>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
gpio1: gpio@18140 {
|
||||
reg = <0x18140 0x40>;
|
||||
compatible = "marvell,orion-gpio";
|
||||
ngpios = <14>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Dedicated section for devices behind 32bit controllers so we
|
||||
* can configure specific DMA mapping for them
|
||||
*/
|
||||
behind-32bit-controller@7f000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <0x2>;
|
||||
#size-cells = <0x2>;
|
||||
ranges = <0x0 0x0 0x0 0x7f000000 0x0 0x1000000>;
|
||||
/* Host phy ram starts at 0x200M */
|
||||
dma-ranges = <0x0 0x0 0x2 0x0 0x1 0x0>;
|
||||
dma-coherent;
|
||||
|
||||
eth0: ethernet@20000 {
|
||||
compatible = "marvell,armada-ac5-neta";
|
||||
reg = <0x0 0x20000 0x0 0x4000>;
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cnm_clock>;
|
||||
phy-mode = "sgmii";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
eth1: ethernet@24000 {
|
||||
compatible = "marvell,armada-ac5-neta";
|
||||
reg = <0x0 0x24000 0x0 0x4000>;
|
||||
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cnm_clock>;
|
||||
phy-mode = "sgmii";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb0: usb@80000 {
|
||||
compatible = "marvell,ac5-ehci";
|
||||
reg = <0x0 0x80000 0x0 0x500>;
|
||||
interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb1: usb@a0000 {
|
||||
compatible = "marvell,ac5-ehci";
|
||||
reg = <0x0 0xa0000 0x0 0x500>;
|
||||
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
pinctrl0: pinctrl@80020100 {
|
||||
compatible = "marvell,mvebu-pinctrl";
|
||||
reg = <0 0x80020100 0 0x20>;
|
||||
pin-count = <46>;
|
||||
max-func = <0xf>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
spi0: spi@805a0000 {
|
||||
compatible = "marvell,armada-3700-spi";
|
||||
reg = <0x0 0x805a0000 0x0 0x50>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
clocks = <&spi_clock>;
|
||||
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-cs = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi1: spi@805a8000 {
|
||||
compatible = "marvell,armada-3700-spi";
|
||||
reg = <0x0 0x805a8000 0x0 0x50>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
clocks = <&spi_clock>;
|
||||
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-cs = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gic: interrupt-controller@80600000 {
|
||||
compatible = "arm,gic-v3";
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-controller;
|
||||
reg = <0x0 0x80600000 0x0 0x10000>, /* GICD */
|
||||
<0x0 0x80660000 0x0 0x40000>; /* GICR */
|
||||
interrupts = <GIC_PPI 6 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
cnm_clock: cnm-clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <328000000>;
|
||||
};
|
||||
|
||||
spi_clock: spi-clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <200000000>;
|
||||
};
|
||||
};
|
||||
};
|
17
arch/arm/dts/ac5-98dx35xx.dtsi
Normal file
17
arch/arm/dts/ac5-98dx35xx.dtsi
Normal file
@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Device Tree For AC5X.
|
||||
*
|
||||
* Copyright (C) 2022 Allied Telesis Labs
|
||||
*/
|
||||
|
||||
#include "ac5-98dx25xx.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Marvell AC5X SoC";
|
||||
compatible = "marvell,ac5x", "marvell,ac5";
|
||||
};
|
||||
|
||||
&cnm_clock {
|
||||
clock-frequency = <325000000>;
|
||||
};
|
@ -50,6 +50,10 @@ config ARMADA_8K
|
||||
bool
|
||||
select ARM64
|
||||
|
||||
config ALLEYCAT_5
|
||||
bool
|
||||
select ARM64
|
||||
|
||||
# Armada PLL frequency (used for NAND clock generation)
|
||||
config SYS_MVEBU_PLL_CLOCK
|
||||
int
|
||||
|
@ -6,6 +6,7 @@ ifdef CONFIG_ARM64
|
||||
|
||||
obj-$(CONFIG_ARMADA_3700) += armada3700/
|
||||
obj-$(CONFIG_ARMADA_8K) += armada8k/
|
||||
obj-$(CONFIG_ALLEYCAT_5) += alleycat5/
|
||||
obj-y += arm64-common.o
|
||||
|
||||
else # CONFIG_ARM64
|
||||
|
8
arch/arm/mach-mvebu/alleycat5/Makefile
Normal file
8
arch/arm/mach-mvebu/alleycat5/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Copyright (C) 2016 Stefan Roese <sr@denx.de>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y = cpu.o
|
||||
obj-y += soc.o
|
124
arch/arm/mach-mvebu/alleycat5/cpu.c
Normal file
124
arch/arm/mach-mvebu/alleycat5/cpu.c
Normal file
@ -0,0 +1,124 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2018 Marvell International Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include "soc.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define RAM_SIZE SZ_1G
|
||||
|
||||
static struct mm_region ac5_mem_map[] = {
|
||||
{
|
||||
/* RAM */
|
||||
.phys = CONFIG_SYS_SDRAM_BASE,
|
||||
.virt = CONFIG_SYS_SDRAM_BASE,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||
PTE_BLOCK_INNER_SHARE
|
||||
},
|
||||
{
|
||||
/* MMIO regions */
|
||||
.phys = 0x00000000,
|
||||
.virt = 0xa0000000,
|
||||
.size = 0x100000,
|
||||
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE |
|
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
||||
},
|
||||
{
|
||||
/* MMIO regions */
|
||||
.phys = 0x100000,
|
||||
.virt = 0x100000,
|
||||
.size = 0x3ff00000,
|
||||
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE |
|
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
||||
},
|
||||
{
|
||||
/* MMIO regions */
|
||||
.phys = 0x7F000000,
|
||||
.virt = 0x7F000000,
|
||||
.size = 0x21000000,
|
||||
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE |
|
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
||||
},
|
||||
{
|
||||
0,
|
||||
}
|
||||
};
|
||||
|
||||
struct mm_region *mem_map = ac5_mem_map;
|
||||
|
||||
void reset_cpu(void)
|
||||
{
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
soc_print_device_info();
|
||||
soc_print_clock_info();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alleycat5_dram_init(void)
|
||||
{
|
||||
#define SCRATCH_PAD_REG 0x80010018
|
||||
int ret;
|
||||
|
||||
/* override DDR_FW size if DTS is set with size */
|
||||
ret = fdtdec_setup_mem_size_base();
|
||||
if (ret == -EINVAL)
|
||||
gd->ram_size = readl(SCRATCH_PAD_REG) * 4ULL;
|
||||
|
||||
/* if DRAM size == 0, print error message */
|
||||
if (gd->ram_size == 0) {
|
||||
pr_err("DRAM size not initialized - check DRAM configuration\n");
|
||||
printf("\n Using temporary DRAM size of 512MB.\n\n");
|
||||
gd->ram_size = SZ_512M;
|
||||
}
|
||||
|
||||
ac5_mem_map[0].size = gd->ram_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alleycat5_dram_init_banksize(void)
|
||||
{
|
||||
/*
|
||||
* Config single DRAM bank
|
||||
*/
|
||||
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
|
||||
gd->bd->bi_dram[0].size = gd->ram_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_ref_clk
|
||||
*
|
||||
* return: reference clock in MHz
|
||||
*/
|
||||
u32 get_ref_clk(void)
|
||||
{
|
||||
return 25;
|
||||
}
|
298
arch/arm/mach-mvebu/alleycat5/soc.c
Normal file
298
arch/arm/mach-mvebu/alleycat5/soc.c
Normal file
@ -0,0 +1,298 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2018 Marvell International Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-armada8k/cache_llc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#include <dm/device.h>
|
||||
|
||||
#define DEVICE_ID_REG 0x7F90004C
|
||||
#define DEVICE_ID_MASK 0xffff0
|
||||
#define REV_ID_MASK 0xf
|
||||
#define DEVICE_ID_OFFSET 4
|
||||
#define REV_ID_OFFSET 0
|
||||
|
||||
#define DEVICE_SAR_REG 0x944F8204
|
||||
|
||||
#define DEVICE_ID_SUB_REV (MVEBU_REGISTER(0x2400230))
|
||||
#define DEVICE_ID_SUB_REV_OFFSET 7
|
||||
#define DEVICE_ID_SUB_REV_MASK (0xffff << DEVICE_ID_SUB_REV_OFFSET)
|
||||
|
||||
#define AC5X_DEV_ID 0x9800
|
||||
|
||||
struct soc_info {
|
||||
u32 dev_id;
|
||||
u32 rev_id;
|
||||
char *soc_name;
|
||||
};
|
||||
|
||||
static struct soc_info soc_info_table[] = {
|
||||
/* Two reserved entries for unidentified devices - don't change */
|
||||
{ 0xB4FF, 0x0, "Unidentified Alleycat5"},
|
||||
{ 0x98FF, 0x0, "Unidentified Alleycat5x"},
|
||||
|
||||
{ 0xB400, 0x2, "Alleycat5-plus 98DX2538-A2"},
|
||||
{ 0xB401, 0x2, "Alleycat5-plus 98DX2535-A2"},
|
||||
{ 0xB402, 0x2, "Alleycat5-plus 98DX2532-A2"},
|
||||
{ 0xB403, 0x2, "Alleycat5-plus 98DX2531-A2"},
|
||||
{ 0xB408, 0x2, "Alleycat5 98DX2528-A2"},
|
||||
{ 0xB409, 0x2, "Alleycat5 98DX2525-A2"},
|
||||
{ 0xB40A, 0x2, "Alleycat5 98DX2522-A2"},
|
||||
{ 0xB40B, 0x2, "Alleycat5 98DX2521-A2"},
|
||||
{ 0xB410, 0x2, "Alleycat5-lite 98DX2518-A2"},
|
||||
{ 0xB411, 0x2, "Alleycat5-lite 98DX2515-A2"},
|
||||
{ 0xB412, 0x2, "Alleycat5-lite 98DX2512-A2"},
|
||||
{ 0xB413, 0x2, "Alleycat5-lite 98DX2511-A2"},
|
||||
|
||||
{ 0xB400, 0x1, "Alleycat5-plus 98DX2538-A1"},
|
||||
{ 0xB401, 0x1, "Alleycat5-plus 98DX2535-A1"},
|
||||
{ 0xB402, 0x1, "Alleycat5-plus 98DX2532-A1"},
|
||||
{ 0xB403, 0x1, "Alleycat5-plus 98DX2531-A1"},
|
||||
{ 0xB408, 0x1, "Alleycat5 98DX2528-A1"},
|
||||
{ 0xB409, 0x1, "Alleycat5 98DX2525-A1"},
|
||||
{ 0xB40A, 0x1, "Alleycat5 98DX2522-A1"},
|
||||
{ 0xB40B, 0x1, "Alleycat5 98DX2521-A1"},
|
||||
{ 0xB410, 0x1, "Alleycat5-lite 98DX2518-A1"},
|
||||
{ 0xB411, 0x1, "Alleycat5-lite 98DX2515-A1"},
|
||||
{ 0xB412, 0x1, "Alleycat5-lite 98DX2512-A1"},
|
||||
{ 0xB413, 0x1, "Alleycat5-lite 98DX2511-A1"},
|
||||
{ 0x9800, 0x1, "Alleycat5X 98DX3500M-A1"},
|
||||
{ 0x9806, 0x1, "Alleycat5X 98DX3501M-A1"},
|
||||
{ 0x9801, 0x1, "Alleycat5X 98DX3510M-A1"},
|
||||
{ 0x9802, 0x1, "Alleycat5X 98DX3520M-A1"},
|
||||
{ 0x9803, 0x1, "Alleycat5X 98DX3530M-A1"},
|
||||
{ 0x9804, 0x1, "Alleycat5X 98DX3540M-A1"},
|
||||
{ 0x9805, 0x1, "Alleycat5X 98DX3550M-A1"},
|
||||
{ 0x9820, 0x1, "Alleycat5X 98DX3500-A1"},
|
||||
{ 0x9826, 0x1, "Alleycat5X 98DX3501-A1"},
|
||||
{ 0x9821, 0x1, "Alleycat5X 98DX3510-A1"},
|
||||
{ 0x9861, 0x1, "Alleycat5X 98DX3510H-A1"},
|
||||
{ 0x9841, 0x1, "Alleycat5X 98DX3510MH-A1"},
|
||||
{ 0x9822, 0x1, "Alleycat5X 98DX3520-A1"},
|
||||
{ 0x9823, 0x1, "Alleycat5X 98DX3530-A1"},
|
||||
{ 0x9863, 0x1, "Alleycat5X 98DX3530H-A1"},
|
||||
{ 0x9824, 0x1, "Alleycat5X 98DX3540-A1"},
|
||||
{ 0x9825, 0x1, "Alleycat5X 98DX3550-A1"},
|
||||
|
||||
{ 0xB400, 0x0, "Alleycat5-plus 98DX2538-A0"},
|
||||
{ 0xB401, 0x0, "Alleycat5-plus 98DX2535-A0"},
|
||||
{ 0xB402, 0x0, "Alleycat5-plus 98DX2532-A0"},
|
||||
{ 0xB403, 0x0, "Alleycat5-plus 98DX2531-A0"},
|
||||
{ 0xB408, 0x0, "Alleycat5 98DX2528-A0"},
|
||||
{ 0xB409, 0x0, "Alleycat5 98DX2525-A0"},
|
||||
{ 0xB40A, 0x0, "Alleycat5 98DX2522-A0"},
|
||||
{ 0xB40B, 0x0, "Alleycat5 98DX2521-A0"},
|
||||
{ 0xB410, 0x0, "Alleycat5-lite 98DX2518-A0"},
|
||||
{ 0xB411, 0x0, "Alleycat5-lite 98DX2515-A0"},
|
||||
{ 0xB412, 0x0, "Alleycat5-lite 98DX2512-A0"},
|
||||
{ 0xB413, 0x0, "Alleycat5-lite 98DX2511-A0"},
|
||||
{ 0x9800, 0x0, "Alleycat5X 98DX3500M-A0"},
|
||||
{ 0x9806, 0x0, "Alleycat5X 98DX3501M-A0"},
|
||||
{ 0x9801, 0x0, "Alleycat5X 98DX3510M-A0"},
|
||||
{ 0x9802, 0x0, "Alleycat5X 98DX3520M-A0"},
|
||||
{ 0x9803, 0x0, "Alleycat5X 98DX3530M-A0"},
|
||||
{ 0x9804, 0x0, "Alleycat5X 98DX3540M-A0"},
|
||||
{ 0x9805, 0x0, "Alleycat5X 98DX3550M-A0"},
|
||||
{ 0x9820, 0x0, "Alleycat5X 98DX3500-A0"},
|
||||
{ 0x9826, 0x0, "Alleycat5X 98DX3501-A0"},
|
||||
{ 0x9821, 0x0, "Alleycat5X 98DX3510-A0"},
|
||||
{ 0x9861, 0x0, "Alleycat5X 98DX3510H-A0"},
|
||||
{ 0x9841, 0x0, "Alleycat5X 98DX3510MH-A0"},
|
||||
{ 0x9822, 0x0, "Alleycat5X 98DX3520-A0"},
|
||||
{ 0x9823, 0x0, "Alleycat5X 98DX3530-A0"},
|
||||
{ 0x9863, 0x0, "Alleycat5X 98DX3530H-A0"},
|
||||
{ 0x9824, 0x0, "Alleycat5X 98DX3540-A0"},
|
||||
{ 0x9825, 0x0, "Alleycat5X 98DX3550-A0"},
|
||||
};
|
||||
|
||||
#define BIT_VAL(b) ((1ULL << ((b) + 1)) - 1)
|
||||
#define BIT_RANGE(bl, bh) (BIT_VAL(bh) - BIT_VAL((bl) - 1))
|
||||
|
||||
#define PLL_MAX_CHOICE 4
|
||||
|
||||
#define CPU_TYPE_AC5 0
|
||||
#define CPU_TYPE_AC5x 1
|
||||
#define CPU_TYPE_LAST 2
|
||||
|
||||
enum mvebu_sar_opts {
|
||||
SAR_CPU_FREQ = 0,
|
||||
SAR_DDR_FREQ,
|
||||
SAR_AP_FABRIC_FREQ,
|
||||
SAR_CP_FABRIC_FREQ,
|
||||
SAR_CP0_PCIE0_CLK,
|
||||
SAR_CP0_PCIE1_CLK,
|
||||
SAR_CP1_PCIE0_CLK,
|
||||
SAR_CP1_PCIE1_CLK,
|
||||
SAR_BOOT_SRC,
|
||||
SAR_MAX_IDX
|
||||
};
|
||||
|
||||
static const u32 pll_freq_tbl[CPU_TYPE_LAST][SAR_AP_FABRIC_FREQ + 1][PLL_MAX_CHOICE] = {
|
||||
[CPU_TYPE_AC5] = {
|
||||
[SAR_CPU_FREQ] = {
|
||||
800, 1200, 1400, 1000
|
||||
},
|
||||
[SAR_DDR_FREQ] = {
|
||||
1200, 800, 0, 0
|
||||
},
|
||||
[SAR_AP_FABRIC_FREQ] = {
|
||||
396, 290, 197, 0
|
||||
},
|
||||
},
|
||||
[CPU_TYPE_AC5x] = {
|
||||
[SAR_CPU_FREQ] = {
|
||||
800, 1200, 1500, 1600
|
||||
},
|
||||
[SAR_DDR_FREQ] = {
|
||||
1200, 800, 0, 0
|
||||
},
|
||||
[SAR_AP_FABRIC_FREQ] = {
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const u32 soc_sar_masks_tbl[CPU_TYPE_LAST][SAR_AP_FABRIC_FREQ + 1] = {
|
||||
[CPU_TYPE_AC5] = {
|
||||
[SAR_CPU_FREQ] = BIT_RANGE(18, 20),
|
||||
[SAR_DDR_FREQ] = BIT_RANGE(16, 17),
|
||||
[SAR_AP_FABRIC_FREQ] = BIT_RANGE(22, 23),
|
||||
},
|
||||
[CPU_TYPE_AC5x] = {
|
||||
[SAR_CPU_FREQ] = BIT_RANGE(8, 10),
|
||||
[SAR_DDR_FREQ] = BIT_RANGE(6, 7),
|
||||
[SAR_AP_FABRIC_FREQ] = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static int get_soc_type_rev(u32 *type, u32 *rev)
|
||||
{
|
||||
*type = (readl(DEVICE_ID_REG) & DEVICE_ID_MASK) >> DEVICE_ID_OFFSET;
|
||||
*rev = (readl(DEVICE_ID_REG) & REV_ID_MASK) >> REV_ID_OFFSET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_one_sar_freq(int cpu_type, u32 sar_reg_val, enum mvebu_sar_opts sar_opt, u32 *freq)
|
||||
{
|
||||
u32 mask;
|
||||
unsigned char choice;
|
||||
|
||||
mask = soc_sar_masks_tbl[cpu_type][sar_opt];
|
||||
choice = (sar_reg_val & mask) >> (__builtin_ffs(mask) - 1);
|
||||
*freq = pll_freq_tbl[cpu_type][sar_opt][choice];
|
||||
}
|
||||
|
||||
void get_sar_freq(struct sar_freq_modes *sar_freq)
|
||||
{
|
||||
int cpu_type;
|
||||
u32 soc_type, rev;
|
||||
u32 sar_reg_val = readl(DEVICE_SAR_REG);
|
||||
|
||||
get_soc_type_rev(&soc_type, &rev);
|
||||
cpu_type = (soc_type & 0xFF00) == AC5X_DEV_ID ? CPU_TYPE_AC5x : CPU_TYPE_AC5;
|
||||
|
||||
get_one_sar_freq(cpu_type, sar_reg_val, SAR_CPU_FREQ, &sar_freq->p_clk);
|
||||
get_one_sar_freq(cpu_type, sar_reg_val, SAR_AP_FABRIC_FREQ, &sar_freq->nb_clk);
|
||||
get_one_sar_freq(cpu_type, sar_reg_val, SAR_DDR_FREQ, &sar_freq->d_clk);
|
||||
}
|
||||
|
||||
static int get_soc_table_index(u32 *index)
|
||||
{
|
||||
u32 soc_type;
|
||||
u32 rev, i, ret = 1;
|
||||
|
||||
*index = 0;
|
||||
get_soc_type_rev(&soc_type, &rev);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(soc_info_table) && ret != 0; i++) {
|
||||
if (soc_type != soc_info_table[i].dev_id ||
|
||||
rev != soc_info_table[i].rev_id)
|
||||
continue;
|
||||
|
||||
*index = i;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret && ((soc_type & 0xFF00) == AC5X_DEV_ID))
|
||||
*index = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_soc_name(char **soc_name)
|
||||
{
|
||||
u32 index;
|
||||
|
||||
get_soc_table_index(&index);
|
||||
*soc_name = soc_info_table[index].soc_name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print device's SoC name and AP & CP information */
|
||||
void soc_print_device_info(void)
|
||||
{
|
||||
char *soc_name = NULL;
|
||||
|
||||
get_soc_name(&soc_name);
|
||||
|
||||
printf("SoC: %s\n", soc_name);
|
||||
}
|
||||
|
||||
void soc_print_clock_info(void)
|
||||
{
|
||||
struct sar_freq_modes sar_freq;
|
||||
|
||||
get_sar_freq(&sar_freq);
|
||||
printf("Clock: CPU %4d MHz\n", sar_freq.p_clk);
|
||||
printf("\tDDR %4d MHz\n", sar_freq.d_clk);
|
||||
printf("\tFABRIC %4d MHz\n", sar_freq.nb_clk);
|
||||
printf("\tMSS %4d MHz\n", 200);
|
||||
}
|
||||
|
||||
/*
|
||||
* Override of __weak int mach_cpu_init(void) :
|
||||
* SoC/machine dependent CPU setup
|
||||
*/
|
||||
int mach_cpu_init(void)
|
||||
{
|
||||
u32 phy_i;
|
||||
u64 new_val, phy_base = 0x7F080800;
|
||||
|
||||
/* Init USB PHY */
|
||||
#define USB_STEPPING 0x20000
|
||||
#define WRITE_MASK(addr, mask, val) \
|
||||
{ new_val = (readl(addr) & (~(mask))) | (val);\
|
||||
writel(new_val, addr); }
|
||||
|
||||
for (phy_i = 0; phy_i < 2; phy_i++, phy_base += USB_STEPPING) {
|
||||
WRITE_MASK(phy_base + 0x4, 0x3, 0x2);
|
||||
WRITE_MASK(phy_base + 0xC, 0x3000000, 0x2000000);
|
||||
WRITE_MASK(phy_base + 0x1C, 0x3, 0x2);
|
||||
WRITE_MASK(phy_base + 0x0, 0x1FF007F, 0x600005);
|
||||
WRITE_MASK(phy_base + 0xC, 0x000F000, 0x0002000);
|
||||
/* Calibration Threshold Setting = 4*/
|
||||
WRITE_MASK(phy_base + 0x8, 0x700, 0x400)
|
||||
WRITE_MASK(phy_base + 0x14, 0x000000F, 0x000000a);
|
||||
/* Change AMP to 4*/
|
||||
WRITE_MASK(phy_base + 0xC, 0x3700000, 0x3400000);
|
||||
WRITE_MASK(phy_base + 0x4, 0x3, 0x3);
|
||||
/* Impedance calibration triggering is performed by USB probe */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
u32 type, rev;
|
||||
|
||||
get_soc_type_rev(&type, &rev);
|
||||
|
||||
return 0;
|
||||
}
|
7
arch/arm/mach-mvebu/alleycat5/soc.h
Normal file
7
arch/arm/mach-mvebu/alleycat5/soc.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
|
||||
#ifndef _ALLEYCAT5_SOC_H
|
||||
#define _ALLEYCAT5_SOC_H
|
||||
void soc_print_device_info(void);
|
||||
void soc_print_clock_info(void);
|
||||
#endif /* _ALLEYCAT5_SOC_H */
|
@ -53,6 +53,8 @@ __weak int dram_init_banksize(void)
|
||||
return a8k_dram_init_banksize();
|
||||
else if (CONFIG_IS_ENABLED(ARMADA_3700))
|
||||
return a3700_dram_init_banksize();
|
||||
else if (CONFIG_IS_ENABLED(ALLEYCAT_5))
|
||||
return alleycat5_dram_init_banksize();
|
||||
else
|
||||
return fdtdec_setup_memory_banksize();
|
||||
}
|
||||
@ -68,6 +70,9 @@ __weak int dram_init(void)
|
||||
if (CONFIG_IS_ENABLED(ARMADA_3700))
|
||||
return a3700_dram_init();
|
||||
|
||||
if (CONFIG_IS_ENABLED(ALLEYCAT_5))
|
||||
return alleycat5_dram_init();
|
||||
|
||||
if (fdtdec_setup_mem_size_base() != 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -174,6 +174,10 @@ int a3700_dram_init_banksize(void);
|
||||
/* A3700 PCIe regions fixer for device tree */
|
||||
int a3700_fdt_fix_pcie_regions(void *blob);
|
||||
|
||||
/* Alleycat5 dram functions */
|
||||
int alleycat5_dram_init(void);
|
||||
int alleycat5_dram_init_banksize(void);
|
||||
|
||||
/*
|
||||
* get_ref_clk
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user