[PATCH v3 0/6] arm: mvebu: Support for 98DX25xx/98DX35xx (AlleyCat5)

These patches are based on Marvell's bootloader for the AlleyCat5/5X which was based on u-boot 2018.03. I've split that code into consumable chunks and dropped as much unnecessary stuff as I can. I've also tried to sync the device trees as much as possible with the support that will land in Linux 6.0 although there are still some differences
Changes in v3: - Remove unnecessary changes to RX descriptor handling - Use dev_get_dma_range() to parse dma-ranges property from parent device. - None. Note some changes related to this have been requested and will be looked into I just wanted to get v3 out so the other changes could be reviewed. - Remove unnecessary dma-ranges property from ethernet nodes (mvneta now correctly parses the property from the parent node). - Keep soc_print_clock_info and soc_print_device_info local to alleycat5. - Remove MMC and UBIFS distroboot options (MMC driver is not currently functional, NAND is not populated on the RD-AC5X board) - Remove unnecessary Ethernet configuration - Remove unnecessary NAND configuration - Remove memory node from dts so the value passed by the DDR FW will be used
Changes in v2: - Use distro boot by default - remove unnecessary SPI-NOR partitions
Chris Packham (6): net: mvneta: Add support for AlleyCat5 usb: ehci: ehci-marvell: Support for marvell,ac5-ehci pinctrl: mvebu: Add AlleyCat5 support misc: mvebu: Add sample at reset driver arm: mvebu: Support for 98DX25xx/98DX35xx SoC arm: mvebu: Add RD-AC5X board
arch/arm/dts/Makefile | 3 +- arch/arm/dts/ac5-98dx25xx.dtsi | 290 +++++++++++++++++++++ arch/arm/dts/ac5-98dx35xx-rd.dts | 135 ++++++++++ arch/arm/dts/ac5-98dx35xx.dtsi | 17 ++ arch/arm/mach-mvebu/Kconfig | 13 +- arch/arm/mach-mvebu/Makefile | 1 + arch/arm/mach-mvebu/alleycat5/Makefile | 9 + arch/arm/mach-mvebu/alleycat5/clock.c | 49 ++++ arch/arm/mach-mvebu/alleycat5/clock.h | 11 + arch/arm/mach-mvebu/alleycat5/cpu.c | 129 +++++++++ arch/arm/mach-mvebu/alleycat5/soc.c | 229 ++++++++++++++++ arch/arm/mach-mvebu/alleycat5/soc.h | 6 + arch/arm/mach-mvebu/arm64-common.c | 5 + arch/arm/mach-mvebu/include/mach/cpu.h | 4 + board/Marvell/mvebu_alleycat-5/MAINTAINERS | 6 + board/Marvell/mvebu_alleycat-5/Makefile | 3 + board/Marvell/mvebu_alleycat-5/board.c | 35 +++ configs/mvebu_ac5_rd_defconfig | 88 +++++++ drivers/misc/Kconfig | 6 + drivers/misc/Makefile | 1 + drivers/misc/mvebu_sar/Makefile | 4 + drivers/misc/mvebu_sar/ac5_sar.c | 119 +++++++++ drivers/misc/mvebu_sar/sar-uclass.c | 146 +++++++++++ drivers/net/Kconfig | 2 +- drivers/net/mvneta.c | 43 ++- drivers/pinctrl/mvebu/Kconfig | 2 +- drivers/usb/host/Kconfig | 1 + drivers/usb/host/ehci-marvell.c | 57 +++- include/configs/mvebu_alleycat-5.h | 57 ++++ include/dm/uclass-id.h | 1 + include/fdtdec.h | 4 + include/mvebu/mvebu_chip_sar.h | 73 ++++++ include/mvebu/sar.h | 57 ++++ include/mvebu/var.h | 28 ++ include/sar-uclass.h | 23 ++ lib/fdtdec.c | 6 +- 36 files changed, 1647 insertions(+), 16 deletions(-) create mode 100644 arch/arm/dts/ac5-98dx25xx.dtsi create mode 100644 arch/arm/dts/ac5-98dx35xx-rd.dts create mode 100644 arch/arm/dts/ac5-98dx35xx.dtsi create mode 100644 arch/arm/mach-mvebu/alleycat5/Makefile create mode 100644 arch/arm/mach-mvebu/alleycat5/clock.c create mode 100644 arch/arm/mach-mvebu/alleycat5/clock.h create mode 100644 arch/arm/mach-mvebu/alleycat5/cpu.c create mode 100644 arch/arm/mach-mvebu/alleycat5/soc.c create mode 100644 arch/arm/mach-mvebu/alleycat5/soc.h create mode 100644 board/Marvell/mvebu_alleycat-5/MAINTAINERS create mode 100644 board/Marvell/mvebu_alleycat-5/Makefile create mode 100644 board/Marvell/mvebu_alleycat-5/board.c create mode 100644 configs/mvebu_ac5_rd_defconfig create mode 100644 drivers/misc/mvebu_sar/Makefile create mode 100644 drivers/misc/mvebu_sar/ac5_sar.c create mode 100644 drivers/misc/mvebu_sar/sar-uclass.c create mode 100644 include/configs/mvebu_alleycat-5.h create mode 100644 include/mvebu/mvebu_chip_sar.h create mode 100644 include/mvebu/sar.h create mode 100644 include/mvebu/var.h create mode 100644 include/sar-uclass.h

Add support for the AlleyCat5 SoC. This lacks the mbus from the other users of the mvneta.c driver so a new compatible string is needed to allow for a different window configuration.
Signed-off-by: Chris Packham judge.packham@gmail.com Reviewed-by: Stefan Roese sr@denx.de ---
Changes in v3: - Remove unnecessary changes to RX descriptor handling - Use dev_get_dma_range() to parse dma-ranges property from parent device.
drivers/net/Kconfig | 2 +- drivers/net/mvneta.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6bbbadc5ee..8df3dce6df 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -448,7 +448,7 @@ config MVGBE
config MVNETA bool "Marvell Armada XP/385/3700 network interface support" - depends on ARMADA_XP || ARMADA_38X || ARMADA_3700 + depends on ARMADA_XP || ARMADA_38X || ARMADA_3700 || ALLEYCAT_5 select PHYLIB select DM_MDIO help diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index d2c42c4396..0fbfad11d4 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -91,6 +91,8 @@ DECLARE_GLOBAL_DATA_PTR; #define MVNETA_WIN_SIZE_MASK (0xffff0000) #define MVNETA_BASE_ADDR_ENABLE 0x2290 #define MVNETA_BASE_ADDR_ENABLE_BIT 0x1 +#define MVNETA_AC5_CNM_DDR_TARGET 0x2 +#define MVNETA_AC5_CNM_DDR_ATTR 0xb #define MVNETA_PORT_ACCESS_PROTECT 0x2294 #define MVNETA_PORT_ACCESS_PROTECT_WIN0_RW 0x3 #define MVNETA_PORT_CONFIG 0x2400 @@ -282,6 +284,8 @@ struct mvneta_port { struct gpio_desc phy_reset_gpio; struct gpio_desc sfp_tx_disable_gpio; #endif + + uintptr_t dma_base; /* base address for DMA address decoding */ };
/* The mvneta_tx_desc and mvneta_rx_desc structures describe the @@ -1343,6 +1347,29 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp) mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable); }
+static void mvneta_conf_ac5_cnm_xbar_windows(struct mvneta_port *pp) +{ + int i; + + /* Clear all windows */ + for (i = 0; i < 6; i++) { + mvreg_write(pp, MVNETA_WIN_BASE(i), 0); + mvreg_write(pp, MVNETA_WIN_SIZE(i), 0); + + if (i < 4) + mvreg_write(pp, MVNETA_WIN_REMAP(i), 0); + } + + /* + * Setup window #0 base 0x0 to target XBAR port 2 (AMB2), attribute 0xb, size 4GB + * AMB2 address decoder remaps 0x0 to DDR 64 bit base address + */ + mvreg_write(pp, MVNETA_WIN_BASE(0), + (MVNETA_AC5_CNM_DDR_ATTR << 8) | MVNETA_AC5_CNM_DDR_TARGET); + mvreg_write(pp, MVNETA_WIN_SIZE(0), 0xffff0000); + mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, 0x3e); +} + /* Power up the port */ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) { @@ -1525,7 +1552,7 @@ static int mvneta_recv(struct udevice *dev, int flags, uchar **packetp) * No cache invalidation needed here, since the rx_buffer's are * located in a uncached memory region */ - *packetp = data; + *packetp = data + pp->dma_base;
/* * Only mark one descriptor as free @@ -1544,6 +1571,10 @@ static int mvneta_probe(struct udevice *dev) struct ofnode_phandle_args sfp_args; #endif void *bd_space; + phys_addr_t cpu; + dma_addr_t bus; + u64 size; + int ret;
/* * Allocate buffer area for descs and rx_buffers. This is only @@ -1577,9 +1608,18 @@ static int mvneta_probe(struct udevice *dev) /* Configure MBUS address windows */ if (device_is_compatible(dev, "marvell,armada-3700-neta")) mvneta_bypass_mbus_windows(pp); + else if (device_is_compatible(dev, "marvell,armada-ac5-neta")) + mvneta_conf_ac5_cnm_xbar_windows(pp); else mvneta_conf_mbus_windows(pp);
+ /* fetch dma ranges property */ + ret = dev_get_dma_range(dev, &cpu, &bus, &size); + if (!ret) + pp->dma_base = cpu; + else + pp->dma_base = 0; + #if CONFIG_IS_ENABLED(DM_GPIO) if (!dev_read_phandle_with_args(dev, "sfp", NULL, 0, 0, &sfp_args) && ofnode_is_enabled(sfp_args.node)) @@ -1620,6 +1660,7 @@ static const struct eth_ops mvneta_ops = {
static const struct udevice_id mvneta_ids[] = { { .compatible = "marvell,armada-370-neta" }, + { .compatible = "marvell,armada-ac5-neta" }, { .compatible = "marvell,armada-xp-neta" }, { .compatible = "marvell,armada-3700-neta" }, { }

On 21.09.22 06:59, Chris Packham wrote:
Add support for the AlleyCat5 SoC. This lacks the mbus from the other users of the mvneta.c driver so a new compatible string is needed to allow for a different window configuration.
Signed-off-by: Chris Packham judge.packham@gmail.com Reviewed-by: Stefan Roese sr@denx.de
Looks much better now. ;)
Thanks, Stefan
Changes in v3:
Remove unnecessary changes to RX descriptor handling
Use dev_get_dma_range() to parse dma-ranges property from parent device.
drivers/net/Kconfig | 2 +- drivers/net/mvneta.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6bbbadc5ee..8df3dce6df 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -448,7 +448,7 @@ config MVGBE
config MVNETA bool "Marvell Armada XP/385/3700 network interface support"
- depends on ARMADA_XP || ARMADA_38X || ARMADA_3700
- depends on ARMADA_XP || ARMADA_38X || ARMADA_3700 || ALLEYCAT_5 select PHYLIB select DM_MDIO help
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index d2c42c4396..0fbfad11d4 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -91,6 +91,8 @@ DECLARE_GLOBAL_DATA_PTR; #define MVNETA_WIN_SIZE_MASK (0xffff0000) #define MVNETA_BASE_ADDR_ENABLE 0x2290 #define MVNETA_BASE_ADDR_ENABLE_BIT 0x1 +#define MVNETA_AC5_CNM_DDR_TARGET 0x2 +#define MVNETA_AC5_CNM_DDR_ATTR 0xb #define MVNETA_PORT_ACCESS_PROTECT 0x2294 #define MVNETA_PORT_ACCESS_PROTECT_WIN0_RW 0x3 #define MVNETA_PORT_CONFIG 0x2400 @@ -282,6 +284,8 @@ struct mvneta_port { struct gpio_desc phy_reset_gpio; struct gpio_desc sfp_tx_disable_gpio; #endif
uintptr_t dma_base; /* base address for DMA address decoding */ };
/* The mvneta_tx_desc and mvneta_rx_desc structures describe the
@@ -1343,6 +1347,29 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp) mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable); }
+static void mvneta_conf_ac5_cnm_xbar_windows(struct mvneta_port *pp) +{
- int i;
- /* Clear all windows */
- for (i = 0; i < 6; i++) {
mvreg_write(pp, MVNETA_WIN_BASE(i), 0);
mvreg_write(pp, MVNETA_WIN_SIZE(i), 0);
if (i < 4)
mvreg_write(pp, MVNETA_WIN_REMAP(i), 0);
- }
- /*
* Setup window #0 base 0x0 to target XBAR port 2 (AMB2), attribute 0xb, size 4GB
* AMB2 address decoder remaps 0x0 to DDR 64 bit base address
*/
- mvreg_write(pp, MVNETA_WIN_BASE(0),
(MVNETA_AC5_CNM_DDR_ATTR << 8) | MVNETA_AC5_CNM_DDR_TARGET);
- mvreg_write(pp, MVNETA_WIN_SIZE(0), 0xffff0000);
- mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, 0x3e);
+}
- /* Power up the port */ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) {
@@ -1525,7 +1552,7 @@ static int mvneta_recv(struct udevice *dev, int flags, uchar **packetp) * No cache invalidation needed here, since the rx_buffer's are * located in a uncached memory region */
*packetp = data;
*packetp = data + pp->dma_base;
/*
- Only mark one descriptor as free
@@ -1544,6 +1571,10 @@ static int mvneta_probe(struct udevice *dev) struct ofnode_phandle_args sfp_args; #endif void *bd_space;
phys_addr_t cpu;
dma_addr_t bus;
u64 size;
int ret;
/*
- Allocate buffer area for descs and rx_buffers. This is only
@@ -1577,9 +1608,18 @@ static int mvneta_probe(struct udevice *dev) /* Configure MBUS address windows */ if (device_is_compatible(dev, "marvell,armada-3700-neta")) mvneta_bypass_mbus_windows(pp);
else if (device_is_compatible(dev, "marvell,armada-ac5-neta"))
mvneta_conf_ac5_cnm_xbar_windows(pp);
else mvneta_conf_mbus_windows(pp);
/* fetch dma ranges property */
ret = dev_get_dma_range(dev, &cpu, &bus, &size);
if (!ret)
pp->dma_base = cpu;
else
pp->dma_base = 0;
#if CONFIG_IS_ENABLED(DM_GPIO) if (!dev_read_phandle_with_args(dev, "sfp", NULL, 0, 0, &sfp_args) && ofnode_is_enabled(sfp_args.node))
@@ -1620,6 +1660,7 @@ static const struct eth_ops mvneta_ops = {
static const struct udevice_id mvneta_ids[] = { { .compatible = "marvell,armada-370-neta" },
- { .compatible = "marvell,armada-ac5-neta" }, { .compatible = "marvell,armada-xp-neta" }, { .compatible = "marvell,armada-3700-neta" }, { }
Viele Grüße, Stefan Roese

On Wed, Sep 21, 2022 at 8:00 AM Chris Packham judge.packham@gmail.com wrote:
Add support for the AlleyCat5 SoC. This lacks the mbus from the other users of the mvneta.c driver so a new compatible string is needed to allow for a different window configuration.
Signed-off-by: Chris Packham judge.packham@gmail.com Reviewed-by: Stefan Roese sr@denx.de
Changes in v3:
- Remove unnecessary changes to RX descriptor handling
- Use dev_get_dma_range() to parse dma-ranges property from parent device.
drivers/net/Kconfig | 2 +- drivers/net/mvneta.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6bbbadc5ee..8df3dce6df 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -448,7 +448,7 @@ config MVGBE
config MVNETA bool "Marvell Armada XP/385/3700 network interface support"
depends on ARMADA_XP || ARMADA_38X || ARMADA_3700
depends on ARMADA_XP || ARMADA_38X || ARMADA_3700 || ALLEYCAT_5 select PHYLIB select DM_MDIO help
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index d2c42c4396..0fbfad11d4 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -91,6 +91,8 @@ DECLARE_GLOBAL_DATA_PTR; #define MVNETA_WIN_SIZE_MASK (0xffff0000) #define MVNETA_BASE_ADDR_ENABLE 0x2290 #define MVNETA_BASE_ADDR_ENABLE_BIT 0x1 +#define MVNETA_AC5_CNM_DDR_TARGET 0x2 +#define MVNETA_AC5_CNM_DDR_ATTR 0xb #define MVNETA_PORT_ACCESS_PROTECT 0x2294 #define MVNETA_PORT_ACCESS_PROTECT_WIN0_RW 0x3 #define MVNETA_PORT_CONFIG 0x2400 @@ -282,6 +284,8 @@ struct mvneta_port { struct gpio_desc phy_reset_gpio; struct gpio_desc sfp_tx_disable_gpio; #endif
uintptr_t dma_base; /* base address for DMA address decoding */
};
/* The mvneta_tx_desc and mvneta_rx_desc structures describe the @@ -1343,6 +1347,29 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp) mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable); }
+static void mvneta_conf_ac5_cnm_xbar_windows(struct mvneta_port *pp) +{
int i;
/* Clear all windows */
for (i = 0; i < 6; i++) {
mvreg_write(pp, MVNETA_WIN_BASE(i), 0);
mvreg_write(pp, MVNETA_WIN_SIZE(i), 0);
if (i < 4)
mvreg_write(pp, MVNETA_WIN_REMAP(i), 0);
}
/*
* Setup window #0 base 0x0 to target XBAR port 2 (AMB2), attribute 0xb, size 4GB
* AMB2 address decoder remaps 0x0 to DDR 64 bit base address
*/
mvreg_write(pp, MVNETA_WIN_BASE(0),
(MVNETA_AC5_CNM_DDR_ATTR << 8) | MVNETA_AC5_CNM_DDR_TARGET);
mvreg_write(pp, MVNETA_WIN_SIZE(0), 0xffff0000);
mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, 0x3e);
+}
/* Power up the port */ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) { @@ -1525,7 +1552,7 @@ static int mvneta_recv(struct udevice *dev, int flags, uchar **packetp) * No cache invalidation needed here, since the rx_buffer's are * located in a uncached memory region */
*packetp = data;
*packetp = data + pp->dma_base; /* * Only mark one descriptor as free
@@ -1544,6 +1571,10 @@ static int mvneta_probe(struct udevice *dev) struct ofnode_phandle_args sfp_args; #endif void *bd_space;
phys_addr_t cpu;
dma_addr_t bus;
u64 size;
int ret; /* * Allocate buffer area for descs and rx_buffers. This is only
@@ -1577,9 +1608,18 @@ static int mvneta_probe(struct udevice *dev) /* Configure MBUS address windows */ if (device_is_compatible(dev, "marvell,armada-3700-neta")) mvneta_bypass_mbus_windows(pp);
else if (device_is_compatible(dev, "marvell,armada-ac5-neta"))
mvneta_conf_ac5_cnm_xbar_windows(pp); else mvneta_conf_mbus_windows(pp);
/* fetch dma ranges property */
ret = dev_get_dma_range(dev, &cpu, &bus, &size);
if (!ret)
pp->dma_base = cpu;
else
pp->dma_base = 0;
#if CONFIG_IS_ENABLED(DM_GPIO) if (!dev_read_phandle_with_args(dev, "sfp", NULL, 0, 0, &sfp_args) && ofnode_is_enabled(sfp_args.node)) @@ -1620,6 +1660,7 @@ static const struct eth_ops mvneta_ops = {
static const struct udevice_id mvneta_ids[] = { { .compatible = "marvell,armada-370-neta" },
{ .compatible = "marvell,armada-ac5-neta" }, { .compatible = "marvell,armada-xp-neta" }, { .compatible = "marvell,armada-3700-neta" }, { }
-- 2.37.3
Reviewed-by: Ramon Fried rfried.dev@gmail.com

Unlike the other 64-bit mvebu SoCs the AlleyCat5 uses the older ehci block from the 32-bit SoCs. Adapt the ehci-marvell.c driver to cope with the fact that the ac5 does not have the mbus infrastructure the 32-bit SoCs have and ensure USB_EHCI_IS_TDI is selected.
Signed-off-by: Chris Packham judge.packham@gmail.com ---
(no changes since v1)
drivers/usb/host/Kconfig | 1 + drivers/usb/host/ehci-marvell.c | 57 +++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a0f48f09a7..628078f495 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -178,6 +178,7 @@ config USB_EHCI_MARVELL depends on ARCH_MVEBU || ARCH_KIRKWOOD || ARCH_ORION5X default y select USB_EHCI_IS_TDI if !ARM64 + select USB_EHCI_IS_TDI if ALLEYCAT_5 ---help--- Enables support for the on-chip EHCI controller on MVEBU SoCs.
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c index b7e60c690a..7d859b9cce 100644 --- a/drivers/usb/host/ehci-marvell.c +++ b/drivers/usb/host/ehci-marvell.c @@ -48,12 +48,17 @@ struct ehci_mvebu_priv { fdt_addr_t hcd_base; };
+#define USB_TO_DRAM_TARGET_ID 0x2 +#define USB_TO_DRAM_ATTR_ID 0x0 +#define USB_DRAM_BASE 0x00000000 +#define USB_DRAM_SIZE 0xfff /* don't overrun u-boot source (was 0xffff) */ + /* * Once all the older Marvell SoC's (Orion, Kirkwood) are converted * to the common mvebu archticture including the mbus setup, this * will be the only function needed to configure the access windows */ -static void usb_brg_adrdec_setup(void *base) +static void usb_brg_adrdec_setup(struct udevice *dev, void *base) { const struct mbus_dram_target_info *dram; int i; @@ -65,16 +70,34 @@ static void usb_brg_adrdec_setup(void *base) writel(0, base + USB_WINDOW_BASE(i)); }
- for (i = 0; i < dram->num_cs; i++) { - const struct mbus_dram_window *cs = dram->cs + i; + if (device_is_compatible(dev, "marvell,ac5-ehci")) { + /* + * use decoding window to map dram address seen by usb to 0x0 + */
/* Write size, attributes and target id to control register */ - writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | - (dram->mbus_dram_target_id << 4) | 1, - base + USB_WINDOW_CTRL(i)); + writel((USB_DRAM_SIZE << 16) | (USB_TO_DRAM_ATTR_ID << 8) | + (USB_TO_DRAM_TARGET_ID << 4) | 1, + base + USB_WINDOW_CTRL(0));
/* Write base address to base register */ - writel(cs->base, base + USB_WINDOW_BASE(i)); + writel(USB_DRAM_BASE, base + USB_WINDOW_BASE(0)); + + debug("## AC5 decoding windows, ctrl[%p]=0x%x, base[%p]=0x%x\n", + base + USB_WINDOW_CTRL(0), readl(base + USB_WINDOW_CTRL(0)), + base + USB_WINDOW_BASE(0), readl(base + USB_WINDOW_BASE(0))); + } else { + for (i = 0; i < dram->num_cs; i++) { + const struct mbus_dram_window *cs = dram->cs + i; + + /* Write size, attributes and target id to control register */ + writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | + (dram->mbus_dram_target_id << 4) | 1, + base + USB_WINDOW_CTRL(i)); + + /* Write base address to base register */ + writel(cs->base, base + USB_WINDOW_BASE(i)); + } } }
@@ -126,15 +149,28 @@ static int ehci_mvebu_probe(struct udevice *dev) if (device_is_compatible(dev, "marvell,armada-3700-ehci")) marvell_ehci_ops.powerup_fixup = marvell_ehci_powerup_fixup; else - usb_brg_adrdec_setup((void *)priv->hcd_base); + usb_brg_adrdec_setup(dev, (void *)priv->hcd_base);
hccr = (struct ehci_hccr *)(priv->hcd_base + 0x100); hcor = (struct ehci_hcor *) ((uintptr_t)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
debug("ehci-marvell: init hccr %lx and hcor %lx hc_length %ld\n", - (uintptr_t)hccr, (uintptr_t)hcor, - (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + (uintptr_t)hccr, (uintptr_t)hcor, + (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + +#define PHY_CALIB_OFFSET 0x808 + /* + * Trigger calibration during each usb start/reset: + * BIT 13 to 0, and then to 1 + */ + if (device_is_compatible(dev, "marvell,ac5-ehci")) { + void *phy_calib_reg = (void *)(priv->hcd_base + PHY_CALIB_OFFSET); + u32 val = readl(phy_calib_reg) & (~BIT(13)); + + writel(val, phy_calib_reg); + writel(val | BIT(13), phy_calib_reg); + }
return ehci_register(dev, hccr, hcor, &marvell_ehci_ops, 0, USB_INIT_HOST); @@ -143,6 +179,7 @@ static int ehci_mvebu_probe(struct udevice *dev) static const struct udevice_id ehci_usb_ids[] = { { .compatible = "marvell,orion-ehci", }, { .compatible = "marvell,armada-3700-ehci", }, + { .compatible = "marvell,ac5-ehci", }, { } };

This uses the same IP block as the Armada-8K SoCs.
Signed-off-by: Chris Packham judge.packham@gmail.com ---
(no changes since v1)
drivers/pinctrl/mvebu/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig index 574fb4dfb0..7c51d138c8 100644 --- a/drivers/pinctrl/mvebu/Kconfig +++ b/drivers/pinctrl/mvebu/Kconfig @@ -15,7 +15,7 @@ config PINCTRL_ARMADA_37XX Marvell's Armada-37xx SoC.
config PINCTRL_ARMADA_8K - depends on ARMADA_8K && PINCTRL_FULL + depends on (ARMADA_8K || ALLEYCAT_5) && PINCTRL_FULL bool "Armada 7k/8k pin control driver" help Support pin multiplexing and pin configuration control on

On 21.09.22 06:59, Chris Packham wrote:
This uses the same IP block as the Armada-8K SoCs.
Signed-off-by: Chris Packham judge.packham@gmail.com
(no changes since v1)
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan
drivers/pinctrl/mvebu/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig index 574fb4dfb0..7c51d138c8 100644 --- a/drivers/pinctrl/mvebu/Kconfig +++ b/drivers/pinctrl/mvebu/Kconfig @@ -15,7 +15,7 @@ config PINCTRL_ARMADA_37XX Marvell's Armada-37xx SoC.
config PINCTRL_ARMADA_8K
- depends on ARMADA_8K && PINCTRL_FULL
- depends on (ARMADA_8K || ALLEYCAT_5) && PINCTRL_FULL bool "Armada 7k/8k pin control driver" help Support pin multiplexing and pin configuration control on
Viele Grüße, Stefan Roese

Add a new UCLASS_SAR, the generic SAR code and an Alleycat5 driver. This has been adapted from the Marvell SDK but only the AC5 driver has been brought through (other drivers exist for the ap806, ap807 and cp110 IP blocks).
Signed-off-by: Chris Packham judge.packham@gmail.com ---
Changes in v3: - None. Note some changes related to this have been requested and will be looked into I just wanted to get v3 out so the other changes could be reviewed.
drivers/misc/Kconfig | 6 ++ drivers/misc/Makefile | 1 + drivers/misc/mvebu_sar/Makefile | 4 + drivers/misc/mvebu_sar/ac5_sar.c | 119 +++++++++++++++++++++++ drivers/misc/mvebu_sar/sar-uclass.c | 146 ++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/fdtdec.h | 4 + include/mvebu/mvebu_chip_sar.h | 73 ++++++++++++++ include/mvebu/sar.h | 57 +++++++++++ include/mvebu/var.h | 28 ++++++ include/sar-uclass.h | 23 +++++ lib/fdtdec.c | 6 +- 12 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 drivers/misc/mvebu_sar/Makefile create mode 100644 drivers/misc/mvebu_sar/ac5_sar.c create mode 100644 drivers/misc/mvebu_sar/sar-uclass.c create mode 100644 include/mvebu/mvebu_chip_sar.h create mode 100644 include/mvebu/sar.h create mode 100644 include/mvebu/var.h create mode 100644 include/sar-uclass.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a6da6e215d..4e99ef29d9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -645,4 +645,10 @@ config SL28CPLD the base driver which provides common access methods for the sub-drivers.
+config MVEBU_SAR + bool "MVEBU SAR driver" + depends on ARCH_MVEBU + help + Support MVEBU SAR driver + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index d494639cd9..3cf976edd8 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o obj-$(CONFIG_P2SB) += p2sb-uclass.o obj-$(CONFIG_PCA9551_LED) += pca9551_led.o obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o +obj-$(CONFIG_MVEBU_SAR) += mvebu_sar/ ifdef CONFIG_QFW obj-y += qfw.o obj-$(CONFIG_QFW_PIO) += qfw_pio.o diff --git a/drivers/misc/mvebu_sar/Makefile b/drivers/misc/mvebu_sar/Makefile new file mode 100644 index 0000000000..6f339fb7b4 --- /dev/null +++ b/drivers/misc/mvebu_sar/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_MVEBU_SAR) += sar-uclass.o +obj-$(CONFIG_ALLEYCAT_5) += ac5_sar.o diff --git a/drivers/misc/mvebu_sar/ac5_sar.c b/drivers/misc/mvebu_sar/ac5_sar.c new file mode 100644 index 0000000000..67b2110bc8 --- /dev/null +++ b/drivers/misc/mvebu_sar/ac5_sar.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <fdtdec.h> +#include <mvebu/mvebu_chip_sar.h> +#include <dm.h> + +#include <sar-uclass.h> + +#define MHz 1000000 + +#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 + +static const u32 pll_freq_tbl[CPU_TYPE_LAST][SAR_AP_FABRIC_FREQ + 1][PLL_MAX_CHOICE] = { + [CPU_TYPE_AC5] = { + [SAR_CPU_FREQ] = { + 800 * MHz, 1200 * MHz, 1400 * MHz, 1000 * MHz + }, + [SAR_DDR_FREQ] = { + 1200 * MHz, 800 * MHz, 0, 0 + }, + [SAR_AP_FABRIC_FREQ] = { + 396 * MHz, 290 * MHz, 197 * MHz, 0 + }, + }, + [CPU_TYPE_AC5x] = { + [SAR_CPU_FREQ] = { + 800 * MHz, 1200 * MHz, 1500 * MHz, 1600 * MHz + }, + [SAR_DDR_FREQ] = { + 1200 * MHz, 800 * MHz, 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 ac5_sar_value_get(struct udevice *dev, enum mvebu_sar_opts sar_opt, + struct sar_val *val) +{ + u32 *pSarBase = (u32 *)(((struct dm_sar_pdata *)dev_get_priv(dev))->sar_base); + u32 sar_reg_val = readl(pSarBase); + u32 mask; + unsigned char choice; + int cpu_type = ((readl(0x7f90004c) & 0xFF000) >> 12) == 0x98 ? CPU_TYPE_AC5x : CPU_TYPE_AC5; + + if (sar_opt > SAR_AP_FABRIC_FREQ) { + pr_err("AC5-SAR: Unsupported SAR option %d.\n", sar_opt); + return -EINVAL; + } + + mask = soc_sar_masks_tbl[cpu_type][sar_opt]; + /* The choice within the bits allocated for a specific PLL */ + choice = (sar_reg_val & mask) >> (__builtin_ffs(mask) - 1); + + val->freq = pll_freq_tbl[cpu_type][sar_opt][choice]; + return 0; +} + +static int ac5_sar_init(struct udevice *dev) +{ + int ret, i; + + u32 sar_list[] = { + SAR_CPU_FREQ, + SAR_DDR_FREQ, + SAR_AP_FABRIC_FREQ + }; + + for (i = 0; i < ARRAY_SIZE(sar_list); i++) { + ret = mvebu_sar_id_register(dev, sar_list[i]); + if (ret) { + pr_err("Failed to register SAR %d, for AC5\n", + sar_list[i]); + return ret; + } + } + + return 0; +} + +static const struct sar_ops ac5_sar_ops = { + .sar_init_func = ac5_sar_init, + .sar_value_get_func = ac5_sar_value_get, + .sar_dump_func = NULL, +}; + +U_BOOT_DRIVER(ac5_sar) = { + .name = "ac5_sar", + .id = UCLASS_SAR, + .priv_auto = sizeof(struct dm_sar_pdata), + .ops = &ac5_sar_ops, +}; diff --git a/drivers/misc/mvebu_sar/sar-uclass.c b/drivers/misc/mvebu_sar/sar-uclass.c new file mode 100644 index 0000000000..d9cb019d5d --- /dev/null +++ b/drivers/misc/mvebu_sar/sar-uclass.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <fdtdec.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <sar-uclass.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define SAR_MAX_CHIP 4 + +UCLASS_DRIVER(sar) = { + .name = "sar", + .id = UCLASS_SAR, +}; + +struct udevice *__section(".data") soc_sar_info[SAR_MAX_IDX]; + +int mvebu_sar_id_register(struct udevice *dev, u32 sar_id) +{ + if (soc_sar_info[sar_id]) { + pr_err("sar %d was already registered.\n", sar_id); + return -EBUSY; + } + soc_sar_info[sar_id] = dev; + + return 0; +} + +/* find all drivers for sar device and initialize each driver */ +int mvebu_sar_init(void) +{ + int ret, i; + int node, chip_count, sar_list[SAR_MAX_CHIP]; + const void *blob = gd->fdt_blob; + struct udevice *sar_chip[SAR_MAX_CHIP]; + struct dm_sar_pdata *priv; + const struct sar_ops *ops; + struct udevice *parent; + struct driver_info sar_drivers[SAR_MAX_CHIP]; + void *sar_base = NULL; + const char *sar_driver, *sar_name; + + chip_count = fdtdec_find_aliases_for_id(blob, "sar-reg", + COMPAT_MVEBU_SAR_REG_COMMON, + sar_list, SAR_MAX_CHIP); + + if (chip_count <= 0) { + pr_err("Cannot find sample-at-reset dt entry (%d).\n", + chip_count); + return -ENODEV; + } + uclass_get_device_by_name(UCLASS_ROOT, "root_driver", &parent); + memset(soc_sar_info, 0, sizeof(soc_sar_info)); + + for (i = 0; i < chip_count ; i++) { + node = sar_list[i]; + if (node <= 0) + continue; + + /* Skip if Node is disabled */ + if (!fdtdec_get_is_enabled(blob, node)) + continue; + /* Binding stage */ + sar_driver = fdt_getprop(blob, node, "sar-driver", NULL); + sar_drivers[i].name = sar_driver; + ret = device_bind_by_name(parent, false, + &sar_drivers[i], &sar_chip[i]); + + if (!sar_chip[i]) { + pr_err("SAR driver binding failed\n"); + return 0; + } + + /* fetch driver info from device-tree */ + sar_base = (void *)fdtdec_get_addr_size_auto_noparent(blob, + node, "reg", 0, NULL, true); + if (!sar_base) { + pr_err("SAR address isn't found in the device-tree\n"); + return 0; + } + sar_name = fdt_getprop(blob, node, "sar-name", NULL); + /* Initialize driver priv struct */ + device_probe(sar_chip[i]); + priv = dev_get_priv(sar_chip[i]); + priv->sar_base = sar_base; + priv->sar_name = sar_name; + ops = device_get_ops(sar_chip[i]); + if (!ops->sar_init_func) + return -EINVAL; + + ret = ops->sar_init_func(sar_chip[i]); + if (ret) { + pr_err("sar_init failed (%d).\n", ret); + return ret; + } + } + + return 0; +} + +int mvebu_sar_value_get(enum mvebu_sar_opts opt, struct sar_val *val) +{ + const struct sar_ops *ops; + + if (soc_sar_info[opt]) { + ops = device_get_ops(soc_sar_info[opt]); + return ops->sar_value_get_func(soc_sar_info[opt], opt, val); + } + + pr_err("SAR - No chip registered on sar %d.\n", opt); + return -ENODEV; +} + +char *mvebu_sar_bootsrc_to_name(enum mvebu_bootsrc_type src) +{ + switch (src) { + case(BOOTSRC_NAND): + return "nand"; + case(BOOTSRC_SPI): + case(BOOTSRC_AP_SPI): + return "spi"; + case(BOOTSRC_SD_EMMC): + case(BOOTSRC_AP_SD_EMMC): + return "mmc"; + case(BOOTSRC_NOR): + return "nor"; + default: + return "unknown"; + } +} + +void mvebu_sar_dump(struct udevice *dev) +{ + const struct sar_ops *ops; + + ops = device_get_ops(dev); + + ops->sar_dump_func(dev); +} diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index a432e43871..2213e76d38 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -107,6 +107,7 @@ enum uclass_id { UCLASS_RESET, /* Reset controller device */ UCLASS_RNG, /* Random Number Generator */ UCLASS_RTC, /* Real time clock device */ + UCLASS_SAR, /* Reset Sample Configuration */ UCLASS_SCMI_AGENT, /* Interface with an SCMI server */ UCLASS_SCSI, /* SCSI device */ UCLASS_SERIAL, /* Serial UART */ diff --git a/include/fdtdec.h b/include/fdtdec.h index 12355afd7f..d8923ba443 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -199,6 +199,10 @@ enum fdt_compat_id { COMPAT_ALTERA_SOCFPGA_FPGA0, /* SOCFPGA FPGA manager */ COMPAT_ALTERA_SOCFPGA_NOC, /* SOCFPGA Arria 10 NOC */ COMPAT_ALTERA_SOCFPGA_CLK_INIT, /* SOCFPGA Arria 10 clk init */ + COMPAT_MVEBU_SAR, /* Marvell Sampled-at-Reset */ + COMPAT_MVEBU_SAR_REG_COMMON, /* Marvell Sampled-at-Reset Common */ + COMPAT_MVEBU_SAR_REG_AP806, /* Marvell Sampled-at-Reset for ap806/ap807 */ + COMPAT_MVEBU_SAR_REG_CP110, /* Marvell Sampled-at-Reset for cp110 */
COMPAT_COUNT, }; diff --git a/include/mvebu/mvebu_chip_sar.h b/include/mvebu/mvebu_chip_sar.h new file mode 100644 index 0000000000..4781aa06c4 --- /dev/null +++ b/include/mvebu/mvebu_chip_sar.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#ifndef _MVEBU_CHIP_SAR_H_ +#define _MVEBU_CHIP_SAR_H_ + +#include <asm/types.h> + +struct udevice; + +/* + * List of boot source options. + * Return value for each of the options: + * - SAR_CPU_FREQ: Frequency (Hz) + * - SAR_DDR_FREQ: Frequency (Hz) + * - SAR_AP_FABRIC_FREQ: Frequency (Hz) + * - SAR_CP_FABRIC_FREQ: Frequency (Hz) + * - SAR_BOOT_SRC: Boot source type (see mvebu_bootsrc_type) + */ +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 +}; + +enum mvebu_bootsrc_type { + BOOTSRC_NAND, + BOOTSRC_SPI, + BOOTSRC_AP_SPI, + BOOTSRC_SD_EMMC, + BOOTSRC_AP_SD_EMMC, + BOOTSRC_NOR, + BOOTSRC_MAX_IDX +}; + +/* + * sample-at-reset information + * raw_sar_val: Raw value out of the sample-at-reset register. + * This is hw dependent and should not be used for comparison + * purposes (useful for debug, or verbose information). + * bootsrc (SAR_BOOT_SRC): + * type: Boot source interface type. + * index: When applicable, indicates the interface index (e.g. SPI #1, + * NAND #0). + * freq: Frequency in Hz. + */ +struct sar_val { + u32 raw_sar_val; + union { + struct { + enum mvebu_bootsrc_type type; + int index; + } bootsrc; + u32 freq; + u32 clk_direction; /* input = 0 */ + }; +}; + +int mvebu_sar_init(void); +int mvebu_sar_value_get(enum mvebu_sar_opts opt, struct sar_val *val); +void mvebu_sar_dump(struct udevice *dev); +char *mvebu_sar_bootsrc_to_name(enum mvebu_bootsrc_type src); + +#endif /* _MVEBU_CHIP_SAR_H_ */ diff --git a/include/mvebu/sar.h b/include/mvebu/sar.h new file mode 100644 index 0000000000..bd0837d6a3 --- /dev/null +++ b/include/mvebu/sar.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#ifndef _SAR_H_ +#define _SAR_H_ + +#include <linux/compiler.h> +#include <mvebu/var.h> + +#define MAX_SAR_CHIPS 4 +#define MAX_SAR 8 + +enum sar_variables { + CPUS_NUM_SAR = 0, + CPU0_ENDIANESS_SAR, + FREQ_SAR, + CPU_FREQ_SAR, + FAB_REQ_SAR, + BOOT_SRC_SAR, + BOOT_WIDTH_SAR, + PEX_MODE_SAR, + L2_SIZE_SAR, + DRAM_ECC_SAR, + DRAM_BUS_WIDTH_SAR, +}; + +struct sar_var { + u8 start_bit; + u8 bit_length; + u8 option_cnt; + u8 active; + bool swap_bit; + char *desc; + char *key; + struct var_opts option_desc[MAX_VAR_OPTIONS]; +}; + +struct sar_data { + u32 chip_addr[MAX_SAR_CHIPS]; + u8 chip_count; + u8 bit_width; + struct sar_var sar_lookup[MAX_SAR]; +}; + +int sar_read_all(void); +int sar_default_key(const char *key); +int sar_default_all(void); +int sar_write_key(const char *key, int val); +int sar_print_key(const char *key); +void sar_list_keys(void); +int sar_list_key_opts(const char *key); +int sar_is_available(void); +void sar_init(void); + +#endif /* _SAR_H_ */ diff --git a/include/mvebu/var.h b/include/mvebu/var.h new file mode 100644 index 0000000000..6bd315c841 --- /dev/null +++ b/include/mvebu/var.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#ifndef _VAR_H_ +#define _VAR_H_ + +#include <linux/compiler.h> + +#define INVALID_KEY 0xFF +#define MAX_VAR_OPTIONS 10 + +#define VAR_IS_DEFAULT 0x1 +#define VAR_IS_LAST 0x2 + +struct var_opts { + u8 value; + char *desc; + u8 flags; +}; + +struct var_desc { + char *key; + char *description; +}; + +#endif /* _VAR_H_ */ diff --git a/include/sar-uclass.h b/include/sar-uclass.h new file mode 100644 index 0000000000..8b9cc08847 --- /dev/null +++ b/include/sar-uclass.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#include <mvebu/mvebu_chip_sar.h> + +struct udevice; + +struct sar_ops { + int (*sar_init_func)(struct udevice *dev); + int (*sar_dump_func)(struct udevice *dev); + int (*sar_value_get_func)(struct udevice *dev, enum mvebu_sar_opts sar, + struct sar_val *val); + int (*sar_bootsrc_get)(struct udevice *dev, u32 *idx); +}; + +struct dm_sar_pdata { + void __iomem *sar_base; + const char *sar_name; +}; + +int mvebu_sar_id_register(struct udevice *dev, u32 sar_id); diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 96b6b71a60..26e5c82bcd 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -74,7 +74,11 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(ALTERA_SOCFPGA_F2SDR2, "altr,socfpga-fpga2sdram2-bridge"), COMPAT(ALTERA_SOCFPGA_FPGA0, "altr,socfpga-a10-fpga-mgr"), COMPAT(ALTERA_SOCFPGA_NOC, "altr,socfpga-a10-noc"), - COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init") + COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init"), + COMPAT(MVEBU_SAR, "marvell,sample-at-reset"), + COMPAT(MVEBU_SAR_REG_COMMON, "marvell,sample-at-reset-common"), + COMPAT(MVEBU_SAR_REG_AP806, "marvell,sample-at-reset-ap806"), + COMPAT(MVEBU_SAR_REG_CP110, "marvell,sample-at-reset-cp110"), };
static const char *const fdt_src_name[] = {

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 ---
Changes in v3: - Remove unnecessary dma-ranges property from ethernet nodes (mvneta now correctly parses the property from the parent node). - Keep soc_print_clock_info and soc_print_device_info local to alleycat5.
arch/arm/dts/ac5-98dx25xx.dtsi | 290 +++++++++++++++++++++++++ arch/arm/dts/ac5-98dx35xx.dtsi | 17 ++ arch/arm/mach-mvebu/Kconfig | 4 + arch/arm/mach-mvebu/Makefile | 1 + arch/arm/mach-mvebu/alleycat5/Makefile | 9 + arch/arm/mach-mvebu/alleycat5/clock.c | 49 +++++ arch/arm/mach-mvebu/alleycat5/clock.h | 11 + arch/arm/mach-mvebu/alleycat5/cpu.c | 129 +++++++++++ arch/arm/mach-mvebu/alleycat5/soc.c | 229 +++++++++++++++++++ arch/arm/mach-mvebu/alleycat5/soc.h | 6 + arch/arm/mach-mvebu/arm64-common.c | 5 + arch/arm/mach-mvebu/include/mach/cpu.h | 4 + 12 files changed, 754 insertions(+) create mode 100644 arch/arm/dts/ac5-98dx25xx.dtsi create mode 100644 arch/arm/dts/ac5-98dx35xx.dtsi create mode 100644 arch/arm/mach-mvebu/alleycat5/Makefile create mode 100644 arch/arm/mach-mvebu/alleycat5/clock.c create mode 100644 arch/arm/mach-mvebu/alleycat5/clock.h create mode 100644 arch/arm/mach-mvebu/alleycat5/cpu.c create mode 100644 arch/arm/mach-mvebu/alleycat5/soc.c create mode 100644 arch/arm/mach-mvebu/alleycat5/soc.h
diff --git a/arch/arm/dts/ac5-98dx25xx.dtsi b/arch/arm/dts/ac5-98dx25xx.dtsi new file mode 100644 index 0000000000..64516938e8 --- /dev/null +++ b/arch/arm/dts/ac5-98dx25xx.dtsi @@ -0,0 +1,290 @@ +// 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>; + }; + + config-space { + #address-cells = <0x1>; + #size-cells = <0x1>; + compatible = "simple-bus"; + + sar-reg { + compatible = "marvell,sample-at-reset-common"; + sar-driver = "ac5_sar"; + sar-name = "ac5_sar"; + status = "okay"; + }; + }; + + 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>; + }; + }; +}; diff --git a/arch/arm/dts/ac5-98dx35xx.dtsi b/arch/arm/dts/ac5-98dx35xx.dtsi new file mode 100644 index 0000000000..2ab72f854b --- /dev/null +++ b/arch/arm/dts/ac5-98dx35xx.dtsi @@ -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>; +}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index a81b8e2b0d..45efa24194 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -49,6 +49,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 diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 103e64cf20..f7d7f5f8ef 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -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 diff --git a/arch/arm/mach-mvebu/alleycat5/Makefile b/arch/arm/mach-mvebu/alleycat5/Makefile new file mode 100644 index 0000000000..43b8b70c84 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2016 Stefan Roese sr@denx.de +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o +obj-y += soc.o +obj-y += clock.o diff --git a/arch/arm/mach-mvebu/alleycat5/clock.c b/arch/arm/mach-mvebu/alleycat5/clock.c new file mode 100644 index 0000000000..7c64da1ab6 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/clock.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#include <common.h> +#include <mvebu/mvebu_chip_sar.h> +#include "clock.h" + +#define CONFIG_MSS_FREQUENCY (200 * 1000000) + +static u32 soc_ring_clk_get(void) +{ + struct sar_val sar; + + mvebu_sar_value_get(SAR_AP_FABRIC_FREQ, &sar); + return sar.freq; +} + +static u32 soc_mss_clk_get(void) +{ + return CONFIG_MSS_FREQUENCY; +} + +static u32 soc_cpu_clk_get(void) +{ + struct sar_val sar; + + mvebu_sar_value_get(SAR_CPU_FREQ, &sar); + return sar.freq; +} + +static u32 soc_ddr_clk_get(void) +{ + struct sar_val sar; + + mvebu_sar_value_get(SAR_DDR_FREQ, &sar); + return sar.freq; +} + +void soc_print_clock_info(void) +{ + char buf[32]; + + printf("Clock: CPU %4s MHz\n", strmhz(buf, soc_cpu_clk_get())); + printf("\tDDR %4s MHz\n", strmhz(buf, soc_ddr_clk_get())); + printf("\tFABRIC %4s MHz\n", strmhz(buf, soc_ring_clk_get())); + printf("\tMSS %4s MHz\n", strmhz(buf, soc_mss_clk_get())); +} diff --git a/arch/arm/mach-mvebu/alleycat5/clock.h b/arch/arm/mach-mvebu/alleycat5/clock.h new file mode 100644 index 0000000000..6d6927446c --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/clock.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#ifndef _ALLEYCAT5_CLOCK_H_ +#define _ALLEYCAT5_CLOCK_H_ + +void soc_print_clock_info(void); + +#endif /* _ALLEYCAT5_CLOCK_H_ */ diff --git a/arch/arm/mach-mvebu/alleycat5/cpu.c b/arch/arm/mach-mvebu/alleycat5/cpu.c new file mode 100644 index 0000000000..b29f01be8b --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/cpu.c @@ -0,0 +1,129 @@ +// 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/arch/soc.h> +#include <asm/armv8/mmu.h> +#include "clock.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) +{ +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + soc_print_device_info(); + soc_print_clock_info(); + + return 0; +} +#endif + +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; +} diff --git a/arch/arm/mach-mvebu/alleycat5/soc.c b/arch/arm/mach-mvebu/alleycat5/soc.c new file mode 100644 index 0000000000..f388d4ee40 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.c @@ -0,0 +1,229 @@ +// 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/soc.h> +#include <mvebu/mvebu_chip_sar.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 AP_DEV_ID_STATUS_REG (SOC_REGS_PHY_BASE + 0x6F8240) +#define JTAG_DEV_ID_STATUS_REG (SOC_REGS_PHY_BASE + 0x6F8244) +#define AP_DEV_ID_STATUS_MASK 0xfff +#define AP_DEV_REV_ID_STATUS_MASK 0xf0000000 +#define SW_REV_STATUS_OFFSET 16 +#define AP_REV_STATUS_OFFSET 28 +#define SW_REV_STATUS_MASK 0xf + +#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 NF_CLOCK_SEL_MASK 0x1 +#define SOC_MUX_NAND_EN_MASK 0x1 +#define CLOCK_1Mhz 1000000 +#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"}, +}; + +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 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); +} + +/* Return NAND clock in Hz */ +u32 mvebu_get_nand_clock(void) +{ + return 200 * 1000000; +} + +int soc_early_init_f(void) +{ +#ifdef CONFIG_MVEBU_SAR +/* Sample at reset register init */ + mvebu_sar_init(); +#endif + return 0; +} + +/* + * Override of __weak int mach_cpu_init(void) : + * SoC/machine dependent CPU setup + */ +int mach_cpu_init(void) +{ + u32 phy_i; + u64 newVal, phyBase = 0x7F080800; + + /* Init USB PHY */ +#define USB_STEPPING 0x20000 +#define WRITE_MASK(addr, mask, val) \ + { newVal = (readl(addr) & (~(mask))) | val;\ + writel(newVal, addr); } + + for (phy_i = 0; phy_i < 2; phy_i++, phyBase += USB_STEPPING) { + WRITE_MASK(phyBase + 0x4, 0x3, 0x2); + WRITE_MASK(phyBase + 0xC, 0x3000000, 0x2000000); + WRITE_MASK(phyBase + 0x1C, 0x3, 0x2); + WRITE_MASK(phyBase + 0x0, 0x1FF007F, 0x600005); + WRITE_MASK(phyBase + 0xC, 0x000F000, 0x0002000); + /* Calibration Threshold Setting = 4*/ + WRITE_MASK(phyBase + 0x8, 0x700, 0x400) + WRITE_MASK(phyBase + 0x14, 0x000000F, 0x000000a); + /* Change AMP to 4*/ + WRITE_MASK(phyBase + 0xC, 0x3700000, 0x3400000); + WRITE_MASK(phyBase + 0x4, 0x3, 0x3); + /* Impedance calibration triggering is performed by USB probe */ + } + + return 0; +} + +#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{ + u32 type, rev; + + get_soc_type_rev(&type, &rev); + + return 0; +} +#endif diff --git a/arch/arm/mach-mvebu/alleycat5/soc.h b/arch/arm/mach-mvebu/alleycat5/soc.h new file mode 100644 index 0000000000..97bf3554d7 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _ALLEYCAT5_SOC_H +#define _ALLEYCAT5_SOC_H +void soc_print_device_info(void); +#endif /* _ALLEYCAT5_SOC_H */ diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 238edbe6ba..7b8f7641b4 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -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;
diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index b127fce865..c17c2440f1 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -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 *

On 21.09.22 06:59, Chris Packham wrote:
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
Changes in v3:
Remove unnecessary dma-ranges property from ethernet nodes (mvneta now correctly parses the property from the parent node).
Keep soc_print_clock_info and soc_print_device_info local to alleycat5.
arch/arm/dts/ac5-98dx25xx.dtsi | 290 +++++++++++++++++++++++++ arch/arm/dts/ac5-98dx35xx.dtsi | 17 ++ arch/arm/mach-mvebu/Kconfig | 4 + arch/arm/mach-mvebu/Makefile | 1 + arch/arm/mach-mvebu/alleycat5/Makefile | 9 + arch/arm/mach-mvebu/alleycat5/clock.c | 49 +++++ arch/arm/mach-mvebu/alleycat5/clock.h | 11 + arch/arm/mach-mvebu/alleycat5/cpu.c | 129 +++++++++++ arch/arm/mach-mvebu/alleycat5/soc.c | 229 +++++++++++++++++++ arch/arm/mach-mvebu/alleycat5/soc.h | 6 + arch/arm/mach-mvebu/arm64-common.c | 5 + arch/arm/mach-mvebu/include/mach/cpu.h | 4 + 12 files changed, 754 insertions(+) create mode 100644 arch/arm/dts/ac5-98dx25xx.dtsi create mode 100644 arch/arm/dts/ac5-98dx35xx.dtsi create mode 100644 arch/arm/mach-mvebu/alleycat5/Makefile create mode 100644 arch/arm/mach-mvebu/alleycat5/clock.c create mode 100644 arch/arm/mach-mvebu/alleycat5/clock.h create mode 100644 arch/arm/mach-mvebu/alleycat5/cpu.c create mode 100644 arch/arm/mach-mvebu/alleycat5/soc.c create mode 100644 arch/arm/mach-mvebu/alleycat5/soc.h
diff --git a/arch/arm/dts/ac5-98dx25xx.dtsi b/arch/arm/dts/ac5-98dx25xx.dtsi new file mode 100644 index 0000000000..64516938e8 --- /dev/null +++ b/arch/arm/dts/ac5-98dx25xx.dtsi @@ -0,0 +1,290 @@ +// 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>;
- };
- config-space {
#address-cells = <0x1>;
#size-cells = <0x1>;
compatible = "simple-bus";
sar-reg {
compatible = "marvell,sample-at-reset-common";
sar-driver = "ac5_sar";
sar-name = "ac5_sar";
status = "okay";
};
- };
- 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>;
};
- };
+}; diff --git a/arch/arm/dts/ac5-98dx35xx.dtsi b/arch/arm/dts/ac5-98dx35xx.dtsi new file mode 100644 index 0000000000..2ab72f854b --- /dev/null +++ b/arch/arm/dts/ac5-98dx35xx.dtsi @@ -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>;
+}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index a81b8e2b0d..45efa24194 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -49,6 +49,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
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 103e64cf20..f7d7f5f8ef 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -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 diff --git a/arch/arm/mach-mvebu/alleycat5/Makefile b/arch/arm/mach-mvebu/alleycat5/Makefile new file mode 100644 index 0000000000..43b8b70c84 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2016 Stefan Roese sr@denx.de +# +# SPDX-License-Identifier: GPL-2.0+ +#
+obj-y = cpu.o +obj-y += soc.o +obj-y += clock.o diff --git a/arch/arm/mach-mvebu/alleycat5/clock.c b/arch/arm/mach-mvebu/alleycat5/clock.c new file mode 100644 index 0000000000..7c64da1ab6 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/clock.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2018 Marvell International Ltd.
- */
+#include <common.h> +#include <mvebu/mvebu_chip_sar.h> +#include "clock.h"
+#define CONFIG_MSS_FREQUENCY (200 * 1000000)
+static u32 soc_ring_clk_get(void) +{
- struct sar_val sar;
- mvebu_sar_value_get(SAR_AP_FABRIC_FREQ, &sar);
- return sar.freq;
+}
+static u32 soc_mss_clk_get(void) +{
- return CONFIG_MSS_FREQUENCY;
+}
+static u32 soc_cpu_clk_get(void) +{
- struct sar_val sar;
- mvebu_sar_value_get(SAR_CPU_FREQ, &sar);
- return sar.freq;
+}
+static u32 soc_ddr_clk_get(void) +{
- struct sar_val sar;
- mvebu_sar_value_get(SAR_DDR_FREQ, &sar);
- return sar.freq;
+}
+void soc_print_clock_info(void) +{
- char buf[32];
- printf("Clock: CPU %4s MHz\n", strmhz(buf, soc_cpu_clk_get()));
- printf("\tDDR %4s MHz\n", strmhz(buf, soc_ddr_clk_get()));
- printf("\tFABRIC %4s MHz\n", strmhz(buf, soc_ring_clk_get()));
- printf("\tMSS %4s MHz\n", strmhz(buf, soc_mss_clk_get()));
+} diff --git a/arch/arm/mach-mvebu/alleycat5/clock.h b/arch/arm/mach-mvebu/alleycat5/clock.h new file mode 100644 index 0000000000..6d6927446c --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/clock.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2018 Marvell International Ltd.
- */
+#ifndef _ALLEYCAT5_CLOCK_H_ +#define _ALLEYCAT5_CLOCK_H_
+void soc_print_clock_info(void);
+#endif /* _ALLEYCAT5_CLOCK_H_ */ diff --git a/arch/arm/mach-mvebu/alleycat5/cpu.c b/arch/arm/mach-mvebu/alleycat5/cpu.c new file mode 100644 index 0000000000..b29f01be8b --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/cpu.c @@ -0,0 +1,129 @@ +// 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/arch/soc.h> +#include <asm/armv8/mmu.h> +#include "clock.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) +{ +}
+#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{
- soc_print_device_info();
- soc_print_clock_info();
- return 0;
+} +#endif
Remove this #ifdef here?
+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;
Nitpick: Remove empty line.
- 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;
+} diff --git a/arch/arm/mach-mvebu/alleycat5/soc.c b/arch/arm/mach-mvebu/alleycat5/soc.c new file mode 100644 index 0000000000..f388d4ee40 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.c @@ -0,0 +1,229 @@ +// 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/soc.h> +#include <mvebu/mvebu_chip_sar.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 AP_DEV_ID_STATUS_REG (SOC_REGS_PHY_BASE + 0x6F8240) +#define JTAG_DEV_ID_STATUS_REG (SOC_REGS_PHY_BASE + 0x6F8244) +#define AP_DEV_ID_STATUS_MASK 0xfff +#define AP_DEV_REV_ID_STATUS_MASK 0xf0000000 +#define SW_REV_STATUS_OFFSET 16 +#define AP_REV_STATUS_OFFSET 28 +#define SW_REV_STATUS_MASK 0xf
+#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 NF_CLOCK_SEL_MASK 0x1 +#define SOC_MUX_NAND_EN_MASK 0x1 +#define CLOCK_1Mhz 1000000 +#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"},
+};
+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 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);
+}
+/* Return NAND clock in Hz */ +u32 mvebu_get_nand_clock(void) +{
- return 200 * 1000000;
+}
Is this still needed?
+int soc_early_init_f(void) +{ +#ifdef CONFIG_MVEBU_SAR +/* Sample at reset register init */
- mvebu_sar_init();
+#endif
Won't CONFIG_MVEBU_SAR always be enabled? Remove the #ifdef in this case.
- return 0;
+}
+/*
- Override of __weak int mach_cpu_init(void) :
- SoC/machine dependent CPU setup
- */
+int mach_cpu_init(void) +{
- u32 phy_i;
- u64 newVal, phyBase = 0x7F080800;
No CamelCase please.
- /* Init USB PHY */
+#define USB_STEPPING 0x20000 +#define WRITE_MASK(addr, mask, val) \
- { newVal = (readl(addr) & (~(mask))) | val;\
- writel(newVal, addr); }
- for (phy_i = 0; phy_i < 2; phy_i++, phyBase += USB_STEPPING) {
WRITE_MASK(phyBase + 0x4, 0x3, 0x2);
WRITE_MASK(phyBase + 0xC, 0x3000000, 0x2000000);
WRITE_MASK(phyBase + 0x1C, 0x3, 0x2);
WRITE_MASK(phyBase + 0x0, 0x1FF007F, 0x600005);
WRITE_MASK(phyBase + 0xC, 0x000F000, 0x0002000);
/* Calibration Threshold Setting = 4*/
WRITE_MASK(phyBase + 0x8, 0x700, 0x400)
WRITE_MASK(phyBase + 0x14, 0x000000F, 0x000000a);
/* Change AMP to 4*/
WRITE_MASK(phyBase + 0xC, 0x3700000, 0x3400000);
WRITE_MASK(phyBase + 0x4, 0x3, 0x3);
/* Impedance calibration triggering is performed by USB probe */
- }
- return 0;
+}
+#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{
- u32 type, rev;
- get_soc_type_rev(&type, &rev);
- return 0;
+} +#endif
Remove the #ifdef here as well?
Thanks, Stefan
diff --git a/arch/arm/mach-mvebu/alleycat5/soc.h b/arch/arm/mach-mvebu/alleycat5/soc.h new file mode 100644 index 0000000000..97bf3554d7 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef _ALLEYCAT5_SOC_H +#define _ALLEYCAT5_SOC_H +void soc_print_device_info(void); +#endif /* _ALLEYCAT5_SOC_H */ diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 238edbe6ba..7b8f7641b4 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -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))
else return fdtdec_setup_memory_banksize(); }return alleycat5_dram_init_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;
diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index b127fce865..c17c2440f1 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -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
Viele Grüße, Stefan Roese

On Wed, Sep 21, 2022 at 5:58 PM Stefan Roese sr@denx.de wrote:
On 21.09.22 06:59, Chris Packham wrote:
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
<snip>
diff --git a/arch/arm/mach-mvebu/alleycat5/soc.c b/arch/arm/mach-mvebu/alleycat5/soc.c new file mode 100644 index 0000000000..f388d4ee40 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.c
<snip>
+/* Return NAND clock in Hz */ +u32 mvebu_get_nand_clock(void) +{
return 200 * 1000000;
+}
Is this still needed?
It will be needed eventually. After I get this landed I'll start work on getting our board upstreamed and that does make use of the NAND interface. There are some NAND driver changes that go along with this so I'll move this over into that patch series.

On Wed, Sep 21, 2022 at 5:58 PM Stefan Roese sr@denx.de wrote:
On 21.09.22 06:59, Chris Packham wrote:
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
<snip>
diff --git a/arch/arm/mach-mvebu/alleycat5/soc.c b/arch/arm/mach-mvebu/alleycat5/soc.c new file mode 100644 index 0000000000..f388d4ee40 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.c
<snip>
+int soc_early_init_f(void) +{ +#ifdef CONFIG_MVEBU_SAR +/* Sample at reset register init */
mvebu_sar_init();
+#endif
Won't CONFIG_MVEBU_SAR always be enabled? Remove the #ifdef in this case.
return 0;
+}
Currently it is possible to turn it off. As I've said I think I do need to look at the whole SAR business and see if it can be done differently.
One useful thing it does do is tell me about how the hardware has been strapped. U-Boot itself doesn't care about that specifically as the separate mv_ddr blob that runs before ATF is the thing that actually uses the SAR values. But U- Boot is the first place that can give me some friendly output about the board and knowing the CPU/DDR clock speed is useful at that level.

On Thursday 22 September 2022 09:25:37 Chris Packham wrote:
On Wed, Sep 21, 2022 at 5:58 PM Stefan Roese sr@denx.de wrote:
On 21.09.22 06:59, Chris Packham wrote:
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
<snip>
diff --git a/arch/arm/mach-mvebu/alleycat5/soc.c b/arch/arm/mach-mvebu/alleycat5/soc.c new file mode 100644 index 0000000000..f388d4ee40 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.c
<snip>
+int soc_early_init_f(void) +{ +#ifdef CONFIG_MVEBU_SAR +/* Sample at reset register init */
mvebu_sar_init();
+#endif
Won't CONFIG_MVEBU_SAR always be enabled? Remove the #ifdef in this case.
return 0;
+}
Currently it is possible to turn it off. As I've said I think I do need to look at the whole SAR business and see if it can be done differently.
One useful thing it does do is tell me about how the hardware has been strapped. U-Boot itself doesn't care about that specifically as the separate mv_ddr blob that runs before ATF is the thing that actually uses the SAR values. But U- Boot is the first place that can give me some friendly output about the board and knowing the CPU/DDR clock speed is useful at that level.
I agree that the last thing - print information about CPU/DDR clock speed is useful [1]. But I do not see reason why to complicate it such much via new uclass OOP model for other things in DTS, which moreover use already deprecated structure and requires hack in fdtdec.c file.
I think that the whole SAR code can be simplified and written straightforward for AC5 to be easier for developer to read... but this step is not probably such simple as it is required to first understand what is this "complicated" code doing and it is probably boring job :-(
For 32-bit Armada there is already very simple SAR register handling to check and detect TCLK speed. So I think AC5 is similar in this area, but more has more complicated code logic and "very simple 32-bit SAR" is not suitable to reuse.
[1] - Btw, I added this print in A3720 secure firmware, because it is really useful and important (!) and secure firmware is who configures it

On Thu, Sep 22, 2022 at 9:40 AM Pali Rohár pali@kernel.org wrote:
On Thursday 22 September 2022 09:25:37 Chris Packham wrote:
On Wed, Sep 21, 2022 at 5:58 PM Stefan Roese sr@denx.de wrote:
On 21.09.22 06:59, Chris Packham wrote:
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
<snip>
diff --git a/arch/arm/mach-mvebu/alleycat5/soc.c b/arch/arm/mach-mvebu/alleycat5/soc.c new file mode 100644 index 0000000000..f388d4ee40 --- /dev/null +++ b/arch/arm/mach-mvebu/alleycat5/soc.c
<snip>
+int soc_early_init_f(void) +{ +#ifdef CONFIG_MVEBU_SAR +/* Sample at reset register init */
mvebu_sar_init();
+#endif
Won't CONFIG_MVEBU_SAR always be enabled? Remove the #ifdef in this case.
return 0;
+}
Currently it is possible to turn it off. As I've said I think I do need to look at the whole SAR business and see if it can be done differently.
One useful thing it does do is tell me about how the hardware has been strapped. U-Boot itself doesn't care about that specifically as the separate mv_ddr blob that runs before ATF is the thing that actually uses the SAR values. But U- Boot is the first place that can give me some friendly output about the board and knowing the CPU/DDR clock speed is useful at that level.
I agree that the last thing - print information about CPU/DDR clock speed is useful [1]. But I do not see reason why to complicate it such much via new uclass OOP model for other things in DTS, which moreover use already deprecated structure and requires hack in fdtdec.c file.
Agreed. The fact that I can turn the driver off and (after fixing some code that calls into it directly) everything still works (except for the reporting of the clock speeds) it does indicate that I don't really need this.
I think that the whole SAR code can be simplified and written straightforward for AC5 to be easier for developer to read... but this step is not probably such simple as it is required to first understand what is this "complicated" code doing and it is probably boring job :-(
Not boring but it doesn't help that Marvell don't document the SAR registers so I can only go by following their overly complicated code.
For 32-bit Armada there is already very simple SAR register handling to check and detect TCLK speed. So I think AC5 is similar in this area, but more has more complicated code logic and "very simple 32-bit SAR" is not suitable to reuse.
I think I can come up with something that replaces the sar-uclass business with code that just accesses the relevant register(s) directly in the alleycat5/soc.c code.
[1] - Btw, I added this print in A3720 secure firmware, because it is really useful and important (!) and secure firmware is who configures it

On Thursday 22 September 2022 09:55:24 Chris Packham wrote:
Not boring but it doesn't help that Marvell don't document the SAR registers so I can only go by following their overly complicated code.
Ah :-( This is never ending story with Marvell... nobody is able to gain access to the documentation. And developers than has to just guess what it could mean...

The RD-AC5X-32G16HVG6HLG-A0 development board main components and features include: * Main 12V/54V power supply * 270 Gbps throughput packet processor on the main board * DDR4: * SR1: 2GB DDR4 2400MT/S(1GB x 2 pcs ) with ECC(1GB x 1 pcs) * SR2: 4GB DDR4 2400MT/S(2GB x 2 pcs ) with ECC(2GB x 1 pcs) * PCB co-layout with 4GB device to support 8GB (Dual CS) requirement * 16GB eMMC (Samsung KLMAG1JETD-B041006) * 16MB SPI NOR(GD25Q127C) * 32 x 1000 Base-T interfaces * 16 x 2500 Base-T interfaces * SR1: 88E2540*4 * SR2: 88E2580*1+88E2540*2 * Six (6) x 25G Base-R SFP28 interfaces * One (1) x RJ-45 console connector, interfacing to the on board UART * One (1) x USB Type-A connector, interfacing to the USB 2.0 port (0) * One (1) x USB Type-mini B connector, interfacing to the USB 2.0 port (1) * One (1) x RJ-45 1G Base-T Management port, interfacing to the host port (shared with PCIe) Connected to 88E1512 Gigabit Ethernet Phy * One (1) x Oculink port, interfacing to the PCIe port for external CPU connection * POE 802.3AT support on Port 1 ~ Port 32, 802.3BT support on Port 33 ~ Port 48 (Microsemi PD69208T4, PD69208M or TI TPS2388,TPS23881 solution) * POE total power budget 780W * LED interfaces per network port/POE * LED interfaces (common) showing system status * PTP TC mode Supported (Reserved M.2 connector to support BC mode)
Signed-off-by: Chris Packham judge.packham@gmail.com ---
Changes in v3: - Remove MMC and UBIFS distroboot options (MMC driver is not currently functional, NAND is not populated on the RD-AC5X board) - Remove unnecessary Ethernet configuration - Remove unnecessary NAND configuration - Remove memory node from dts so the value passed by the DDR FW will be used
Changes in v2: - Use distro boot by default - remove unnecessary SPI-NOR partitions
arch/arm/dts/Makefile | 3 +- arch/arm/dts/ac5-98dx35xx-rd.dts | 135 +++++++++++++++++++++ arch/arm/mach-mvebu/Kconfig | 9 +- board/Marvell/mvebu_alleycat-5/MAINTAINERS | 6 + board/Marvell/mvebu_alleycat-5/Makefile | 3 + board/Marvell/mvebu_alleycat-5/board.c | 35 ++++++ configs/mvebu_ac5_rd_defconfig | 88 ++++++++++++++ include/configs/mvebu_alleycat-5.h | 57 +++++++++ 8 files changed, 334 insertions(+), 2 deletions(-) create mode 100644 arch/arm/dts/ac5-98dx35xx-rd.dts create mode 100644 board/Marvell/mvebu_alleycat-5/MAINTAINERS create mode 100644 board/Marvell/mvebu_alleycat-5/Makefile create mode 100644 board/Marvell/mvebu_alleycat-5/board.c create mode 100644 configs/mvebu_ac5_rd_defconfig create mode 100644 include/configs/mvebu_alleycat-5.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 965895bc2a..57a5272884 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -274,7 +274,8 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ cn9132-db-A.dtb \ cn9132-db-B.dtb \ cn9130-crb-A.dtb \ - cn9130-crb-B.dtb + cn9130-crb-B.dtb \ + ac5-98dx35xx-rd.dtb endif
dtb-$(CONFIG_ARCH_SYNQUACER) += synquacer-sc2a11-developerbox.dtb diff --git a/arch/arm/dts/ac5-98dx35xx-rd.dts b/arch/arm/dts/ac5-98dx35xx-rd.dts new file mode 100644 index 0000000000..7f1c8a5e22 --- /dev/null +++ b/arch/arm/dts/ac5-98dx35xx-rd.dts @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree For RD-AC5X. + * + * Copyright (C) 2021 Marvell + * Copyright (C) 2022 Allied Telesis Labs + */ +/* + * Device Tree file for Marvell Alleycat 5X development board + * This board file supports the B configuration of the board + */ + +/dts-v1/; + +#include "ac5-98dx35xx.dtsi" + +/ { + model = "Marvell RD-AC5X Board"; + compatible = "marvell,rd-ac5x", "marvell,ac5x", "marvell,ac5"; + + aliases { + serial0 = &uart0; + spiflash0 = &spiflash0; + gpio0 = &gpio0; + gpio1 = &gpio1; + ethernet0 = ð0; + ethernet1 = ð1; + spi0 = &spi0; + i2c0 = &i2c0; + i2c1 = &i2c1; + usb0 = &usb0; + usb1 = &usb1; + pinctrl0 = &pinctrl0; + sar-reg0 = "/config-space/sar-reg"; + }; + + usb1phy: usb-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + config-space { + sar-reg { + reg = <0x944F8204 0x1>; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +ð0 { + status = "okay"; + phy-handle = <&phy0>; +}; + +/* USB0 is a host USB */ +&usb0 { + status = "okay"; +}; + +/* USB1 is a peripheral USB */ +&usb1 { + status = "okay"; + phys = <&usb1phy>; + phy-names = "usb-phy"; + dr_mode = "peripheral"; +}; + +&spi0 { + status = "okay"; + + spiflash0: flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; /* 1-single, 2-dual, 4-quad */ + spi-rx-bus-width = <1>; /* 1-single, 2-dual, 4-quad */ + reg = <0>; + + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +&pinctrl0 { + /* + * MPP Bus: MPP# mode# + * eMMC [0-11] 0x1 + * SPI[0] [12-17] 0x1 + * TSEN_INT [18] 0x1 + * DEV_INIT [19] 0x1 + * SPI[1] [20-23] 0x3 + * UART[1] [24-25] 0x3 + * I2C[0] [26-27] 0x1 + * XSMI[0] [28-29] 0x1 // SCH use SMI[0], reversed due to CPSS problem + * SMI[1] [30-31] 0x2 // SCH use XSMI[1], reversed due to CPSS problem + * UART[0] [32-33] 0x1 + * OOB_SMI [34-35] 0x1 + * PTP_CLK0_OUT [36] 0x1 + * PTP_PULSE_OUT [37] 0x1 + * RCVR_CLK_OUT [38] 0x1 + * GPIO(in/out) [39] 0x0 + * GPIO(in/out) [40] 0x0 + * PTP_REF_CLK [41] 0x1 + * PTP_CLK0 [42] 0x1 + * LED0_CLK [43] 0x1 + * LED0_STB [44] 0x1 + * LED0_DATA [45] 0x1 + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 3 3 3 3 3 3 1 1 1 1 + 2 2 1 1 1 1 1 1 1 0 + 0 1 1 1 1 1 >; +}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 45efa24194..2120cb473f 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -97,7 +97,7 @@ config CUSTOMER_BOARD_SUPPORT bool
choice - prompt "Armada XP/375/38x/3700/7K/8K board select" + prompt "Armada XP/375/38x/3700/7K/8K/Alleycat-5 board select" optional
config TARGET_CLEARFOG @@ -149,6 +149,10 @@ config TARGET_MVEBU_ARMADA_8K select BOARD_LATE_INIT imply SCSI
+config TARGET_MVEBU_ALLEYCAT5 + bool "Support AlleyCat 5 platforms" + select ALLEYCAT_5 + config TARGET_OCTEONTX2_CN913x bool "Support CN913x platforms" select ARMADA_8K @@ -257,6 +261,7 @@ config SYS_BOARD default "x530" if TARGET_X530 default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236 + default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
config SYS_CONFIG_NAME default "clearfog" if TARGET_CLEARFOG @@ -277,6 +282,7 @@ config SYS_CONFIG_NAME default "x530" if TARGET_X530 default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236 + default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
config SYS_VENDOR default "Marvell" if TARGET_DB_MV784MP_GP @@ -296,6 +302,7 @@ config SYS_VENDOR default "gdsys" if TARGET_CONTROLCENTERDC default "alliedtelesis" if TARGET_X530 default "mikrotik" if TARGET_CRS3XX_98DX3236 + default "Marvell" if TARGET_MVEBU_ALLEYCAT5
config SYS_SOC default "mvebu" diff --git a/board/Marvell/mvebu_alleycat-5/MAINTAINERS b/board/Marvell/mvebu_alleycat-5/MAINTAINERS new file mode 100644 index 0000000000..480c07c5f0 --- /dev/null +++ b/board/Marvell/mvebu_alleycat-5/MAINTAINERS @@ -0,0 +1,6 @@ +RD-AC5X BOARD +M: Chris Packham chris.packham@alliedtelesis.co.nz +S: Maintained +F: board/Marvell/mvebu_alleycat-5/ +F: include/configs/mvebu_alleycat-5.h +F: configs/mvebu_ac5_rd_defconfig diff --git a/board/Marvell/mvebu_alleycat-5/Makefile b/board/Marvell/mvebu_alleycat-5/Makefile new file mode 100644 index 0000000000..29254b4d64 --- /dev/null +++ b/board/Marvell/mvebu_alleycat-5/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := board.o diff --git a/board/Marvell/mvebu_alleycat-5/board.c b/board/Marvell/mvebu_alleycat-5/board.c new file mode 100644 index 0000000000..3303d3c2c9 --- /dev/null +++ b/board/Marvell/mvebu_alleycat-5/board.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <common.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +__weak int soc_early_init_f(void) +{ + return 0; +} + +int board_early_init_f(void) +{ + soc_early_init_f(); + + return 0; +} + +int board_early_init_r(void) +{ + return 0; +} + +int board_init(void) +{ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + return 0; +} + +int board_late_init(void) +{ + return 0; +} diff --git a/configs/mvebu_ac5_rd_defconfig b/configs/mvebu_ac5_rd_defconfig new file mode 100644 index 0000000000..b87d337e26 --- /dev/null +++ b/configs/mvebu_ac5_rd_defconfig @@ -0,0 +1,88 @@ +CONFIG_ARM=y +CONFIG_ARCH_CPU_INIT=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_TEXT_BASE=0x200000000 +CONFIG_SYS_MALLOC_LEN=0x900000 +CONFIG_TARGET_MVEBU_ALLEYCAT5=y +CONFIG_ENV_SIZE=0x10000 +CONFIG_ENV_OFFSET=0x400000 +CONFIG_ENV_SECT_SIZE=0x10000 +CONFIG_DM_GPIO=y +CONFIG_DEBUG_UART_BASE=0x7f012000 +CONFIG_DEBUG_UART_CLOCK=325000000 +CONFIG_SYS_LOAD_ADDR=0x202000000 +CONFIG_DEBUG_UART=y +CONFIG_SYS_MEMTEST_START=0x200800000 +CONFIG_SYS_MEMTEST_END=0x200ffffff +CONFIG_DISTRO_DEFAULTS=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x200FF0000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +CONFIG_BOOTDELAY=-1 +CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_ARCH_EARLY_INIT_R=y +CONFIG_ARCH_MISC_INIT=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_CMD_BOOTZ=y +CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10 +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_MVEBU_BUBT=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_UBI=y +CONFIG_MAC_PARTITION=y +CONFIG_OF_EMBED=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_CLK=y +CONFIG_CLK_MVEBU=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_MISC=y +CONFIG_MVEBU_SAR=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_XENON=y +CONFIG_MTD=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_PHY_MARVELL=y +CONFIG_PHY_GIGE=y +CONFIG_E1000=y +CONFIG_MVNETA=y +CONFIG_MVMDIO=y +CONFIG_PCI=y +CONFIG_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_ARMADA_8K=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_RTC=y +CONFIG_DM_SCSI=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_SYS_NS16550=y +CONFIG_MVEBU_A3700_SPI=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_ASIX88179=y +CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y diff --git a/include/configs/mvebu_alleycat-5.h b/include/configs/mvebu_alleycat-5.h new file mode 100644 index 0000000000..b3b33499e5 --- /dev/null +++ b/include/configs/mvebu_alleycat-5.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Marvell International Ltd + */ + +#ifndef _CONFIG_MVEBU_ALLEYCAY_5_H +#define _CONFIG_MVEBU_ALLEYCAY_5_H + +#include <asm/arch/soc.h> + +/* + * High Level Configuration Options (easy to change) + */ +#define CONFIG_DISPLAY_BOARDINFO_LATE + +/* additions for new ARM relocation support */ +#define CONFIG_SYS_SDRAM_BASE 0x200000000 + +/* auto boot */ +#define CONFIG_PREBOOT + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, \ + 115200, 230400, 460800, 921600 } + +/* Default Env vars */ +#define CONFIG_IPADDR 0.0.0.0 /* In order to cause an error */ +#define CONFIG_SERVERIP 0.0.0.0 /* In order to cause an error */ +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_GATEWAYIP 0.0.0.0 +#define CONFIG_ROOTPATH "/srv/nfs/" /* Default Dir for NFS */ +#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */ + +#define BOOT_TARGET_DEVICES(func) \ + func(USB, usb, 0) \ + func(DHCP, dhcp, na) + +#include <config_distro_bootcmd.h> + +#define CONFIG_EXTRA_ENV_SETTINGS \ + BOOTENV \ + "kernel_addr_r=0x202000000\0" \ + "fdt_addr_r=0x201000000\0" \ + "ramdisk_addr_r=0x206000000\0" \ + "fdtfile=marvell/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ + "console=console=ttyS0,115200 earlycon=uart8250,mmio32,0xf0512000\0"\ + +/* + * High Level Configuration Options (easy to change) + */ +#define CONFIG_SYS_TCLK 325000000 + +/* tbd #define CONFIG_BOARD_EARLY_INIT_R */ + +#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3) + +#endif /* _CONFIG_MVEBU_ALLEYCAY_5_H */

On 21.09.22 06:59, Chris Packham wrote:
The RD-AC5X-32G16HVG6HLG-A0 development board main components and features include:
- Main 12V/54V power supply
- 270 Gbps throughput packet processor on the main board
- DDR4:
- SR1: 2GB DDR4 2400MT/S(1GB x 2 pcs ) with ECC(1GB x 1 pcs)
- SR2: 4GB DDR4 2400MT/S(2GB x 2 pcs ) with ECC(2GB x 1 pcs)
- PCB co-layout with 4GB device to support 8GB (Dual CS) requirement
- 16GB eMMC (Samsung KLMAG1JETD-B041006)
- 16MB SPI NOR(GD25Q127C)
- 32 x 1000 Base-T interfaces
- 16 x 2500 Base-T interfaces
- SR1: 88E2540*4
- SR2: 88E2580*1+88E2540*2
- Six (6) x 25G Base-R SFP28 interfaces
- One (1) x RJ-45 console connector, interfacing to the on board UART
- One (1) x USB Type-A connector, interfacing to the USB 2.0 port (0)
- One (1) x USB Type-mini B connector, interfacing to the USB 2.0 port (1)
- One (1) x RJ-45 1G Base-T Management port, interfacing to the host port (shared with PCIe) Connected to 88E1512 Gigabit Ethernet Phy
- One (1) x Oculink port, interfacing to the PCIe port for external CPU connection
- POE 802.3AT support on Port 1 ~ Port 32, 802.3BT support on Port 33 ~ Port 48 (Microsemi PD69208T4, PD69208M or TI TPS2388,TPS23881 solution)
- POE total power budget 780W
- LED interfaces per network port/POE
- LED interfaces (common) showing system status
- PTP TC mode Supported (Reserved M.2 connector to support BC mode)
Signed-off-by: Chris Packham judge.packham@gmail.com
Changes in v3:
- Remove MMC and UBIFS distroboot options (MMC driver is not currently functional, NAND is not populated on the RD-AC5X board)
- Remove unnecessary Ethernet configuration
- Remove unnecessary NAND configuration
- Remove memory node from dts so the value passed by the DDR FW will be used
Changes in v2:
Use distro boot by default
remove unnecessary SPI-NOR partitions
arch/arm/dts/Makefile | 3 +- arch/arm/dts/ac5-98dx35xx-rd.dts | 135 +++++++++++++++++++++ arch/arm/mach-mvebu/Kconfig | 9 +- board/Marvell/mvebu_alleycat-5/MAINTAINERS | 6 + board/Marvell/mvebu_alleycat-5/Makefile | 3 + board/Marvell/mvebu_alleycat-5/board.c | 35 ++++++ configs/mvebu_ac5_rd_defconfig | 88 ++++++++++++++ include/configs/mvebu_alleycat-5.h | 57 +++++++++ 8 files changed, 334 insertions(+), 2 deletions(-) create mode 100644 arch/arm/dts/ac5-98dx35xx-rd.dts create mode 100644 board/Marvell/mvebu_alleycat-5/MAINTAINERS create mode 100644 board/Marvell/mvebu_alleycat-5/Makefile create mode 100644 board/Marvell/mvebu_alleycat-5/board.c create mode 100644 configs/mvebu_ac5_rd_defconfig create mode 100644 include/configs/mvebu_alleycat-5.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 965895bc2a..57a5272884 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -274,7 +274,8 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ cn9132-db-A.dtb \ cn9132-db-B.dtb \ cn9130-crb-A.dtb \
- cn9130-crb-B.dtb
cn9130-crb-B.dtb \
ac5-98dx35xx-rd.dtb endif
dtb-$(CONFIG_ARCH_SYNQUACER) += synquacer-sc2a11-developerbox.dtb
diff --git a/arch/arm/dts/ac5-98dx35xx-rd.dts b/arch/arm/dts/ac5-98dx35xx-rd.dts new file mode 100644 index 0000000000..7f1c8a5e22 --- /dev/null +++ b/arch/arm/dts/ac5-98dx35xx-rd.dts @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/*
- Device Tree For RD-AC5X.
- Copyright (C) 2021 Marvell
- Copyright (C) 2022 Allied Telesis Labs
- */
+/*
- Device Tree file for Marvell Alleycat 5X development board
- This board file supports the B configuration of the board
- */
+/dts-v1/;
+#include "ac5-98dx35xx.dtsi"
+/ {
- model = "Marvell RD-AC5X Board";
- compatible = "marvell,rd-ac5x", "marvell,ac5x", "marvell,ac5";
- aliases {
serial0 = &uart0;
spiflash0 = &spiflash0;
gpio0 = &gpio0;
gpio1 = &gpio1;
ethernet0 = ð0;
ethernet1 = ð1;
spi0 = &spi0;
i2c0 = &i2c0;
i2c1 = &i2c1;
usb0 = &usb0;
usb1 = &usb1;
pinctrl0 = &pinctrl0;
sar-reg0 = "/config-space/sar-reg";
- };
- usb1phy: usb-phy {
compatible = "usb-nop-xceiv";
#phy-cells = <0>;
- };
- chosen {
stdout-path = "serial0:115200n8";
- };
- config-space {
sar-reg {
reg = <0x944F8204 0x1>;
};
- };
+};
+&uart0 {
- status = "okay";
+};
+&mdio {
- phy0: ethernet-phy@0 {
reg = <0>;
- };
+};
+&i2c0 {
- status = "okay";
+};
+&i2c1 {
- status = "okay";
+};
+ð0 {
- status = "okay";
- phy-handle = <&phy0>;
+};
+/* USB0 is a host USB */ +&usb0 {
- status = "okay";
+};
+/* USB1 is a peripheral USB */ +&usb1 {
- status = "okay";
- phys = <&usb1phy>;
- phy-names = "usb-phy";
- dr_mode = "peripheral";
+};
+&spi0 {
- status = "okay";
- spiflash0: flash@0 {
compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>; /* 1-single, 2-dual, 4-quad */
spi-rx-bus-width = <1>; /* 1-single, 2-dual, 4-quad */
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
- };
+};
+&pinctrl0 {
- /*
* MPP Bus: MPP# mode#
* eMMC [0-11] 0x1
* SPI[0] [12-17] 0x1
* TSEN_INT [18] 0x1
* DEV_INIT [19] 0x1
* SPI[1] [20-23] 0x3
* UART[1] [24-25] 0x3
* I2C[0] [26-27] 0x1
* XSMI[0] [28-29] 0x1 // SCH use SMI[0], reversed due to CPSS problem
* SMI[1] [30-31] 0x2 // SCH use XSMI[1], reversed due to CPSS problem
* UART[0] [32-33] 0x1
* OOB_SMI [34-35] 0x1
* PTP_CLK0_OUT [36] 0x1
* PTP_PULSE_OUT [37] 0x1
* RCVR_CLK_OUT [38] 0x1
* GPIO(in/out) [39] 0x0
* GPIO(in/out) [40] 0x0
* PTP_REF_CLK [41] 0x1
* PTP_CLK0 [42] 0x1
* LED0_CLK [43] 0x1
* LED0_STB [44] 0x1
* LED0_DATA [45] 0x1
*/
- /* 0 1 2 3 4 5 6 7 8 9 */
- pin-func = < 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
3 3 3 3 3 3 1 1 1 1
2 2 1 1 1 1 1 1 1 0
0 1 1 1 1 1 >;
+}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 45efa24194..2120cb473f 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -97,7 +97,7 @@ config CUSTOMER_BOARD_SUPPORT bool
choice
- prompt "Armada XP/375/38x/3700/7K/8K board select"
prompt "Armada XP/375/38x/3700/7K/8K/Alleycat-5 board select" optional
config TARGET_CLEARFOG
@@ -149,6 +149,10 @@ config TARGET_MVEBU_ARMADA_8K select BOARD_LATE_INIT imply SCSI
+config TARGET_MVEBU_ALLEYCAT5
- bool "Support AlleyCat 5 platforms"
- select ALLEYCAT_5
- config TARGET_OCTEONTX2_CN913x bool "Support CN913x platforms" select ARMADA_8K
@@ -257,6 +261,7 @@ config SYS_BOARD default "x530" if TARGET_X530 default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236
default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
config SYS_CONFIG_NAME default "clearfog" if TARGET_CLEARFOG
@@ -277,6 +282,7 @@ config SYS_CONFIG_NAME default "x530" if TARGET_X530 default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236
default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
config SYS_VENDOR default "Marvell" if TARGET_DB_MV784MP_GP
@@ -296,6 +302,7 @@ config SYS_VENDOR default "gdsys" if TARGET_CONTROLCENTERDC default "alliedtelesis" if TARGET_X530 default "mikrotik" if TARGET_CRS3XX_98DX3236
default "Marvell" if TARGET_MVEBU_ALLEYCAT5
config SYS_SOC default "mvebu"
diff --git a/board/Marvell/mvebu_alleycat-5/MAINTAINERS b/board/Marvell/mvebu_alleycat-5/MAINTAINERS new file mode 100644 index 0000000000..480c07c5f0 --- /dev/null +++ b/board/Marvell/mvebu_alleycat-5/MAINTAINERS @@ -0,0 +1,6 @@ +RD-AC5X BOARD +M: Chris Packham chris.packham@alliedtelesis.co.nz +S: Maintained +F: board/Marvell/mvebu_alleycat-5/ +F: include/configs/mvebu_alleycat-5.h +F: configs/mvebu_ac5_rd_defconfig diff --git a/board/Marvell/mvebu_alleycat-5/Makefile b/board/Marvell/mvebu_alleycat-5/Makefile new file mode 100644 index 0000000000..29254b4d64 --- /dev/null +++ b/board/Marvell/mvebu_alleycat-5/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+
+obj-y := board.o diff --git a/board/Marvell/mvebu_alleycat-5/board.c b/board/Marvell/mvebu_alleycat-5/board.c new file mode 100644 index 0000000000..3303d3c2c9 --- /dev/null +++ b/board/Marvell/mvebu_alleycat-5/board.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+
+#include <common.h> +#include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR;
+__weak int soc_early_init_f(void) +{
- return 0;
+}
+int board_early_init_f(void) +{
- soc_early_init_f();
- return 0;
+}
Why not remove this code and disable CONFIG_BOARD_EARLY_INIT_F?
+int board_early_init_r(void) +{
- return 0;
+}
Again, just disable CONFIG_BOARD_EARLY_INIT_R instead and remove this empty function.
+int board_init(void) +{
- gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
- return 0;
+}
+int board_late_init(void) +{
- return 0;
+}
Remove CONFIG_BOARD_LATE_INIT?
diff --git a/configs/mvebu_ac5_rd_defconfig b/configs/mvebu_ac5_rd_defconfig new file mode 100644 index 0000000000..b87d337e26 --- /dev/null +++ b/configs/mvebu_ac5_rd_defconfig @@ -0,0 +1,88 @@ +CONFIG_ARM=y +CONFIG_ARCH_CPU_INIT=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_TEXT_BASE=0x200000000 +CONFIG_SYS_MALLOC_LEN=0x900000 +CONFIG_TARGET_MVEBU_ALLEYCAT5=y +CONFIG_ENV_SIZE=0x10000 +CONFIG_ENV_OFFSET=0x400000 +CONFIG_ENV_SECT_SIZE=0x10000 +CONFIG_DM_GPIO=y +CONFIG_DEBUG_UART_BASE=0x7f012000 +CONFIG_DEBUG_UART_CLOCK=325000000 +CONFIG_SYS_LOAD_ADDR=0x202000000 +CONFIG_DEBUG_UART=y
Do you want to have the DEBUG_UART enabled in the official defconfig?
+CONFIG_SYS_MEMTEST_START=0x200800000 +CONFIG_SYS_MEMTEST_END=0x200ffffff +CONFIG_DISTRO_DEFAULTS=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x200FF0000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +CONFIG_BOOTDELAY=-1 +CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_ARCH_EARLY_INIT_R=y +CONFIG_ARCH_MISC_INIT=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_CMD_BOOTZ=y +CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10 +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_MVEBU_BUBT=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_UBI=y +CONFIG_MAC_PARTITION=y +CONFIG_OF_EMBED=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_CLK=y +CONFIG_CLK_MVEBU=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_MISC=y +CONFIG_MVEBU_SAR=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_XENON=y +CONFIG_MTD=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_PHY_MARVELL=y +CONFIG_PHY_GIGE=y +CONFIG_E1000=y +CONFIG_MVNETA=y +CONFIG_MVMDIO=y +CONFIG_PCI=y +CONFIG_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_ARMADA_8K=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_RTC=y +CONFIG_DM_SCSI=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_SYS_NS16550=y +CONFIG_MVEBU_A3700_SPI=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_ASIX88179=y +CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y diff --git a/include/configs/mvebu_alleycat-5.h b/include/configs/mvebu_alleycat-5.h new file mode 100644 index 0000000000..b3b33499e5 --- /dev/null +++ b/include/configs/mvebu_alleycat-5.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2018 Marvell International Ltd
- */
+#ifndef _CONFIG_MVEBU_ALLEYCAY_5_H +#define _CONFIG_MVEBU_ALLEYCAY_5_H
+#include <asm/arch/soc.h>
+/*
- High Level Configuration Options (easy to change)
- */
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+/* additions for new ARM relocation support */ +#define CONFIG_SYS_SDRAM_BASE 0x200000000
+/* auto boot */ +#define CONFIG_PREBOOT
This is moved to Kconfig now: CONFIG_USE_PREBOOT.
+#define CONFIG_BAUDRATE 115200
Also moved to Kconfig.
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, \
115200, 230400, 460800, 921600 }
+/* Default Env vars */ +#define CONFIG_IPADDR 0.0.0.0 /* In order to cause an error */ +#define CONFIG_SERVERIP 0.0.0.0 /* In order to cause an error */ +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_GATEWAYIP 0.0.0.0 +#define CONFIG_ROOTPATH "/srv/nfs/" /* Default Dir for NFS */ +#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */
Moved to Kconfig.
+#define BOOT_TARGET_DEVICES(func) \
- func(USB, usb, 0) \
- func(DHCP, dhcp, na)
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
- BOOTENV \
- "kernel_addr_r=0x202000000\0" \
- "fdt_addr_r=0x201000000\0" \
- "ramdisk_addr_r=0x206000000\0" \
- "fdtfile=marvell/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
- "console=console=ttyS0,115200 earlycon=uart8250,mmio32,0xf0512000\0"\
+/*
- High Level Configuration Options (easy to change)
- */
+#define CONFIG_SYS_TCLK 325000000
+/* tbd #define CONFIG_BOARD_EARLY_INIT_R */
Remove.
+#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3)
Kconfig now. Please double check all the other defines here as well.
Thanks, Stefan

On Wednesday 21 September 2022 16:59:41 Chris Packham wrote:
diff --git a/arch/arm/dts/ac5-98dx35xx-rd.dts b/arch/arm/dts/ac5-98dx35xx-rd.dts
...
+/ {
- model = "Marvell RD-AC5X Board";
- compatible = "marvell,rd-ac5x", "marvell,ac5x", "marvell,ac5";
- aliases {
serial0 = &uart0;
...
- };
...
- chosen {
stdout-path = "serial0:115200n8";
- };
...
diff --git a/include/configs/mvebu_alleycat-5.h b/include/configs/mvebu_alleycat-5.h
...
+#define CONFIG_EXTRA_ENV_SETTINGS \
...
- "console=console=ttyS0,115200 earlycon=uart8250,mmio32,0xf0512000\0"\
Hello! Is not this console=console= line suspicious?
And also because default console device is selected by /chosen/stdout-path DT property and earlycon address is also parsed from DTS, I have feeling that specifying it on cmdline is just duplication of DTS.
Try to boot your arm64 kernel with just "earlycon" string without specifying uart8250,mmio32... I think that it should work fine.
I think that main issue here is that people just choose one board or config file, copy it and simple modify it and letting all those historic relict not needed in u-boot anymore. And due to this copy+paste stuff nobody knows what is needed, what not and nobody knows answer to important question "why it is there?".
But I understand it. The best for developer is to take something which works and do just simple modification for specific board to achieve functionality. Doing more modification or trying to understand if there is not unnecessary code consume lot of time which people do not have...
(nothing wrong; just I'm reading code and trying to understand it what it is doing or why it is there... and detect possible dead code patterns :-))

On Thu, Sep 22, 2022 at 9:55 AM Pali Rohár pali@kernel.org wrote:
On Wednesday 21 September 2022 16:59:41 Chris Packham wrote:
diff --git a/arch/arm/dts/ac5-98dx35xx-rd.dts b/arch/arm/dts/ac5-98dx35xx-rd.dts
...
+/ {
model = "Marvell RD-AC5X Board";
compatible = "marvell,rd-ac5x", "marvell,ac5x", "marvell,ac5";
aliases {
serial0 = &uart0;
...
};
...
chosen {
stdout-path = "serial0:115200n8";
};
...
diff --git a/include/configs/mvebu_alleycat-5.h b/include/configs/mvebu_alleycat-5.h
...
+#define CONFIG_EXTRA_ENV_SETTINGS \
...
"console=console=ttyS0,115200 earlycon=uart8250,mmio32,0xf0512000\0"\
Hello! Is not this console=console= line suspicious?
And also because default console device is selected by /chosen/stdout-path DT property and earlycon address is also parsed from DTS, I have feeling that specifying it on cmdline is just duplication of DTS.
Try to boot your arm64 kernel with just "earlycon" string without specifying uart8250,mmio32... I think that it should work fine.
Yeah I think this is a relic. The original code had all kinds of magic for manipulating bootargs that involved pulling in the console from the environment. I think it can go as the default should come from the DTS. Anything else is up to the user to configure bootargs appropriately.
I think that main issue here is that people just choose one board or config file, copy it and simple modify it and letting all those historic relict not needed in u-boot anymore. And due to this copy+paste stuff nobody knows what is needed, what not and nobody knows answer to important question "why it is there?".
But I understand it. The best for developer is to take something which works and do just simple modification for specific board to achieve functionality. Doing more modification or trying to understand if there is not unnecessary code consume lot of time which people do not have...
(nothing wrong; just I'm reading code and trying to understand it what it is doing or why it is there... and detect possible dead code patterns :-))
I think you're right to point it out. I encounter the same thing all the time at $dayjob and try to push back against the blind copy-pasting so I should really know better (there is an amount of rebase fatigue from porting the old code).
participants (4)
-
Chris Packham
-
Pali Rohár
-
Ramon Fried
-
Stefan Roese